~ubuntu-branches/ubuntu/maverick/dolfin/maverick

« back to all changes in this revision

Viewing changes to demo/pde/cahn-hilliard/cpp/CahnHilliard2D.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Johannes Ring
  • Date: 2009-10-12 14:13:18 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20091012141318-hkbxl0sq555vqv7d
Tags: 0.9.4-1
* New upstream release. This version cleans up the design of the
  function class by adding a new abstraction for user-defined
  functions called Expression. A number of minor bugfixes and
  improvements have also been made.
* debian/watch: Update for new flat directory structure.
* Update debian/copyright.
* debian/rules: Use explicit paths to PETSc 3.0.0 and SLEPc 3.0.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#include "CahnHilliard2D.h"
2
 
/// Constructor
3
 
UFC_CahnHilliard2DBilinearForm_finite_element_0_0::UFC_CahnHilliard2DBilinearForm_finite_element_0_0() : ufc::finite_element()
4
 
{
5
 
    // Do nothing
6
 
}
7
 
 
8
 
/// Destructor
9
 
UFC_CahnHilliard2DBilinearForm_finite_element_0_0::~UFC_CahnHilliard2DBilinearForm_finite_element_0_0()
10
 
{
11
 
    // Do nothing
12
 
}
13
 
 
14
 
/// Return a string identifying the finite element
15
 
const char* UFC_CahnHilliard2DBilinearForm_finite_element_0_0::signature() const
16
 
{
17
 
    return "FiniteElement('Lagrange', 'triangle', 1)";
18
 
}
19
 
 
20
 
/// Return the cell shape
21
 
ufc::shape UFC_CahnHilliard2DBilinearForm_finite_element_0_0::cell_shape() const
22
 
{
23
 
    return ufc::triangle;
24
 
}
25
 
 
26
 
/// Return the dimension of the finite element function space
27
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_0_0::space_dimension() const
28
 
{
29
 
    return 3;
30
 
}
31
 
 
32
 
/// Return the rank of the value space
33
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_0_0::value_rank() const
34
 
{
35
 
    return 0;
36
 
}
37
 
 
38
 
/// Return the dimension of the value space for axis i
39
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_0_0::value_dimension(unsigned int i) const
40
 
{
41
 
    return 1;
42
 
}
43
 
 
44
 
/// Evaluate basis function i at given point in cell
45
 
void UFC_CahnHilliard2DBilinearForm_finite_element_0_0::evaluate_basis(unsigned int i,
46
 
                                   double* values,
47
 
                                   const double* coordinates,
48
 
                                   const ufc::cell& c) const
49
 
{
50
 
    // Extract vertex coordinates
51
 
    const double * const * element_coordinates = c.coordinates;
52
 
    
53
 
    // Compute Jacobian of affine map from reference cell
54
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
55
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
56
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
57
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
58
 
      
59
 
    // Compute determinant of Jacobian
60
 
    const double detJ = J_00*J_11 - J_01*J_10;
61
 
    
62
 
    // Compute inverse of Jacobian
63
 
    
64
 
    // Get coordinates and map to the reference (UFC) element
65
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
66
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
67
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
68
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
69
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
70
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
71
 
    
72
 
    // Map coordinates to the reference square
73
 
    if (std::abs(y - 1.0) < 1e-14)
74
 
      x = -1.0;
75
 
    else
76
 
      x = 2.0 *x/(1.0 - y) - 1.0;
77
 
    y = 2.0*y - 1.0;
78
 
    
79
 
    // Reset values
80
 
    *values = 0;
81
 
    
82
 
    // Map degree of freedom to element degree of freedom
83
 
    const unsigned int dof = i;
84
 
    
85
 
    // Generate scalings
86
 
    const double scalings_y_0 = 1;
87
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
88
 
    
89
 
    // Compute psitilde_a
90
 
    const double psitilde_a_0 = 1;
91
 
    const double psitilde_a_1 = x;
92
 
    
93
 
    // Compute psitilde_bs
94
 
    const double psitilde_bs_0_0 = 1;
95
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
96
 
    const double psitilde_bs_1_0 = 1;
97
 
    
98
 
    // Compute basisvalues
99
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
100
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
101
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
102
 
    
103
 
    // Table(s) of coefficients
104
 
    const static double coefficients0[3][3] = \
105
 
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
106
 
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
107
 
    {0.471404520791032, 0, 0.333333333333333}};
108
 
    
109
 
    // Extract relevant coefficients
110
 
    const double coeff0_0 = coefficients0[dof][0];
111
 
    const double coeff0_1 = coefficients0[dof][1];
112
 
    const double coeff0_2 = coefficients0[dof][2];
113
 
    
114
 
    // Compute value(s)
115
 
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
116
 
}
117
 
 
118
 
/// Evaluate all basis functions at given point in cell
119
 
void UFC_CahnHilliard2DBilinearForm_finite_element_0_0::evaluate_basis_all(double* values,
120
 
                                       const double* coordinates,
121
 
                                       const ufc::cell& c) const
122
 
{
123
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
124
 
}
125
 
 
126
 
/// Evaluate order n derivatives of basis function i at given point in cell
127
 
void UFC_CahnHilliard2DBilinearForm_finite_element_0_0::evaluate_basis_derivatives(unsigned int i,
128
 
                                               unsigned int n,
129
 
                                               double* values,
130
 
                                               const double* coordinates,
131
 
                                               const ufc::cell& c) const
132
 
{
133
 
    // Extract vertex coordinates
134
 
    const double * const * element_coordinates = c.coordinates;
135
 
    
136
 
    // Compute Jacobian of affine map from reference cell
137
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
138
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
139
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
140
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
141
 
      
142
 
    // Compute determinant of Jacobian
143
 
    const double detJ = J_00*J_11 - J_01*J_10;
144
 
    
145
 
    // Compute inverse of Jacobian
146
 
    
147
 
    // Get coordinates and map to the reference (UFC) element
148
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
149
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
150
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
151
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
152
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
153
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
154
 
    
155
 
    // Map coordinates to the reference square
156
 
    if (std::abs(y - 1.0) < 1e-14)
157
 
      x = -1.0;
158
 
    else
159
 
      x = 2.0 *x/(1.0 - y) - 1.0;
160
 
    y = 2.0*y - 1.0;
161
 
    
162
 
    // Compute number of derivatives
163
 
    unsigned int num_derivatives = 1;
164
 
    
165
 
    for (unsigned int j = 0; j < n; j++)
166
 
      num_derivatives *= 2;
167
 
    
168
 
    
169
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
170
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
171
 
        
172
 
    for (unsigned int j = 0; j < num_derivatives; j++)
173
 
    {
174
 
      combinations[j] = new unsigned int [n];
175
 
      for (unsigned int k = 0; k < n; k++)
176
 
        combinations[j][k] = 0;
177
 
    }
178
 
        
179
 
    // Generate combinations of derivatives
180
 
    for (unsigned int row = 1; row < num_derivatives; row++)
181
 
    {
182
 
      for (unsigned int num = 0; num < row; num++)
183
 
      {
184
 
        for (unsigned int col = n-1; col+1 > 0; col--)
185
 
        {
186
 
          if (combinations[row][col] + 1 > 1)
187
 
            combinations[row][col] = 0;
188
 
          else
189
 
          {
190
 
            combinations[row][col] += 1;
191
 
            break;
192
 
          }
193
 
        }
194
 
      }
195
 
    }
196
 
    
197
 
    // Compute inverse of Jacobian
198
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
199
 
    
200
 
    // Declare transformation matrix
201
 
    // Declare pointer to two dimensional array and initialise
202
 
    double **transform = new double *[num_derivatives];
203
 
        
204
 
    for (unsigned int j = 0; j < num_derivatives; j++)
205
 
    {
206
 
      transform[j] = new double [num_derivatives];
207
 
      for (unsigned int k = 0; k < num_derivatives; k++)
208
 
        transform[j][k] = 1;
209
 
    }
210
 
    
211
 
    // Construct transformation matrix
212
 
    for (unsigned int row = 0; row < num_derivatives; row++)
213
 
    {
214
 
      for (unsigned int col = 0; col < num_derivatives; col++)
215
 
      {
216
 
        for (unsigned int k = 0; k < n; k++)
217
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
218
 
      }
219
 
    }
220
 
    
221
 
    // Reset values
222
 
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
223
 
      values[j] = 0;
224
 
    
225
 
    // Map degree of freedom to element degree of freedom
226
 
    const unsigned int dof = i;
227
 
    
228
 
    // Generate scalings
229
 
    const double scalings_y_0 = 1;
230
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
231
 
    
232
 
    // Compute psitilde_a
233
 
    const double psitilde_a_0 = 1;
234
 
    const double psitilde_a_1 = x;
235
 
    
236
 
    // Compute psitilde_bs
237
 
    const double psitilde_bs_0_0 = 1;
238
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
239
 
    const double psitilde_bs_1_0 = 1;
240
 
    
241
 
    // Compute basisvalues
242
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
243
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
244
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
245
 
    
246
 
    // Table(s) of coefficients
247
 
    const static double coefficients0[3][3] = \
248
 
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
249
 
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
250
 
    {0.471404520791032, 0, 0.333333333333333}};
251
 
    
252
 
    // Interesting (new) part
253
 
    // Tables of derivatives of the polynomial base (transpose)
254
 
    const static double dmats0[3][3] = \
255
 
    {{0, 0, 0},
256
 
    {4.89897948556636, 0, 0},
257
 
    {0, 0, 0}};
258
 
    
259
 
    const static double dmats1[3][3] = \
260
 
    {{0, 0, 0},
261
 
    {2.44948974278318, 0, 0},
262
 
    {4.24264068711928, 0, 0}};
263
 
    
264
 
    // Compute reference derivatives
265
 
    // Declare pointer to array of derivatives on FIAT element
266
 
    double *derivatives = new double [num_derivatives];
267
 
    
268
 
    // Declare coefficients
269
 
    double coeff0_0 = 0;
270
 
    double coeff0_1 = 0;
271
 
    double coeff0_2 = 0;
272
 
    
273
 
    // Declare new coefficients
274
 
    double new_coeff0_0 = 0;
275
 
    double new_coeff0_1 = 0;
276
 
    double new_coeff0_2 = 0;
277
 
    
278
 
    // Loop possible derivatives
279
 
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
280
 
    {
281
 
      // Get values from coefficients array
282
 
      new_coeff0_0 = coefficients0[dof][0];
283
 
      new_coeff0_1 = coefficients0[dof][1];
284
 
      new_coeff0_2 = coefficients0[dof][2];
285
 
    
286
 
      // Loop derivative order
287
 
      for (unsigned int j = 0; j < n; j++)
288
 
      {
289
 
        // Update old coefficients
290
 
        coeff0_0 = new_coeff0_0;
291
 
        coeff0_1 = new_coeff0_1;
292
 
        coeff0_2 = new_coeff0_2;
293
 
    
294
 
        if(combinations[deriv_num][j] == 0)
295
 
        {
296
 
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
297
 
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
298
 
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
299
 
        }
300
 
        if(combinations[deriv_num][j] == 1)
301
 
        {
302
 
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
303
 
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
304
 
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
305
 
        }
306
 
    
307
 
      }
308
 
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
309
 
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
310
 
    }
311
 
    
312
 
    // Transform derivatives back to physical element
313
 
    for (unsigned int row = 0; row < num_derivatives; row++)
314
 
    {
315
 
      for (unsigned int col = 0; col < num_derivatives; col++)
316
 
      {
317
 
        values[row] += transform[row][col]*derivatives[col];
318
 
      }
319
 
    }
320
 
    // Delete pointer to array of derivatives on FIAT element
321
 
    delete [] derivatives;
322
 
    
323
 
    // Delete pointer to array of combinations of derivatives and transform
324
 
    for (unsigned int row = 0; row < num_derivatives; row++)
325
 
    {
326
 
      delete [] combinations[row];
327
 
      delete [] transform[row];
328
 
    }
329
 
    
330
 
    delete [] combinations;
331
 
    delete [] transform;
332
 
}
333
 
 
334
 
/// Evaluate order n derivatives of all basis functions at given point in cell
335
 
void UFC_CahnHilliard2DBilinearForm_finite_element_0_0::evaluate_basis_derivatives_all(unsigned int n,
336
 
                                                   double* values,
337
 
                                                   const double* coordinates,
338
 
                                                   const ufc::cell& c) const
339
 
{
340
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
341
 
}
342
 
 
343
 
/// Evaluate linear functional for dof i on the function f
344
 
double UFC_CahnHilliard2DBilinearForm_finite_element_0_0::evaluate_dof(unsigned int i,
345
 
                                   const ufc::function& f,
346
 
                                   const ufc::cell& c) const
347
 
{
348
 
    // The reference points, direction and weights:
349
 
    const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
350
 
    const static double W[3][1] = {{1}, {1}, {1}};
351
 
    const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
352
 
    
353
 
    const double * const * x = c.coordinates;
354
 
    double result = 0.0;
355
 
    // Iterate over the points:
356
 
    // Evaluate basis functions for affine mapping
357
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
358
 
    const double w1 = X[i][0][0];
359
 
    const double w2 = X[i][0][1];
360
 
    
361
 
    // Compute affine mapping y = F(X)
362
 
    double y[2];
363
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
364
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
365
 
    
366
 
    // Evaluate function at physical points
367
 
    double values[1];
368
 
    f.evaluate(values, y, c);
369
 
    
370
 
    // Map function values using appropriate mapping
371
 
    // Affine map: Do nothing
372
 
    
373
 
    // Note that we do not map the weights (yet).
374
 
    
375
 
    // Take directional components
376
 
    for(int k = 0; k < 1; k++)
377
 
      result += values[k]*D[i][0][k];
378
 
    // Multiply by weights 
379
 
    result *= W[i][0];
380
 
    
381
 
    return result;
382
 
}
383
 
 
384
 
/// Evaluate linear functionals for all dofs on the function f
385
 
void UFC_CahnHilliard2DBilinearForm_finite_element_0_0::evaluate_dofs(double* values,
386
 
                                  const ufc::function& f,
387
 
                                  const ufc::cell& c) const
388
 
{
389
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
390
 
}
391
 
 
392
 
/// Interpolate vertex values from dof values
393
 
void UFC_CahnHilliard2DBilinearForm_finite_element_0_0::interpolate_vertex_values(double* vertex_values,
394
 
                                              const double* dof_values,
395
 
                                              const ufc::cell& c) const
396
 
{
397
 
    // Evaluate at vertices and use affine mapping
398
 
    vertex_values[0] = dof_values[0];
399
 
    vertex_values[1] = dof_values[1];
400
 
    vertex_values[2] = dof_values[2];
401
 
}
402
 
 
403
 
/// Return the number of sub elements (for a mixed element)
404
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_0_0::num_sub_elements() const
405
 
{
406
 
    return 1;
407
 
}
408
 
 
409
 
/// Create a new finite element for sub element i (for a mixed element)
410
 
ufc::finite_element* UFC_CahnHilliard2DBilinearForm_finite_element_0_0::create_sub_element(unsigned int i) const
411
 
{
412
 
    return new UFC_CahnHilliard2DBilinearForm_finite_element_0_0();
413
 
}
414
 
 
415
 
 
416
 
/// Constructor
417
 
UFC_CahnHilliard2DBilinearForm_finite_element_0_1::UFC_CahnHilliard2DBilinearForm_finite_element_0_1() : ufc::finite_element()
418
 
{
419
 
    // Do nothing
420
 
}
421
 
 
422
 
/// Destructor
423
 
UFC_CahnHilliard2DBilinearForm_finite_element_0_1::~UFC_CahnHilliard2DBilinearForm_finite_element_0_1()
424
 
{
425
 
    // Do nothing
426
 
}
427
 
 
428
 
/// Return a string identifying the finite element
429
 
const char* UFC_CahnHilliard2DBilinearForm_finite_element_0_1::signature() const
430
 
{
431
 
    return "FiniteElement('Lagrange', 'triangle', 1)";
432
 
}
433
 
 
434
 
/// Return the cell shape
435
 
ufc::shape UFC_CahnHilliard2DBilinearForm_finite_element_0_1::cell_shape() const
436
 
{
437
 
    return ufc::triangle;
438
 
}
439
 
 
440
 
/// Return the dimension of the finite element function space
441
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_0_1::space_dimension() const
442
 
{
443
 
    return 3;
444
 
}
445
 
 
446
 
/// Return the rank of the value space
447
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_0_1::value_rank() const
448
 
{
449
 
    return 0;
450
 
}
451
 
 
452
 
/// Return the dimension of the value space for axis i
453
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_0_1::value_dimension(unsigned int i) const
454
 
{
455
 
    return 1;
456
 
}
457
 
 
458
 
/// Evaluate basis function i at given point in cell
459
 
void UFC_CahnHilliard2DBilinearForm_finite_element_0_1::evaluate_basis(unsigned int i,
460
 
                                   double* values,
461
 
                                   const double* coordinates,
462
 
                                   const ufc::cell& c) const
463
 
{
464
 
    // Extract vertex coordinates
465
 
    const double * const * element_coordinates = c.coordinates;
466
 
    
467
 
    // Compute Jacobian of affine map from reference cell
468
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
469
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
470
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
471
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
472
 
      
473
 
    // Compute determinant of Jacobian
474
 
    const double detJ = J_00*J_11 - J_01*J_10;
475
 
    
476
 
    // Compute inverse of Jacobian
477
 
    
478
 
    // Get coordinates and map to the reference (UFC) element
479
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
480
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
481
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
482
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
483
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
484
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
485
 
    
486
 
    // Map coordinates to the reference square
487
 
    if (std::abs(y - 1.0) < 1e-14)
488
 
      x = -1.0;
489
 
    else
490
 
      x = 2.0 *x/(1.0 - y) - 1.0;
491
 
    y = 2.0*y - 1.0;
492
 
    
493
 
    // Reset values
494
 
    *values = 0;
495
 
    
496
 
    // Map degree of freedom to element degree of freedom
497
 
    const unsigned int dof = i;
498
 
    
499
 
    // Generate scalings
500
 
    const double scalings_y_0 = 1;
501
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
502
 
    
503
 
    // Compute psitilde_a
504
 
    const double psitilde_a_0 = 1;
505
 
    const double psitilde_a_1 = x;
506
 
    
507
 
    // Compute psitilde_bs
508
 
    const double psitilde_bs_0_0 = 1;
509
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
510
 
    const double psitilde_bs_1_0 = 1;
511
 
    
512
 
    // Compute basisvalues
513
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
514
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
515
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
516
 
    
517
 
    // Table(s) of coefficients
518
 
    const static double coefficients0[3][3] = \
519
 
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
520
 
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
521
 
    {0.471404520791032, 0, 0.333333333333333}};
522
 
    
523
 
    // Extract relevant coefficients
524
 
    const double coeff0_0 = coefficients0[dof][0];
525
 
    const double coeff0_1 = coefficients0[dof][1];
526
 
    const double coeff0_2 = coefficients0[dof][2];
527
 
    
528
 
    // Compute value(s)
529
 
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
530
 
}
531
 
 
532
 
/// Evaluate all basis functions at given point in cell
533
 
void UFC_CahnHilliard2DBilinearForm_finite_element_0_1::evaluate_basis_all(double* values,
534
 
                                       const double* coordinates,
535
 
                                       const ufc::cell& c) const
536
 
{
537
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
538
 
}
539
 
 
540
 
/// Evaluate order n derivatives of basis function i at given point in cell
541
 
void UFC_CahnHilliard2DBilinearForm_finite_element_0_1::evaluate_basis_derivatives(unsigned int i,
542
 
                                               unsigned int n,
543
 
                                               double* values,
544
 
                                               const double* coordinates,
545
 
                                               const ufc::cell& c) const
546
 
{
547
 
    // Extract vertex coordinates
548
 
    const double * const * element_coordinates = c.coordinates;
549
 
    
550
 
    // Compute Jacobian of affine map from reference cell
551
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
552
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
553
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
554
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
555
 
      
556
 
    // Compute determinant of Jacobian
557
 
    const double detJ = J_00*J_11 - J_01*J_10;
558
 
    
559
 
    // Compute inverse of Jacobian
560
 
    
561
 
    // Get coordinates and map to the reference (UFC) element
562
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
563
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
564
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
565
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
566
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
567
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
568
 
    
569
 
    // Map coordinates to the reference square
570
 
    if (std::abs(y - 1.0) < 1e-14)
571
 
      x = -1.0;
572
 
    else
573
 
      x = 2.0 *x/(1.0 - y) - 1.0;
574
 
    y = 2.0*y - 1.0;
575
 
    
576
 
    // Compute number of derivatives
577
 
    unsigned int num_derivatives = 1;
578
 
    
579
 
    for (unsigned int j = 0; j < n; j++)
580
 
      num_derivatives *= 2;
581
 
    
582
 
    
583
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
584
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
585
 
        
586
 
    for (unsigned int j = 0; j < num_derivatives; j++)
587
 
    {
588
 
      combinations[j] = new unsigned int [n];
589
 
      for (unsigned int k = 0; k < n; k++)
590
 
        combinations[j][k] = 0;
591
 
    }
592
 
        
593
 
    // Generate combinations of derivatives
594
 
    for (unsigned int row = 1; row < num_derivatives; row++)
595
 
    {
596
 
      for (unsigned int num = 0; num < row; num++)
597
 
      {
598
 
        for (unsigned int col = n-1; col+1 > 0; col--)
599
 
        {
600
 
          if (combinations[row][col] + 1 > 1)
601
 
            combinations[row][col] = 0;
602
 
          else
603
 
          {
604
 
            combinations[row][col] += 1;
605
 
            break;
606
 
          }
607
 
        }
608
 
      }
609
 
    }
610
 
    
611
 
    // Compute inverse of Jacobian
612
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
613
 
    
614
 
    // Declare transformation matrix
615
 
    // Declare pointer to two dimensional array and initialise
616
 
    double **transform = new double *[num_derivatives];
617
 
        
618
 
    for (unsigned int j = 0; j < num_derivatives; j++)
619
 
    {
620
 
      transform[j] = new double [num_derivatives];
621
 
      for (unsigned int k = 0; k < num_derivatives; k++)
622
 
        transform[j][k] = 1;
623
 
    }
624
 
    
625
 
    // Construct transformation matrix
626
 
    for (unsigned int row = 0; row < num_derivatives; row++)
627
 
    {
628
 
      for (unsigned int col = 0; col < num_derivatives; col++)
629
 
      {
630
 
        for (unsigned int k = 0; k < n; k++)
631
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
632
 
      }
633
 
    }
634
 
    
635
 
    // Reset values
636
 
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
637
 
      values[j] = 0;
638
 
    
639
 
    // Map degree of freedom to element degree of freedom
640
 
    const unsigned int dof = i;
641
 
    
642
 
    // Generate scalings
643
 
    const double scalings_y_0 = 1;
644
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
645
 
    
646
 
    // Compute psitilde_a
647
 
    const double psitilde_a_0 = 1;
648
 
    const double psitilde_a_1 = x;
649
 
    
650
 
    // Compute psitilde_bs
651
 
    const double psitilde_bs_0_0 = 1;
652
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
653
 
    const double psitilde_bs_1_0 = 1;
654
 
    
655
 
    // Compute basisvalues
656
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
657
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
658
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
659
 
    
660
 
    // Table(s) of coefficients
661
 
    const static double coefficients0[3][3] = \
662
 
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
663
 
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
664
 
    {0.471404520791032, 0, 0.333333333333333}};
665
 
    
666
 
    // Interesting (new) part
667
 
    // Tables of derivatives of the polynomial base (transpose)
668
 
    const static double dmats0[3][3] = \
669
 
    {{0, 0, 0},
670
 
    {4.89897948556636, 0, 0},
671
 
    {0, 0, 0}};
672
 
    
673
 
    const static double dmats1[3][3] = \
674
 
    {{0, 0, 0},
675
 
    {2.44948974278318, 0, 0},
676
 
    {4.24264068711928, 0, 0}};
677
 
    
678
 
    // Compute reference derivatives
679
 
    // Declare pointer to array of derivatives on FIAT element
680
 
    double *derivatives = new double [num_derivatives];
681
 
    
682
 
    // Declare coefficients
683
 
    double coeff0_0 = 0;
684
 
    double coeff0_1 = 0;
685
 
    double coeff0_2 = 0;
686
 
    
687
 
    // Declare new coefficients
688
 
    double new_coeff0_0 = 0;
689
 
    double new_coeff0_1 = 0;
690
 
    double new_coeff0_2 = 0;
691
 
    
692
 
    // Loop possible derivatives
693
 
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
694
 
    {
695
 
      // Get values from coefficients array
696
 
      new_coeff0_0 = coefficients0[dof][0];
697
 
      new_coeff0_1 = coefficients0[dof][1];
698
 
      new_coeff0_2 = coefficients0[dof][2];
699
 
    
700
 
      // Loop derivative order
701
 
      for (unsigned int j = 0; j < n; j++)
702
 
      {
703
 
        // Update old coefficients
704
 
        coeff0_0 = new_coeff0_0;
705
 
        coeff0_1 = new_coeff0_1;
706
 
        coeff0_2 = new_coeff0_2;
707
 
    
708
 
        if(combinations[deriv_num][j] == 0)
709
 
        {
710
 
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
711
 
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
712
 
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
713
 
        }
714
 
        if(combinations[deriv_num][j] == 1)
715
 
        {
716
 
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
717
 
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
718
 
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
719
 
        }
720
 
    
721
 
      }
722
 
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
723
 
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
724
 
    }
725
 
    
726
 
    // Transform derivatives back to physical element
727
 
    for (unsigned int row = 0; row < num_derivatives; row++)
728
 
    {
729
 
      for (unsigned int col = 0; col < num_derivatives; col++)
730
 
      {
731
 
        values[row] += transform[row][col]*derivatives[col];
732
 
      }
733
 
    }
734
 
    // Delete pointer to array of derivatives on FIAT element
735
 
    delete [] derivatives;
736
 
    
737
 
    // Delete pointer to array of combinations of derivatives and transform
738
 
    for (unsigned int row = 0; row < num_derivatives; row++)
739
 
    {
740
 
      delete [] combinations[row];
741
 
      delete [] transform[row];
742
 
    }
743
 
    
744
 
    delete [] combinations;
745
 
    delete [] transform;
746
 
}
747
 
 
748
 
/// Evaluate order n derivatives of all basis functions at given point in cell
749
 
void UFC_CahnHilliard2DBilinearForm_finite_element_0_1::evaluate_basis_derivatives_all(unsigned int n,
750
 
                                                   double* values,
751
 
                                                   const double* coordinates,
752
 
                                                   const ufc::cell& c) const
753
 
{
754
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
755
 
}
756
 
 
757
 
/// Evaluate linear functional for dof i on the function f
758
 
double UFC_CahnHilliard2DBilinearForm_finite_element_0_1::evaluate_dof(unsigned int i,
759
 
                                   const ufc::function& f,
760
 
                                   const ufc::cell& c) const
761
 
{
762
 
    // The reference points, direction and weights:
763
 
    const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
764
 
    const static double W[3][1] = {{1}, {1}, {1}};
765
 
    const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
766
 
    
767
 
    const double * const * x = c.coordinates;
768
 
    double result = 0.0;
769
 
    // Iterate over the points:
770
 
    // Evaluate basis functions for affine mapping
771
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
772
 
    const double w1 = X[i][0][0];
773
 
    const double w2 = X[i][0][1];
774
 
    
775
 
    // Compute affine mapping y = F(X)
776
 
    double y[2];
777
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
778
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
779
 
    
780
 
    // Evaluate function at physical points
781
 
    double values[1];
782
 
    f.evaluate(values, y, c);
783
 
    
784
 
    // Map function values using appropriate mapping
785
 
    // Affine map: Do nothing
786
 
    
787
 
    // Note that we do not map the weights (yet).
788
 
    
789
 
    // Take directional components
790
 
    for(int k = 0; k < 1; k++)
791
 
      result += values[k]*D[i][0][k];
792
 
    // Multiply by weights 
793
 
    result *= W[i][0];
794
 
    
795
 
    return result;
796
 
}
797
 
 
798
 
/// Evaluate linear functionals for all dofs on the function f
799
 
void UFC_CahnHilliard2DBilinearForm_finite_element_0_1::evaluate_dofs(double* values,
800
 
                                  const ufc::function& f,
801
 
                                  const ufc::cell& c) const
802
 
{
803
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
804
 
}
805
 
 
806
 
/// Interpolate vertex values from dof values
807
 
void UFC_CahnHilliard2DBilinearForm_finite_element_0_1::interpolate_vertex_values(double* vertex_values,
808
 
                                              const double* dof_values,
809
 
                                              const ufc::cell& c) const
810
 
{
811
 
    // Evaluate at vertices and use affine mapping
812
 
    vertex_values[0] = dof_values[0];
813
 
    vertex_values[1] = dof_values[1];
814
 
    vertex_values[2] = dof_values[2];
815
 
}
816
 
 
817
 
/// Return the number of sub elements (for a mixed element)
818
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_0_1::num_sub_elements() const
819
 
{
820
 
    return 1;
821
 
}
822
 
 
823
 
/// Create a new finite element for sub element i (for a mixed element)
824
 
ufc::finite_element* UFC_CahnHilliard2DBilinearForm_finite_element_0_1::create_sub_element(unsigned int i) const
825
 
{
826
 
    return new UFC_CahnHilliard2DBilinearForm_finite_element_0_1();
827
 
}
828
 
 
829
 
 
830
 
/// Constructor
831
 
UFC_CahnHilliard2DBilinearForm_finite_element_0::UFC_CahnHilliard2DBilinearForm_finite_element_0() : ufc::finite_element()
832
 
{
833
 
    // Do nothing
834
 
}
835
 
 
836
 
/// Destructor
837
 
UFC_CahnHilliard2DBilinearForm_finite_element_0::~UFC_CahnHilliard2DBilinearForm_finite_element_0()
838
 
{
839
 
    // Do nothing
840
 
}
841
 
 
842
 
/// Return a string identifying the finite element
843
 
const char* UFC_CahnHilliard2DBilinearForm_finite_element_0::signature() const
844
 
{
845
 
    return "MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
846
 
}
847
 
 
848
 
/// Return the cell shape
849
 
ufc::shape UFC_CahnHilliard2DBilinearForm_finite_element_0::cell_shape() const
850
 
{
851
 
    return ufc::triangle;
852
 
}
853
 
 
854
 
/// Return the dimension of the finite element function space
855
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_0::space_dimension() const
856
 
{
857
 
    return 6;
858
 
}
859
 
 
860
 
/// Return the rank of the value space
861
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_0::value_rank() const
862
 
{
863
 
    return 1;
864
 
}
865
 
 
866
 
/// Return the dimension of the value space for axis i
867
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_0::value_dimension(unsigned int i) const
868
 
{
869
 
    return 2;
870
 
}
871
 
 
872
 
/// Evaluate basis function i at given point in cell
873
 
void UFC_CahnHilliard2DBilinearForm_finite_element_0::evaluate_basis(unsigned int i,
874
 
                                   double* values,
875
 
                                   const double* coordinates,
876
 
                                   const ufc::cell& c) const
877
 
{
878
 
    // Extract vertex coordinates
879
 
    const double * const * element_coordinates = c.coordinates;
880
 
    
881
 
    // Compute Jacobian of affine map from reference cell
882
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
883
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
884
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
885
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
886
 
      
887
 
    // Compute determinant of Jacobian
888
 
    const double detJ = J_00*J_11 - J_01*J_10;
889
 
    
890
 
    // Compute inverse of Jacobian
891
 
    
892
 
    // Get coordinates and map to the reference (UFC) element
893
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
894
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
895
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
896
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
897
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
898
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
899
 
    
900
 
    // Map coordinates to the reference square
901
 
    if (std::abs(y - 1.0) < 1e-14)
902
 
      x = -1.0;
903
 
    else
904
 
      x = 2.0 *x/(1.0 - y) - 1.0;
905
 
    y = 2.0*y - 1.0;
906
 
    
907
 
    // Reset values
908
 
    values[0] = 0;
909
 
    values[1] = 0;
910
 
    
911
 
    if (0 <= i && i <= 2)
912
 
    {
913
 
      // Map degree of freedom to element degree of freedom
914
 
      const unsigned int dof = i;
915
 
    
916
 
      // Generate scalings
917
 
      const double scalings_y_0 = 1;
918
 
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
919
 
    
920
 
      // Compute psitilde_a
921
 
      const double psitilde_a_0 = 1;
922
 
      const double psitilde_a_1 = x;
923
 
    
924
 
      // Compute psitilde_bs
925
 
      const double psitilde_bs_0_0 = 1;
926
 
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
927
 
      const double psitilde_bs_1_0 = 1;
928
 
    
929
 
      // Compute basisvalues
930
 
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
931
 
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
932
 
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
933
 
    
934
 
      // Table(s) of coefficients
935
 
      const static double coefficients0[3][3] =   \
936
 
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
937
 
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
938
 
      {0.471404520791032, 0, 0.333333333333333}};
939
 
    
940
 
      // Extract relevant coefficients
941
 
      const double coeff0_0 =   coefficients0[dof][0];
942
 
      const double coeff0_1 =   coefficients0[dof][1];
943
 
      const double coeff0_2 =   coefficients0[dof][2];
944
 
    
945
 
      // Compute value(s)
946
 
      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
947
 
    }
948
 
    
949
 
    if (3 <= i && i <= 5)
950
 
    {
951
 
      // Map degree of freedom to element degree of freedom
952
 
      const unsigned int dof = i - 3;
953
 
    
954
 
      // Generate scalings
955
 
      const double scalings_y_0 = 1;
956
 
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
957
 
    
958
 
      // Compute psitilde_a
959
 
      const double psitilde_a_0 = 1;
960
 
      const double psitilde_a_1 = x;
961
 
    
962
 
      // Compute psitilde_bs
963
 
      const double psitilde_bs_0_0 = 1;
964
 
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
965
 
      const double psitilde_bs_1_0 = 1;
966
 
    
967
 
      // Compute basisvalues
968
 
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
969
 
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
970
 
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
971
 
    
972
 
      // Table(s) of coefficients
973
 
      const static double coefficients0[3][3] =   \
974
 
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
975
 
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
976
 
      {0.471404520791032, 0, 0.333333333333333}};
977
 
    
978
 
      // Extract relevant coefficients
979
 
      const double coeff0_0 =   coefficients0[dof][0];
980
 
      const double coeff0_1 =   coefficients0[dof][1];
981
 
      const double coeff0_2 =   coefficients0[dof][2];
982
 
    
983
 
      // Compute value(s)
984
 
      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
985
 
    }
986
 
    
987
 
}
988
 
 
989
 
/// Evaluate all basis functions at given point in cell
990
 
void UFC_CahnHilliard2DBilinearForm_finite_element_0::evaluate_basis_all(double* values,
991
 
                                       const double* coordinates,
992
 
                                       const ufc::cell& c) const
993
 
{
994
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
995
 
}
996
 
 
997
 
/// Evaluate order n derivatives of basis function i at given point in cell
998
 
void UFC_CahnHilliard2DBilinearForm_finite_element_0::evaluate_basis_derivatives(unsigned int i,
999
 
                                               unsigned int n,
1000
 
                                               double* values,
1001
 
                                               const double* coordinates,
1002
 
                                               const ufc::cell& c) const
1003
 
{
1004
 
    // Extract vertex coordinates
1005
 
    const double * const * element_coordinates = c.coordinates;
1006
 
    
1007
 
    // Compute Jacobian of affine map from reference cell
1008
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1009
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1010
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1011
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1012
 
      
1013
 
    // Compute determinant of Jacobian
1014
 
    const double detJ = J_00*J_11 - J_01*J_10;
1015
 
    
1016
 
    // Compute inverse of Jacobian
1017
 
    
1018
 
    // Get coordinates and map to the reference (UFC) element
1019
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1020
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
1021
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1022
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1023
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
1024
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1025
 
    
1026
 
    // Map coordinates to the reference square
1027
 
    if (std::abs(y - 1.0) < 1e-14)
1028
 
      x = -1.0;
1029
 
    else
1030
 
      x = 2.0 *x/(1.0 - y) - 1.0;
1031
 
    y = 2.0*y - 1.0;
1032
 
    
1033
 
    // Compute number of derivatives
1034
 
    unsigned int num_derivatives = 1;
1035
 
    
1036
 
    for (unsigned int j = 0; j < n; j++)
1037
 
      num_derivatives *= 2;
1038
 
    
1039
 
    
1040
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
1041
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
1042
 
        
1043
 
    for (unsigned int j = 0; j < num_derivatives; j++)
1044
 
    {
1045
 
      combinations[j] = new unsigned int [n];
1046
 
      for (unsigned int k = 0; k < n; k++)
1047
 
        combinations[j][k] = 0;
1048
 
    }
1049
 
        
1050
 
    // Generate combinations of derivatives
1051
 
    for (unsigned int row = 1; row < num_derivatives; row++)
1052
 
    {
1053
 
      for (unsigned int num = 0; num < row; num++)
1054
 
      {
1055
 
        for (unsigned int col = n-1; col+1 > 0; col--)
1056
 
        {
1057
 
          if (combinations[row][col] + 1 > 1)
1058
 
            combinations[row][col] = 0;
1059
 
          else
1060
 
          {
1061
 
            combinations[row][col] += 1;
1062
 
            break;
1063
 
          }
1064
 
        }
1065
 
      }
1066
 
    }
1067
 
    
1068
 
    // Compute inverse of Jacobian
1069
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
1070
 
    
1071
 
    // Declare transformation matrix
1072
 
    // Declare pointer to two dimensional array and initialise
1073
 
    double **transform = new double *[num_derivatives];
1074
 
        
1075
 
    for (unsigned int j = 0; j < num_derivatives; j++)
1076
 
    {
1077
 
      transform[j] = new double [num_derivatives];
1078
 
      for (unsigned int k = 0; k < num_derivatives; k++)
1079
 
        transform[j][k] = 1;
1080
 
    }
1081
 
    
1082
 
    // Construct transformation matrix
1083
 
    for (unsigned int row = 0; row < num_derivatives; row++)
1084
 
    {
1085
 
      for (unsigned int col = 0; col < num_derivatives; col++)
1086
 
      {
1087
 
        for (unsigned int k = 0; k < n; k++)
1088
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
1089
 
      }
1090
 
    }
1091
 
    
1092
 
    // Reset values
1093
 
    for (unsigned int j = 0; j < 2*num_derivatives; j++)
1094
 
      values[j] = 0;
1095
 
    
1096
 
    if (0 <= i && i <= 2)
1097
 
    {
1098
 
      // Map degree of freedom to element degree of freedom
1099
 
      const unsigned int dof = i;
1100
 
    
1101
 
      // Generate scalings
1102
 
      const double scalings_y_0 = 1;
1103
 
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1104
 
    
1105
 
      // Compute psitilde_a
1106
 
      const double psitilde_a_0 = 1;
1107
 
      const double psitilde_a_1 = x;
1108
 
    
1109
 
      // Compute psitilde_bs
1110
 
      const double psitilde_bs_0_0 = 1;
1111
 
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
1112
 
      const double psitilde_bs_1_0 = 1;
1113
 
    
1114
 
      // Compute basisvalues
1115
 
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1116
 
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1117
 
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1118
 
    
1119
 
      // Table(s) of coefficients
1120
 
      const static double coefficients0[3][3] =   \
1121
 
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
1122
 
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
1123
 
      {0.471404520791032, 0, 0.333333333333333}};
1124
 
    
1125
 
      // Interesting (new) part
1126
 
      // Tables of derivatives of the polynomial base (transpose)
1127
 
      const static double dmats0[3][3] =   \
1128
 
      {{0, 0, 0},
1129
 
      {4.89897948556636, 0, 0},
1130
 
      {0, 0, 0}};
1131
 
    
1132
 
      const static double dmats1[3][3] =   \
1133
 
      {{0, 0, 0},
1134
 
      {2.44948974278318, 0, 0},
1135
 
      {4.24264068711928, 0, 0}};
1136
 
    
1137
 
      // Compute reference derivatives
1138
 
      // Declare pointer to array of derivatives on FIAT element
1139
 
      double *derivatives = new double [num_derivatives];
1140
 
    
1141
 
      // Declare coefficients
1142
 
      double coeff0_0 = 0;
1143
 
      double coeff0_1 = 0;
1144
 
      double coeff0_2 = 0;
1145
 
    
1146
 
      // Declare new coefficients
1147
 
      double new_coeff0_0 = 0;
1148
 
      double new_coeff0_1 = 0;
1149
 
      double new_coeff0_2 = 0;
1150
 
    
1151
 
      // Loop possible derivatives
1152
 
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
1153
 
      {
1154
 
        // Get values from coefficients array
1155
 
        new_coeff0_0 = coefficients0[dof][0];
1156
 
        new_coeff0_1 = coefficients0[dof][1];
1157
 
        new_coeff0_2 = coefficients0[dof][2];
1158
 
    
1159
 
        // Loop derivative order
1160
 
        for (unsigned int j = 0; j < n; j++)
1161
 
        {
1162
 
          // Update old coefficients
1163
 
          coeff0_0 = new_coeff0_0;
1164
 
          coeff0_1 = new_coeff0_1;
1165
 
          coeff0_2 = new_coeff0_2;
1166
 
    
1167
 
          if(combinations[deriv_num][j] == 0)
1168
 
          {
1169
 
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
1170
 
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
1171
 
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
1172
 
          }
1173
 
          if(combinations[deriv_num][j] == 1)
1174
 
          {
1175
 
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
1176
 
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
1177
 
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
1178
 
          }
1179
 
    
1180
 
        }
1181
 
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
1182
 
        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
1183
 
      }
1184
 
    
1185
 
      // Transform derivatives back to physical element
1186
 
      for (unsigned int row = 0; row < num_derivatives; row++)
1187
 
      {
1188
 
        for (unsigned int col = 0; col < num_derivatives; col++)
1189
 
        {
1190
 
          values[row] += transform[row][col]*derivatives[col];
1191
 
        }
1192
 
      }
1193
 
      // Delete pointer to array of derivatives on FIAT element
1194
 
      delete [] derivatives;
1195
 
    
1196
 
      // Delete pointer to array of combinations of derivatives and transform
1197
 
      for (unsigned int row = 0; row < num_derivatives; row++)
1198
 
      {
1199
 
        delete [] combinations[row];
1200
 
        delete [] transform[row];
1201
 
      }
1202
 
    
1203
 
      delete [] combinations;
1204
 
      delete [] transform;
1205
 
    }
1206
 
    
1207
 
    if (3 <= i && i <= 5)
1208
 
    {
1209
 
      // Map degree of freedom to element degree of freedom
1210
 
      const unsigned int dof = i - 3;
1211
 
    
1212
 
      // Generate scalings
1213
 
      const double scalings_y_0 = 1;
1214
 
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1215
 
    
1216
 
      // Compute psitilde_a
1217
 
      const double psitilde_a_0 = 1;
1218
 
      const double psitilde_a_1 = x;
1219
 
    
1220
 
      // Compute psitilde_bs
1221
 
      const double psitilde_bs_0_0 = 1;
1222
 
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
1223
 
      const double psitilde_bs_1_0 = 1;
1224
 
    
1225
 
      // Compute basisvalues
1226
 
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1227
 
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1228
 
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1229
 
    
1230
 
      // Table(s) of coefficients
1231
 
      const static double coefficients0[3][3] =   \
1232
 
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
1233
 
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
1234
 
      {0.471404520791032, 0, 0.333333333333333}};
1235
 
    
1236
 
      // Interesting (new) part
1237
 
      // Tables of derivatives of the polynomial base (transpose)
1238
 
      const static double dmats0[3][3] =   \
1239
 
      {{0, 0, 0},
1240
 
      {4.89897948556636, 0, 0},
1241
 
      {0, 0, 0}};
1242
 
    
1243
 
      const static double dmats1[3][3] =   \
1244
 
      {{0, 0, 0},
1245
 
      {2.44948974278318, 0, 0},
1246
 
      {4.24264068711928, 0, 0}};
1247
 
    
1248
 
      // Compute reference derivatives
1249
 
      // Declare pointer to array of derivatives on FIAT element
1250
 
      double *derivatives = new double [num_derivatives];
1251
 
    
1252
 
      // Declare coefficients
1253
 
      double coeff0_0 = 0;
1254
 
      double coeff0_1 = 0;
1255
 
      double coeff0_2 = 0;
1256
 
    
1257
 
      // Declare new coefficients
1258
 
      double new_coeff0_0 = 0;
1259
 
      double new_coeff0_1 = 0;
1260
 
      double new_coeff0_2 = 0;
1261
 
    
1262
 
      // Loop possible derivatives
1263
 
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
1264
 
      {
1265
 
        // Get values from coefficients array
1266
 
        new_coeff0_0 = coefficients0[dof][0];
1267
 
        new_coeff0_1 = coefficients0[dof][1];
1268
 
        new_coeff0_2 = coefficients0[dof][2];
1269
 
    
1270
 
        // Loop derivative order
1271
 
        for (unsigned int j = 0; j < n; j++)
1272
 
        {
1273
 
          // Update old coefficients
1274
 
          coeff0_0 = new_coeff0_0;
1275
 
          coeff0_1 = new_coeff0_1;
1276
 
          coeff0_2 = new_coeff0_2;
1277
 
    
1278
 
          if(combinations[deriv_num][j] == 0)
1279
 
          {
1280
 
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
1281
 
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
1282
 
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
1283
 
          }
1284
 
          if(combinations[deriv_num][j] == 1)
1285
 
          {
1286
 
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
1287
 
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
1288
 
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
1289
 
          }
1290
 
    
1291
 
        }
1292
 
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
1293
 
        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
1294
 
      }
1295
 
    
1296
 
      // Transform derivatives back to physical element
1297
 
      for (unsigned int row = 0; row < num_derivatives; row++)
1298
 
      {
1299
 
        for (unsigned int col = 0; col < num_derivatives; col++)
1300
 
        {
1301
 
          values[num_derivatives + row] += transform[row][col]*derivatives[col];
1302
 
        }
1303
 
      }
1304
 
      // Delete pointer to array of derivatives on FIAT element
1305
 
      delete [] derivatives;
1306
 
    
1307
 
      // Delete pointer to array of combinations of derivatives and transform
1308
 
      for (unsigned int row = 0; row < num_derivatives; row++)
1309
 
      {
1310
 
        delete [] combinations[row];
1311
 
        delete [] transform[row];
1312
 
      }
1313
 
    
1314
 
      delete [] combinations;
1315
 
      delete [] transform;
1316
 
    }
1317
 
    
1318
 
}
1319
 
 
1320
 
/// Evaluate order n derivatives of all basis functions at given point in cell
1321
 
void UFC_CahnHilliard2DBilinearForm_finite_element_0::evaluate_basis_derivatives_all(unsigned int n,
1322
 
                                                   double* values,
1323
 
                                                   const double* coordinates,
1324
 
                                                   const ufc::cell& c) const
1325
 
{
1326
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
1327
 
}
1328
 
 
1329
 
/// Evaluate linear functional for dof i on the function f
1330
 
double UFC_CahnHilliard2DBilinearForm_finite_element_0::evaluate_dof(unsigned int i,
1331
 
                                   const ufc::function& f,
1332
 
                                   const ufc::cell& c) const
1333
 
{
1334
 
    // The reference points, direction and weights:
1335
 
    const static double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
1336
 
    const static double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
1337
 
    const static double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
1338
 
    
1339
 
    const double * const * x = c.coordinates;
1340
 
    double result = 0.0;
1341
 
    // Iterate over the points:
1342
 
    // Evaluate basis functions for affine mapping
1343
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
1344
 
    const double w1 = X[i][0][0];
1345
 
    const double w2 = X[i][0][1];
1346
 
    
1347
 
    // Compute affine mapping y = F(X)
1348
 
    double y[2];
1349
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
1350
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
1351
 
    
1352
 
    // Evaluate function at physical points
1353
 
    double values[2];
1354
 
    f.evaluate(values, y, c);
1355
 
    
1356
 
    // Map function values using appropriate mapping
1357
 
    // Affine map: Do nothing
1358
 
    
1359
 
    // Note that we do not map the weights (yet).
1360
 
    
1361
 
    // Take directional components
1362
 
    for(int k = 0; k < 2; k++)
1363
 
      result += values[k]*D[i][0][k];
1364
 
    // Multiply by weights 
1365
 
    result *= W[i][0];
1366
 
    
1367
 
    return result;
1368
 
}
1369
 
 
1370
 
/// Evaluate linear functionals for all dofs on the function f
1371
 
void UFC_CahnHilliard2DBilinearForm_finite_element_0::evaluate_dofs(double* values,
1372
 
                                  const ufc::function& f,
1373
 
                                  const ufc::cell& c) const
1374
 
{
1375
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1376
 
}
1377
 
 
1378
 
/// Interpolate vertex values from dof values
1379
 
void UFC_CahnHilliard2DBilinearForm_finite_element_0::interpolate_vertex_values(double* vertex_values,
1380
 
                                              const double* dof_values,
1381
 
                                              const ufc::cell& c) const
1382
 
{
1383
 
    // Evaluate at vertices and use affine mapping
1384
 
    vertex_values[0] = dof_values[0];
1385
 
    vertex_values[2] = dof_values[1];
1386
 
    vertex_values[4] = dof_values[2];
1387
 
    // Evaluate at vertices and use affine mapping
1388
 
    vertex_values[1] = dof_values[3];
1389
 
    vertex_values[3] = dof_values[4];
1390
 
    vertex_values[5] = dof_values[5];
1391
 
}
1392
 
 
1393
 
/// Return the number of sub elements (for a mixed element)
1394
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_0::num_sub_elements() const
1395
 
{
1396
 
    return 2;
1397
 
}
1398
 
 
1399
 
/// Create a new finite element for sub element i (for a mixed element)
1400
 
ufc::finite_element* UFC_CahnHilliard2DBilinearForm_finite_element_0::create_sub_element(unsigned int i) const
1401
 
{
1402
 
    switch ( i )
1403
 
    {
1404
 
    case 0:
1405
 
      return new UFC_CahnHilliard2DBilinearForm_finite_element_0_0();
1406
 
      break;
1407
 
    case 1:
1408
 
      return new UFC_CahnHilliard2DBilinearForm_finite_element_0_1();
1409
 
      break;
1410
 
    }
1411
 
    return 0;
1412
 
}
1413
 
 
1414
 
 
1415
 
/// Constructor
1416
 
UFC_CahnHilliard2DBilinearForm_finite_element_1_0::UFC_CahnHilliard2DBilinearForm_finite_element_1_0() : ufc::finite_element()
1417
 
{
1418
 
    // Do nothing
1419
 
}
1420
 
 
1421
 
/// Destructor
1422
 
UFC_CahnHilliard2DBilinearForm_finite_element_1_0::~UFC_CahnHilliard2DBilinearForm_finite_element_1_0()
1423
 
{
1424
 
    // Do nothing
1425
 
}
1426
 
 
1427
 
/// Return a string identifying the finite element
1428
 
const char* UFC_CahnHilliard2DBilinearForm_finite_element_1_0::signature() const
1429
 
{
1430
 
    return "FiniteElement('Lagrange', 'triangle', 1)";
1431
 
}
1432
 
 
1433
 
/// Return the cell shape
1434
 
ufc::shape UFC_CahnHilliard2DBilinearForm_finite_element_1_0::cell_shape() const
1435
 
{
1436
 
    return ufc::triangle;
1437
 
}
1438
 
 
1439
 
/// Return the dimension of the finite element function space
1440
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_1_0::space_dimension() const
1441
 
{
1442
 
    return 3;
1443
 
}
1444
 
 
1445
 
/// Return the rank of the value space
1446
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_1_0::value_rank() const
1447
 
{
1448
 
    return 0;
1449
 
}
1450
 
 
1451
 
/// Return the dimension of the value space for axis i
1452
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_1_0::value_dimension(unsigned int i) const
1453
 
{
1454
 
    return 1;
1455
 
}
1456
 
 
1457
 
/// Evaluate basis function i at given point in cell
1458
 
void UFC_CahnHilliard2DBilinearForm_finite_element_1_0::evaluate_basis(unsigned int i,
1459
 
                                   double* values,
1460
 
                                   const double* coordinates,
1461
 
                                   const ufc::cell& c) const
1462
 
{
1463
 
    // Extract vertex coordinates
1464
 
    const double * const * element_coordinates = c.coordinates;
1465
 
    
1466
 
    // Compute Jacobian of affine map from reference cell
1467
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1468
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1469
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1470
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1471
 
      
1472
 
    // Compute determinant of Jacobian
1473
 
    const double detJ = J_00*J_11 - J_01*J_10;
1474
 
    
1475
 
    // Compute inverse of Jacobian
1476
 
    
1477
 
    // Get coordinates and map to the reference (UFC) element
1478
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1479
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
1480
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1481
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1482
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
1483
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1484
 
    
1485
 
    // Map coordinates to the reference square
1486
 
    if (std::abs(y - 1.0) < 1e-14)
1487
 
      x = -1.0;
1488
 
    else
1489
 
      x = 2.0 *x/(1.0 - y) - 1.0;
1490
 
    y = 2.0*y - 1.0;
1491
 
    
1492
 
    // Reset values
1493
 
    *values = 0;
1494
 
    
1495
 
    // Map degree of freedom to element degree of freedom
1496
 
    const unsigned int dof = i;
1497
 
    
1498
 
    // Generate scalings
1499
 
    const double scalings_y_0 = 1;
1500
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1501
 
    
1502
 
    // Compute psitilde_a
1503
 
    const double psitilde_a_0 = 1;
1504
 
    const double psitilde_a_1 = x;
1505
 
    
1506
 
    // Compute psitilde_bs
1507
 
    const double psitilde_bs_0_0 = 1;
1508
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
1509
 
    const double psitilde_bs_1_0 = 1;
1510
 
    
1511
 
    // Compute basisvalues
1512
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1513
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1514
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1515
 
    
1516
 
    // Table(s) of coefficients
1517
 
    const static double coefficients0[3][3] = \
1518
 
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
1519
 
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
1520
 
    {0.471404520791032, 0, 0.333333333333333}};
1521
 
    
1522
 
    // Extract relevant coefficients
1523
 
    const double coeff0_0 = coefficients0[dof][0];
1524
 
    const double coeff0_1 = coefficients0[dof][1];
1525
 
    const double coeff0_2 = coefficients0[dof][2];
1526
 
    
1527
 
    // Compute value(s)
1528
 
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
1529
 
}
1530
 
 
1531
 
/// Evaluate all basis functions at given point in cell
1532
 
void UFC_CahnHilliard2DBilinearForm_finite_element_1_0::evaluate_basis_all(double* values,
1533
 
                                       const double* coordinates,
1534
 
                                       const ufc::cell& c) const
1535
 
{
1536
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
1537
 
}
1538
 
 
1539
 
/// Evaluate order n derivatives of basis function i at given point in cell
1540
 
void UFC_CahnHilliard2DBilinearForm_finite_element_1_0::evaluate_basis_derivatives(unsigned int i,
1541
 
                                               unsigned int n,
1542
 
                                               double* values,
1543
 
                                               const double* coordinates,
1544
 
                                               const ufc::cell& c) const
1545
 
{
1546
 
    // Extract vertex coordinates
1547
 
    const double * const * element_coordinates = c.coordinates;
1548
 
    
1549
 
    // Compute Jacobian of affine map from reference cell
1550
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1551
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1552
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1553
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1554
 
      
1555
 
    // Compute determinant of Jacobian
1556
 
    const double detJ = J_00*J_11 - J_01*J_10;
1557
 
    
1558
 
    // Compute inverse of Jacobian
1559
 
    
1560
 
    // Get coordinates and map to the reference (UFC) element
1561
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1562
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
1563
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1564
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1565
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
1566
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1567
 
    
1568
 
    // Map coordinates to the reference square
1569
 
    if (std::abs(y - 1.0) < 1e-14)
1570
 
      x = -1.0;
1571
 
    else
1572
 
      x = 2.0 *x/(1.0 - y) - 1.0;
1573
 
    y = 2.0*y - 1.0;
1574
 
    
1575
 
    // Compute number of derivatives
1576
 
    unsigned int num_derivatives = 1;
1577
 
    
1578
 
    for (unsigned int j = 0; j < n; j++)
1579
 
      num_derivatives *= 2;
1580
 
    
1581
 
    
1582
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
1583
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
1584
 
        
1585
 
    for (unsigned int j = 0; j < num_derivatives; j++)
1586
 
    {
1587
 
      combinations[j] = new unsigned int [n];
1588
 
      for (unsigned int k = 0; k < n; k++)
1589
 
        combinations[j][k] = 0;
1590
 
    }
1591
 
        
1592
 
    // Generate combinations of derivatives
1593
 
    for (unsigned int row = 1; row < num_derivatives; row++)
1594
 
    {
1595
 
      for (unsigned int num = 0; num < row; num++)
1596
 
      {
1597
 
        for (unsigned int col = n-1; col+1 > 0; col--)
1598
 
        {
1599
 
          if (combinations[row][col] + 1 > 1)
1600
 
            combinations[row][col] = 0;
1601
 
          else
1602
 
          {
1603
 
            combinations[row][col] += 1;
1604
 
            break;
1605
 
          }
1606
 
        }
1607
 
      }
1608
 
    }
1609
 
    
1610
 
    // Compute inverse of Jacobian
1611
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
1612
 
    
1613
 
    // Declare transformation matrix
1614
 
    // Declare pointer to two dimensional array and initialise
1615
 
    double **transform = new double *[num_derivatives];
1616
 
        
1617
 
    for (unsigned int j = 0; j < num_derivatives; j++)
1618
 
    {
1619
 
      transform[j] = new double [num_derivatives];
1620
 
      for (unsigned int k = 0; k < num_derivatives; k++)
1621
 
        transform[j][k] = 1;
1622
 
    }
1623
 
    
1624
 
    // Construct transformation matrix
1625
 
    for (unsigned int row = 0; row < num_derivatives; row++)
1626
 
    {
1627
 
      for (unsigned int col = 0; col < num_derivatives; col++)
1628
 
      {
1629
 
        for (unsigned int k = 0; k < n; k++)
1630
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
1631
 
      }
1632
 
    }
1633
 
    
1634
 
    // Reset values
1635
 
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
1636
 
      values[j] = 0;
1637
 
    
1638
 
    // Map degree of freedom to element degree of freedom
1639
 
    const unsigned int dof = i;
1640
 
    
1641
 
    // Generate scalings
1642
 
    const double scalings_y_0 = 1;
1643
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1644
 
    
1645
 
    // Compute psitilde_a
1646
 
    const double psitilde_a_0 = 1;
1647
 
    const double psitilde_a_1 = x;
1648
 
    
1649
 
    // Compute psitilde_bs
1650
 
    const double psitilde_bs_0_0 = 1;
1651
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
1652
 
    const double psitilde_bs_1_0 = 1;
1653
 
    
1654
 
    // Compute basisvalues
1655
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1656
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1657
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1658
 
    
1659
 
    // Table(s) of coefficients
1660
 
    const static double coefficients0[3][3] = \
1661
 
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
1662
 
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
1663
 
    {0.471404520791032, 0, 0.333333333333333}};
1664
 
    
1665
 
    // Interesting (new) part
1666
 
    // Tables of derivatives of the polynomial base (transpose)
1667
 
    const static double dmats0[3][3] = \
1668
 
    {{0, 0, 0},
1669
 
    {4.89897948556636, 0, 0},
1670
 
    {0, 0, 0}};
1671
 
    
1672
 
    const static double dmats1[3][3] = \
1673
 
    {{0, 0, 0},
1674
 
    {2.44948974278318, 0, 0},
1675
 
    {4.24264068711928, 0, 0}};
1676
 
    
1677
 
    // Compute reference derivatives
1678
 
    // Declare pointer to array of derivatives on FIAT element
1679
 
    double *derivatives = new double [num_derivatives];
1680
 
    
1681
 
    // Declare coefficients
1682
 
    double coeff0_0 = 0;
1683
 
    double coeff0_1 = 0;
1684
 
    double coeff0_2 = 0;
1685
 
    
1686
 
    // Declare new coefficients
1687
 
    double new_coeff0_0 = 0;
1688
 
    double new_coeff0_1 = 0;
1689
 
    double new_coeff0_2 = 0;
1690
 
    
1691
 
    // Loop possible derivatives
1692
 
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
1693
 
    {
1694
 
      // Get values from coefficients array
1695
 
      new_coeff0_0 = coefficients0[dof][0];
1696
 
      new_coeff0_1 = coefficients0[dof][1];
1697
 
      new_coeff0_2 = coefficients0[dof][2];
1698
 
    
1699
 
      // Loop derivative order
1700
 
      for (unsigned int j = 0; j < n; j++)
1701
 
      {
1702
 
        // Update old coefficients
1703
 
        coeff0_0 = new_coeff0_0;
1704
 
        coeff0_1 = new_coeff0_1;
1705
 
        coeff0_2 = new_coeff0_2;
1706
 
    
1707
 
        if(combinations[deriv_num][j] == 0)
1708
 
        {
1709
 
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
1710
 
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
1711
 
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
1712
 
        }
1713
 
        if(combinations[deriv_num][j] == 1)
1714
 
        {
1715
 
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
1716
 
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
1717
 
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
1718
 
        }
1719
 
    
1720
 
      }
1721
 
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
1722
 
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
1723
 
    }
1724
 
    
1725
 
    // Transform derivatives back to physical element
1726
 
    for (unsigned int row = 0; row < num_derivatives; row++)
1727
 
    {
1728
 
      for (unsigned int col = 0; col < num_derivatives; col++)
1729
 
      {
1730
 
        values[row] += transform[row][col]*derivatives[col];
1731
 
      }
1732
 
    }
1733
 
    // Delete pointer to array of derivatives on FIAT element
1734
 
    delete [] derivatives;
1735
 
    
1736
 
    // Delete pointer to array of combinations of derivatives and transform
1737
 
    for (unsigned int row = 0; row < num_derivatives; row++)
1738
 
    {
1739
 
      delete [] combinations[row];
1740
 
      delete [] transform[row];
1741
 
    }
1742
 
    
1743
 
    delete [] combinations;
1744
 
    delete [] transform;
1745
 
}
1746
 
 
1747
 
/// Evaluate order n derivatives of all basis functions at given point in cell
1748
 
void UFC_CahnHilliard2DBilinearForm_finite_element_1_0::evaluate_basis_derivatives_all(unsigned int n,
1749
 
                                                   double* values,
1750
 
                                                   const double* coordinates,
1751
 
                                                   const ufc::cell& c) const
1752
 
{
1753
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
1754
 
}
1755
 
 
1756
 
/// Evaluate linear functional for dof i on the function f
1757
 
double UFC_CahnHilliard2DBilinearForm_finite_element_1_0::evaluate_dof(unsigned int i,
1758
 
                                   const ufc::function& f,
1759
 
                                   const ufc::cell& c) const
1760
 
{
1761
 
    // The reference points, direction and weights:
1762
 
    const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
1763
 
    const static double W[3][1] = {{1}, {1}, {1}};
1764
 
    const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
1765
 
    
1766
 
    const double * const * x = c.coordinates;
1767
 
    double result = 0.0;
1768
 
    // Iterate over the points:
1769
 
    // Evaluate basis functions for affine mapping
1770
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
1771
 
    const double w1 = X[i][0][0];
1772
 
    const double w2 = X[i][0][1];
1773
 
    
1774
 
    // Compute affine mapping y = F(X)
1775
 
    double y[2];
1776
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
1777
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
1778
 
    
1779
 
    // Evaluate function at physical points
1780
 
    double values[1];
1781
 
    f.evaluate(values, y, c);
1782
 
    
1783
 
    // Map function values using appropriate mapping
1784
 
    // Affine map: Do nothing
1785
 
    
1786
 
    // Note that we do not map the weights (yet).
1787
 
    
1788
 
    // Take directional components
1789
 
    for(int k = 0; k < 1; k++)
1790
 
      result += values[k]*D[i][0][k];
1791
 
    // Multiply by weights 
1792
 
    result *= W[i][0];
1793
 
    
1794
 
    return result;
1795
 
}
1796
 
 
1797
 
/// Evaluate linear functionals for all dofs on the function f
1798
 
void UFC_CahnHilliard2DBilinearForm_finite_element_1_0::evaluate_dofs(double* values,
1799
 
                                  const ufc::function& f,
1800
 
                                  const ufc::cell& c) const
1801
 
{
1802
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1803
 
}
1804
 
 
1805
 
/// Interpolate vertex values from dof values
1806
 
void UFC_CahnHilliard2DBilinearForm_finite_element_1_0::interpolate_vertex_values(double* vertex_values,
1807
 
                                              const double* dof_values,
1808
 
                                              const ufc::cell& c) const
1809
 
{
1810
 
    // Evaluate at vertices and use affine mapping
1811
 
    vertex_values[0] = dof_values[0];
1812
 
    vertex_values[1] = dof_values[1];
1813
 
    vertex_values[2] = dof_values[2];
1814
 
}
1815
 
 
1816
 
/// Return the number of sub elements (for a mixed element)
1817
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_1_0::num_sub_elements() const
1818
 
{
1819
 
    return 1;
1820
 
}
1821
 
 
1822
 
/// Create a new finite element for sub element i (for a mixed element)
1823
 
ufc::finite_element* UFC_CahnHilliard2DBilinearForm_finite_element_1_0::create_sub_element(unsigned int i) const
1824
 
{
1825
 
    return new UFC_CahnHilliard2DBilinearForm_finite_element_1_0();
1826
 
}
1827
 
 
1828
 
 
1829
 
/// Constructor
1830
 
UFC_CahnHilliard2DBilinearForm_finite_element_1_1::UFC_CahnHilliard2DBilinearForm_finite_element_1_1() : ufc::finite_element()
1831
 
{
1832
 
    // Do nothing
1833
 
}
1834
 
 
1835
 
/// Destructor
1836
 
UFC_CahnHilliard2DBilinearForm_finite_element_1_1::~UFC_CahnHilliard2DBilinearForm_finite_element_1_1()
1837
 
{
1838
 
    // Do nothing
1839
 
}
1840
 
 
1841
 
/// Return a string identifying the finite element
1842
 
const char* UFC_CahnHilliard2DBilinearForm_finite_element_1_1::signature() const
1843
 
{
1844
 
    return "FiniteElement('Lagrange', 'triangle', 1)";
1845
 
}
1846
 
 
1847
 
/// Return the cell shape
1848
 
ufc::shape UFC_CahnHilliard2DBilinearForm_finite_element_1_1::cell_shape() const
1849
 
{
1850
 
    return ufc::triangle;
1851
 
}
1852
 
 
1853
 
/// Return the dimension of the finite element function space
1854
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_1_1::space_dimension() const
1855
 
{
1856
 
    return 3;
1857
 
}
1858
 
 
1859
 
/// Return the rank of the value space
1860
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_1_1::value_rank() const
1861
 
{
1862
 
    return 0;
1863
 
}
1864
 
 
1865
 
/// Return the dimension of the value space for axis i
1866
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_1_1::value_dimension(unsigned int i) const
1867
 
{
1868
 
    return 1;
1869
 
}
1870
 
 
1871
 
/// Evaluate basis function i at given point in cell
1872
 
void UFC_CahnHilliard2DBilinearForm_finite_element_1_1::evaluate_basis(unsigned int i,
1873
 
                                   double* values,
1874
 
                                   const double* coordinates,
1875
 
                                   const ufc::cell& c) const
1876
 
{
1877
 
    // Extract vertex coordinates
1878
 
    const double * const * element_coordinates = c.coordinates;
1879
 
    
1880
 
    // Compute Jacobian of affine map from reference cell
1881
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1882
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1883
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1884
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1885
 
      
1886
 
    // Compute determinant of Jacobian
1887
 
    const double detJ = J_00*J_11 - J_01*J_10;
1888
 
    
1889
 
    // Compute inverse of Jacobian
1890
 
    
1891
 
    // Get coordinates and map to the reference (UFC) element
1892
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1893
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
1894
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1895
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1896
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
1897
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1898
 
    
1899
 
    // Map coordinates to the reference square
1900
 
    if (std::abs(y - 1.0) < 1e-14)
1901
 
      x = -1.0;
1902
 
    else
1903
 
      x = 2.0 *x/(1.0 - y) - 1.0;
1904
 
    y = 2.0*y - 1.0;
1905
 
    
1906
 
    // Reset values
1907
 
    *values = 0;
1908
 
    
1909
 
    // Map degree of freedom to element degree of freedom
1910
 
    const unsigned int dof = i;
1911
 
    
1912
 
    // Generate scalings
1913
 
    const double scalings_y_0 = 1;
1914
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
1915
 
    
1916
 
    // Compute psitilde_a
1917
 
    const double psitilde_a_0 = 1;
1918
 
    const double psitilde_a_1 = x;
1919
 
    
1920
 
    // Compute psitilde_bs
1921
 
    const double psitilde_bs_0_0 = 1;
1922
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
1923
 
    const double psitilde_bs_1_0 = 1;
1924
 
    
1925
 
    // Compute basisvalues
1926
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
1927
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
1928
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
1929
 
    
1930
 
    // Table(s) of coefficients
1931
 
    const static double coefficients0[3][3] = \
1932
 
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
1933
 
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
1934
 
    {0.471404520791032, 0, 0.333333333333333}};
1935
 
    
1936
 
    // Extract relevant coefficients
1937
 
    const double coeff0_0 = coefficients0[dof][0];
1938
 
    const double coeff0_1 = coefficients0[dof][1];
1939
 
    const double coeff0_2 = coefficients0[dof][2];
1940
 
    
1941
 
    // Compute value(s)
1942
 
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
1943
 
}
1944
 
 
1945
 
/// Evaluate all basis functions at given point in cell
1946
 
void UFC_CahnHilliard2DBilinearForm_finite_element_1_1::evaluate_basis_all(double* values,
1947
 
                                       const double* coordinates,
1948
 
                                       const ufc::cell& c) const
1949
 
{
1950
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
1951
 
}
1952
 
 
1953
 
/// Evaluate order n derivatives of basis function i at given point in cell
1954
 
void UFC_CahnHilliard2DBilinearForm_finite_element_1_1::evaluate_basis_derivatives(unsigned int i,
1955
 
                                               unsigned int n,
1956
 
                                               double* values,
1957
 
                                               const double* coordinates,
1958
 
                                               const ufc::cell& c) const
1959
 
{
1960
 
    // Extract vertex coordinates
1961
 
    const double * const * element_coordinates = c.coordinates;
1962
 
    
1963
 
    // Compute Jacobian of affine map from reference cell
1964
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
1965
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1966
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1967
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1968
 
      
1969
 
    // Compute determinant of Jacobian
1970
 
    const double detJ = J_00*J_11 - J_01*J_10;
1971
 
    
1972
 
    // Compute inverse of Jacobian
1973
 
    
1974
 
    // Get coordinates and map to the reference (UFC) element
1975
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
1976
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
1977
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
1978
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
1979
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
1980
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
1981
 
    
1982
 
    // Map coordinates to the reference square
1983
 
    if (std::abs(y - 1.0) < 1e-14)
1984
 
      x = -1.0;
1985
 
    else
1986
 
      x = 2.0 *x/(1.0 - y) - 1.0;
1987
 
    y = 2.0*y - 1.0;
1988
 
    
1989
 
    // Compute number of derivatives
1990
 
    unsigned int num_derivatives = 1;
1991
 
    
1992
 
    for (unsigned int j = 0; j < n; j++)
1993
 
      num_derivatives *= 2;
1994
 
    
1995
 
    
1996
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
1997
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
1998
 
        
1999
 
    for (unsigned int j = 0; j < num_derivatives; j++)
2000
 
    {
2001
 
      combinations[j] = new unsigned int [n];
2002
 
      for (unsigned int k = 0; k < n; k++)
2003
 
        combinations[j][k] = 0;
2004
 
    }
2005
 
        
2006
 
    // Generate combinations of derivatives
2007
 
    for (unsigned int row = 1; row < num_derivatives; row++)
2008
 
    {
2009
 
      for (unsigned int num = 0; num < row; num++)
2010
 
      {
2011
 
        for (unsigned int col = n-1; col+1 > 0; col--)
2012
 
        {
2013
 
          if (combinations[row][col] + 1 > 1)
2014
 
            combinations[row][col] = 0;
2015
 
          else
2016
 
          {
2017
 
            combinations[row][col] += 1;
2018
 
            break;
2019
 
          }
2020
 
        }
2021
 
      }
2022
 
    }
2023
 
    
2024
 
    // Compute inverse of Jacobian
2025
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
2026
 
    
2027
 
    // Declare transformation matrix
2028
 
    // Declare pointer to two dimensional array and initialise
2029
 
    double **transform = new double *[num_derivatives];
2030
 
        
2031
 
    for (unsigned int j = 0; j < num_derivatives; j++)
2032
 
    {
2033
 
      transform[j] = new double [num_derivatives];
2034
 
      for (unsigned int k = 0; k < num_derivatives; k++)
2035
 
        transform[j][k] = 1;
2036
 
    }
2037
 
    
2038
 
    // Construct transformation matrix
2039
 
    for (unsigned int row = 0; row < num_derivatives; row++)
2040
 
    {
2041
 
      for (unsigned int col = 0; col < num_derivatives; col++)
2042
 
      {
2043
 
        for (unsigned int k = 0; k < n; k++)
2044
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
2045
 
      }
2046
 
    }
2047
 
    
2048
 
    // Reset values
2049
 
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
2050
 
      values[j] = 0;
2051
 
    
2052
 
    // Map degree of freedom to element degree of freedom
2053
 
    const unsigned int dof = i;
2054
 
    
2055
 
    // Generate scalings
2056
 
    const double scalings_y_0 = 1;
2057
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2058
 
    
2059
 
    // Compute psitilde_a
2060
 
    const double psitilde_a_0 = 1;
2061
 
    const double psitilde_a_1 = x;
2062
 
    
2063
 
    // Compute psitilde_bs
2064
 
    const double psitilde_bs_0_0 = 1;
2065
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
2066
 
    const double psitilde_bs_1_0 = 1;
2067
 
    
2068
 
    // Compute basisvalues
2069
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2070
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2071
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2072
 
    
2073
 
    // Table(s) of coefficients
2074
 
    const static double coefficients0[3][3] = \
2075
 
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
2076
 
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
2077
 
    {0.471404520791032, 0, 0.333333333333333}};
2078
 
    
2079
 
    // Interesting (new) part
2080
 
    // Tables of derivatives of the polynomial base (transpose)
2081
 
    const static double dmats0[3][3] = \
2082
 
    {{0, 0, 0},
2083
 
    {4.89897948556636, 0, 0},
2084
 
    {0, 0, 0}};
2085
 
    
2086
 
    const static double dmats1[3][3] = \
2087
 
    {{0, 0, 0},
2088
 
    {2.44948974278318, 0, 0},
2089
 
    {4.24264068711928, 0, 0}};
2090
 
    
2091
 
    // Compute reference derivatives
2092
 
    // Declare pointer to array of derivatives on FIAT element
2093
 
    double *derivatives = new double [num_derivatives];
2094
 
    
2095
 
    // Declare coefficients
2096
 
    double coeff0_0 = 0;
2097
 
    double coeff0_1 = 0;
2098
 
    double coeff0_2 = 0;
2099
 
    
2100
 
    // Declare new coefficients
2101
 
    double new_coeff0_0 = 0;
2102
 
    double new_coeff0_1 = 0;
2103
 
    double new_coeff0_2 = 0;
2104
 
    
2105
 
    // Loop possible derivatives
2106
 
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
2107
 
    {
2108
 
      // Get values from coefficients array
2109
 
      new_coeff0_0 = coefficients0[dof][0];
2110
 
      new_coeff0_1 = coefficients0[dof][1];
2111
 
      new_coeff0_2 = coefficients0[dof][2];
2112
 
    
2113
 
      // Loop derivative order
2114
 
      for (unsigned int j = 0; j < n; j++)
2115
 
      {
2116
 
        // Update old coefficients
2117
 
        coeff0_0 = new_coeff0_0;
2118
 
        coeff0_1 = new_coeff0_1;
2119
 
        coeff0_2 = new_coeff0_2;
2120
 
    
2121
 
        if(combinations[deriv_num][j] == 0)
2122
 
        {
2123
 
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
2124
 
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
2125
 
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
2126
 
        }
2127
 
        if(combinations[deriv_num][j] == 1)
2128
 
        {
2129
 
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
2130
 
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
2131
 
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
2132
 
        }
2133
 
    
2134
 
      }
2135
 
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
2136
 
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
2137
 
    }
2138
 
    
2139
 
    // Transform derivatives back to physical element
2140
 
    for (unsigned int row = 0; row < num_derivatives; row++)
2141
 
    {
2142
 
      for (unsigned int col = 0; col < num_derivatives; col++)
2143
 
      {
2144
 
        values[row] += transform[row][col]*derivatives[col];
2145
 
      }
2146
 
    }
2147
 
    // Delete pointer to array of derivatives on FIAT element
2148
 
    delete [] derivatives;
2149
 
    
2150
 
    // Delete pointer to array of combinations of derivatives and transform
2151
 
    for (unsigned int row = 0; row < num_derivatives; row++)
2152
 
    {
2153
 
      delete [] combinations[row];
2154
 
      delete [] transform[row];
2155
 
    }
2156
 
    
2157
 
    delete [] combinations;
2158
 
    delete [] transform;
2159
 
}
2160
 
 
2161
 
/// Evaluate order n derivatives of all basis functions at given point in cell
2162
 
void UFC_CahnHilliard2DBilinearForm_finite_element_1_1::evaluate_basis_derivatives_all(unsigned int n,
2163
 
                                                   double* values,
2164
 
                                                   const double* coordinates,
2165
 
                                                   const ufc::cell& c) const
2166
 
{
2167
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
2168
 
}
2169
 
 
2170
 
/// Evaluate linear functional for dof i on the function f
2171
 
double UFC_CahnHilliard2DBilinearForm_finite_element_1_1::evaluate_dof(unsigned int i,
2172
 
                                   const ufc::function& f,
2173
 
                                   const ufc::cell& c) const
2174
 
{
2175
 
    // The reference points, direction and weights:
2176
 
    const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
2177
 
    const static double W[3][1] = {{1}, {1}, {1}};
2178
 
    const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
2179
 
    
2180
 
    const double * const * x = c.coordinates;
2181
 
    double result = 0.0;
2182
 
    // Iterate over the points:
2183
 
    // Evaluate basis functions for affine mapping
2184
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
2185
 
    const double w1 = X[i][0][0];
2186
 
    const double w2 = X[i][0][1];
2187
 
    
2188
 
    // Compute affine mapping y = F(X)
2189
 
    double y[2];
2190
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
2191
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
2192
 
    
2193
 
    // Evaluate function at physical points
2194
 
    double values[1];
2195
 
    f.evaluate(values, y, c);
2196
 
    
2197
 
    // Map function values using appropriate mapping
2198
 
    // Affine map: Do nothing
2199
 
    
2200
 
    // Note that we do not map the weights (yet).
2201
 
    
2202
 
    // Take directional components
2203
 
    for(int k = 0; k < 1; k++)
2204
 
      result += values[k]*D[i][0][k];
2205
 
    // Multiply by weights 
2206
 
    result *= W[i][0];
2207
 
    
2208
 
    return result;
2209
 
}
2210
 
 
2211
 
/// Evaluate linear functionals for all dofs on the function f
2212
 
void UFC_CahnHilliard2DBilinearForm_finite_element_1_1::evaluate_dofs(double* values,
2213
 
                                  const ufc::function& f,
2214
 
                                  const ufc::cell& c) const
2215
 
{
2216
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2217
 
}
2218
 
 
2219
 
/// Interpolate vertex values from dof values
2220
 
void UFC_CahnHilliard2DBilinearForm_finite_element_1_1::interpolate_vertex_values(double* vertex_values,
2221
 
                                              const double* dof_values,
2222
 
                                              const ufc::cell& c) const
2223
 
{
2224
 
    // Evaluate at vertices and use affine mapping
2225
 
    vertex_values[0] = dof_values[0];
2226
 
    vertex_values[1] = dof_values[1];
2227
 
    vertex_values[2] = dof_values[2];
2228
 
}
2229
 
 
2230
 
/// Return the number of sub elements (for a mixed element)
2231
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_1_1::num_sub_elements() const
2232
 
{
2233
 
    return 1;
2234
 
}
2235
 
 
2236
 
/// Create a new finite element for sub element i (for a mixed element)
2237
 
ufc::finite_element* UFC_CahnHilliard2DBilinearForm_finite_element_1_1::create_sub_element(unsigned int i) const
2238
 
{
2239
 
    return new UFC_CahnHilliard2DBilinearForm_finite_element_1_1();
2240
 
}
2241
 
 
2242
 
 
2243
 
/// Constructor
2244
 
UFC_CahnHilliard2DBilinearForm_finite_element_1::UFC_CahnHilliard2DBilinearForm_finite_element_1() : ufc::finite_element()
2245
 
{
2246
 
    // Do nothing
2247
 
}
2248
 
 
2249
 
/// Destructor
2250
 
UFC_CahnHilliard2DBilinearForm_finite_element_1::~UFC_CahnHilliard2DBilinearForm_finite_element_1()
2251
 
{
2252
 
    // Do nothing
2253
 
}
2254
 
 
2255
 
/// Return a string identifying the finite element
2256
 
const char* UFC_CahnHilliard2DBilinearForm_finite_element_1::signature() const
2257
 
{
2258
 
    return "MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
2259
 
}
2260
 
 
2261
 
/// Return the cell shape
2262
 
ufc::shape UFC_CahnHilliard2DBilinearForm_finite_element_1::cell_shape() const
2263
 
{
2264
 
    return ufc::triangle;
2265
 
}
2266
 
 
2267
 
/// Return the dimension of the finite element function space
2268
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_1::space_dimension() const
2269
 
{
2270
 
    return 6;
2271
 
}
2272
 
 
2273
 
/// Return the rank of the value space
2274
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_1::value_rank() const
2275
 
{
2276
 
    return 1;
2277
 
}
2278
 
 
2279
 
/// Return the dimension of the value space for axis i
2280
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_1::value_dimension(unsigned int i) const
2281
 
{
2282
 
    return 2;
2283
 
}
2284
 
 
2285
 
/// Evaluate basis function i at given point in cell
2286
 
void UFC_CahnHilliard2DBilinearForm_finite_element_1::evaluate_basis(unsigned int i,
2287
 
                                   double* values,
2288
 
                                   const double* coordinates,
2289
 
                                   const ufc::cell& c) const
2290
 
{
2291
 
    // Extract vertex coordinates
2292
 
    const double * const * element_coordinates = c.coordinates;
2293
 
    
2294
 
    // Compute Jacobian of affine map from reference cell
2295
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
2296
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
2297
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
2298
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
2299
 
      
2300
 
    // Compute determinant of Jacobian
2301
 
    const double detJ = J_00*J_11 - J_01*J_10;
2302
 
    
2303
 
    // Compute inverse of Jacobian
2304
 
    
2305
 
    // Get coordinates and map to the reference (UFC) element
2306
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
2307
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
2308
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
2309
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
2310
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
2311
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
2312
 
    
2313
 
    // Map coordinates to the reference square
2314
 
    if (std::abs(y - 1.0) < 1e-14)
2315
 
      x = -1.0;
2316
 
    else
2317
 
      x = 2.0 *x/(1.0 - y) - 1.0;
2318
 
    y = 2.0*y - 1.0;
2319
 
    
2320
 
    // Reset values
2321
 
    values[0] = 0;
2322
 
    values[1] = 0;
2323
 
    
2324
 
    if (0 <= i && i <= 2)
2325
 
    {
2326
 
      // Map degree of freedom to element degree of freedom
2327
 
      const unsigned int dof = i;
2328
 
    
2329
 
      // Generate scalings
2330
 
      const double scalings_y_0 = 1;
2331
 
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2332
 
    
2333
 
      // Compute psitilde_a
2334
 
      const double psitilde_a_0 = 1;
2335
 
      const double psitilde_a_1 = x;
2336
 
    
2337
 
      // Compute psitilde_bs
2338
 
      const double psitilde_bs_0_0 = 1;
2339
 
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
2340
 
      const double psitilde_bs_1_0 = 1;
2341
 
    
2342
 
      // Compute basisvalues
2343
 
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2344
 
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2345
 
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2346
 
    
2347
 
      // Table(s) of coefficients
2348
 
      const static double coefficients0[3][3] =   \
2349
 
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
2350
 
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
2351
 
      {0.471404520791032, 0, 0.333333333333333}};
2352
 
    
2353
 
      // Extract relevant coefficients
2354
 
      const double coeff0_0 =   coefficients0[dof][0];
2355
 
      const double coeff0_1 =   coefficients0[dof][1];
2356
 
      const double coeff0_2 =   coefficients0[dof][2];
2357
 
    
2358
 
      // Compute value(s)
2359
 
      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
2360
 
    }
2361
 
    
2362
 
    if (3 <= i && i <= 5)
2363
 
    {
2364
 
      // Map degree of freedom to element degree of freedom
2365
 
      const unsigned int dof = i - 3;
2366
 
    
2367
 
      // Generate scalings
2368
 
      const double scalings_y_0 = 1;
2369
 
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2370
 
    
2371
 
      // Compute psitilde_a
2372
 
      const double psitilde_a_0 = 1;
2373
 
      const double psitilde_a_1 = x;
2374
 
    
2375
 
      // Compute psitilde_bs
2376
 
      const double psitilde_bs_0_0 = 1;
2377
 
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
2378
 
      const double psitilde_bs_1_0 = 1;
2379
 
    
2380
 
      // Compute basisvalues
2381
 
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2382
 
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2383
 
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2384
 
    
2385
 
      // Table(s) of coefficients
2386
 
      const static double coefficients0[3][3] =   \
2387
 
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
2388
 
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
2389
 
      {0.471404520791032, 0, 0.333333333333333}};
2390
 
    
2391
 
      // Extract relevant coefficients
2392
 
      const double coeff0_0 =   coefficients0[dof][0];
2393
 
      const double coeff0_1 =   coefficients0[dof][1];
2394
 
      const double coeff0_2 =   coefficients0[dof][2];
2395
 
    
2396
 
      // Compute value(s)
2397
 
      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
2398
 
    }
2399
 
    
2400
 
}
2401
 
 
2402
 
/// Evaluate all basis functions at given point in cell
2403
 
void UFC_CahnHilliard2DBilinearForm_finite_element_1::evaluate_basis_all(double* values,
2404
 
                                       const double* coordinates,
2405
 
                                       const ufc::cell& c) const
2406
 
{
2407
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
2408
 
}
2409
 
 
2410
 
/// Evaluate order n derivatives of basis function i at given point in cell
2411
 
void UFC_CahnHilliard2DBilinearForm_finite_element_1::evaluate_basis_derivatives(unsigned int i,
2412
 
                                               unsigned int n,
2413
 
                                               double* values,
2414
 
                                               const double* coordinates,
2415
 
                                               const ufc::cell& c) const
2416
 
{
2417
 
    // Extract vertex coordinates
2418
 
    const double * const * element_coordinates = c.coordinates;
2419
 
    
2420
 
    // Compute Jacobian of affine map from reference cell
2421
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
2422
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
2423
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
2424
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
2425
 
      
2426
 
    // Compute determinant of Jacobian
2427
 
    const double detJ = J_00*J_11 - J_01*J_10;
2428
 
    
2429
 
    // Compute inverse of Jacobian
2430
 
    
2431
 
    // Get coordinates and map to the reference (UFC) element
2432
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
2433
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
2434
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
2435
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
2436
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
2437
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
2438
 
    
2439
 
    // Map coordinates to the reference square
2440
 
    if (std::abs(y - 1.0) < 1e-14)
2441
 
      x = -1.0;
2442
 
    else
2443
 
      x = 2.0 *x/(1.0 - y) - 1.0;
2444
 
    y = 2.0*y - 1.0;
2445
 
    
2446
 
    // Compute number of derivatives
2447
 
    unsigned int num_derivatives = 1;
2448
 
    
2449
 
    for (unsigned int j = 0; j < n; j++)
2450
 
      num_derivatives *= 2;
2451
 
    
2452
 
    
2453
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
2454
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
2455
 
        
2456
 
    for (unsigned int j = 0; j < num_derivatives; j++)
2457
 
    {
2458
 
      combinations[j] = new unsigned int [n];
2459
 
      for (unsigned int k = 0; k < n; k++)
2460
 
        combinations[j][k] = 0;
2461
 
    }
2462
 
        
2463
 
    // Generate combinations of derivatives
2464
 
    for (unsigned int row = 1; row < num_derivatives; row++)
2465
 
    {
2466
 
      for (unsigned int num = 0; num < row; num++)
2467
 
      {
2468
 
        for (unsigned int col = n-1; col+1 > 0; col--)
2469
 
        {
2470
 
          if (combinations[row][col] + 1 > 1)
2471
 
            combinations[row][col] = 0;
2472
 
          else
2473
 
          {
2474
 
            combinations[row][col] += 1;
2475
 
            break;
2476
 
          }
2477
 
        }
2478
 
      }
2479
 
    }
2480
 
    
2481
 
    // Compute inverse of Jacobian
2482
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
2483
 
    
2484
 
    // Declare transformation matrix
2485
 
    // Declare pointer to two dimensional array and initialise
2486
 
    double **transform = new double *[num_derivatives];
2487
 
        
2488
 
    for (unsigned int j = 0; j < num_derivatives; j++)
2489
 
    {
2490
 
      transform[j] = new double [num_derivatives];
2491
 
      for (unsigned int k = 0; k < num_derivatives; k++)
2492
 
        transform[j][k] = 1;
2493
 
    }
2494
 
    
2495
 
    // Construct transformation matrix
2496
 
    for (unsigned int row = 0; row < num_derivatives; row++)
2497
 
    {
2498
 
      for (unsigned int col = 0; col < num_derivatives; col++)
2499
 
      {
2500
 
        for (unsigned int k = 0; k < n; k++)
2501
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
2502
 
      }
2503
 
    }
2504
 
    
2505
 
    // Reset values
2506
 
    for (unsigned int j = 0; j < 2*num_derivatives; j++)
2507
 
      values[j] = 0;
2508
 
    
2509
 
    if (0 <= i && i <= 2)
2510
 
    {
2511
 
      // Map degree of freedom to element degree of freedom
2512
 
      const unsigned int dof = i;
2513
 
    
2514
 
      // Generate scalings
2515
 
      const double scalings_y_0 = 1;
2516
 
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2517
 
    
2518
 
      // Compute psitilde_a
2519
 
      const double psitilde_a_0 = 1;
2520
 
      const double psitilde_a_1 = x;
2521
 
    
2522
 
      // Compute psitilde_bs
2523
 
      const double psitilde_bs_0_0 = 1;
2524
 
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
2525
 
      const double psitilde_bs_1_0 = 1;
2526
 
    
2527
 
      // Compute basisvalues
2528
 
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2529
 
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2530
 
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2531
 
    
2532
 
      // Table(s) of coefficients
2533
 
      const static double coefficients0[3][3] =   \
2534
 
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
2535
 
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
2536
 
      {0.471404520791032, 0, 0.333333333333333}};
2537
 
    
2538
 
      // Interesting (new) part
2539
 
      // Tables of derivatives of the polynomial base (transpose)
2540
 
      const static double dmats0[3][3] =   \
2541
 
      {{0, 0, 0},
2542
 
      {4.89897948556636, 0, 0},
2543
 
      {0, 0, 0}};
2544
 
    
2545
 
      const static double dmats1[3][3] =   \
2546
 
      {{0, 0, 0},
2547
 
      {2.44948974278318, 0, 0},
2548
 
      {4.24264068711928, 0, 0}};
2549
 
    
2550
 
      // Compute reference derivatives
2551
 
      // Declare pointer to array of derivatives on FIAT element
2552
 
      double *derivatives = new double [num_derivatives];
2553
 
    
2554
 
      // Declare coefficients
2555
 
      double coeff0_0 = 0;
2556
 
      double coeff0_1 = 0;
2557
 
      double coeff0_2 = 0;
2558
 
    
2559
 
      // Declare new coefficients
2560
 
      double new_coeff0_0 = 0;
2561
 
      double new_coeff0_1 = 0;
2562
 
      double new_coeff0_2 = 0;
2563
 
    
2564
 
      // Loop possible derivatives
2565
 
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
2566
 
      {
2567
 
        // Get values from coefficients array
2568
 
        new_coeff0_0 = coefficients0[dof][0];
2569
 
        new_coeff0_1 = coefficients0[dof][1];
2570
 
        new_coeff0_2 = coefficients0[dof][2];
2571
 
    
2572
 
        // Loop derivative order
2573
 
        for (unsigned int j = 0; j < n; j++)
2574
 
        {
2575
 
          // Update old coefficients
2576
 
          coeff0_0 = new_coeff0_0;
2577
 
          coeff0_1 = new_coeff0_1;
2578
 
          coeff0_2 = new_coeff0_2;
2579
 
    
2580
 
          if(combinations[deriv_num][j] == 0)
2581
 
          {
2582
 
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
2583
 
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
2584
 
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
2585
 
          }
2586
 
          if(combinations[deriv_num][j] == 1)
2587
 
          {
2588
 
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
2589
 
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
2590
 
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
2591
 
          }
2592
 
    
2593
 
        }
2594
 
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
2595
 
        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
2596
 
      }
2597
 
    
2598
 
      // Transform derivatives back to physical element
2599
 
      for (unsigned int row = 0; row < num_derivatives; row++)
2600
 
      {
2601
 
        for (unsigned int col = 0; col < num_derivatives; col++)
2602
 
        {
2603
 
          values[row] += transform[row][col]*derivatives[col];
2604
 
        }
2605
 
      }
2606
 
      // Delete pointer to array of derivatives on FIAT element
2607
 
      delete [] derivatives;
2608
 
    
2609
 
      // Delete pointer to array of combinations of derivatives and transform
2610
 
      for (unsigned int row = 0; row < num_derivatives; row++)
2611
 
      {
2612
 
        delete [] combinations[row];
2613
 
        delete [] transform[row];
2614
 
      }
2615
 
    
2616
 
      delete [] combinations;
2617
 
      delete [] transform;
2618
 
    }
2619
 
    
2620
 
    if (3 <= i && i <= 5)
2621
 
    {
2622
 
      // Map degree of freedom to element degree of freedom
2623
 
      const unsigned int dof = i - 3;
2624
 
    
2625
 
      // Generate scalings
2626
 
      const double scalings_y_0 = 1;
2627
 
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2628
 
    
2629
 
      // Compute psitilde_a
2630
 
      const double psitilde_a_0 = 1;
2631
 
      const double psitilde_a_1 = x;
2632
 
    
2633
 
      // Compute psitilde_bs
2634
 
      const double psitilde_bs_0_0 = 1;
2635
 
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
2636
 
      const double psitilde_bs_1_0 = 1;
2637
 
    
2638
 
      // Compute basisvalues
2639
 
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2640
 
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2641
 
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2642
 
    
2643
 
      // Table(s) of coefficients
2644
 
      const static double coefficients0[3][3] =   \
2645
 
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
2646
 
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
2647
 
      {0.471404520791032, 0, 0.333333333333333}};
2648
 
    
2649
 
      // Interesting (new) part
2650
 
      // Tables of derivatives of the polynomial base (transpose)
2651
 
      const static double dmats0[3][3] =   \
2652
 
      {{0, 0, 0},
2653
 
      {4.89897948556636, 0, 0},
2654
 
      {0, 0, 0}};
2655
 
    
2656
 
      const static double dmats1[3][3] =   \
2657
 
      {{0, 0, 0},
2658
 
      {2.44948974278318, 0, 0},
2659
 
      {4.24264068711928, 0, 0}};
2660
 
    
2661
 
      // Compute reference derivatives
2662
 
      // Declare pointer to array of derivatives on FIAT element
2663
 
      double *derivatives = new double [num_derivatives];
2664
 
    
2665
 
      // Declare coefficients
2666
 
      double coeff0_0 = 0;
2667
 
      double coeff0_1 = 0;
2668
 
      double coeff0_2 = 0;
2669
 
    
2670
 
      // Declare new coefficients
2671
 
      double new_coeff0_0 = 0;
2672
 
      double new_coeff0_1 = 0;
2673
 
      double new_coeff0_2 = 0;
2674
 
    
2675
 
      // Loop possible derivatives
2676
 
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
2677
 
      {
2678
 
        // Get values from coefficients array
2679
 
        new_coeff0_0 = coefficients0[dof][0];
2680
 
        new_coeff0_1 = coefficients0[dof][1];
2681
 
        new_coeff0_2 = coefficients0[dof][2];
2682
 
    
2683
 
        // Loop derivative order
2684
 
        for (unsigned int j = 0; j < n; j++)
2685
 
        {
2686
 
          // Update old coefficients
2687
 
          coeff0_0 = new_coeff0_0;
2688
 
          coeff0_1 = new_coeff0_1;
2689
 
          coeff0_2 = new_coeff0_2;
2690
 
    
2691
 
          if(combinations[deriv_num][j] == 0)
2692
 
          {
2693
 
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
2694
 
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
2695
 
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
2696
 
          }
2697
 
          if(combinations[deriv_num][j] == 1)
2698
 
          {
2699
 
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
2700
 
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
2701
 
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
2702
 
          }
2703
 
    
2704
 
        }
2705
 
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
2706
 
        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
2707
 
      }
2708
 
    
2709
 
      // Transform derivatives back to physical element
2710
 
      for (unsigned int row = 0; row < num_derivatives; row++)
2711
 
      {
2712
 
        for (unsigned int col = 0; col < num_derivatives; col++)
2713
 
        {
2714
 
          values[num_derivatives + row] += transform[row][col]*derivatives[col];
2715
 
        }
2716
 
      }
2717
 
      // Delete pointer to array of derivatives on FIAT element
2718
 
      delete [] derivatives;
2719
 
    
2720
 
      // Delete pointer to array of combinations of derivatives and transform
2721
 
      for (unsigned int row = 0; row < num_derivatives; row++)
2722
 
      {
2723
 
        delete [] combinations[row];
2724
 
        delete [] transform[row];
2725
 
      }
2726
 
    
2727
 
      delete [] combinations;
2728
 
      delete [] transform;
2729
 
    }
2730
 
    
2731
 
}
2732
 
 
2733
 
/// Evaluate order n derivatives of all basis functions at given point in cell
2734
 
void UFC_CahnHilliard2DBilinearForm_finite_element_1::evaluate_basis_derivatives_all(unsigned int n,
2735
 
                                                   double* values,
2736
 
                                                   const double* coordinates,
2737
 
                                                   const ufc::cell& c) const
2738
 
{
2739
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
2740
 
}
2741
 
 
2742
 
/// Evaluate linear functional for dof i on the function f
2743
 
double UFC_CahnHilliard2DBilinearForm_finite_element_1::evaluate_dof(unsigned int i,
2744
 
                                   const ufc::function& f,
2745
 
                                   const ufc::cell& c) const
2746
 
{
2747
 
    // The reference points, direction and weights:
2748
 
    const static double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
2749
 
    const static double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
2750
 
    const static double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
2751
 
    
2752
 
    const double * const * x = c.coordinates;
2753
 
    double result = 0.0;
2754
 
    // Iterate over the points:
2755
 
    // Evaluate basis functions for affine mapping
2756
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
2757
 
    const double w1 = X[i][0][0];
2758
 
    const double w2 = X[i][0][1];
2759
 
    
2760
 
    // Compute affine mapping y = F(X)
2761
 
    double y[2];
2762
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
2763
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
2764
 
    
2765
 
    // Evaluate function at physical points
2766
 
    double values[2];
2767
 
    f.evaluate(values, y, c);
2768
 
    
2769
 
    // Map function values using appropriate mapping
2770
 
    // Affine map: Do nothing
2771
 
    
2772
 
    // Note that we do not map the weights (yet).
2773
 
    
2774
 
    // Take directional components
2775
 
    for(int k = 0; k < 2; k++)
2776
 
      result += values[k]*D[i][0][k];
2777
 
    // Multiply by weights 
2778
 
    result *= W[i][0];
2779
 
    
2780
 
    return result;
2781
 
}
2782
 
 
2783
 
/// Evaluate linear functionals for all dofs on the function f
2784
 
void UFC_CahnHilliard2DBilinearForm_finite_element_1::evaluate_dofs(double* values,
2785
 
                                  const ufc::function& f,
2786
 
                                  const ufc::cell& c) const
2787
 
{
2788
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
2789
 
}
2790
 
 
2791
 
/// Interpolate vertex values from dof values
2792
 
void UFC_CahnHilliard2DBilinearForm_finite_element_1::interpolate_vertex_values(double* vertex_values,
2793
 
                                              const double* dof_values,
2794
 
                                              const ufc::cell& c) const
2795
 
{
2796
 
    // Evaluate at vertices and use affine mapping
2797
 
    vertex_values[0] = dof_values[0];
2798
 
    vertex_values[2] = dof_values[1];
2799
 
    vertex_values[4] = dof_values[2];
2800
 
    // Evaluate at vertices and use affine mapping
2801
 
    vertex_values[1] = dof_values[3];
2802
 
    vertex_values[3] = dof_values[4];
2803
 
    vertex_values[5] = dof_values[5];
2804
 
}
2805
 
 
2806
 
/// Return the number of sub elements (for a mixed element)
2807
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_1::num_sub_elements() const
2808
 
{
2809
 
    return 2;
2810
 
}
2811
 
 
2812
 
/// Create a new finite element for sub element i (for a mixed element)
2813
 
ufc::finite_element* UFC_CahnHilliard2DBilinearForm_finite_element_1::create_sub_element(unsigned int i) const
2814
 
{
2815
 
    switch ( i )
2816
 
    {
2817
 
    case 0:
2818
 
      return new UFC_CahnHilliard2DBilinearForm_finite_element_1_0();
2819
 
      break;
2820
 
    case 1:
2821
 
      return new UFC_CahnHilliard2DBilinearForm_finite_element_1_1();
2822
 
      break;
2823
 
    }
2824
 
    return 0;
2825
 
}
2826
 
 
2827
 
 
2828
 
/// Constructor
2829
 
UFC_CahnHilliard2DBilinearForm_finite_element_2_0::UFC_CahnHilliard2DBilinearForm_finite_element_2_0() : ufc::finite_element()
2830
 
{
2831
 
    // Do nothing
2832
 
}
2833
 
 
2834
 
/// Destructor
2835
 
UFC_CahnHilliard2DBilinearForm_finite_element_2_0::~UFC_CahnHilliard2DBilinearForm_finite_element_2_0()
2836
 
{
2837
 
    // Do nothing
2838
 
}
2839
 
 
2840
 
/// Return a string identifying the finite element
2841
 
const char* UFC_CahnHilliard2DBilinearForm_finite_element_2_0::signature() const
2842
 
{
2843
 
    return "FiniteElement('Lagrange', 'triangle', 1)";
2844
 
}
2845
 
 
2846
 
/// Return the cell shape
2847
 
ufc::shape UFC_CahnHilliard2DBilinearForm_finite_element_2_0::cell_shape() const
2848
 
{
2849
 
    return ufc::triangle;
2850
 
}
2851
 
 
2852
 
/// Return the dimension of the finite element function space
2853
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_2_0::space_dimension() const
2854
 
{
2855
 
    return 3;
2856
 
}
2857
 
 
2858
 
/// Return the rank of the value space
2859
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_2_0::value_rank() const
2860
 
{
2861
 
    return 0;
2862
 
}
2863
 
 
2864
 
/// Return the dimension of the value space for axis i
2865
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_2_0::value_dimension(unsigned int i) const
2866
 
{
2867
 
    return 1;
2868
 
}
2869
 
 
2870
 
/// Evaluate basis function i at given point in cell
2871
 
void UFC_CahnHilliard2DBilinearForm_finite_element_2_0::evaluate_basis(unsigned int i,
2872
 
                                   double* values,
2873
 
                                   const double* coordinates,
2874
 
                                   const ufc::cell& c) const
2875
 
{
2876
 
    // Extract vertex coordinates
2877
 
    const double * const * element_coordinates = c.coordinates;
2878
 
    
2879
 
    // Compute Jacobian of affine map from reference cell
2880
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
2881
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
2882
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
2883
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
2884
 
      
2885
 
    // Compute determinant of Jacobian
2886
 
    const double detJ = J_00*J_11 - J_01*J_10;
2887
 
    
2888
 
    // Compute inverse of Jacobian
2889
 
    
2890
 
    // Get coordinates and map to the reference (UFC) element
2891
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
2892
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
2893
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
2894
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
2895
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
2896
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
2897
 
    
2898
 
    // Map coordinates to the reference square
2899
 
    if (std::abs(y - 1.0) < 1e-14)
2900
 
      x = -1.0;
2901
 
    else
2902
 
      x = 2.0 *x/(1.0 - y) - 1.0;
2903
 
    y = 2.0*y - 1.0;
2904
 
    
2905
 
    // Reset values
2906
 
    *values = 0;
2907
 
    
2908
 
    // Map degree of freedom to element degree of freedom
2909
 
    const unsigned int dof = i;
2910
 
    
2911
 
    // Generate scalings
2912
 
    const double scalings_y_0 = 1;
2913
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
2914
 
    
2915
 
    // Compute psitilde_a
2916
 
    const double psitilde_a_0 = 1;
2917
 
    const double psitilde_a_1 = x;
2918
 
    
2919
 
    // Compute psitilde_bs
2920
 
    const double psitilde_bs_0_0 = 1;
2921
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
2922
 
    const double psitilde_bs_1_0 = 1;
2923
 
    
2924
 
    // Compute basisvalues
2925
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
2926
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
2927
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
2928
 
    
2929
 
    // Table(s) of coefficients
2930
 
    const static double coefficients0[3][3] = \
2931
 
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
2932
 
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
2933
 
    {0.471404520791032, 0, 0.333333333333333}};
2934
 
    
2935
 
    // Extract relevant coefficients
2936
 
    const double coeff0_0 = coefficients0[dof][0];
2937
 
    const double coeff0_1 = coefficients0[dof][1];
2938
 
    const double coeff0_2 = coefficients0[dof][2];
2939
 
    
2940
 
    // Compute value(s)
2941
 
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
2942
 
}
2943
 
 
2944
 
/// Evaluate all basis functions at given point in cell
2945
 
void UFC_CahnHilliard2DBilinearForm_finite_element_2_0::evaluate_basis_all(double* values,
2946
 
                                       const double* coordinates,
2947
 
                                       const ufc::cell& c) const
2948
 
{
2949
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
2950
 
}
2951
 
 
2952
 
/// Evaluate order n derivatives of basis function i at given point in cell
2953
 
void UFC_CahnHilliard2DBilinearForm_finite_element_2_0::evaluate_basis_derivatives(unsigned int i,
2954
 
                                               unsigned int n,
2955
 
                                               double* values,
2956
 
                                               const double* coordinates,
2957
 
                                               const ufc::cell& c) const
2958
 
{
2959
 
    // Extract vertex coordinates
2960
 
    const double * const * element_coordinates = c.coordinates;
2961
 
    
2962
 
    // Compute Jacobian of affine map from reference cell
2963
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
2964
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
2965
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
2966
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
2967
 
      
2968
 
    // Compute determinant of Jacobian
2969
 
    const double detJ = J_00*J_11 - J_01*J_10;
2970
 
    
2971
 
    // Compute inverse of Jacobian
2972
 
    
2973
 
    // Get coordinates and map to the reference (UFC) element
2974
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
2975
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
2976
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
2977
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
2978
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
2979
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
2980
 
    
2981
 
    // Map coordinates to the reference square
2982
 
    if (std::abs(y - 1.0) < 1e-14)
2983
 
      x = -1.0;
2984
 
    else
2985
 
      x = 2.0 *x/(1.0 - y) - 1.0;
2986
 
    y = 2.0*y - 1.0;
2987
 
    
2988
 
    // Compute number of derivatives
2989
 
    unsigned int num_derivatives = 1;
2990
 
    
2991
 
    for (unsigned int j = 0; j < n; j++)
2992
 
      num_derivatives *= 2;
2993
 
    
2994
 
    
2995
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
2996
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
2997
 
        
2998
 
    for (unsigned int j = 0; j < num_derivatives; j++)
2999
 
    {
3000
 
      combinations[j] = new unsigned int [n];
3001
 
      for (unsigned int k = 0; k < n; k++)
3002
 
        combinations[j][k] = 0;
3003
 
    }
3004
 
        
3005
 
    // Generate combinations of derivatives
3006
 
    for (unsigned int row = 1; row < num_derivatives; row++)
3007
 
    {
3008
 
      for (unsigned int num = 0; num < row; num++)
3009
 
      {
3010
 
        for (unsigned int col = n-1; col+1 > 0; col--)
3011
 
        {
3012
 
          if (combinations[row][col] + 1 > 1)
3013
 
            combinations[row][col] = 0;
3014
 
          else
3015
 
          {
3016
 
            combinations[row][col] += 1;
3017
 
            break;
3018
 
          }
3019
 
        }
3020
 
      }
3021
 
    }
3022
 
    
3023
 
    // Compute inverse of Jacobian
3024
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
3025
 
    
3026
 
    // Declare transformation matrix
3027
 
    // Declare pointer to two dimensional array and initialise
3028
 
    double **transform = new double *[num_derivatives];
3029
 
        
3030
 
    for (unsigned int j = 0; j < num_derivatives; j++)
3031
 
    {
3032
 
      transform[j] = new double [num_derivatives];
3033
 
      for (unsigned int k = 0; k < num_derivatives; k++)
3034
 
        transform[j][k] = 1;
3035
 
    }
3036
 
    
3037
 
    // Construct transformation matrix
3038
 
    for (unsigned int row = 0; row < num_derivatives; row++)
3039
 
    {
3040
 
      for (unsigned int col = 0; col < num_derivatives; col++)
3041
 
      {
3042
 
        for (unsigned int k = 0; k < n; k++)
3043
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
3044
 
      }
3045
 
    }
3046
 
    
3047
 
    // Reset values
3048
 
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
3049
 
      values[j] = 0;
3050
 
    
3051
 
    // Map degree of freedom to element degree of freedom
3052
 
    const unsigned int dof = i;
3053
 
    
3054
 
    // Generate scalings
3055
 
    const double scalings_y_0 = 1;
3056
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3057
 
    
3058
 
    // Compute psitilde_a
3059
 
    const double psitilde_a_0 = 1;
3060
 
    const double psitilde_a_1 = x;
3061
 
    
3062
 
    // Compute psitilde_bs
3063
 
    const double psitilde_bs_0_0 = 1;
3064
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
3065
 
    const double psitilde_bs_1_0 = 1;
3066
 
    
3067
 
    // Compute basisvalues
3068
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3069
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3070
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3071
 
    
3072
 
    // Table(s) of coefficients
3073
 
    const static double coefficients0[3][3] = \
3074
 
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
3075
 
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
3076
 
    {0.471404520791032, 0, 0.333333333333333}};
3077
 
    
3078
 
    // Interesting (new) part
3079
 
    // Tables of derivatives of the polynomial base (transpose)
3080
 
    const static double dmats0[3][3] = \
3081
 
    {{0, 0, 0},
3082
 
    {4.89897948556636, 0, 0},
3083
 
    {0, 0, 0}};
3084
 
    
3085
 
    const static double dmats1[3][3] = \
3086
 
    {{0, 0, 0},
3087
 
    {2.44948974278318, 0, 0},
3088
 
    {4.24264068711928, 0, 0}};
3089
 
    
3090
 
    // Compute reference derivatives
3091
 
    // Declare pointer to array of derivatives on FIAT element
3092
 
    double *derivatives = new double [num_derivatives];
3093
 
    
3094
 
    // Declare coefficients
3095
 
    double coeff0_0 = 0;
3096
 
    double coeff0_1 = 0;
3097
 
    double coeff0_2 = 0;
3098
 
    
3099
 
    // Declare new coefficients
3100
 
    double new_coeff0_0 = 0;
3101
 
    double new_coeff0_1 = 0;
3102
 
    double new_coeff0_2 = 0;
3103
 
    
3104
 
    // Loop possible derivatives
3105
 
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
3106
 
    {
3107
 
      // Get values from coefficients array
3108
 
      new_coeff0_0 = coefficients0[dof][0];
3109
 
      new_coeff0_1 = coefficients0[dof][1];
3110
 
      new_coeff0_2 = coefficients0[dof][2];
3111
 
    
3112
 
      // Loop derivative order
3113
 
      for (unsigned int j = 0; j < n; j++)
3114
 
      {
3115
 
        // Update old coefficients
3116
 
        coeff0_0 = new_coeff0_0;
3117
 
        coeff0_1 = new_coeff0_1;
3118
 
        coeff0_2 = new_coeff0_2;
3119
 
    
3120
 
        if(combinations[deriv_num][j] == 0)
3121
 
        {
3122
 
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
3123
 
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
3124
 
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
3125
 
        }
3126
 
        if(combinations[deriv_num][j] == 1)
3127
 
        {
3128
 
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
3129
 
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
3130
 
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
3131
 
        }
3132
 
    
3133
 
      }
3134
 
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
3135
 
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
3136
 
    }
3137
 
    
3138
 
    // Transform derivatives back to physical element
3139
 
    for (unsigned int row = 0; row < num_derivatives; row++)
3140
 
    {
3141
 
      for (unsigned int col = 0; col < num_derivatives; col++)
3142
 
      {
3143
 
        values[row] += transform[row][col]*derivatives[col];
3144
 
      }
3145
 
    }
3146
 
    // Delete pointer to array of derivatives on FIAT element
3147
 
    delete [] derivatives;
3148
 
    
3149
 
    // Delete pointer to array of combinations of derivatives and transform
3150
 
    for (unsigned int row = 0; row < num_derivatives; row++)
3151
 
    {
3152
 
      delete [] combinations[row];
3153
 
      delete [] transform[row];
3154
 
    }
3155
 
    
3156
 
    delete [] combinations;
3157
 
    delete [] transform;
3158
 
}
3159
 
 
3160
 
/// Evaluate order n derivatives of all basis functions at given point in cell
3161
 
void UFC_CahnHilliard2DBilinearForm_finite_element_2_0::evaluate_basis_derivatives_all(unsigned int n,
3162
 
                                                   double* values,
3163
 
                                                   const double* coordinates,
3164
 
                                                   const ufc::cell& c) const
3165
 
{
3166
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
3167
 
}
3168
 
 
3169
 
/// Evaluate linear functional for dof i on the function f
3170
 
double UFC_CahnHilliard2DBilinearForm_finite_element_2_0::evaluate_dof(unsigned int i,
3171
 
                                   const ufc::function& f,
3172
 
                                   const ufc::cell& c) const
3173
 
{
3174
 
    // The reference points, direction and weights:
3175
 
    const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
3176
 
    const static double W[3][1] = {{1}, {1}, {1}};
3177
 
    const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
3178
 
    
3179
 
    const double * const * x = c.coordinates;
3180
 
    double result = 0.0;
3181
 
    // Iterate over the points:
3182
 
    // Evaluate basis functions for affine mapping
3183
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
3184
 
    const double w1 = X[i][0][0];
3185
 
    const double w2 = X[i][0][1];
3186
 
    
3187
 
    // Compute affine mapping y = F(X)
3188
 
    double y[2];
3189
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
3190
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
3191
 
    
3192
 
    // Evaluate function at physical points
3193
 
    double values[1];
3194
 
    f.evaluate(values, y, c);
3195
 
    
3196
 
    // Map function values using appropriate mapping
3197
 
    // Affine map: Do nothing
3198
 
    
3199
 
    // Note that we do not map the weights (yet).
3200
 
    
3201
 
    // Take directional components
3202
 
    for(int k = 0; k < 1; k++)
3203
 
      result += values[k]*D[i][0][k];
3204
 
    // Multiply by weights 
3205
 
    result *= W[i][0];
3206
 
    
3207
 
    return result;
3208
 
}
3209
 
 
3210
 
/// Evaluate linear functionals for all dofs on the function f
3211
 
void UFC_CahnHilliard2DBilinearForm_finite_element_2_0::evaluate_dofs(double* values,
3212
 
                                  const ufc::function& f,
3213
 
                                  const ufc::cell& c) const
3214
 
{
3215
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
3216
 
}
3217
 
 
3218
 
/// Interpolate vertex values from dof values
3219
 
void UFC_CahnHilliard2DBilinearForm_finite_element_2_0::interpolate_vertex_values(double* vertex_values,
3220
 
                                              const double* dof_values,
3221
 
                                              const ufc::cell& c) const
3222
 
{
3223
 
    // Evaluate at vertices and use affine mapping
3224
 
    vertex_values[0] = dof_values[0];
3225
 
    vertex_values[1] = dof_values[1];
3226
 
    vertex_values[2] = dof_values[2];
3227
 
}
3228
 
 
3229
 
/// Return the number of sub elements (for a mixed element)
3230
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_2_0::num_sub_elements() const
3231
 
{
3232
 
    return 1;
3233
 
}
3234
 
 
3235
 
/// Create a new finite element for sub element i (for a mixed element)
3236
 
ufc::finite_element* UFC_CahnHilliard2DBilinearForm_finite_element_2_0::create_sub_element(unsigned int i) const
3237
 
{
3238
 
    return new UFC_CahnHilliard2DBilinearForm_finite_element_2_0();
3239
 
}
3240
 
 
3241
 
 
3242
 
/// Constructor
3243
 
UFC_CahnHilliard2DBilinearForm_finite_element_2_1::UFC_CahnHilliard2DBilinearForm_finite_element_2_1() : ufc::finite_element()
3244
 
{
3245
 
    // Do nothing
3246
 
}
3247
 
 
3248
 
/// Destructor
3249
 
UFC_CahnHilliard2DBilinearForm_finite_element_2_1::~UFC_CahnHilliard2DBilinearForm_finite_element_2_1()
3250
 
{
3251
 
    // Do nothing
3252
 
}
3253
 
 
3254
 
/// Return a string identifying the finite element
3255
 
const char* UFC_CahnHilliard2DBilinearForm_finite_element_2_1::signature() const
3256
 
{
3257
 
    return "FiniteElement('Lagrange', 'triangle', 1)";
3258
 
}
3259
 
 
3260
 
/// Return the cell shape
3261
 
ufc::shape UFC_CahnHilliard2DBilinearForm_finite_element_2_1::cell_shape() const
3262
 
{
3263
 
    return ufc::triangle;
3264
 
}
3265
 
 
3266
 
/// Return the dimension of the finite element function space
3267
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_2_1::space_dimension() const
3268
 
{
3269
 
    return 3;
3270
 
}
3271
 
 
3272
 
/// Return the rank of the value space
3273
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_2_1::value_rank() const
3274
 
{
3275
 
    return 0;
3276
 
}
3277
 
 
3278
 
/// Return the dimension of the value space for axis i
3279
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_2_1::value_dimension(unsigned int i) const
3280
 
{
3281
 
    return 1;
3282
 
}
3283
 
 
3284
 
/// Evaluate basis function i at given point in cell
3285
 
void UFC_CahnHilliard2DBilinearForm_finite_element_2_1::evaluate_basis(unsigned int i,
3286
 
                                   double* values,
3287
 
                                   const double* coordinates,
3288
 
                                   const ufc::cell& c) const
3289
 
{
3290
 
    // Extract vertex coordinates
3291
 
    const double * const * element_coordinates = c.coordinates;
3292
 
    
3293
 
    // Compute Jacobian of affine map from reference cell
3294
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
3295
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
3296
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
3297
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
3298
 
      
3299
 
    // Compute determinant of Jacobian
3300
 
    const double detJ = J_00*J_11 - J_01*J_10;
3301
 
    
3302
 
    // Compute inverse of Jacobian
3303
 
    
3304
 
    // Get coordinates and map to the reference (UFC) element
3305
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
3306
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
3307
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
3308
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
3309
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
3310
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
3311
 
    
3312
 
    // Map coordinates to the reference square
3313
 
    if (std::abs(y - 1.0) < 1e-14)
3314
 
      x = -1.0;
3315
 
    else
3316
 
      x = 2.0 *x/(1.0 - y) - 1.0;
3317
 
    y = 2.0*y - 1.0;
3318
 
    
3319
 
    // Reset values
3320
 
    *values = 0;
3321
 
    
3322
 
    // Map degree of freedom to element degree of freedom
3323
 
    const unsigned int dof = i;
3324
 
    
3325
 
    // Generate scalings
3326
 
    const double scalings_y_0 = 1;
3327
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3328
 
    
3329
 
    // Compute psitilde_a
3330
 
    const double psitilde_a_0 = 1;
3331
 
    const double psitilde_a_1 = x;
3332
 
    
3333
 
    // Compute psitilde_bs
3334
 
    const double psitilde_bs_0_0 = 1;
3335
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
3336
 
    const double psitilde_bs_1_0 = 1;
3337
 
    
3338
 
    // Compute basisvalues
3339
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3340
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3341
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3342
 
    
3343
 
    // Table(s) of coefficients
3344
 
    const static double coefficients0[3][3] = \
3345
 
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
3346
 
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
3347
 
    {0.471404520791032, 0, 0.333333333333333}};
3348
 
    
3349
 
    // Extract relevant coefficients
3350
 
    const double coeff0_0 = coefficients0[dof][0];
3351
 
    const double coeff0_1 = coefficients0[dof][1];
3352
 
    const double coeff0_2 = coefficients0[dof][2];
3353
 
    
3354
 
    // Compute value(s)
3355
 
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
3356
 
}
3357
 
 
3358
 
/// Evaluate all basis functions at given point in cell
3359
 
void UFC_CahnHilliard2DBilinearForm_finite_element_2_1::evaluate_basis_all(double* values,
3360
 
                                       const double* coordinates,
3361
 
                                       const ufc::cell& c) const
3362
 
{
3363
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
3364
 
}
3365
 
 
3366
 
/// Evaluate order n derivatives of basis function i at given point in cell
3367
 
void UFC_CahnHilliard2DBilinearForm_finite_element_2_1::evaluate_basis_derivatives(unsigned int i,
3368
 
                                               unsigned int n,
3369
 
                                               double* values,
3370
 
                                               const double* coordinates,
3371
 
                                               const ufc::cell& c) const
3372
 
{
3373
 
    // Extract vertex coordinates
3374
 
    const double * const * element_coordinates = c.coordinates;
3375
 
    
3376
 
    // Compute Jacobian of affine map from reference cell
3377
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
3378
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
3379
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
3380
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
3381
 
      
3382
 
    // Compute determinant of Jacobian
3383
 
    const double detJ = J_00*J_11 - J_01*J_10;
3384
 
    
3385
 
    // Compute inverse of Jacobian
3386
 
    
3387
 
    // Get coordinates and map to the reference (UFC) element
3388
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
3389
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
3390
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
3391
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
3392
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
3393
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
3394
 
    
3395
 
    // Map coordinates to the reference square
3396
 
    if (std::abs(y - 1.0) < 1e-14)
3397
 
      x = -1.0;
3398
 
    else
3399
 
      x = 2.0 *x/(1.0 - y) - 1.0;
3400
 
    y = 2.0*y - 1.0;
3401
 
    
3402
 
    // Compute number of derivatives
3403
 
    unsigned int num_derivatives = 1;
3404
 
    
3405
 
    for (unsigned int j = 0; j < n; j++)
3406
 
      num_derivatives *= 2;
3407
 
    
3408
 
    
3409
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
3410
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
3411
 
        
3412
 
    for (unsigned int j = 0; j < num_derivatives; j++)
3413
 
    {
3414
 
      combinations[j] = new unsigned int [n];
3415
 
      for (unsigned int k = 0; k < n; k++)
3416
 
        combinations[j][k] = 0;
3417
 
    }
3418
 
        
3419
 
    // Generate combinations of derivatives
3420
 
    for (unsigned int row = 1; row < num_derivatives; row++)
3421
 
    {
3422
 
      for (unsigned int num = 0; num < row; num++)
3423
 
      {
3424
 
        for (unsigned int col = n-1; col+1 > 0; col--)
3425
 
        {
3426
 
          if (combinations[row][col] + 1 > 1)
3427
 
            combinations[row][col] = 0;
3428
 
          else
3429
 
          {
3430
 
            combinations[row][col] += 1;
3431
 
            break;
3432
 
          }
3433
 
        }
3434
 
      }
3435
 
    }
3436
 
    
3437
 
    // Compute inverse of Jacobian
3438
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
3439
 
    
3440
 
    // Declare transformation matrix
3441
 
    // Declare pointer to two dimensional array and initialise
3442
 
    double **transform = new double *[num_derivatives];
3443
 
        
3444
 
    for (unsigned int j = 0; j < num_derivatives; j++)
3445
 
    {
3446
 
      transform[j] = new double [num_derivatives];
3447
 
      for (unsigned int k = 0; k < num_derivatives; k++)
3448
 
        transform[j][k] = 1;
3449
 
    }
3450
 
    
3451
 
    // Construct transformation matrix
3452
 
    for (unsigned int row = 0; row < num_derivatives; row++)
3453
 
    {
3454
 
      for (unsigned int col = 0; col < num_derivatives; col++)
3455
 
      {
3456
 
        for (unsigned int k = 0; k < n; k++)
3457
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
3458
 
      }
3459
 
    }
3460
 
    
3461
 
    // Reset values
3462
 
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
3463
 
      values[j] = 0;
3464
 
    
3465
 
    // Map degree of freedom to element degree of freedom
3466
 
    const unsigned int dof = i;
3467
 
    
3468
 
    // Generate scalings
3469
 
    const double scalings_y_0 = 1;
3470
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3471
 
    
3472
 
    // Compute psitilde_a
3473
 
    const double psitilde_a_0 = 1;
3474
 
    const double psitilde_a_1 = x;
3475
 
    
3476
 
    // Compute psitilde_bs
3477
 
    const double psitilde_bs_0_0 = 1;
3478
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
3479
 
    const double psitilde_bs_1_0 = 1;
3480
 
    
3481
 
    // Compute basisvalues
3482
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3483
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3484
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3485
 
    
3486
 
    // Table(s) of coefficients
3487
 
    const static double coefficients0[3][3] = \
3488
 
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
3489
 
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
3490
 
    {0.471404520791032, 0, 0.333333333333333}};
3491
 
    
3492
 
    // Interesting (new) part
3493
 
    // Tables of derivatives of the polynomial base (transpose)
3494
 
    const static double dmats0[3][3] = \
3495
 
    {{0, 0, 0},
3496
 
    {4.89897948556636, 0, 0},
3497
 
    {0, 0, 0}};
3498
 
    
3499
 
    const static double dmats1[3][3] = \
3500
 
    {{0, 0, 0},
3501
 
    {2.44948974278318, 0, 0},
3502
 
    {4.24264068711928, 0, 0}};
3503
 
    
3504
 
    // Compute reference derivatives
3505
 
    // Declare pointer to array of derivatives on FIAT element
3506
 
    double *derivatives = new double [num_derivatives];
3507
 
    
3508
 
    // Declare coefficients
3509
 
    double coeff0_0 = 0;
3510
 
    double coeff0_1 = 0;
3511
 
    double coeff0_2 = 0;
3512
 
    
3513
 
    // Declare new coefficients
3514
 
    double new_coeff0_0 = 0;
3515
 
    double new_coeff0_1 = 0;
3516
 
    double new_coeff0_2 = 0;
3517
 
    
3518
 
    // Loop possible derivatives
3519
 
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
3520
 
    {
3521
 
      // Get values from coefficients array
3522
 
      new_coeff0_0 = coefficients0[dof][0];
3523
 
      new_coeff0_1 = coefficients0[dof][1];
3524
 
      new_coeff0_2 = coefficients0[dof][2];
3525
 
    
3526
 
      // Loop derivative order
3527
 
      for (unsigned int j = 0; j < n; j++)
3528
 
      {
3529
 
        // Update old coefficients
3530
 
        coeff0_0 = new_coeff0_0;
3531
 
        coeff0_1 = new_coeff0_1;
3532
 
        coeff0_2 = new_coeff0_2;
3533
 
    
3534
 
        if(combinations[deriv_num][j] == 0)
3535
 
        {
3536
 
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
3537
 
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
3538
 
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
3539
 
        }
3540
 
        if(combinations[deriv_num][j] == 1)
3541
 
        {
3542
 
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
3543
 
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
3544
 
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
3545
 
        }
3546
 
    
3547
 
      }
3548
 
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
3549
 
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
3550
 
    }
3551
 
    
3552
 
    // Transform derivatives back to physical element
3553
 
    for (unsigned int row = 0; row < num_derivatives; row++)
3554
 
    {
3555
 
      for (unsigned int col = 0; col < num_derivatives; col++)
3556
 
      {
3557
 
        values[row] += transform[row][col]*derivatives[col];
3558
 
      }
3559
 
    }
3560
 
    // Delete pointer to array of derivatives on FIAT element
3561
 
    delete [] derivatives;
3562
 
    
3563
 
    // Delete pointer to array of combinations of derivatives and transform
3564
 
    for (unsigned int row = 0; row < num_derivatives; row++)
3565
 
    {
3566
 
      delete [] combinations[row];
3567
 
      delete [] transform[row];
3568
 
    }
3569
 
    
3570
 
    delete [] combinations;
3571
 
    delete [] transform;
3572
 
}
3573
 
 
3574
 
/// Evaluate order n derivatives of all basis functions at given point in cell
3575
 
void UFC_CahnHilliard2DBilinearForm_finite_element_2_1::evaluate_basis_derivatives_all(unsigned int n,
3576
 
                                                   double* values,
3577
 
                                                   const double* coordinates,
3578
 
                                                   const ufc::cell& c) const
3579
 
{
3580
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
3581
 
}
3582
 
 
3583
 
/// Evaluate linear functional for dof i on the function f
3584
 
double UFC_CahnHilliard2DBilinearForm_finite_element_2_1::evaluate_dof(unsigned int i,
3585
 
                                   const ufc::function& f,
3586
 
                                   const ufc::cell& c) const
3587
 
{
3588
 
    // The reference points, direction and weights:
3589
 
    const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
3590
 
    const static double W[3][1] = {{1}, {1}, {1}};
3591
 
    const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
3592
 
    
3593
 
    const double * const * x = c.coordinates;
3594
 
    double result = 0.0;
3595
 
    // Iterate over the points:
3596
 
    // Evaluate basis functions for affine mapping
3597
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
3598
 
    const double w1 = X[i][0][0];
3599
 
    const double w2 = X[i][0][1];
3600
 
    
3601
 
    // Compute affine mapping y = F(X)
3602
 
    double y[2];
3603
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
3604
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
3605
 
    
3606
 
    // Evaluate function at physical points
3607
 
    double values[1];
3608
 
    f.evaluate(values, y, c);
3609
 
    
3610
 
    // Map function values using appropriate mapping
3611
 
    // Affine map: Do nothing
3612
 
    
3613
 
    // Note that we do not map the weights (yet).
3614
 
    
3615
 
    // Take directional components
3616
 
    for(int k = 0; k < 1; k++)
3617
 
      result += values[k]*D[i][0][k];
3618
 
    // Multiply by weights 
3619
 
    result *= W[i][0];
3620
 
    
3621
 
    return result;
3622
 
}
3623
 
 
3624
 
/// Evaluate linear functionals for all dofs on the function f
3625
 
void UFC_CahnHilliard2DBilinearForm_finite_element_2_1::evaluate_dofs(double* values,
3626
 
                                  const ufc::function& f,
3627
 
                                  const ufc::cell& c) const
3628
 
{
3629
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
3630
 
}
3631
 
 
3632
 
/// Interpolate vertex values from dof values
3633
 
void UFC_CahnHilliard2DBilinearForm_finite_element_2_1::interpolate_vertex_values(double* vertex_values,
3634
 
                                              const double* dof_values,
3635
 
                                              const ufc::cell& c) const
3636
 
{
3637
 
    // Evaluate at vertices and use affine mapping
3638
 
    vertex_values[0] = dof_values[0];
3639
 
    vertex_values[1] = dof_values[1];
3640
 
    vertex_values[2] = dof_values[2];
3641
 
}
3642
 
 
3643
 
/// Return the number of sub elements (for a mixed element)
3644
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_2_1::num_sub_elements() const
3645
 
{
3646
 
    return 1;
3647
 
}
3648
 
 
3649
 
/// Create a new finite element for sub element i (for a mixed element)
3650
 
ufc::finite_element* UFC_CahnHilliard2DBilinearForm_finite_element_2_1::create_sub_element(unsigned int i) const
3651
 
{
3652
 
    return new UFC_CahnHilliard2DBilinearForm_finite_element_2_1();
3653
 
}
3654
 
 
3655
 
 
3656
 
/// Constructor
3657
 
UFC_CahnHilliard2DBilinearForm_finite_element_2::UFC_CahnHilliard2DBilinearForm_finite_element_2() : ufc::finite_element()
3658
 
{
3659
 
    // Do nothing
3660
 
}
3661
 
 
3662
 
/// Destructor
3663
 
UFC_CahnHilliard2DBilinearForm_finite_element_2::~UFC_CahnHilliard2DBilinearForm_finite_element_2()
3664
 
{
3665
 
    // Do nothing
3666
 
}
3667
 
 
3668
 
/// Return a string identifying the finite element
3669
 
const char* UFC_CahnHilliard2DBilinearForm_finite_element_2::signature() const
3670
 
{
3671
 
    return "MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
3672
 
}
3673
 
 
3674
 
/// Return the cell shape
3675
 
ufc::shape UFC_CahnHilliard2DBilinearForm_finite_element_2::cell_shape() const
3676
 
{
3677
 
    return ufc::triangle;
3678
 
}
3679
 
 
3680
 
/// Return the dimension of the finite element function space
3681
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_2::space_dimension() const
3682
 
{
3683
 
    return 6;
3684
 
}
3685
 
 
3686
 
/// Return the rank of the value space
3687
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_2::value_rank() const
3688
 
{
3689
 
    return 1;
3690
 
}
3691
 
 
3692
 
/// Return the dimension of the value space for axis i
3693
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_2::value_dimension(unsigned int i) const
3694
 
{
3695
 
    return 2;
3696
 
}
3697
 
 
3698
 
/// Evaluate basis function i at given point in cell
3699
 
void UFC_CahnHilliard2DBilinearForm_finite_element_2::evaluate_basis(unsigned int i,
3700
 
                                   double* values,
3701
 
                                   const double* coordinates,
3702
 
                                   const ufc::cell& c) const
3703
 
{
3704
 
    // Extract vertex coordinates
3705
 
    const double * const * element_coordinates = c.coordinates;
3706
 
    
3707
 
    // Compute Jacobian of affine map from reference cell
3708
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
3709
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
3710
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
3711
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
3712
 
      
3713
 
    // Compute determinant of Jacobian
3714
 
    const double detJ = J_00*J_11 - J_01*J_10;
3715
 
    
3716
 
    // Compute inverse of Jacobian
3717
 
    
3718
 
    // Get coordinates and map to the reference (UFC) element
3719
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
3720
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
3721
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
3722
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
3723
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
3724
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
3725
 
    
3726
 
    // Map coordinates to the reference square
3727
 
    if (std::abs(y - 1.0) < 1e-14)
3728
 
      x = -1.0;
3729
 
    else
3730
 
      x = 2.0 *x/(1.0 - y) - 1.0;
3731
 
    y = 2.0*y - 1.0;
3732
 
    
3733
 
    // Reset values
3734
 
    values[0] = 0;
3735
 
    values[1] = 0;
3736
 
    
3737
 
    if (0 <= i && i <= 2)
3738
 
    {
3739
 
      // Map degree of freedom to element degree of freedom
3740
 
      const unsigned int dof = i;
3741
 
    
3742
 
      // Generate scalings
3743
 
      const double scalings_y_0 = 1;
3744
 
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3745
 
    
3746
 
      // Compute psitilde_a
3747
 
      const double psitilde_a_0 = 1;
3748
 
      const double psitilde_a_1 = x;
3749
 
    
3750
 
      // Compute psitilde_bs
3751
 
      const double psitilde_bs_0_0 = 1;
3752
 
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
3753
 
      const double psitilde_bs_1_0 = 1;
3754
 
    
3755
 
      // Compute basisvalues
3756
 
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3757
 
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3758
 
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3759
 
    
3760
 
      // Table(s) of coefficients
3761
 
      const static double coefficients0[3][3] =   \
3762
 
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
3763
 
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
3764
 
      {0.471404520791032, 0, 0.333333333333333}};
3765
 
    
3766
 
      // Extract relevant coefficients
3767
 
      const double coeff0_0 =   coefficients0[dof][0];
3768
 
      const double coeff0_1 =   coefficients0[dof][1];
3769
 
      const double coeff0_2 =   coefficients0[dof][2];
3770
 
    
3771
 
      // Compute value(s)
3772
 
      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
3773
 
    }
3774
 
    
3775
 
    if (3 <= i && i <= 5)
3776
 
    {
3777
 
      // Map degree of freedom to element degree of freedom
3778
 
      const unsigned int dof = i - 3;
3779
 
    
3780
 
      // Generate scalings
3781
 
      const double scalings_y_0 = 1;
3782
 
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3783
 
    
3784
 
      // Compute psitilde_a
3785
 
      const double psitilde_a_0 = 1;
3786
 
      const double psitilde_a_1 = x;
3787
 
    
3788
 
      // Compute psitilde_bs
3789
 
      const double psitilde_bs_0_0 = 1;
3790
 
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
3791
 
      const double psitilde_bs_1_0 = 1;
3792
 
    
3793
 
      // Compute basisvalues
3794
 
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3795
 
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3796
 
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3797
 
    
3798
 
      // Table(s) of coefficients
3799
 
      const static double coefficients0[3][3] =   \
3800
 
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
3801
 
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
3802
 
      {0.471404520791032, 0, 0.333333333333333}};
3803
 
    
3804
 
      // Extract relevant coefficients
3805
 
      const double coeff0_0 =   coefficients0[dof][0];
3806
 
      const double coeff0_1 =   coefficients0[dof][1];
3807
 
      const double coeff0_2 =   coefficients0[dof][2];
3808
 
    
3809
 
      // Compute value(s)
3810
 
      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
3811
 
    }
3812
 
    
3813
 
}
3814
 
 
3815
 
/// Evaluate all basis functions at given point in cell
3816
 
void UFC_CahnHilliard2DBilinearForm_finite_element_2::evaluate_basis_all(double* values,
3817
 
                                       const double* coordinates,
3818
 
                                       const ufc::cell& c) const
3819
 
{
3820
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
3821
 
}
3822
 
 
3823
 
/// Evaluate order n derivatives of basis function i at given point in cell
3824
 
void UFC_CahnHilliard2DBilinearForm_finite_element_2::evaluate_basis_derivatives(unsigned int i,
3825
 
                                               unsigned int n,
3826
 
                                               double* values,
3827
 
                                               const double* coordinates,
3828
 
                                               const ufc::cell& c) const
3829
 
{
3830
 
    // Extract vertex coordinates
3831
 
    const double * const * element_coordinates = c.coordinates;
3832
 
    
3833
 
    // Compute Jacobian of affine map from reference cell
3834
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
3835
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
3836
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
3837
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
3838
 
      
3839
 
    // Compute determinant of Jacobian
3840
 
    const double detJ = J_00*J_11 - J_01*J_10;
3841
 
    
3842
 
    // Compute inverse of Jacobian
3843
 
    
3844
 
    // Get coordinates and map to the reference (UFC) element
3845
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
3846
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
3847
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
3848
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
3849
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
3850
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
3851
 
    
3852
 
    // Map coordinates to the reference square
3853
 
    if (std::abs(y - 1.0) < 1e-14)
3854
 
      x = -1.0;
3855
 
    else
3856
 
      x = 2.0 *x/(1.0 - y) - 1.0;
3857
 
    y = 2.0*y - 1.0;
3858
 
    
3859
 
    // Compute number of derivatives
3860
 
    unsigned int num_derivatives = 1;
3861
 
    
3862
 
    for (unsigned int j = 0; j < n; j++)
3863
 
      num_derivatives *= 2;
3864
 
    
3865
 
    
3866
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
3867
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
3868
 
        
3869
 
    for (unsigned int j = 0; j < num_derivatives; j++)
3870
 
    {
3871
 
      combinations[j] = new unsigned int [n];
3872
 
      for (unsigned int k = 0; k < n; k++)
3873
 
        combinations[j][k] = 0;
3874
 
    }
3875
 
        
3876
 
    // Generate combinations of derivatives
3877
 
    for (unsigned int row = 1; row < num_derivatives; row++)
3878
 
    {
3879
 
      for (unsigned int num = 0; num < row; num++)
3880
 
      {
3881
 
        for (unsigned int col = n-1; col+1 > 0; col--)
3882
 
        {
3883
 
          if (combinations[row][col] + 1 > 1)
3884
 
            combinations[row][col] = 0;
3885
 
          else
3886
 
          {
3887
 
            combinations[row][col] += 1;
3888
 
            break;
3889
 
          }
3890
 
        }
3891
 
      }
3892
 
    }
3893
 
    
3894
 
    // Compute inverse of Jacobian
3895
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
3896
 
    
3897
 
    // Declare transformation matrix
3898
 
    // Declare pointer to two dimensional array and initialise
3899
 
    double **transform = new double *[num_derivatives];
3900
 
        
3901
 
    for (unsigned int j = 0; j < num_derivatives; j++)
3902
 
    {
3903
 
      transform[j] = new double [num_derivatives];
3904
 
      for (unsigned int k = 0; k < num_derivatives; k++)
3905
 
        transform[j][k] = 1;
3906
 
    }
3907
 
    
3908
 
    // Construct transformation matrix
3909
 
    for (unsigned int row = 0; row < num_derivatives; row++)
3910
 
    {
3911
 
      for (unsigned int col = 0; col < num_derivatives; col++)
3912
 
      {
3913
 
        for (unsigned int k = 0; k < n; k++)
3914
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
3915
 
      }
3916
 
    }
3917
 
    
3918
 
    // Reset values
3919
 
    for (unsigned int j = 0; j < 2*num_derivatives; j++)
3920
 
      values[j] = 0;
3921
 
    
3922
 
    if (0 <= i && i <= 2)
3923
 
    {
3924
 
      // Map degree of freedom to element degree of freedom
3925
 
      const unsigned int dof = i;
3926
 
    
3927
 
      // Generate scalings
3928
 
      const double scalings_y_0 = 1;
3929
 
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
3930
 
    
3931
 
      // Compute psitilde_a
3932
 
      const double psitilde_a_0 = 1;
3933
 
      const double psitilde_a_1 = x;
3934
 
    
3935
 
      // Compute psitilde_bs
3936
 
      const double psitilde_bs_0_0 = 1;
3937
 
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
3938
 
      const double psitilde_bs_1_0 = 1;
3939
 
    
3940
 
      // Compute basisvalues
3941
 
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
3942
 
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
3943
 
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
3944
 
    
3945
 
      // Table(s) of coefficients
3946
 
      const static double coefficients0[3][3] =   \
3947
 
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
3948
 
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
3949
 
      {0.471404520791032, 0, 0.333333333333333}};
3950
 
    
3951
 
      // Interesting (new) part
3952
 
      // Tables of derivatives of the polynomial base (transpose)
3953
 
      const static double dmats0[3][3] =   \
3954
 
      {{0, 0, 0},
3955
 
      {4.89897948556636, 0, 0},
3956
 
      {0, 0, 0}};
3957
 
    
3958
 
      const static double dmats1[3][3] =   \
3959
 
      {{0, 0, 0},
3960
 
      {2.44948974278318, 0, 0},
3961
 
      {4.24264068711928, 0, 0}};
3962
 
    
3963
 
      // Compute reference derivatives
3964
 
      // Declare pointer to array of derivatives on FIAT element
3965
 
      double *derivatives = new double [num_derivatives];
3966
 
    
3967
 
      // Declare coefficients
3968
 
      double coeff0_0 = 0;
3969
 
      double coeff0_1 = 0;
3970
 
      double coeff0_2 = 0;
3971
 
    
3972
 
      // Declare new coefficients
3973
 
      double new_coeff0_0 = 0;
3974
 
      double new_coeff0_1 = 0;
3975
 
      double new_coeff0_2 = 0;
3976
 
    
3977
 
      // Loop possible derivatives
3978
 
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
3979
 
      {
3980
 
        // Get values from coefficients array
3981
 
        new_coeff0_0 = coefficients0[dof][0];
3982
 
        new_coeff0_1 = coefficients0[dof][1];
3983
 
        new_coeff0_2 = coefficients0[dof][2];
3984
 
    
3985
 
        // Loop derivative order
3986
 
        for (unsigned int j = 0; j < n; j++)
3987
 
        {
3988
 
          // Update old coefficients
3989
 
          coeff0_0 = new_coeff0_0;
3990
 
          coeff0_1 = new_coeff0_1;
3991
 
          coeff0_2 = new_coeff0_2;
3992
 
    
3993
 
          if(combinations[deriv_num][j] == 0)
3994
 
          {
3995
 
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
3996
 
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
3997
 
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
3998
 
          }
3999
 
          if(combinations[deriv_num][j] == 1)
4000
 
          {
4001
 
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
4002
 
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
4003
 
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
4004
 
          }
4005
 
    
4006
 
        }
4007
 
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
4008
 
        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
4009
 
      }
4010
 
    
4011
 
      // Transform derivatives back to physical element
4012
 
      for (unsigned int row = 0; row < num_derivatives; row++)
4013
 
      {
4014
 
        for (unsigned int col = 0; col < num_derivatives; col++)
4015
 
        {
4016
 
          values[row] += transform[row][col]*derivatives[col];
4017
 
        }
4018
 
      }
4019
 
      // Delete pointer to array of derivatives on FIAT element
4020
 
      delete [] derivatives;
4021
 
    
4022
 
      // Delete pointer to array of combinations of derivatives and transform
4023
 
      for (unsigned int row = 0; row < num_derivatives; row++)
4024
 
      {
4025
 
        delete [] combinations[row];
4026
 
        delete [] transform[row];
4027
 
      }
4028
 
    
4029
 
      delete [] combinations;
4030
 
      delete [] transform;
4031
 
    }
4032
 
    
4033
 
    if (3 <= i && i <= 5)
4034
 
    {
4035
 
      // Map degree of freedom to element degree of freedom
4036
 
      const unsigned int dof = i - 3;
4037
 
    
4038
 
      // Generate scalings
4039
 
      const double scalings_y_0 = 1;
4040
 
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
4041
 
    
4042
 
      // Compute psitilde_a
4043
 
      const double psitilde_a_0 = 1;
4044
 
      const double psitilde_a_1 = x;
4045
 
    
4046
 
      // Compute psitilde_bs
4047
 
      const double psitilde_bs_0_0 = 1;
4048
 
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
4049
 
      const double psitilde_bs_1_0 = 1;
4050
 
    
4051
 
      // Compute basisvalues
4052
 
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
4053
 
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
4054
 
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
4055
 
    
4056
 
      // Table(s) of coefficients
4057
 
      const static double coefficients0[3][3] =   \
4058
 
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
4059
 
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
4060
 
      {0.471404520791032, 0, 0.333333333333333}};
4061
 
    
4062
 
      // Interesting (new) part
4063
 
      // Tables of derivatives of the polynomial base (transpose)
4064
 
      const static double dmats0[3][3] =   \
4065
 
      {{0, 0, 0},
4066
 
      {4.89897948556636, 0, 0},
4067
 
      {0, 0, 0}};
4068
 
    
4069
 
      const static double dmats1[3][3] =   \
4070
 
      {{0, 0, 0},
4071
 
      {2.44948974278318, 0, 0},
4072
 
      {4.24264068711928, 0, 0}};
4073
 
    
4074
 
      // Compute reference derivatives
4075
 
      // Declare pointer to array of derivatives on FIAT element
4076
 
      double *derivatives = new double [num_derivatives];
4077
 
    
4078
 
      // Declare coefficients
4079
 
      double coeff0_0 = 0;
4080
 
      double coeff0_1 = 0;
4081
 
      double coeff0_2 = 0;
4082
 
    
4083
 
      // Declare new coefficients
4084
 
      double new_coeff0_0 = 0;
4085
 
      double new_coeff0_1 = 0;
4086
 
      double new_coeff0_2 = 0;
4087
 
    
4088
 
      // Loop possible derivatives
4089
 
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
4090
 
      {
4091
 
        // Get values from coefficients array
4092
 
        new_coeff0_0 = coefficients0[dof][0];
4093
 
        new_coeff0_1 = coefficients0[dof][1];
4094
 
        new_coeff0_2 = coefficients0[dof][2];
4095
 
    
4096
 
        // Loop derivative order
4097
 
        for (unsigned int j = 0; j < n; j++)
4098
 
        {
4099
 
          // Update old coefficients
4100
 
          coeff0_0 = new_coeff0_0;
4101
 
          coeff0_1 = new_coeff0_1;
4102
 
          coeff0_2 = new_coeff0_2;
4103
 
    
4104
 
          if(combinations[deriv_num][j] == 0)
4105
 
          {
4106
 
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
4107
 
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
4108
 
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
4109
 
          }
4110
 
          if(combinations[deriv_num][j] == 1)
4111
 
          {
4112
 
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
4113
 
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
4114
 
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
4115
 
          }
4116
 
    
4117
 
        }
4118
 
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
4119
 
        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
4120
 
      }
4121
 
    
4122
 
      // Transform derivatives back to physical element
4123
 
      for (unsigned int row = 0; row < num_derivatives; row++)
4124
 
      {
4125
 
        for (unsigned int col = 0; col < num_derivatives; col++)
4126
 
        {
4127
 
          values[num_derivatives + row] += transform[row][col]*derivatives[col];
4128
 
        }
4129
 
      }
4130
 
      // Delete pointer to array of derivatives on FIAT element
4131
 
      delete [] derivatives;
4132
 
    
4133
 
      // Delete pointer to array of combinations of derivatives and transform
4134
 
      for (unsigned int row = 0; row < num_derivatives; row++)
4135
 
      {
4136
 
        delete [] combinations[row];
4137
 
        delete [] transform[row];
4138
 
      }
4139
 
    
4140
 
      delete [] combinations;
4141
 
      delete [] transform;
4142
 
    }
4143
 
    
4144
 
}
4145
 
 
4146
 
/// Evaluate order n derivatives of all basis functions at given point in cell
4147
 
void UFC_CahnHilliard2DBilinearForm_finite_element_2::evaluate_basis_derivatives_all(unsigned int n,
4148
 
                                                   double* values,
4149
 
                                                   const double* coordinates,
4150
 
                                                   const ufc::cell& c) const
4151
 
{
4152
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
4153
 
}
4154
 
 
4155
 
/// Evaluate linear functional for dof i on the function f
4156
 
double UFC_CahnHilliard2DBilinearForm_finite_element_2::evaluate_dof(unsigned int i,
4157
 
                                   const ufc::function& f,
4158
 
                                   const ufc::cell& c) const
4159
 
{
4160
 
    // The reference points, direction and weights:
4161
 
    const static double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
4162
 
    const static double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
4163
 
    const static double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
4164
 
    
4165
 
    const double * const * x = c.coordinates;
4166
 
    double result = 0.0;
4167
 
    // Iterate over the points:
4168
 
    // Evaluate basis functions for affine mapping
4169
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
4170
 
    const double w1 = X[i][0][0];
4171
 
    const double w2 = X[i][0][1];
4172
 
    
4173
 
    // Compute affine mapping y = F(X)
4174
 
    double y[2];
4175
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
4176
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
4177
 
    
4178
 
    // Evaluate function at physical points
4179
 
    double values[2];
4180
 
    f.evaluate(values, y, c);
4181
 
    
4182
 
    // Map function values using appropriate mapping
4183
 
    // Affine map: Do nothing
4184
 
    
4185
 
    // Note that we do not map the weights (yet).
4186
 
    
4187
 
    // Take directional components
4188
 
    for(int k = 0; k < 2; k++)
4189
 
      result += values[k]*D[i][0][k];
4190
 
    // Multiply by weights 
4191
 
    result *= W[i][0];
4192
 
    
4193
 
    return result;
4194
 
}
4195
 
 
4196
 
/// Evaluate linear functionals for all dofs on the function f
4197
 
void UFC_CahnHilliard2DBilinearForm_finite_element_2::evaluate_dofs(double* values,
4198
 
                                  const ufc::function& f,
4199
 
                                  const ufc::cell& c) const
4200
 
{
4201
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
4202
 
}
4203
 
 
4204
 
/// Interpolate vertex values from dof values
4205
 
void UFC_CahnHilliard2DBilinearForm_finite_element_2::interpolate_vertex_values(double* vertex_values,
4206
 
                                              const double* dof_values,
4207
 
                                              const ufc::cell& c) const
4208
 
{
4209
 
    // Evaluate at vertices and use affine mapping
4210
 
    vertex_values[0] = dof_values[0];
4211
 
    vertex_values[2] = dof_values[1];
4212
 
    vertex_values[4] = dof_values[2];
4213
 
    // Evaluate at vertices and use affine mapping
4214
 
    vertex_values[1] = dof_values[3];
4215
 
    vertex_values[3] = dof_values[4];
4216
 
    vertex_values[5] = dof_values[5];
4217
 
}
4218
 
 
4219
 
/// Return the number of sub elements (for a mixed element)
4220
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_2::num_sub_elements() const
4221
 
{
4222
 
    return 2;
4223
 
}
4224
 
 
4225
 
/// Create a new finite element for sub element i (for a mixed element)
4226
 
ufc::finite_element* UFC_CahnHilliard2DBilinearForm_finite_element_2::create_sub_element(unsigned int i) const
4227
 
{
4228
 
    switch ( i )
4229
 
    {
4230
 
    case 0:
4231
 
      return new UFC_CahnHilliard2DBilinearForm_finite_element_2_0();
4232
 
      break;
4233
 
    case 1:
4234
 
      return new UFC_CahnHilliard2DBilinearForm_finite_element_2_1();
4235
 
      break;
4236
 
    }
4237
 
    return 0;
4238
 
}
4239
 
 
4240
 
 
4241
 
/// Constructor
4242
 
UFC_CahnHilliard2DBilinearForm_finite_element_3::UFC_CahnHilliard2DBilinearForm_finite_element_3() : ufc::finite_element()
4243
 
{
4244
 
    // Do nothing
4245
 
}
4246
 
 
4247
 
/// Destructor
4248
 
UFC_CahnHilliard2DBilinearForm_finite_element_3::~UFC_CahnHilliard2DBilinearForm_finite_element_3()
4249
 
{
4250
 
    // Do nothing
4251
 
}
4252
 
 
4253
 
/// Return a string identifying the finite element
4254
 
const char* UFC_CahnHilliard2DBilinearForm_finite_element_3::signature() const
4255
 
{
4256
 
    return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
4257
 
}
4258
 
 
4259
 
/// Return the cell shape
4260
 
ufc::shape UFC_CahnHilliard2DBilinearForm_finite_element_3::cell_shape() const
4261
 
{
4262
 
    return ufc::triangle;
4263
 
}
4264
 
 
4265
 
/// Return the dimension of the finite element function space
4266
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_3::space_dimension() const
4267
 
{
4268
 
    return 1;
4269
 
}
4270
 
 
4271
 
/// Return the rank of the value space
4272
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_3::value_rank() const
4273
 
{
4274
 
    return 0;
4275
 
}
4276
 
 
4277
 
/// Return the dimension of the value space for axis i
4278
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_3::value_dimension(unsigned int i) const
4279
 
{
4280
 
    return 1;
4281
 
}
4282
 
 
4283
 
/// Evaluate basis function i at given point in cell
4284
 
void UFC_CahnHilliard2DBilinearForm_finite_element_3::evaluate_basis(unsigned int i,
4285
 
                                   double* values,
4286
 
                                   const double* coordinates,
4287
 
                                   const ufc::cell& c) const
4288
 
{
4289
 
    // Extract vertex coordinates
4290
 
    const double * const * element_coordinates = c.coordinates;
4291
 
    
4292
 
    // Compute Jacobian of affine map from reference cell
4293
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
4294
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
4295
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
4296
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
4297
 
      
4298
 
    // Compute determinant of Jacobian
4299
 
    const double detJ = J_00*J_11 - J_01*J_10;
4300
 
    
4301
 
    // Compute inverse of Jacobian
4302
 
    
4303
 
    // Get coordinates and map to the reference (UFC) element
4304
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
4305
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
4306
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
4307
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
4308
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
4309
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
4310
 
    
4311
 
    // Map coordinates to the reference square
4312
 
    if (std::abs(y - 1.0) < 1e-14)
4313
 
      x = -1.0;
4314
 
    else
4315
 
      x = 2.0 *x/(1.0 - y) - 1.0;
4316
 
    y = 2.0*y - 1.0;
4317
 
    
4318
 
    // Reset values
4319
 
    *values = 0;
4320
 
    
4321
 
    // Map degree of freedom to element degree of freedom
4322
 
    const unsigned int dof = i;
4323
 
    
4324
 
    // Generate scalings
4325
 
    const double scalings_y_0 = 1;
4326
 
    
4327
 
    // Compute psitilde_a
4328
 
    const double psitilde_a_0 = 1;
4329
 
    
4330
 
    // Compute psitilde_bs
4331
 
    const double psitilde_bs_0_0 = 1;
4332
 
    
4333
 
    // Compute basisvalues
4334
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
4335
 
    
4336
 
    // Table(s) of coefficients
4337
 
    const static double coefficients0[1][1] = \
4338
 
    {{1.41421356237309}};
4339
 
    
4340
 
    // Extract relevant coefficients
4341
 
    const double coeff0_0 = coefficients0[dof][0];
4342
 
    
4343
 
    // Compute value(s)
4344
 
    *values = coeff0_0*basisvalue0;
4345
 
}
4346
 
 
4347
 
/// Evaluate all basis functions at given point in cell
4348
 
void UFC_CahnHilliard2DBilinearForm_finite_element_3::evaluate_basis_all(double* values,
4349
 
                                       const double* coordinates,
4350
 
                                       const ufc::cell& c) const
4351
 
{
4352
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
4353
 
}
4354
 
 
4355
 
/// Evaluate order n derivatives of basis function i at given point in cell
4356
 
void UFC_CahnHilliard2DBilinearForm_finite_element_3::evaluate_basis_derivatives(unsigned int i,
4357
 
                                               unsigned int n,
4358
 
                                               double* values,
4359
 
                                               const double* coordinates,
4360
 
                                               const ufc::cell& c) const
4361
 
{
4362
 
    // Extract vertex coordinates
4363
 
    const double * const * element_coordinates = c.coordinates;
4364
 
    
4365
 
    // Compute Jacobian of affine map from reference cell
4366
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
4367
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
4368
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
4369
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
4370
 
      
4371
 
    // Compute determinant of Jacobian
4372
 
    const double detJ = J_00*J_11 - J_01*J_10;
4373
 
    
4374
 
    // Compute inverse of Jacobian
4375
 
    
4376
 
    // Get coordinates and map to the reference (UFC) element
4377
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
4378
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
4379
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
4380
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
4381
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
4382
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
4383
 
    
4384
 
    // Map coordinates to the reference square
4385
 
    if (std::abs(y - 1.0) < 1e-14)
4386
 
      x = -1.0;
4387
 
    else
4388
 
      x = 2.0 *x/(1.0 - y) - 1.0;
4389
 
    y = 2.0*y - 1.0;
4390
 
    
4391
 
    // Compute number of derivatives
4392
 
    unsigned int num_derivatives = 1;
4393
 
    
4394
 
    for (unsigned int j = 0; j < n; j++)
4395
 
      num_derivatives *= 2;
4396
 
    
4397
 
    
4398
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
4399
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
4400
 
        
4401
 
    for (unsigned int j = 0; j < num_derivatives; j++)
4402
 
    {
4403
 
      combinations[j] = new unsigned int [n];
4404
 
      for (unsigned int k = 0; k < n; k++)
4405
 
        combinations[j][k] = 0;
4406
 
    }
4407
 
        
4408
 
    // Generate combinations of derivatives
4409
 
    for (unsigned int row = 1; row < num_derivatives; row++)
4410
 
    {
4411
 
      for (unsigned int num = 0; num < row; num++)
4412
 
      {
4413
 
        for (unsigned int col = n-1; col+1 > 0; col--)
4414
 
        {
4415
 
          if (combinations[row][col] + 1 > 1)
4416
 
            combinations[row][col] = 0;
4417
 
          else
4418
 
          {
4419
 
            combinations[row][col] += 1;
4420
 
            break;
4421
 
          }
4422
 
        }
4423
 
      }
4424
 
    }
4425
 
    
4426
 
    // Compute inverse of Jacobian
4427
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
4428
 
    
4429
 
    // Declare transformation matrix
4430
 
    // Declare pointer to two dimensional array and initialise
4431
 
    double **transform = new double *[num_derivatives];
4432
 
        
4433
 
    for (unsigned int j = 0; j < num_derivatives; j++)
4434
 
    {
4435
 
      transform[j] = new double [num_derivatives];
4436
 
      for (unsigned int k = 0; k < num_derivatives; k++)
4437
 
        transform[j][k] = 1;
4438
 
    }
4439
 
    
4440
 
    // Construct transformation matrix
4441
 
    for (unsigned int row = 0; row < num_derivatives; row++)
4442
 
    {
4443
 
      for (unsigned int col = 0; col < num_derivatives; col++)
4444
 
      {
4445
 
        for (unsigned int k = 0; k < n; k++)
4446
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
4447
 
      }
4448
 
    }
4449
 
    
4450
 
    // Reset values
4451
 
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
4452
 
      values[j] = 0;
4453
 
    
4454
 
    // Map degree of freedom to element degree of freedom
4455
 
    const unsigned int dof = i;
4456
 
    
4457
 
    // Generate scalings
4458
 
    const double scalings_y_0 = 1;
4459
 
    
4460
 
    // Compute psitilde_a
4461
 
    const double psitilde_a_0 = 1;
4462
 
    
4463
 
    // Compute psitilde_bs
4464
 
    const double psitilde_bs_0_0 = 1;
4465
 
    
4466
 
    // Compute basisvalues
4467
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
4468
 
    
4469
 
    // Table(s) of coefficients
4470
 
    const static double coefficients0[1][1] = \
4471
 
    {{1.41421356237309}};
4472
 
    
4473
 
    // Interesting (new) part
4474
 
    // Tables of derivatives of the polynomial base (transpose)
4475
 
    const static double dmats0[1][1] = \
4476
 
    {{0}};
4477
 
    
4478
 
    const static double dmats1[1][1] = \
4479
 
    {{0}};
4480
 
    
4481
 
    // Compute reference derivatives
4482
 
    // Declare pointer to array of derivatives on FIAT element
4483
 
    double *derivatives = new double [num_derivatives];
4484
 
    
4485
 
    // Declare coefficients
4486
 
    double coeff0_0 = 0;
4487
 
    
4488
 
    // Declare new coefficients
4489
 
    double new_coeff0_0 = 0;
4490
 
    
4491
 
    // Loop possible derivatives
4492
 
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
4493
 
    {
4494
 
      // Get values from coefficients array
4495
 
      new_coeff0_0 = coefficients0[dof][0];
4496
 
    
4497
 
      // Loop derivative order
4498
 
      for (unsigned int j = 0; j < n; j++)
4499
 
      {
4500
 
        // Update old coefficients
4501
 
        coeff0_0 = new_coeff0_0;
4502
 
    
4503
 
        if(combinations[deriv_num][j] == 0)
4504
 
        {
4505
 
          new_coeff0_0 = coeff0_0*dmats0[0][0];
4506
 
        }
4507
 
        if(combinations[deriv_num][j] == 1)
4508
 
        {
4509
 
          new_coeff0_0 = coeff0_0*dmats1[0][0];
4510
 
        }
4511
 
    
4512
 
      }
4513
 
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
4514
 
      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
4515
 
    }
4516
 
    
4517
 
    // Transform derivatives back to physical element
4518
 
    for (unsigned int row = 0; row < num_derivatives; row++)
4519
 
    {
4520
 
      for (unsigned int col = 0; col < num_derivatives; col++)
4521
 
      {
4522
 
        values[row] += transform[row][col]*derivatives[col];
4523
 
      }
4524
 
    }
4525
 
    // Delete pointer to array of derivatives on FIAT element
4526
 
    delete [] derivatives;
4527
 
    
4528
 
    // Delete pointer to array of combinations of derivatives and transform
4529
 
    for (unsigned int row = 0; row < num_derivatives; row++)
4530
 
    {
4531
 
      delete [] combinations[row];
4532
 
      delete [] transform[row];
4533
 
    }
4534
 
    
4535
 
    delete [] combinations;
4536
 
    delete [] transform;
4537
 
}
4538
 
 
4539
 
/// Evaluate order n derivatives of all basis functions at given point in cell
4540
 
void UFC_CahnHilliard2DBilinearForm_finite_element_3::evaluate_basis_derivatives_all(unsigned int n,
4541
 
                                                   double* values,
4542
 
                                                   const double* coordinates,
4543
 
                                                   const ufc::cell& c) const
4544
 
{
4545
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
4546
 
}
4547
 
 
4548
 
/// Evaluate linear functional for dof i on the function f
4549
 
double UFC_CahnHilliard2DBilinearForm_finite_element_3::evaluate_dof(unsigned int i,
4550
 
                                   const ufc::function& f,
4551
 
                                   const ufc::cell& c) const
4552
 
{
4553
 
    // The reference points, direction and weights:
4554
 
    const static double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
4555
 
    const static double W[1][1] = {{1}};
4556
 
    const static double D[1][1][1] = {{{1}}};
4557
 
    
4558
 
    const double * const * x = c.coordinates;
4559
 
    double result = 0.0;
4560
 
    // Iterate over the points:
4561
 
    // Evaluate basis functions for affine mapping
4562
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
4563
 
    const double w1 = X[i][0][0];
4564
 
    const double w2 = X[i][0][1];
4565
 
    
4566
 
    // Compute affine mapping y = F(X)
4567
 
    double y[2];
4568
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
4569
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
4570
 
    
4571
 
    // Evaluate function at physical points
4572
 
    double values[1];
4573
 
    f.evaluate(values, y, c);
4574
 
    
4575
 
    // Map function values using appropriate mapping
4576
 
    // Affine map: Do nothing
4577
 
    
4578
 
    // Note that we do not map the weights (yet).
4579
 
    
4580
 
    // Take directional components
4581
 
    for(int k = 0; k < 1; k++)
4582
 
      result += values[k]*D[i][0][k];
4583
 
    // Multiply by weights 
4584
 
    result *= W[i][0];
4585
 
    
4586
 
    return result;
4587
 
}
4588
 
 
4589
 
/// Evaluate linear functionals for all dofs on the function f
4590
 
void UFC_CahnHilliard2DBilinearForm_finite_element_3::evaluate_dofs(double* values,
4591
 
                                  const ufc::function& f,
4592
 
                                  const ufc::cell& c) const
4593
 
{
4594
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
4595
 
}
4596
 
 
4597
 
/// Interpolate vertex values from dof values
4598
 
void UFC_CahnHilliard2DBilinearForm_finite_element_3::interpolate_vertex_values(double* vertex_values,
4599
 
                                              const double* dof_values,
4600
 
                                              const ufc::cell& c) const
4601
 
{
4602
 
    // Evaluate at vertices and use affine mapping
4603
 
    vertex_values[0] = dof_values[0];
4604
 
    vertex_values[1] = dof_values[0];
4605
 
    vertex_values[2] = dof_values[0];
4606
 
}
4607
 
 
4608
 
/// Return the number of sub elements (for a mixed element)
4609
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_3::num_sub_elements() const
4610
 
{
4611
 
    return 1;
4612
 
}
4613
 
 
4614
 
/// Create a new finite element for sub element i (for a mixed element)
4615
 
ufc::finite_element* UFC_CahnHilliard2DBilinearForm_finite_element_3::create_sub_element(unsigned int i) const
4616
 
{
4617
 
    return new UFC_CahnHilliard2DBilinearForm_finite_element_3();
4618
 
}
4619
 
 
4620
 
 
4621
 
/// Constructor
4622
 
UFC_CahnHilliard2DBilinearForm_finite_element_4::UFC_CahnHilliard2DBilinearForm_finite_element_4() : ufc::finite_element()
4623
 
{
4624
 
    // Do nothing
4625
 
}
4626
 
 
4627
 
/// Destructor
4628
 
UFC_CahnHilliard2DBilinearForm_finite_element_4::~UFC_CahnHilliard2DBilinearForm_finite_element_4()
4629
 
{
4630
 
    // Do nothing
4631
 
}
4632
 
 
4633
 
/// Return a string identifying the finite element
4634
 
const char* UFC_CahnHilliard2DBilinearForm_finite_element_4::signature() const
4635
 
{
4636
 
    return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
4637
 
}
4638
 
 
4639
 
/// Return the cell shape
4640
 
ufc::shape UFC_CahnHilliard2DBilinearForm_finite_element_4::cell_shape() const
4641
 
{
4642
 
    return ufc::triangle;
4643
 
}
4644
 
 
4645
 
/// Return the dimension of the finite element function space
4646
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_4::space_dimension() const
4647
 
{
4648
 
    return 1;
4649
 
}
4650
 
 
4651
 
/// Return the rank of the value space
4652
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_4::value_rank() const
4653
 
{
4654
 
    return 0;
4655
 
}
4656
 
 
4657
 
/// Return the dimension of the value space for axis i
4658
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_4::value_dimension(unsigned int i) const
4659
 
{
4660
 
    return 1;
4661
 
}
4662
 
 
4663
 
/// Evaluate basis function i at given point in cell
4664
 
void UFC_CahnHilliard2DBilinearForm_finite_element_4::evaluate_basis(unsigned int i,
4665
 
                                   double* values,
4666
 
                                   const double* coordinates,
4667
 
                                   const ufc::cell& c) const
4668
 
{
4669
 
    // Extract vertex coordinates
4670
 
    const double * const * element_coordinates = c.coordinates;
4671
 
    
4672
 
    // Compute Jacobian of affine map from reference cell
4673
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
4674
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
4675
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
4676
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
4677
 
      
4678
 
    // Compute determinant of Jacobian
4679
 
    const double detJ = J_00*J_11 - J_01*J_10;
4680
 
    
4681
 
    // Compute inverse of Jacobian
4682
 
    
4683
 
    // Get coordinates and map to the reference (UFC) element
4684
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
4685
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
4686
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
4687
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
4688
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
4689
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
4690
 
    
4691
 
    // Map coordinates to the reference square
4692
 
    if (std::abs(y - 1.0) < 1e-14)
4693
 
      x = -1.0;
4694
 
    else
4695
 
      x = 2.0 *x/(1.0 - y) - 1.0;
4696
 
    y = 2.0*y - 1.0;
4697
 
    
4698
 
    // Reset values
4699
 
    *values = 0;
4700
 
    
4701
 
    // Map degree of freedom to element degree of freedom
4702
 
    const unsigned int dof = i;
4703
 
    
4704
 
    // Generate scalings
4705
 
    const double scalings_y_0 = 1;
4706
 
    
4707
 
    // Compute psitilde_a
4708
 
    const double psitilde_a_0 = 1;
4709
 
    
4710
 
    // Compute psitilde_bs
4711
 
    const double psitilde_bs_0_0 = 1;
4712
 
    
4713
 
    // Compute basisvalues
4714
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
4715
 
    
4716
 
    // Table(s) of coefficients
4717
 
    const static double coefficients0[1][1] = \
4718
 
    {{1.41421356237309}};
4719
 
    
4720
 
    // Extract relevant coefficients
4721
 
    const double coeff0_0 = coefficients0[dof][0];
4722
 
    
4723
 
    // Compute value(s)
4724
 
    *values = coeff0_0*basisvalue0;
4725
 
}
4726
 
 
4727
 
/// Evaluate all basis functions at given point in cell
4728
 
void UFC_CahnHilliard2DBilinearForm_finite_element_4::evaluate_basis_all(double* values,
4729
 
                                       const double* coordinates,
4730
 
                                       const ufc::cell& c) const
4731
 
{
4732
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
4733
 
}
4734
 
 
4735
 
/// Evaluate order n derivatives of basis function i at given point in cell
4736
 
void UFC_CahnHilliard2DBilinearForm_finite_element_4::evaluate_basis_derivatives(unsigned int i,
4737
 
                                               unsigned int n,
4738
 
                                               double* values,
4739
 
                                               const double* coordinates,
4740
 
                                               const ufc::cell& c) const
4741
 
{
4742
 
    // Extract vertex coordinates
4743
 
    const double * const * element_coordinates = c.coordinates;
4744
 
    
4745
 
    // Compute Jacobian of affine map from reference cell
4746
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
4747
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
4748
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
4749
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
4750
 
      
4751
 
    // Compute determinant of Jacobian
4752
 
    const double detJ = J_00*J_11 - J_01*J_10;
4753
 
    
4754
 
    // Compute inverse of Jacobian
4755
 
    
4756
 
    // Get coordinates and map to the reference (UFC) element
4757
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
4758
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
4759
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
4760
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
4761
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
4762
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
4763
 
    
4764
 
    // Map coordinates to the reference square
4765
 
    if (std::abs(y - 1.0) < 1e-14)
4766
 
      x = -1.0;
4767
 
    else
4768
 
      x = 2.0 *x/(1.0 - y) - 1.0;
4769
 
    y = 2.0*y - 1.0;
4770
 
    
4771
 
    // Compute number of derivatives
4772
 
    unsigned int num_derivatives = 1;
4773
 
    
4774
 
    for (unsigned int j = 0; j < n; j++)
4775
 
      num_derivatives *= 2;
4776
 
    
4777
 
    
4778
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
4779
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
4780
 
        
4781
 
    for (unsigned int j = 0; j < num_derivatives; j++)
4782
 
    {
4783
 
      combinations[j] = new unsigned int [n];
4784
 
      for (unsigned int k = 0; k < n; k++)
4785
 
        combinations[j][k] = 0;
4786
 
    }
4787
 
        
4788
 
    // Generate combinations of derivatives
4789
 
    for (unsigned int row = 1; row < num_derivatives; row++)
4790
 
    {
4791
 
      for (unsigned int num = 0; num < row; num++)
4792
 
      {
4793
 
        for (unsigned int col = n-1; col+1 > 0; col--)
4794
 
        {
4795
 
          if (combinations[row][col] + 1 > 1)
4796
 
            combinations[row][col] = 0;
4797
 
          else
4798
 
          {
4799
 
            combinations[row][col] += 1;
4800
 
            break;
4801
 
          }
4802
 
        }
4803
 
      }
4804
 
    }
4805
 
    
4806
 
    // Compute inverse of Jacobian
4807
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
4808
 
    
4809
 
    // Declare transformation matrix
4810
 
    // Declare pointer to two dimensional array and initialise
4811
 
    double **transform = new double *[num_derivatives];
4812
 
        
4813
 
    for (unsigned int j = 0; j < num_derivatives; j++)
4814
 
    {
4815
 
      transform[j] = new double [num_derivatives];
4816
 
      for (unsigned int k = 0; k < num_derivatives; k++)
4817
 
        transform[j][k] = 1;
4818
 
    }
4819
 
    
4820
 
    // Construct transformation matrix
4821
 
    for (unsigned int row = 0; row < num_derivatives; row++)
4822
 
    {
4823
 
      for (unsigned int col = 0; col < num_derivatives; col++)
4824
 
      {
4825
 
        for (unsigned int k = 0; k < n; k++)
4826
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
4827
 
      }
4828
 
    }
4829
 
    
4830
 
    // Reset values
4831
 
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
4832
 
      values[j] = 0;
4833
 
    
4834
 
    // Map degree of freedom to element degree of freedom
4835
 
    const unsigned int dof = i;
4836
 
    
4837
 
    // Generate scalings
4838
 
    const double scalings_y_0 = 1;
4839
 
    
4840
 
    // Compute psitilde_a
4841
 
    const double psitilde_a_0 = 1;
4842
 
    
4843
 
    // Compute psitilde_bs
4844
 
    const double psitilde_bs_0_0 = 1;
4845
 
    
4846
 
    // Compute basisvalues
4847
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
4848
 
    
4849
 
    // Table(s) of coefficients
4850
 
    const static double coefficients0[1][1] = \
4851
 
    {{1.41421356237309}};
4852
 
    
4853
 
    // Interesting (new) part
4854
 
    // Tables of derivatives of the polynomial base (transpose)
4855
 
    const static double dmats0[1][1] = \
4856
 
    {{0}};
4857
 
    
4858
 
    const static double dmats1[1][1] = \
4859
 
    {{0}};
4860
 
    
4861
 
    // Compute reference derivatives
4862
 
    // Declare pointer to array of derivatives on FIAT element
4863
 
    double *derivatives = new double [num_derivatives];
4864
 
    
4865
 
    // Declare coefficients
4866
 
    double coeff0_0 = 0;
4867
 
    
4868
 
    // Declare new coefficients
4869
 
    double new_coeff0_0 = 0;
4870
 
    
4871
 
    // Loop possible derivatives
4872
 
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
4873
 
    {
4874
 
      // Get values from coefficients array
4875
 
      new_coeff0_0 = coefficients0[dof][0];
4876
 
    
4877
 
      // Loop derivative order
4878
 
      for (unsigned int j = 0; j < n; j++)
4879
 
      {
4880
 
        // Update old coefficients
4881
 
        coeff0_0 = new_coeff0_0;
4882
 
    
4883
 
        if(combinations[deriv_num][j] == 0)
4884
 
        {
4885
 
          new_coeff0_0 = coeff0_0*dmats0[0][0];
4886
 
        }
4887
 
        if(combinations[deriv_num][j] == 1)
4888
 
        {
4889
 
          new_coeff0_0 = coeff0_0*dmats1[0][0];
4890
 
        }
4891
 
    
4892
 
      }
4893
 
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
4894
 
      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
4895
 
    }
4896
 
    
4897
 
    // Transform derivatives back to physical element
4898
 
    for (unsigned int row = 0; row < num_derivatives; row++)
4899
 
    {
4900
 
      for (unsigned int col = 0; col < num_derivatives; col++)
4901
 
      {
4902
 
        values[row] += transform[row][col]*derivatives[col];
4903
 
      }
4904
 
    }
4905
 
    // Delete pointer to array of derivatives on FIAT element
4906
 
    delete [] derivatives;
4907
 
    
4908
 
    // Delete pointer to array of combinations of derivatives and transform
4909
 
    for (unsigned int row = 0; row < num_derivatives; row++)
4910
 
    {
4911
 
      delete [] combinations[row];
4912
 
      delete [] transform[row];
4913
 
    }
4914
 
    
4915
 
    delete [] combinations;
4916
 
    delete [] transform;
4917
 
}
4918
 
 
4919
 
/// Evaluate order n derivatives of all basis functions at given point in cell
4920
 
void UFC_CahnHilliard2DBilinearForm_finite_element_4::evaluate_basis_derivatives_all(unsigned int n,
4921
 
                                                   double* values,
4922
 
                                                   const double* coordinates,
4923
 
                                                   const ufc::cell& c) const
4924
 
{
4925
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
4926
 
}
4927
 
 
4928
 
/// Evaluate linear functional for dof i on the function f
4929
 
double UFC_CahnHilliard2DBilinearForm_finite_element_4::evaluate_dof(unsigned int i,
4930
 
                                   const ufc::function& f,
4931
 
                                   const ufc::cell& c) const
4932
 
{
4933
 
    // The reference points, direction and weights:
4934
 
    const static double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
4935
 
    const static double W[1][1] = {{1}};
4936
 
    const static double D[1][1][1] = {{{1}}};
4937
 
    
4938
 
    const double * const * x = c.coordinates;
4939
 
    double result = 0.0;
4940
 
    // Iterate over the points:
4941
 
    // Evaluate basis functions for affine mapping
4942
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
4943
 
    const double w1 = X[i][0][0];
4944
 
    const double w2 = X[i][0][1];
4945
 
    
4946
 
    // Compute affine mapping y = F(X)
4947
 
    double y[2];
4948
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
4949
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
4950
 
    
4951
 
    // Evaluate function at physical points
4952
 
    double values[1];
4953
 
    f.evaluate(values, y, c);
4954
 
    
4955
 
    // Map function values using appropriate mapping
4956
 
    // Affine map: Do nothing
4957
 
    
4958
 
    // Note that we do not map the weights (yet).
4959
 
    
4960
 
    // Take directional components
4961
 
    for(int k = 0; k < 1; k++)
4962
 
      result += values[k]*D[i][0][k];
4963
 
    // Multiply by weights 
4964
 
    result *= W[i][0];
4965
 
    
4966
 
    return result;
4967
 
}
4968
 
 
4969
 
/// Evaluate linear functionals for all dofs on the function f
4970
 
void UFC_CahnHilliard2DBilinearForm_finite_element_4::evaluate_dofs(double* values,
4971
 
                                  const ufc::function& f,
4972
 
                                  const ufc::cell& c) const
4973
 
{
4974
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
4975
 
}
4976
 
 
4977
 
/// Interpolate vertex values from dof values
4978
 
void UFC_CahnHilliard2DBilinearForm_finite_element_4::interpolate_vertex_values(double* vertex_values,
4979
 
                                              const double* dof_values,
4980
 
                                              const ufc::cell& c) const
4981
 
{
4982
 
    // Evaluate at vertices and use affine mapping
4983
 
    vertex_values[0] = dof_values[0];
4984
 
    vertex_values[1] = dof_values[0];
4985
 
    vertex_values[2] = dof_values[0];
4986
 
}
4987
 
 
4988
 
/// Return the number of sub elements (for a mixed element)
4989
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_4::num_sub_elements() const
4990
 
{
4991
 
    return 1;
4992
 
}
4993
 
 
4994
 
/// Create a new finite element for sub element i (for a mixed element)
4995
 
ufc::finite_element* UFC_CahnHilliard2DBilinearForm_finite_element_4::create_sub_element(unsigned int i) const
4996
 
{
4997
 
    return new UFC_CahnHilliard2DBilinearForm_finite_element_4();
4998
 
}
4999
 
 
5000
 
 
5001
 
/// Constructor
5002
 
UFC_CahnHilliard2DBilinearForm_finite_element_5::UFC_CahnHilliard2DBilinearForm_finite_element_5() : ufc::finite_element()
5003
 
{
5004
 
    // Do nothing
5005
 
}
5006
 
 
5007
 
/// Destructor
5008
 
UFC_CahnHilliard2DBilinearForm_finite_element_5::~UFC_CahnHilliard2DBilinearForm_finite_element_5()
5009
 
{
5010
 
    // Do nothing
5011
 
}
5012
 
 
5013
 
/// Return a string identifying the finite element
5014
 
const char* UFC_CahnHilliard2DBilinearForm_finite_element_5::signature() const
5015
 
{
5016
 
    return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
5017
 
}
5018
 
 
5019
 
/// Return the cell shape
5020
 
ufc::shape UFC_CahnHilliard2DBilinearForm_finite_element_5::cell_shape() const
5021
 
{
5022
 
    return ufc::triangle;
5023
 
}
5024
 
 
5025
 
/// Return the dimension of the finite element function space
5026
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_5::space_dimension() const
5027
 
{
5028
 
    return 1;
5029
 
}
5030
 
 
5031
 
/// Return the rank of the value space
5032
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_5::value_rank() const
5033
 
{
5034
 
    return 0;
5035
 
}
5036
 
 
5037
 
/// Return the dimension of the value space for axis i
5038
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_5::value_dimension(unsigned int i) const
5039
 
{
5040
 
    return 1;
5041
 
}
5042
 
 
5043
 
/// Evaluate basis function i at given point in cell
5044
 
void UFC_CahnHilliard2DBilinearForm_finite_element_5::evaluate_basis(unsigned int i,
5045
 
                                   double* values,
5046
 
                                   const double* coordinates,
5047
 
                                   const ufc::cell& c) const
5048
 
{
5049
 
    // Extract vertex coordinates
5050
 
    const double * const * element_coordinates = c.coordinates;
5051
 
    
5052
 
    // Compute Jacobian of affine map from reference cell
5053
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
5054
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
5055
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
5056
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
5057
 
      
5058
 
    // Compute determinant of Jacobian
5059
 
    const double detJ = J_00*J_11 - J_01*J_10;
5060
 
    
5061
 
    // Compute inverse of Jacobian
5062
 
    
5063
 
    // Get coordinates and map to the reference (UFC) element
5064
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
5065
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
5066
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
5067
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
5068
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
5069
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
5070
 
    
5071
 
    // Map coordinates to the reference square
5072
 
    if (std::abs(y - 1.0) < 1e-14)
5073
 
      x = -1.0;
5074
 
    else
5075
 
      x = 2.0 *x/(1.0 - y) - 1.0;
5076
 
    y = 2.0*y - 1.0;
5077
 
    
5078
 
    // Reset values
5079
 
    *values = 0;
5080
 
    
5081
 
    // Map degree of freedom to element degree of freedom
5082
 
    const unsigned int dof = i;
5083
 
    
5084
 
    // Generate scalings
5085
 
    const double scalings_y_0 = 1;
5086
 
    
5087
 
    // Compute psitilde_a
5088
 
    const double psitilde_a_0 = 1;
5089
 
    
5090
 
    // Compute psitilde_bs
5091
 
    const double psitilde_bs_0_0 = 1;
5092
 
    
5093
 
    // Compute basisvalues
5094
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
5095
 
    
5096
 
    // Table(s) of coefficients
5097
 
    const static double coefficients0[1][1] = \
5098
 
    {{1.41421356237309}};
5099
 
    
5100
 
    // Extract relevant coefficients
5101
 
    const double coeff0_0 = coefficients0[dof][0];
5102
 
    
5103
 
    // Compute value(s)
5104
 
    *values = coeff0_0*basisvalue0;
5105
 
}
5106
 
 
5107
 
/// Evaluate all basis functions at given point in cell
5108
 
void UFC_CahnHilliard2DBilinearForm_finite_element_5::evaluate_basis_all(double* values,
5109
 
                                       const double* coordinates,
5110
 
                                       const ufc::cell& c) const
5111
 
{
5112
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
5113
 
}
5114
 
 
5115
 
/// Evaluate order n derivatives of basis function i at given point in cell
5116
 
void UFC_CahnHilliard2DBilinearForm_finite_element_5::evaluate_basis_derivatives(unsigned int i,
5117
 
                                               unsigned int n,
5118
 
                                               double* values,
5119
 
                                               const double* coordinates,
5120
 
                                               const ufc::cell& c) const
5121
 
{
5122
 
    // Extract vertex coordinates
5123
 
    const double * const * element_coordinates = c.coordinates;
5124
 
    
5125
 
    // Compute Jacobian of affine map from reference cell
5126
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
5127
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
5128
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
5129
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
5130
 
      
5131
 
    // Compute determinant of Jacobian
5132
 
    const double detJ = J_00*J_11 - J_01*J_10;
5133
 
    
5134
 
    // Compute inverse of Jacobian
5135
 
    
5136
 
    // Get coordinates and map to the reference (UFC) element
5137
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
5138
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
5139
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
5140
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
5141
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
5142
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
5143
 
    
5144
 
    // Map coordinates to the reference square
5145
 
    if (std::abs(y - 1.0) < 1e-14)
5146
 
      x = -1.0;
5147
 
    else
5148
 
      x = 2.0 *x/(1.0 - y) - 1.0;
5149
 
    y = 2.0*y - 1.0;
5150
 
    
5151
 
    // Compute number of derivatives
5152
 
    unsigned int num_derivatives = 1;
5153
 
    
5154
 
    for (unsigned int j = 0; j < n; j++)
5155
 
      num_derivatives *= 2;
5156
 
    
5157
 
    
5158
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
5159
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
5160
 
        
5161
 
    for (unsigned int j = 0; j < num_derivatives; j++)
5162
 
    {
5163
 
      combinations[j] = new unsigned int [n];
5164
 
      for (unsigned int k = 0; k < n; k++)
5165
 
        combinations[j][k] = 0;
5166
 
    }
5167
 
        
5168
 
    // Generate combinations of derivatives
5169
 
    for (unsigned int row = 1; row < num_derivatives; row++)
5170
 
    {
5171
 
      for (unsigned int num = 0; num < row; num++)
5172
 
      {
5173
 
        for (unsigned int col = n-1; col+1 > 0; col--)
5174
 
        {
5175
 
          if (combinations[row][col] + 1 > 1)
5176
 
            combinations[row][col] = 0;
5177
 
          else
5178
 
          {
5179
 
            combinations[row][col] += 1;
5180
 
            break;
5181
 
          }
5182
 
        }
5183
 
      }
5184
 
    }
5185
 
    
5186
 
    // Compute inverse of Jacobian
5187
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
5188
 
    
5189
 
    // Declare transformation matrix
5190
 
    // Declare pointer to two dimensional array and initialise
5191
 
    double **transform = new double *[num_derivatives];
5192
 
        
5193
 
    for (unsigned int j = 0; j < num_derivatives; j++)
5194
 
    {
5195
 
      transform[j] = new double [num_derivatives];
5196
 
      for (unsigned int k = 0; k < num_derivatives; k++)
5197
 
        transform[j][k] = 1;
5198
 
    }
5199
 
    
5200
 
    // Construct transformation matrix
5201
 
    for (unsigned int row = 0; row < num_derivatives; row++)
5202
 
    {
5203
 
      for (unsigned int col = 0; col < num_derivatives; col++)
5204
 
      {
5205
 
        for (unsigned int k = 0; k < n; k++)
5206
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
5207
 
      }
5208
 
    }
5209
 
    
5210
 
    // Reset values
5211
 
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
5212
 
      values[j] = 0;
5213
 
    
5214
 
    // Map degree of freedom to element degree of freedom
5215
 
    const unsigned int dof = i;
5216
 
    
5217
 
    // Generate scalings
5218
 
    const double scalings_y_0 = 1;
5219
 
    
5220
 
    // Compute psitilde_a
5221
 
    const double psitilde_a_0 = 1;
5222
 
    
5223
 
    // Compute psitilde_bs
5224
 
    const double psitilde_bs_0_0 = 1;
5225
 
    
5226
 
    // Compute basisvalues
5227
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
5228
 
    
5229
 
    // Table(s) of coefficients
5230
 
    const static double coefficients0[1][1] = \
5231
 
    {{1.41421356237309}};
5232
 
    
5233
 
    // Interesting (new) part
5234
 
    // Tables of derivatives of the polynomial base (transpose)
5235
 
    const static double dmats0[1][1] = \
5236
 
    {{0}};
5237
 
    
5238
 
    const static double dmats1[1][1] = \
5239
 
    {{0}};
5240
 
    
5241
 
    // Compute reference derivatives
5242
 
    // Declare pointer to array of derivatives on FIAT element
5243
 
    double *derivatives = new double [num_derivatives];
5244
 
    
5245
 
    // Declare coefficients
5246
 
    double coeff0_0 = 0;
5247
 
    
5248
 
    // Declare new coefficients
5249
 
    double new_coeff0_0 = 0;
5250
 
    
5251
 
    // Loop possible derivatives
5252
 
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
5253
 
    {
5254
 
      // Get values from coefficients array
5255
 
      new_coeff0_0 = coefficients0[dof][0];
5256
 
    
5257
 
      // Loop derivative order
5258
 
      for (unsigned int j = 0; j < n; j++)
5259
 
      {
5260
 
        // Update old coefficients
5261
 
        coeff0_0 = new_coeff0_0;
5262
 
    
5263
 
        if(combinations[deriv_num][j] == 0)
5264
 
        {
5265
 
          new_coeff0_0 = coeff0_0*dmats0[0][0];
5266
 
        }
5267
 
        if(combinations[deriv_num][j] == 1)
5268
 
        {
5269
 
          new_coeff0_0 = coeff0_0*dmats1[0][0];
5270
 
        }
5271
 
    
5272
 
      }
5273
 
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
5274
 
      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
5275
 
    }
5276
 
    
5277
 
    // Transform derivatives back to physical element
5278
 
    for (unsigned int row = 0; row < num_derivatives; row++)
5279
 
    {
5280
 
      for (unsigned int col = 0; col < num_derivatives; col++)
5281
 
      {
5282
 
        values[row] += transform[row][col]*derivatives[col];
5283
 
      }
5284
 
    }
5285
 
    // Delete pointer to array of derivatives on FIAT element
5286
 
    delete [] derivatives;
5287
 
    
5288
 
    // Delete pointer to array of combinations of derivatives and transform
5289
 
    for (unsigned int row = 0; row < num_derivatives; row++)
5290
 
    {
5291
 
      delete [] combinations[row];
5292
 
      delete [] transform[row];
5293
 
    }
5294
 
    
5295
 
    delete [] combinations;
5296
 
    delete [] transform;
5297
 
}
5298
 
 
5299
 
/// Evaluate order n derivatives of all basis functions at given point in cell
5300
 
void UFC_CahnHilliard2DBilinearForm_finite_element_5::evaluate_basis_derivatives_all(unsigned int n,
5301
 
                                                   double* values,
5302
 
                                                   const double* coordinates,
5303
 
                                                   const ufc::cell& c) const
5304
 
{
5305
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
5306
 
}
5307
 
 
5308
 
/// Evaluate linear functional for dof i on the function f
5309
 
double UFC_CahnHilliard2DBilinearForm_finite_element_5::evaluate_dof(unsigned int i,
5310
 
                                   const ufc::function& f,
5311
 
                                   const ufc::cell& c) const
5312
 
{
5313
 
    // The reference points, direction and weights:
5314
 
    const static double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
5315
 
    const static double W[1][1] = {{1}};
5316
 
    const static double D[1][1][1] = {{{1}}};
5317
 
    
5318
 
    const double * const * x = c.coordinates;
5319
 
    double result = 0.0;
5320
 
    // Iterate over the points:
5321
 
    // Evaluate basis functions for affine mapping
5322
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
5323
 
    const double w1 = X[i][0][0];
5324
 
    const double w2 = X[i][0][1];
5325
 
    
5326
 
    // Compute affine mapping y = F(X)
5327
 
    double y[2];
5328
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
5329
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
5330
 
    
5331
 
    // Evaluate function at physical points
5332
 
    double values[1];
5333
 
    f.evaluate(values, y, c);
5334
 
    
5335
 
    // Map function values using appropriate mapping
5336
 
    // Affine map: Do nothing
5337
 
    
5338
 
    // Note that we do not map the weights (yet).
5339
 
    
5340
 
    // Take directional components
5341
 
    for(int k = 0; k < 1; k++)
5342
 
      result += values[k]*D[i][0][k];
5343
 
    // Multiply by weights 
5344
 
    result *= W[i][0];
5345
 
    
5346
 
    return result;
5347
 
}
5348
 
 
5349
 
/// Evaluate linear functionals for all dofs on the function f
5350
 
void UFC_CahnHilliard2DBilinearForm_finite_element_5::evaluate_dofs(double* values,
5351
 
                                  const ufc::function& f,
5352
 
                                  const ufc::cell& c) const
5353
 
{
5354
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
5355
 
}
5356
 
 
5357
 
/// Interpolate vertex values from dof values
5358
 
void UFC_CahnHilliard2DBilinearForm_finite_element_5::interpolate_vertex_values(double* vertex_values,
5359
 
                                              const double* dof_values,
5360
 
                                              const ufc::cell& c) const
5361
 
{
5362
 
    // Evaluate at vertices and use affine mapping
5363
 
    vertex_values[0] = dof_values[0];
5364
 
    vertex_values[1] = dof_values[0];
5365
 
    vertex_values[2] = dof_values[0];
5366
 
}
5367
 
 
5368
 
/// Return the number of sub elements (for a mixed element)
5369
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_5::num_sub_elements() const
5370
 
{
5371
 
    return 1;
5372
 
}
5373
 
 
5374
 
/// Create a new finite element for sub element i (for a mixed element)
5375
 
ufc::finite_element* UFC_CahnHilliard2DBilinearForm_finite_element_5::create_sub_element(unsigned int i) const
5376
 
{
5377
 
    return new UFC_CahnHilliard2DBilinearForm_finite_element_5();
5378
 
}
5379
 
 
5380
 
 
5381
 
/// Constructor
5382
 
UFC_CahnHilliard2DBilinearForm_finite_element_6::UFC_CahnHilliard2DBilinearForm_finite_element_6() : ufc::finite_element()
5383
 
{
5384
 
    // Do nothing
5385
 
}
5386
 
 
5387
 
/// Destructor
5388
 
UFC_CahnHilliard2DBilinearForm_finite_element_6::~UFC_CahnHilliard2DBilinearForm_finite_element_6()
5389
 
{
5390
 
    // Do nothing
5391
 
}
5392
 
 
5393
 
/// Return a string identifying the finite element
5394
 
const char* UFC_CahnHilliard2DBilinearForm_finite_element_6::signature() const
5395
 
{
5396
 
    return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
5397
 
}
5398
 
 
5399
 
/// Return the cell shape
5400
 
ufc::shape UFC_CahnHilliard2DBilinearForm_finite_element_6::cell_shape() const
5401
 
{
5402
 
    return ufc::triangle;
5403
 
}
5404
 
 
5405
 
/// Return the dimension of the finite element function space
5406
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_6::space_dimension() const
5407
 
{
5408
 
    return 1;
5409
 
}
5410
 
 
5411
 
/// Return the rank of the value space
5412
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_6::value_rank() const
5413
 
{
5414
 
    return 0;
5415
 
}
5416
 
 
5417
 
/// Return the dimension of the value space for axis i
5418
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_6::value_dimension(unsigned int i) const
5419
 
{
5420
 
    return 1;
5421
 
}
5422
 
 
5423
 
/// Evaluate basis function i at given point in cell
5424
 
void UFC_CahnHilliard2DBilinearForm_finite_element_6::evaluate_basis(unsigned int i,
5425
 
                                   double* values,
5426
 
                                   const double* coordinates,
5427
 
                                   const ufc::cell& c) const
5428
 
{
5429
 
    // Extract vertex coordinates
5430
 
    const double * const * element_coordinates = c.coordinates;
5431
 
    
5432
 
    // Compute Jacobian of affine map from reference cell
5433
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
5434
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
5435
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
5436
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
5437
 
      
5438
 
    // Compute determinant of Jacobian
5439
 
    const double detJ = J_00*J_11 - J_01*J_10;
5440
 
    
5441
 
    // Compute inverse of Jacobian
5442
 
    
5443
 
    // Get coordinates and map to the reference (UFC) element
5444
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
5445
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
5446
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
5447
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
5448
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
5449
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
5450
 
    
5451
 
    // Map coordinates to the reference square
5452
 
    if (std::abs(y - 1.0) < 1e-14)
5453
 
      x = -1.0;
5454
 
    else
5455
 
      x = 2.0 *x/(1.0 - y) - 1.0;
5456
 
    y = 2.0*y - 1.0;
5457
 
    
5458
 
    // Reset values
5459
 
    *values = 0;
5460
 
    
5461
 
    // Map degree of freedom to element degree of freedom
5462
 
    const unsigned int dof = i;
5463
 
    
5464
 
    // Generate scalings
5465
 
    const double scalings_y_0 = 1;
5466
 
    
5467
 
    // Compute psitilde_a
5468
 
    const double psitilde_a_0 = 1;
5469
 
    
5470
 
    // Compute psitilde_bs
5471
 
    const double psitilde_bs_0_0 = 1;
5472
 
    
5473
 
    // Compute basisvalues
5474
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
5475
 
    
5476
 
    // Table(s) of coefficients
5477
 
    const static double coefficients0[1][1] = \
5478
 
    {{1.41421356237309}};
5479
 
    
5480
 
    // Extract relevant coefficients
5481
 
    const double coeff0_0 = coefficients0[dof][0];
5482
 
    
5483
 
    // Compute value(s)
5484
 
    *values = coeff0_0*basisvalue0;
5485
 
}
5486
 
 
5487
 
/// Evaluate all basis functions at given point in cell
5488
 
void UFC_CahnHilliard2DBilinearForm_finite_element_6::evaluate_basis_all(double* values,
5489
 
                                       const double* coordinates,
5490
 
                                       const ufc::cell& c) const
5491
 
{
5492
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
5493
 
}
5494
 
 
5495
 
/// Evaluate order n derivatives of basis function i at given point in cell
5496
 
void UFC_CahnHilliard2DBilinearForm_finite_element_6::evaluate_basis_derivatives(unsigned int i,
5497
 
                                               unsigned int n,
5498
 
                                               double* values,
5499
 
                                               const double* coordinates,
5500
 
                                               const ufc::cell& c) const
5501
 
{
5502
 
    // Extract vertex coordinates
5503
 
    const double * const * element_coordinates = c.coordinates;
5504
 
    
5505
 
    // Compute Jacobian of affine map from reference cell
5506
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
5507
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
5508
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
5509
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
5510
 
      
5511
 
    // Compute determinant of Jacobian
5512
 
    const double detJ = J_00*J_11 - J_01*J_10;
5513
 
    
5514
 
    // Compute inverse of Jacobian
5515
 
    
5516
 
    // Get coordinates and map to the reference (UFC) element
5517
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
5518
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
5519
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
5520
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
5521
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
5522
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
5523
 
    
5524
 
    // Map coordinates to the reference square
5525
 
    if (std::abs(y - 1.0) < 1e-14)
5526
 
      x = -1.0;
5527
 
    else
5528
 
      x = 2.0 *x/(1.0 - y) - 1.0;
5529
 
    y = 2.0*y - 1.0;
5530
 
    
5531
 
    // Compute number of derivatives
5532
 
    unsigned int num_derivatives = 1;
5533
 
    
5534
 
    for (unsigned int j = 0; j < n; j++)
5535
 
      num_derivatives *= 2;
5536
 
    
5537
 
    
5538
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
5539
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
5540
 
        
5541
 
    for (unsigned int j = 0; j < num_derivatives; j++)
5542
 
    {
5543
 
      combinations[j] = new unsigned int [n];
5544
 
      for (unsigned int k = 0; k < n; k++)
5545
 
        combinations[j][k] = 0;
5546
 
    }
5547
 
        
5548
 
    // Generate combinations of derivatives
5549
 
    for (unsigned int row = 1; row < num_derivatives; row++)
5550
 
    {
5551
 
      for (unsigned int num = 0; num < row; num++)
5552
 
      {
5553
 
        for (unsigned int col = n-1; col+1 > 0; col--)
5554
 
        {
5555
 
          if (combinations[row][col] + 1 > 1)
5556
 
            combinations[row][col] = 0;
5557
 
          else
5558
 
          {
5559
 
            combinations[row][col] += 1;
5560
 
            break;
5561
 
          }
5562
 
        }
5563
 
      }
5564
 
    }
5565
 
    
5566
 
    // Compute inverse of Jacobian
5567
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
5568
 
    
5569
 
    // Declare transformation matrix
5570
 
    // Declare pointer to two dimensional array and initialise
5571
 
    double **transform = new double *[num_derivatives];
5572
 
        
5573
 
    for (unsigned int j = 0; j < num_derivatives; j++)
5574
 
    {
5575
 
      transform[j] = new double [num_derivatives];
5576
 
      for (unsigned int k = 0; k < num_derivatives; k++)
5577
 
        transform[j][k] = 1;
5578
 
    }
5579
 
    
5580
 
    // Construct transformation matrix
5581
 
    for (unsigned int row = 0; row < num_derivatives; row++)
5582
 
    {
5583
 
      for (unsigned int col = 0; col < num_derivatives; col++)
5584
 
      {
5585
 
        for (unsigned int k = 0; k < n; k++)
5586
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
5587
 
      }
5588
 
    }
5589
 
    
5590
 
    // Reset values
5591
 
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
5592
 
      values[j] = 0;
5593
 
    
5594
 
    // Map degree of freedom to element degree of freedom
5595
 
    const unsigned int dof = i;
5596
 
    
5597
 
    // Generate scalings
5598
 
    const double scalings_y_0 = 1;
5599
 
    
5600
 
    // Compute psitilde_a
5601
 
    const double psitilde_a_0 = 1;
5602
 
    
5603
 
    // Compute psitilde_bs
5604
 
    const double psitilde_bs_0_0 = 1;
5605
 
    
5606
 
    // Compute basisvalues
5607
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
5608
 
    
5609
 
    // Table(s) of coefficients
5610
 
    const static double coefficients0[1][1] = \
5611
 
    {{1.41421356237309}};
5612
 
    
5613
 
    // Interesting (new) part
5614
 
    // Tables of derivatives of the polynomial base (transpose)
5615
 
    const static double dmats0[1][1] = \
5616
 
    {{0}};
5617
 
    
5618
 
    const static double dmats1[1][1] = \
5619
 
    {{0}};
5620
 
    
5621
 
    // Compute reference derivatives
5622
 
    // Declare pointer to array of derivatives on FIAT element
5623
 
    double *derivatives = new double [num_derivatives];
5624
 
    
5625
 
    // Declare coefficients
5626
 
    double coeff0_0 = 0;
5627
 
    
5628
 
    // Declare new coefficients
5629
 
    double new_coeff0_0 = 0;
5630
 
    
5631
 
    // Loop possible derivatives
5632
 
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
5633
 
    {
5634
 
      // Get values from coefficients array
5635
 
      new_coeff0_0 = coefficients0[dof][0];
5636
 
    
5637
 
      // Loop derivative order
5638
 
      for (unsigned int j = 0; j < n; j++)
5639
 
      {
5640
 
        // Update old coefficients
5641
 
        coeff0_0 = new_coeff0_0;
5642
 
    
5643
 
        if(combinations[deriv_num][j] == 0)
5644
 
        {
5645
 
          new_coeff0_0 = coeff0_0*dmats0[0][0];
5646
 
        }
5647
 
        if(combinations[deriv_num][j] == 1)
5648
 
        {
5649
 
          new_coeff0_0 = coeff0_0*dmats1[0][0];
5650
 
        }
5651
 
    
5652
 
      }
5653
 
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
5654
 
      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
5655
 
    }
5656
 
    
5657
 
    // Transform derivatives back to physical element
5658
 
    for (unsigned int row = 0; row < num_derivatives; row++)
5659
 
    {
5660
 
      for (unsigned int col = 0; col < num_derivatives; col++)
5661
 
      {
5662
 
        values[row] += transform[row][col]*derivatives[col];
5663
 
      }
5664
 
    }
5665
 
    // Delete pointer to array of derivatives on FIAT element
5666
 
    delete [] derivatives;
5667
 
    
5668
 
    // Delete pointer to array of combinations of derivatives and transform
5669
 
    for (unsigned int row = 0; row < num_derivatives; row++)
5670
 
    {
5671
 
      delete [] combinations[row];
5672
 
      delete [] transform[row];
5673
 
    }
5674
 
    
5675
 
    delete [] combinations;
5676
 
    delete [] transform;
5677
 
}
5678
 
 
5679
 
/// Evaluate order n derivatives of all basis functions at given point in cell
5680
 
void UFC_CahnHilliard2DBilinearForm_finite_element_6::evaluate_basis_derivatives_all(unsigned int n,
5681
 
                                                   double* values,
5682
 
                                                   const double* coordinates,
5683
 
                                                   const ufc::cell& c) const
5684
 
{
5685
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
5686
 
}
5687
 
 
5688
 
/// Evaluate linear functional for dof i on the function f
5689
 
double UFC_CahnHilliard2DBilinearForm_finite_element_6::evaluate_dof(unsigned int i,
5690
 
                                   const ufc::function& f,
5691
 
                                   const ufc::cell& c) const
5692
 
{
5693
 
    // The reference points, direction and weights:
5694
 
    const static double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
5695
 
    const static double W[1][1] = {{1}};
5696
 
    const static double D[1][1][1] = {{{1}}};
5697
 
    
5698
 
    const double * const * x = c.coordinates;
5699
 
    double result = 0.0;
5700
 
    // Iterate over the points:
5701
 
    // Evaluate basis functions for affine mapping
5702
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
5703
 
    const double w1 = X[i][0][0];
5704
 
    const double w2 = X[i][0][1];
5705
 
    
5706
 
    // Compute affine mapping y = F(X)
5707
 
    double y[2];
5708
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
5709
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
5710
 
    
5711
 
    // Evaluate function at physical points
5712
 
    double values[1];
5713
 
    f.evaluate(values, y, c);
5714
 
    
5715
 
    // Map function values using appropriate mapping
5716
 
    // Affine map: Do nothing
5717
 
    
5718
 
    // Note that we do not map the weights (yet).
5719
 
    
5720
 
    // Take directional components
5721
 
    for(int k = 0; k < 1; k++)
5722
 
      result += values[k]*D[i][0][k];
5723
 
    // Multiply by weights 
5724
 
    result *= W[i][0];
5725
 
    
5726
 
    return result;
5727
 
}
5728
 
 
5729
 
/// Evaluate linear functionals for all dofs on the function f
5730
 
void UFC_CahnHilliard2DBilinearForm_finite_element_6::evaluate_dofs(double* values,
5731
 
                                  const ufc::function& f,
5732
 
                                  const ufc::cell& c) const
5733
 
{
5734
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
5735
 
}
5736
 
 
5737
 
/// Interpolate vertex values from dof values
5738
 
void UFC_CahnHilliard2DBilinearForm_finite_element_6::interpolate_vertex_values(double* vertex_values,
5739
 
                                              const double* dof_values,
5740
 
                                              const ufc::cell& c) const
5741
 
{
5742
 
    // Evaluate at vertices and use affine mapping
5743
 
    vertex_values[0] = dof_values[0];
5744
 
    vertex_values[1] = dof_values[0];
5745
 
    vertex_values[2] = dof_values[0];
5746
 
}
5747
 
 
5748
 
/// Return the number of sub elements (for a mixed element)
5749
 
unsigned int UFC_CahnHilliard2DBilinearForm_finite_element_6::num_sub_elements() const
5750
 
{
5751
 
    return 1;
5752
 
}
5753
 
 
5754
 
/// Create a new finite element for sub element i (for a mixed element)
5755
 
ufc::finite_element* UFC_CahnHilliard2DBilinearForm_finite_element_6::create_sub_element(unsigned int i) const
5756
 
{
5757
 
    return new UFC_CahnHilliard2DBilinearForm_finite_element_6();
5758
 
}
5759
 
 
5760
 
/// Constructor
5761
 
UFC_CahnHilliard2DBilinearForm_dof_map_0_0::UFC_CahnHilliard2DBilinearForm_dof_map_0_0() : ufc::dof_map()
5762
 
{
5763
 
    __global_dimension = 0;
5764
 
}
5765
 
 
5766
 
/// Destructor
5767
 
UFC_CahnHilliard2DBilinearForm_dof_map_0_0::~UFC_CahnHilliard2DBilinearForm_dof_map_0_0()
5768
 
{
5769
 
    // Do nothing
5770
 
}
5771
 
 
5772
 
/// Return a string identifying the dof map
5773
 
const char* UFC_CahnHilliard2DBilinearForm_dof_map_0_0::signature() const
5774
 
{
5775
 
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
5776
 
}
5777
 
 
5778
 
/// Return true iff mesh entities of topological dimension d are needed
5779
 
bool UFC_CahnHilliard2DBilinearForm_dof_map_0_0::needs_mesh_entities(unsigned int d) const
5780
 
{
5781
 
    switch ( d )
5782
 
    {
5783
 
    case 0:
5784
 
      return true;
5785
 
      break;
5786
 
    case 1:
5787
 
      return false;
5788
 
      break;
5789
 
    case 2:
5790
 
      return false;
5791
 
      break;
5792
 
    }
5793
 
    return false;
5794
 
}
5795
 
 
5796
 
/// Initialize dof map for mesh (return true iff init_cell() is needed)
5797
 
bool UFC_CahnHilliard2DBilinearForm_dof_map_0_0::init_mesh(const ufc::mesh& m)
5798
 
{
5799
 
    __global_dimension = m.num_entities[0];
5800
 
    return false;
5801
 
}
5802
 
 
5803
 
/// Initialize dof map for given cell
5804
 
void UFC_CahnHilliard2DBilinearForm_dof_map_0_0::init_cell(const ufc::mesh& m,
5805
 
                              const ufc::cell& c)
5806
 
{
5807
 
    // Do nothing
5808
 
}
5809
 
 
5810
 
/// Finish initialization of dof map for cells
5811
 
void UFC_CahnHilliard2DBilinearForm_dof_map_0_0::init_cell_finalize()
5812
 
{
5813
 
    // Do nothing
5814
 
}
5815
 
 
5816
 
/// Return the dimension of the global finite element function space
5817
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0_0::global_dimension() const
5818
 
{
5819
 
    return __global_dimension;
5820
 
}
5821
 
 
5822
 
/// Return the dimension of the local finite element function space
5823
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0_0::local_dimension() const
5824
 
{
5825
 
    return 3;
5826
 
}
5827
 
 
5828
 
// Return the geometric dimension of the coordinates this dof map provides
5829
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0_0::geometric_dimension() const
5830
 
{
5831
 
    return 2;
5832
 
}
5833
 
 
5834
 
/// Return the number of dofs on each cell facet
5835
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0_0::num_facet_dofs() const
5836
 
{
5837
 
    return 2;
5838
 
}
5839
 
 
5840
 
/// Return the number of dofs associated with each cell entity of dimension d
5841
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0_0::num_entity_dofs(unsigned int d) const
5842
 
{
5843
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
5844
 
}
5845
 
 
5846
 
/// Tabulate the local-to-global mapping of dofs on a cell
5847
 
void UFC_CahnHilliard2DBilinearForm_dof_map_0_0::tabulate_dofs(unsigned int* dofs,
5848
 
                                  const ufc::mesh& m,
5849
 
                                  const ufc::cell& c) const
5850
 
{
5851
 
    dofs[0] = c.entity_indices[0][0];
5852
 
    dofs[1] = c.entity_indices[0][1];
5853
 
    dofs[2] = c.entity_indices[0][2];
5854
 
}
5855
 
 
5856
 
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
5857
 
void UFC_CahnHilliard2DBilinearForm_dof_map_0_0::tabulate_facet_dofs(unsigned int* dofs,
5858
 
                                        unsigned int facet) const
5859
 
{
5860
 
    switch ( facet )
5861
 
    {
5862
 
    case 0:
5863
 
      dofs[0] = 1;
5864
 
      dofs[1] = 2;
5865
 
      break;
5866
 
    case 1:
5867
 
      dofs[0] = 0;
5868
 
      dofs[1] = 2;
5869
 
      break;
5870
 
    case 2:
5871
 
      dofs[0] = 0;
5872
 
      dofs[1] = 1;
5873
 
      break;
5874
 
    }
5875
 
}
5876
 
 
5877
 
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
5878
 
void UFC_CahnHilliard2DBilinearForm_dof_map_0_0::tabulate_entity_dofs(unsigned int* dofs,
5879
 
                                  unsigned int d, unsigned int i) const
5880
 
{
5881
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
5882
 
}
5883
 
 
5884
 
/// Tabulate the coordinates of all dofs on a cell
5885
 
void UFC_CahnHilliard2DBilinearForm_dof_map_0_0::tabulate_coordinates(double** coordinates,
5886
 
                                         const ufc::cell& c) const
5887
 
{
5888
 
    const double * const * x = c.coordinates;
5889
 
    coordinates[0][0] = x[0][0];
5890
 
    coordinates[0][1] = x[0][1];
5891
 
    coordinates[1][0] = x[1][0];
5892
 
    coordinates[1][1] = x[1][1];
5893
 
    coordinates[2][0] = x[2][0];
5894
 
    coordinates[2][1] = x[2][1];
5895
 
}
5896
 
 
5897
 
/// Return the number of sub dof maps (for a mixed element)
5898
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0_0::num_sub_dof_maps() const
5899
 
{
5900
 
    return 1;
5901
 
}
5902
 
 
5903
 
/// Create a new dof_map for sub dof map i (for a mixed element)
5904
 
ufc::dof_map* UFC_CahnHilliard2DBilinearForm_dof_map_0_0::create_sub_dof_map(unsigned int i) const
5905
 
{
5906
 
    return new UFC_CahnHilliard2DBilinearForm_dof_map_0_0();
5907
 
}
5908
 
 
5909
 
 
5910
 
/// Constructor
5911
 
UFC_CahnHilliard2DBilinearForm_dof_map_0_1::UFC_CahnHilliard2DBilinearForm_dof_map_0_1() : ufc::dof_map()
5912
 
{
5913
 
    __global_dimension = 0;
5914
 
}
5915
 
 
5916
 
/// Destructor
5917
 
UFC_CahnHilliard2DBilinearForm_dof_map_0_1::~UFC_CahnHilliard2DBilinearForm_dof_map_0_1()
5918
 
{
5919
 
    // Do nothing
5920
 
}
5921
 
 
5922
 
/// Return a string identifying the dof map
5923
 
const char* UFC_CahnHilliard2DBilinearForm_dof_map_0_1::signature() const
5924
 
{
5925
 
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
5926
 
}
5927
 
 
5928
 
/// Return true iff mesh entities of topological dimension d are needed
5929
 
bool UFC_CahnHilliard2DBilinearForm_dof_map_0_1::needs_mesh_entities(unsigned int d) const
5930
 
{
5931
 
    switch ( d )
5932
 
    {
5933
 
    case 0:
5934
 
      return true;
5935
 
      break;
5936
 
    case 1:
5937
 
      return false;
5938
 
      break;
5939
 
    case 2:
5940
 
      return false;
5941
 
      break;
5942
 
    }
5943
 
    return false;
5944
 
}
5945
 
 
5946
 
/// Initialize dof map for mesh (return true iff init_cell() is needed)
5947
 
bool UFC_CahnHilliard2DBilinearForm_dof_map_0_1::init_mesh(const ufc::mesh& m)
5948
 
{
5949
 
    __global_dimension = m.num_entities[0];
5950
 
    return false;
5951
 
}
5952
 
 
5953
 
/// Initialize dof map for given cell
5954
 
void UFC_CahnHilliard2DBilinearForm_dof_map_0_1::init_cell(const ufc::mesh& m,
5955
 
                              const ufc::cell& c)
5956
 
{
5957
 
    // Do nothing
5958
 
}
5959
 
 
5960
 
/// Finish initialization of dof map for cells
5961
 
void UFC_CahnHilliard2DBilinearForm_dof_map_0_1::init_cell_finalize()
5962
 
{
5963
 
    // Do nothing
5964
 
}
5965
 
 
5966
 
/// Return the dimension of the global finite element function space
5967
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0_1::global_dimension() const
5968
 
{
5969
 
    return __global_dimension;
5970
 
}
5971
 
 
5972
 
/// Return the dimension of the local finite element function space
5973
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0_1::local_dimension() const
5974
 
{
5975
 
    return 3;
5976
 
}
5977
 
 
5978
 
// Return the geometric dimension of the coordinates this dof map provides
5979
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0_1::geometric_dimension() const
5980
 
{
5981
 
    return 2;
5982
 
}
5983
 
 
5984
 
/// Return the number of dofs on each cell facet
5985
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0_1::num_facet_dofs() const
5986
 
{
5987
 
    return 2;
5988
 
}
5989
 
 
5990
 
/// Return the number of dofs associated with each cell entity of dimension d
5991
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0_1::num_entity_dofs(unsigned int d) const
5992
 
{
5993
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
5994
 
}
5995
 
 
5996
 
/// Tabulate the local-to-global mapping of dofs on a cell
5997
 
void UFC_CahnHilliard2DBilinearForm_dof_map_0_1::tabulate_dofs(unsigned int* dofs,
5998
 
                                  const ufc::mesh& m,
5999
 
                                  const ufc::cell& c) const
6000
 
{
6001
 
    dofs[0] = c.entity_indices[0][0];
6002
 
    dofs[1] = c.entity_indices[0][1];
6003
 
    dofs[2] = c.entity_indices[0][2];
6004
 
}
6005
 
 
6006
 
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
6007
 
void UFC_CahnHilliard2DBilinearForm_dof_map_0_1::tabulate_facet_dofs(unsigned int* dofs,
6008
 
                                        unsigned int facet) const
6009
 
{
6010
 
    switch ( facet )
6011
 
    {
6012
 
    case 0:
6013
 
      dofs[0] = 1;
6014
 
      dofs[1] = 2;
6015
 
      break;
6016
 
    case 1:
6017
 
      dofs[0] = 0;
6018
 
      dofs[1] = 2;
6019
 
      break;
6020
 
    case 2:
6021
 
      dofs[0] = 0;
6022
 
      dofs[1] = 1;
6023
 
      break;
6024
 
    }
6025
 
}
6026
 
 
6027
 
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
6028
 
void UFC_CahnHilliard2DBilinearForm_dof_map_0_1::tabulate_entity_dofs(unsigned int* dofs,
6029
 
                                  unsigned int d, unsigned int i) const
6030
 
{
6031
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6032
 
}
6033
 
 
6034
 
/// Tabulate the coordinates of all dofs on a cell
6035
 
void UFC_CahnHilliard2DBilinearForm_dof_map_0_1::tabulate_coordinates(double** coordinates,
6036
 
                                         const ufc::cell& c) const
6037
 
{
6038
 
    const double * const * x = c.coordinates;
6039
 
    coordinates[0][0] = x[0][0];
6040
 
    coordinates[0][1] = x[0][1];
6041
 
    coordinates[1][0] = x[1][0];
6042
 
    coordinates[1][1] = x[1][1];
6043
 
    coordinates[2][0] = x[2][0];
6044
 
    coordinates[2][1] = x[2][1];
6045
 
}
6046
 
 
6047
 
/// Return the number of sub dof maps (for a mixed element)
6048
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0_1::num_sub_dof_maps() const
6049
 
{
6050
 
    return 1;
6051
 
}
6052
 
 
6053
 
/// Create a new dof_map for sub dof map i (for a mixed element)
6054
 
ufc::dof_map* UFC_CahnHilliard2DBilinearForm_dof_map_0_1::create_sub_dof_map(unsigned int i) const
6055
 
{
6056
 
    return new UFC_CahnHilliard2DBilinearForm_dof_map_0_1();
6057
 
}
6058
 
 
6059
 
 
6060
 
/// Constructor
6061
 
UFC_CahnHilliard2DBilinearForm_dof_map_0::UFC_CahnHilliard2DBilinearForm_dof_map_0() : ufc::dof_map()
6062
 
{
6063
 
    __global_dimension = 0;
6064
 
}
6065
 
 
6066
 
/// Destructor
6067
 
UFC_CahnHilliard2DBilinearForm_dof_map_0::~UFC_CahnHilliard2DBilinearForm_dof_map_0()
6068
 
{
6069
 
    // Do nothing
6070
 
}
6071
 
 
6072
 
/// Return a string identifying the dof map
6073
 
const char* UFC_CahnHilliard2DBilinearForm_dof_map_0::signature() const
6074
 
{
6075
 
    return "FFC dof map for MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
6076
 
}
6077
 
 
6078
 
/// Return true iff mesh entities of topological dimension d are needed
6079
 
bool UFC_CahnHilliard2DBilinearForm_dof_map_0::needs_mesh_entities(unsigned int d) const
6080
 
{
6081
 
    switch ( d )
6082
 
    {
6083
 
    case 0:
6084
 
      return true;
6085
 
      break;
6086
 
    case 1:
6087
 
      return false;
6088
 
      break;
6089
 
    case 2:
6090
 
      return false;
6091
 
      break;
6092
 
    }
6093
 
    return false;
6094
 
}
6095
 
 
6096
 
/// Initialize dof map for mesh (return true iff init_cell() is needed)
6097
 
bool UFC_CahnHilliard2DBilinearForm_dof_map_0::init_mesh(const ufc::mesh& m)
6098
 
{
6099
 
    __global_dimension = 2*m.num_entities[0];
6100
 
    return false;
6101
 
}
6102
 
 
6103
 
/// Initialize dof map for given cell
6104
 
void UFC_CahnHilliard2DBilinearForm_dof_map_0::init_cell(const ufc::mesh& m,
6105
 
                              const ufc::cell& c)
6106
 
{
6107
 
    // Do nothing
6108
 
}
6109
 
 
6110
 
/// Finish initialization of dof map for cells
6111
 
void UFC_CahnHilliard2DBilinearForm_dof_map_0::init_cell_finalize()
6112
 
{
6113
 
    // Do nothing
6114
 
}
6115
 
 
6116
 
/// Return the dimension of the global finite element function space
6117
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0::global_dimension() const
6118
 
{
6119
 
    return __global_dimension;
6120
 
}
6121
 
 
6122
 
/// Return the dimension of the local finite element function space
6123
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0::local_dimension() const
6124
 
{
6125
 
    return 6;
6126
 
}
6127
 
 
6128
 
// Return the geometric dimension of the coordinates this dof map provides
6129
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0::geometric_dimension() const
6130
 
{
6131
 
    return 2;
6132
 
}
6133
 
 
6134
 
/// Return the number of dofs on each cell facet
6135
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0::num_facet_dofs() const
6136
 
{
6137
 
    return 4;
6138
 
}
6139
 
 
6140
 
/// Return the number of dofs associated with each cell entity of dimension d
6141
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0::num_entity_dofs(unsigned int d) const
6142
 
{
6143
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6144
 
}
6145
 
 
6146
 
/// Tabulate the local-to-global mapping of dofs on a cell
6147
 
void UFC_CahnHilliard2DBilinearForm_dof_map_0::tabulate_dofs(unsigned int* dofs,
6148
 
                                  const ufc::mesh& m,
6149
 
                                  const ufc::cell& c) const
6150
 
{
6151
 
    dofs[0] = c.entity_indices[0][0];
6152
 
    dofs[1] = c.entity_indices[0][1];
6153
 
    dofs[2] = c.entity_indices[0][2];
6154
 
    unsigned int offset = m.num_entities[0];
6155
 
    dofs[3] = offset + c.entity_indices[0][0];
6156
 
    dofs[4] = offset + c.entity_indices[0][1];
6157
 
    dofs[5] = offset + c.entity_indices[0][2];
6158
 
}
6159
 
 
6160
 
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
6161
 
void UFC_CahnHilliard2DBilinearForm_dof_map_0::tabulate_facet_dofs(unsigned int* dofs,
6162
 
                                        unsigned int facet) const
6163
 
{
6164
 
    switch ( facet )
6165
 
    {
6166
 
    case 0:
6167
 
      dofs[0] = 1;
6168
 
      dofs[1] = 2;
6169
 
      dofs[2] = 4;
6170
 
      dofs[3] = 5;
6171
 
      break;
6172
 
    case 1:
6173
 
      dofs[0] = 0;
6174
 
      dofs[1] = 2;
6175
 
      dofs[2] = 3;
6176
 
      dofs[3] = 5;
6177
 
      break;
6178
 
    case 2:
6179
 
      dofs[0] = 0;
6180
 
      dofs[1] = 1;
6181
 
      dofs[2] = 3;
6182
 
      dofs[3] = 4;
6183
 
      break;
6184
 
    }
6185
 
}
6186
 
 
6187
 
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
6188
 
void UFC_CahnHilliard2DBilinearForm_dof_map_0::tabulate_entity_dofs(unsigned int* dofs,
6189
 
                                  unsigned int d, unsigned int i) const
6190
 
{
6191
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6192
 
}
6193
 
 
6194
 
/// Tabulate the coordinates of all dofs on a cell
6195
 
void UFC_CahnHilliard2DBilinearForm_dof_map_0::tabulate_coordinates(double** coordinates,
6196
 
                                         const ufc::cell& c) const
6197
 
{
6198
 
    const double * const * x = c.coordinates;
6199
 
    coordinates[0][0] = x[0][0];
6200
 
    coordinates[0][1] = x[0][1];
6201
 
    coordinates[1][0] = x[1][0];
6202
 
    coordinates[1][1] = x[1][1];
6203
 
    coordinates[2][0] = x[2][0];
6204
 
    coordinates[2][1] = x[2][1];
6205
 
    coordinates[3][0] = x[0][0];
6206
 
    coordinates[3][1] = x[0][1];
6207
 
    coordinates[4][0] = x[1][0];
6208
 
    coordinates[4][1] = x[1][1];
6209
 
    coordinates[5][0] = x[2][0];
6210
 
    coordinates[5][1] = x[2][1];
6211
 
}
6212
 
 
6213
 
/// Return the number of sub dof maps (for a mixed element)
6214
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_0::num_sub_dof_maps() const
6215
 
{
6216
 
    return 2;
6217
 
}
6218
 
 
6219
 
/// Create a new dof_map for sub dof map i (for a mixed element)
6220
 
ufc::dof_map* UFC_CahnHilliard2DBilinearForm_dof_map_0::create_sub_dof_map(unsigned int i) const
6221
 
{
6222
 
    switch ( i )
6223
 
    {
6224
 
    case 0:
6225
 
      return new UFC_CahnHilliard2DBilinearForm_dof_map_0_0();
6226
 
      break;
6227
 
    case 1:
6228
 
      return new UFC_CahnHilliard2DBilinearForm_dof_map_0_1();
6229
 
      break;
6230
 
    }
6231
 
    return 0;
6232
 
}
6233
 
 
6234
 
 
6235
 
/// Constructor
6236
 
UFC_CahnHilliard2DBilinearForm_dof_map_1_0::UFC_CahnHilliard2DBilinearForm_dof_map_1_0() : ufc::dof_map()
6237
 
{
6238
 
    __global_dimension = 0;
6239
 
}
6240
 
 
6241
 
/// Destructor
6242
 
UFC_CahnHilliard2DBilinearForm_dof_map_1_0::~UFC_CahnHilliard2DBilinearForm_dof_map_1_0()
6243
 
{
6244
 
    // Do nothing
6245
 
}
6246
 
 
6247
 
/// Return a string identifying the dof map
6248
 
const char* UFC_CahnHilliard2DBilinearForm_dof_map_1_0::signature() const
6249
 
{
6250
 
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
6251
 
}
6252
 
 
6253
 
/// Return true iff mesh entities of topological dimension d are needed
6254
 
bool UFC_CahnHilliard2DBilinearForm_dof_map_1_0::needs_mesh_entities(unsigned int d) const
6255
 
{
6256
 
    switch ( d )
6257
 
    {
6258
 
    case 0:
6259
 
      return true;
6260
 
      break;
6261
 
    case 1:
6262
 
      return false;
6263
 
      break;
6264
 
    case 2:
6265
 
      return false;
6266
 
      break;
6267
 
    }
6268
 
    return false;
6269
 
}
6270
 
 
6271
 
/// Initialize dof map for mesh (return true iff init_cell() is needed)
6272
 
bool UFC_CahnHilliard2DBilinearForm_dof_map_1_0::init_mesh(const ufc::mesh& m)
6273
 
{
6274
 
    __global_dimension = m.num_entities[0];
6275
 
    return false;
6276
 
}
6277
 
 
6278
 
/// Initialize dof map for given cell
6279
 
void UFC_CahnHilliard2DBilinearForm_dof_map_1_0::init_cell(const ufc::mesh& m,
6280
 
                              const ufc::cell& c)
6281
 
{
6282
 
    // Do nothing
6283
 
}
6284
 
 
6285
 
/// Finish initialization of dof map for cells
6286
 
void UFC_CahnHilliard2DBilinearForm_dof_map_1_0::init_cell_finalize()
6287
 
{
6288
 
    // Do nothing
6289
 
}
6290
 
 
6291
 
/// Return the dimension of the global finite element function space
6292
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1_0::global_dimension() const
6293
 
{
6294
 
    return __global_dimension;
6295
 
}
6296
 
 
6297
 
/// Return the dimension of the local finite element function space
6298
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1_0::local_dimension() const
6299
 
{
6300
 
    return 3;
6301
 
}
6302
 
 
6303
 
// Return the geometric dimension of the coordinates this dof map provides
6304
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1_0::geometric_dimension() const
6305
 
{
6306
 
    return 2;
6307
 
}
6308
 
 
6309
 
/// Return the number of dofs on each cell facet
6310
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1_0::num_facet_dofs() const
6311
 
{
6312
 
    return 2;
6313
 
}
6314
 
 
6315
 
/// Return the number of dofs associated with each cell entity of dimension d
6316
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1_0::num_entity_dofs(unsigned int d) const
6317
 
{
6318
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6319
 
}
6320
 
 
6321
 
/// Tabulate the local-to-global mapping of dofs on a cell
6322
 
void UFC_CahnHilliard2DBilinearForm_dof_map_1_0::tabulate_dofs(unsigned int* dofs,
6323
 
                                  const ufc::mesh& m,
6324
 
                                  const ufc::cell& c) const
6325
 
{
6326
 
    dofs[0] = c.entity_indices[0][0];
6327
 
    dofs[1] = c.entity_indices[0][1];
6328
 
    dofs[2] = c.entity_indices[0][2];
6329
 
}
6330
 
 
6331
 
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
6332
 
void UFC_CahnHilliard2DBilinearForm_dof_map_1_0::tabulate_facet_dofs(unsigned int* dofs,
6333
 
                                        unsigned int facet) const
6334
 
{
6335
 
    switch ( facet )
6336
 
    {
6337
 
    case 0:
6338
 
      dofs[0] = 1;
6339
 
      dofs[1] = 2;
6340
 
      break;
6341
 
    case 1:
6342
 
      dofs[0] = 0;
6343
 
      dofs[1] = 2;
6344
 
      break;
6345
 
    case 2:
6346
 
      dofs[0] = 0;
6347
 
      dofs[1] = 1;
6348
 
      break;
6349
 
    }
6350
 
}
6351
 
 
6352
 
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
6353
 
void UFC_CahnHilliard2DBilinearForm_dof_map_1_0::tabulate_entity_dofs(unsigned int* dofs,
6354
 
                                  unsigned int d, unsigned int i) const
6355
 
{
6356
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6357
 
}
6358
 
 
6359
 
/// Tabulate the coordinates of all dofs on a cell
6360
 
void UFC_CahnHilliard2DBilinearForm_dof_map_1_0::tabulate_coordinates(double** coordinates,
6361
 
                                         const ufc::cell& c) const
6362
 
{
6363
 
    const double * const * x = c.coordinates;
6364
 
    coordinates[0][0] = x[0][0];
6365
 
    coordinates[0][1] = x[0][1];
6366
 
    coordinates[1][0] = x[1][0];
6367
 
    coordinates[1][1] = x[1][1];
6368
 
    coordinates[2][0] = x[2][0];
6369
 
    coordinates[2][1] = x[2][1];
6370
 
}
6371
 
 
6372
 
/// Return the number of sub dof maps (for a mixed element)
6373
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1_0::num_sub_dof_maps() const
6374
 
{
6375
 
    return 1;
6376
 
}
6377
 
 
6378
 
/// Create a new dof_map for sub dof map i (for a mixed element)
6379
 
ufc::dof_map* UFC_CahnHilliard2DBilinearForm_dof_map_1_0::create_sub_dof_map(unsigned int i) const
6380
 
{
6381
 
    return new UFC_CahnHilliard2DBilinearForm_dof_map_1_0();
6382
 
}
6383
 
 
6384
 
 
6385
 
/// Constructor
6386
 
UFC_CahnHilliard2DBilinearForm_dof_map_1_1::UFC_CahnHilliard2DBilinearForm_dof_map_1_1() : ufc::dof_map()
6387
 
{
6388
 
    __global_dimension = 0;
6389
 
}
6390
 
 
6391
 
/// Destructor
6392
 
UFC_CahnHilliard2DBilinearForm_dof_map_1_1::~UFC_CahnHilliard2DBilinearForm_dof_map_1_1()
6393
 
{
6394
 
    // Do nothing
6395
 
}
6396
 
 
6397
 
/// Return a string identifying the dof map
6398
 
const char* UFC_CahnHilliard2DBilinearForm_dof_map_1_1::signature() const
6399
 
{
6400
 
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
6401
 
}
6402
 
 
6403
 
/// Return true iff mesh entities of topological dimension d are needed
6404
 
bool UFC_CahnHilliard2DBilinearForm_dof_map_1_1::needs_mesh_entities(unsigned int d) const
6405
 
{
6406
 
    switch ( d )
6407
 
    {
6408
 
    case 0:
6409
 
      return true;
6410
 
      break;
6411
 
    case 1:
6412
 
      return false;
6413
 
      break;
6414
 
    case 2:
6415
 
      return false;
6416
 
      break;
6417
 
    }
6418
 
    return false;
6419
 
}
6420
 
 
6421
 
/// Initialize dof map for mesh (return true iff init_cell() is needed)
6422
 
bool UFC_CahnHilliard2DBilinearForm_dof_map_1_1::init_mesh(const ufc::mesh& m)
6423
 
{
6424
 
    __global_dimension = m.num_entities[0];
6425
 
    return false;
6426
 
}
6427
 
 
6428
 
/// Initialize dof map for given cell
6429
 
void UFC_CahnHilliard2DBilinearForm_dof_map_1_1::init_cell(const ufc::mesh& m,
6430
 
                              const ufc::cell& c)
6431
 
{
6432
 
    // Do nothing
6433
 
}
6434
 
 
6435
 
/// Finish initialization of dof map for cells
6436
 
void UFC_CahnHilliard2DBilinearForm_dof_map_1_1::init_cell_finalize()
6437
 
{
6438
 
    // Do nothing
6439
 
}
6440
 
 
6441
 
/// Return the dimension of the global finite element function space
6442
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1_1::global_dimension() const
6443
 
{
6444
 
    return __global_dimension;
6445
 
}
6446
 
 
6447
 
/// Return the dimension of the local finite element function space
6448
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1_1::local_dimension() const
6449
 
{
6450
 
    return 3;
6451
 
}
6452
 
 
6453
 
// Return the geometric dimension of the coordinates this dof map provides
6454
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1_1::geometric_dimension() const
6455
 
{
6456
 
    return 2;
6457
 
}
6458
 
 
6459
 
/// Return the number of dofs on each cell facet
6460
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1_1::num_facet_dofs() const
6461
 
{
6462
 
    return 2;
6463
 
}
6464
 
 
6465
 
/// Return the number of dofs associated with each cell entity of dimension d
6466
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1_1::num_entity_dofs(unsigned int d) const
6467
 
{
6468
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6469
 
}
6470
 
 
6471
 
/// Tabulate the local-to-global mapping of dofs on a cell
6472
 
void UFC_CahnHilliard2DBilinearForm_dof_map_1_1::tabulate_dofs(unsigned int* dofs,
6473
 
                                  const ufc::mesh& m,
6474
 
                                  const ufc::cell& c) const
6475
 
{
6476
 
    dofs[0] = c.entity_indices[0][0];
6477
 
    dofs[1] = c.entity_indices[0][1];
6478
 
    dofs[2] = c.entity_indices[0][2];
6479
 
}
6480
 
 
6481
 
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
6482
 
void UFC_CahnHilliard2DBilinearForm_dof_map_1_1::tabulate_facet_dofs(unsigned int* dofs,
6483
 
                                        unsigned int facet) const
6484
 
{
6485
 
    switch ( facet )
6486
 
    {
6487
 
    case 0:
6488
 
      dofs[0] = 1;
6489
 
      dofs[1] = 2;
6490
 
      break;
6491
 
    case 1:
6492
 
      dofs[0] = 0;
6493
 
      dofs[1] = 2;
6494
 
      break;
6495
 
    case 2:
6496
 
      dofs[0] = 0;
6497
 
      dofs[1] = 1;
6498
 
      break;
6499
 
    }
6500
 
}
6501
 
 
6502
 
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
6503
 
void UFC_CahnHilliard2DBilinearForm_dof_map_1_1::tabulate_entity_dofs(unsigned int* dofs,
6504
 
                                  unsigned int d, unsigned int i) const
6505
 
{
6506
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6507
 
}
6508
 
 
6509
 
/// Tabulate the coordinates of all dofs on a cell
6510
 
void UFC_CahnHilliard2DBilinearForm_dof_map_1_1::tabulate_coordinates(double** coordinates,
6511
 
                                         const ufc::cell& c) const
6512
 
{
6513
 
    const double * const * x = c.coordinates;
6514
 
    coordinates[0][0] = x[0][0];
6515
 
    coordinates[0][1] = x[0][1];
6516
 
    coordinates[1][0] = x[1][0];
6517
 
    coordinates[1][1] = x[1][1];
6518
 
    coordinates[2][0] = x[2][0];
6519
 
    coordinates[2][1] = x[2][1];
6520
 
}
6521
 
 
6522
 
/// Return the number of sub dof maps (for a mixed element)
6523
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1_1::num_sub_dof_maps() const
6524
 
{
6525
 
    return 1;
6526
 
}
6527
 
 
6528
 
/// Create a new dof_map for sub dof map i (for a mixed element)
6529
 
ufc::dof_map* UFC_CahnHilliard2DBilinearForm_dof_map_1_1::create_sub_dof_map(unsigned int i) const
6530
 
{
6531
 
    return new UFC_CahnHilliard2DBilinearForm_dof_map_1_1();
6532
 
}
6533
 
 
6534
 
 
6535
 
/// Constructor
6536
 
UFC_CahnHilliard2DBilinearForm_dof_map_1::UFC_CahnHilliard2DBilinearForm_dof_map_1() : ufc::dof_map()
6537
 
{
6538
 
    __global_dimension = 0;
6539
 
}
6540
 
 
6541
 
/// Destructor
6542
 
UFC_CahnHilliard2DBilinearForm_dof_map_1::~UFC_CahnHilliard2DBilinearForm_dof_map_1()
6543
 
{
6544
 
    // Do nothing
6545
 
}
6546
 
 
6547
 
/// Return a string identifying the dof map
6548
 
const char* UFC_CahnHilliard2DBilinearForm_dof_map_1::signature() const
6549
 
{
6550
 
    return "FFC dof map for MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
6551
 
}
6552
 
 
6553
 
/// Return true iff mesh entities of topological dimension d are needed
6554
 
bool UFC_CahnHilliard2DBilinearForm_dof_map_1::needs_mesh_entities(unsigned int d) const
6555
 
{
6556
 
    switch ( d )
6557
 
    {
6558
 
    case 0:
6559
 
      return true;
6560
 
      break;
6561
 
    case 1:
6562
 
      return false;
6563
 
      break;
6564
 
    case 2:
6565
 
      return false;
6566
 
      break;
6567
 
    }
6568
 
    return false;
6569
 
}
6570
 
 
6571
 
/// Initialize dof map for mesh (return true iff init_cell() is needed)
6572
 
bool UFC_CahnHilliard2DBilinearForm_dof_map_1::init_mesh(const ufc::mesh& m)
6573
 
{
6574
 
    __global_dimension = 2*m.num_entities[0];
6575
 
    return false;
6576
 
}
6577
 
 
6578
 
/// Initialize dof map for given cell
6579
 
void UFC_CahnHilliard2DBilinearForm_dof_map_1::init_cell(const ufc::mesh& m,
6580
 
                              const ufc::cell& c)
6581
 
{
6582
 
    // Do nothing
6583
 
}
6584
 
 
6585
 
/// Finish initialization of dof map for cells
6586
 
void UFC_CahnHilliard2DBilinearForm_dof_map_1::init_cell_finalize()
6587
 
{
6588
 
    // Do nothing
6589
 
}
6590
 
 
6591
 
/// Return the dimension of the global finite element function space
6592
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1::global_dimension() const
6593
 
{
6594
 
    return __global_dimension;
6595
 
}
6596
 
 
6597
 
/// Return the dimension of the local finite element function space
6598
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1::local_dimension() const
6599
 
{
6600
 
    return 6;
6601
 
}
6602
 
 
6603
 
// Return the geometric dimension of the coordinates this dof map provides
6604
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1::geometric_dimension() const
6605
 
{
6606
 
    return 2;
6607
 
}
6608
 
 
6609
 
/// Return the number of dofs on each cell facet
6610
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1::num_facet_dofs() const
6611
 
{
6612
 
    return 4;
6613
 
}
6614
 
 
6615
 
/// Return the number of dofs associated with each cell entity of dimension d
6616
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1::num_entity_dofs(unsigned int d) const
6617
 
{
6618
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6619
 
}
6620
 
 
6621
 
/// Tabulate the local-to-global mapping of dofs on a cell
6622
 
void UFC_CahnHilliard2DBilinearForm_dof_map_1::tabulate_dofs(unsigned int* dofs,
6623
 
                                  const ufc::mesh& m,
6624
 
                                  const ufc::cell& c) const
6625
 
{
6626
 
    dofs[0] = c.entity_indices[0][0];
6627
 
    dofs[1] = c.entity_indices[0][1];
6628
 
    dofs[2] = c.entity_indices[0][2];
6629
 
    unsigned int offset = m.num_entities[0];
6630
 
    dofs[3] = offset + c.entity_indices[0][0];
6631
 
    dofs[4] = offset + c.entity_indices[0][1];
6632
 
    dofs[5] = offset + c.entity_indices[0][2];
6633
 
}
6634
 
 
6635
 
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
6636
 
void UFC_CahnHilliard2DBilinearForm_dof_map_1::tabulate_facet_dofs(unsigned int* dofs,
6637
 
                                        unsigned int facet) const
6638
 
{
6639
 
    switch ( facet )
6640
 
    {
6641
 
    case 0:
6642
 
      dofs[0] = 1;
6643
 
      dofs[1] = 2;
6644
 
      dofs[2] = 4;
6645
 
      dofs[3] = 5;
6646
 
      break;
6647
 
    case 1:
6648
 
      dofs[0] = 0;
6649
 
      dofs[1] = 2;
6650
 
      dofs[2] = 3;
6651
 
      dofs[3] = 5;
6652
 
      break;
6653
 
    case 2:
6654
 
      dofs[0] = 0;
6655
 
      dofs[1] = 1;
6656
 
      dofs[2] = 3;
6657
 
      dofs[3] = 4;
6658
 
      break;
6659
 
    }
6660
 
}
6661
 
 
6662
 
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
6663
 
void UFC_CahnHilliard2DBilinearForm_dof_map_1::tabulate_entity_dofs(unsigned int* dofs,
6664
 
                                  unsigned int d, unsigned int i) const
6665
 
{
6666
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6667
 
}
6668
 
 
6669
 
/// Tabulate the coordinates of all dofs on a cell
6670
 
void UFC_CahnHilliard2DBilinearForm_dof_map_1::tabulate_coordinates(double** coordinates,
6671
 
                                         const ufc::cell& c) const
6672
 
{
6673
 
    const double * const * x = c.coordinates;
6674
 
    coordinates[0][0] = x[0][0];
6675
 
    coordinates[0][1] = x[0][1];
6676
 
    coordinates[1][0] = x[1][0];
6677
 
    coordinates[1][1] = x[1][1];
6678
 
    coordinates[2][0] = x[2][0];
6679
 
    coordinates[2][1] = x[2][1];
6680
 
    coordinates[3][0] = x[0][0];
6681
 
    coordinates[3][1] = x[0][1];
6682
 
    coordinates[4][0] = x[1][0];
6683
 
    coordinates[4][1] = x[1][1];
6684
 
    coordinates[5][0] = x[2][0];
6685
 
    coordinates[5][1] = x[2][1];
6686
 
}
6687
 
 
6688
 
/// Return the number of sub dof maps (for a mixed element)
6689
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_1::num_sub_dof_maps() const
6690
 
{
6691
 
    return 2;
6692
 
}
6693
 
 
6694
 
/// Create a new dof_map for sub dof map i (for a mixed element)
6695
 
ufc::dof_map* UFC_CahnHilliard2DBilinearForm_dof_map_1::create_sub_dof_map(unsigned int i) const
6696
 
{
6697
 
    switch ( i )
6698
 
    {
6699
 
    case 0:
6700
 
      return new UFC_CahnHilliard2DBilinearForm_dof_map_1_0();
6701
 
      break;
6702
 
    case 1:
6703
 
      return new UFC_CahnHilliard2DBilinearForm_dof_map_1_1();
6704
 
      break;
6705
 
    }
6706
 
    return 0;
6707
 
}
6708
 
 
6709
 
 
6710
 
/// Constructor
6711
 
UFC_CahnHilliard2DBilinearForm_dof_map_2_0::UFC_CahnHilliard2DBilinearForm_dof_map_2_0() : ufc::dof_map()
6712
 
{
6713
 
    __global_dimension = 0;
6714
 
}
6715
 
 
6716
 
/// Destructor
6717
 
UFC_CahnHilliard2DBilinearForm_dof_map_2_0::~UFC_CahnHilliard2DBilinearForm_dof_map_2_0()
6718
 
{
6719
 
    // Do nothing
6720
 
}
6721
 
 
6722
 
/// Return a string identifying the dof map
6723
 
const char* UFC_CahnHilliard2DBilinearForm_dof_map_2_0::signature() const
6724
 
{
6725
 
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
6726
 
}
6727
 
 
6728
 
/// Return true iff mesh entities of topological dimension d are needed
6729
 
bool UFC_CahnHilliard2DBilinearForm_dof_map_2_0::needs_mesh_entities(unsigned int d) const
6730
 
{
6731
 
    switch ( d )
6732
 
    {
6733
 
    case 0:
6734
 
      return true;
6735
 
      break;
6736
 
    case 1:
6737
 
      return false;
6738
 
      break;
6739
 
    case 2:
6740
 
      return false;
6741
 
      break;
6742
 
    }
6743
 
    return false;
6744
 
}
6745
 
 
6746
 
/// Initialize dof map for mesh (return true iff init_cell() is needed)
6747
 
bool UFC_CahnHilliard2DBilinearForm_dof_map_2_0::init_mesh(const ufc::mesh& m)
6748
 
{
6749
 
    __global_dimension = m.num_entities[0];
6750
 
    return false;
6751
 
}
6752
 
 
6753
 
/// Initialize dof map for given cell
6754
 
void UFC_CahnHilliard2DBilinearForm_dof_map_2_0::init_cell(const ufc::mesh& m,
6755
 
                              const ufc::cell& c)
6756
 
{
6757
 
    // Do nothing
6758
 
}
6759
 
 
6760
 
/// Finish initialization of dof map for cells
6761
 
void UFC_CahnHilliard2DBilinearForm_dof_map_2_0::init_cell_finalize()
6762
 
{
6763
 
    // Do nothing
6764
 
}
6765
 
 
6766
 
/// Return the dimension of the global finite element function space
6767
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2_0::global_dimension() const
6768
 
{
6769
 
    return __global_dimension;
6770
 
}
6771
 
 
6772
 
/// Return the dimension of the local finite element function space
6773
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2_0::local_dimension() const
6774
 
{
6775
 
    return 3;
6776
 
}
6777
 
 
6778
 
// Return the geometric dimension of the coordinates this dof map provides
6779
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2_0::geometric_dimension() const
6780
 
{
6781
 
    return 2;
6782
 
}
6783
 
 
6784
 
/// Return the number of dofs on each cell facet
6785
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2_0::num_facet_dofs() const
6786
 
{
6787
 
    return 2;
6788
 
}
6789
 
 
6790
 
/// Return the number of dofs associated with each cell entity of dimension d
6791
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2_0::num_entity_dofs(unsigned int d) const
6792
 
{
6793
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6794
 
}
6795
 
 
6796
 
/// Tabulate the local-to-global mapping of dofs on a cell
6797
 
void UFC_CahnHilliard2DBilinearForm_dof_map_2_0::tabulate_dofs(unsigned int* dofs,
6798
 
                                  const ufc::mesh& m,
6799
 
                                  const ufc::cell& c) const
6800
 
{
6801
 
    dofs[0] = c.entity_indices[0][0];
6802
 
    dofs[1] = c.entity_indices[0][1];
6803
 
    dofs[2] = c.entity_indices[0][2];
6804
 
}
6805
 
 
6806
 
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
6807
 
void UFC_CahnHilliard2DBilinearForm_dof_map_2_0::tabulate_facet_dofs(unsigned int* dofs,
6808
 
                                        unsigned int facet) const
6809
 
{
6810
 
    switch ( facet )
6811
 
    {
6812
 
    case 0:
6813
 
      dofs[0] = 1;
6814
 
      dofs[1] = 2;
6815
 
      break;
6816
 
    case 1:
6817
 
      dofs[0] = 0;
6818
 
      dofs[1] = 2;
6819
 
      break;
6820
 
    case 2:
6821
 
      dofs[0] = 0;
6822
 
      dofs[1] = 1;
6823
 
      break;
6824
 
    }
6825
 
}
6826
 
 
6827
 
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
6828
 
void UFC_CahnHilliard2DBilinearForm_dof_map_2_0::tabulate_entity_dofs(unsigned int* dofs,
6829
 
                                  unsigned int d, unsigned int i) const
6830
 
{
6831
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6832
 
}
6833
 
 
6834
 
/// Tabulate the coordinates of all dofs on a cell
6835
 
void UFC_CahnHilliard2DBilinearForm_dof_map_2_0::tabulate_coordinates(double** coordinates,
6836
 
                                         const ufc::cell& c) const
6837
 
{
6838
 
    const double * const * x = c.coordinates;
6839
 
    coordinates[0][0] = x[0][0];
6840
 
    coordinates[0][1] = x[0][1];
6841
 
    coordinates[1][0] = x[1][0];
6842
 
    coordinates[1][1] = x[1][1];
6843
 
    coordinates[2][0] = x[2][0];
6844
 
    coordinates[2][1] = x[2][1];
6845
 
}
6846
 
 
6847
 
/// Return the number of sub dof maps (for a mixed element)
6848
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2_0::num_sub_dof_maps() const
6849
 
{
6850
 
    return 1;
6851
 
}
6852
 
 
6853
 
/// Create a new dof_map for sub dof map i (for a mixed element)
6854
 
ufc::dof_map* UFC_CahnHilliard2DBilinearForm_dof_map_2_0::create_sub_dof_map(unsigned int i) const
6855
 
{
6856
 
    return new UFC_CahnHilliard2DBilinearForm_dof_map_2_0();
6857
 
}
6858
 
 
6859
 
 
6860
 
/// Constructor
6861
 
UFC_CahnHilliard2DBilinearForm_dof_map_2_1::UFC_CahnHilliard2DBilinearForm_dof_map_2_1() : ufc::dof_map()
6862
 
{
6863
 
    __global_dimension = 0;
6864
 
}
6865
 
 
6866
 
/// Destructor
6867
 
UFC_CahnHilliard2DBilinearForm_dof_map_2_1::~UFC_CahnHilliard2DBilinearForm_dof_map_2_1()
6868
 
{
6869
 
    // Do nothing
6870
 
}
6871
 
 
6872
 
/// Return a string identifying the dof map
6873
 
const char* UFC_CahnHilliard2DBilinearForm_dof_map_2_1::signature() const
6874
 
{
6875
 
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
6876
 
}
6877
 
 
6878
 
/// Return true iff mesh entities of topological dimension d are needed
6879
 
bool UFC_CahnHilliard2DBilinearForm_dof_map_2_1::needs_mesh_entities(unsigned int d) const
6880
 
{
6881
 
    switch ( d )
6882
 
    {
6883
 
    case 0:
6884
 
      return true;
6885
 
      break;
6886
 
    case 1:
6887
 
      return false;
6888
 
      break;
6889
 
    case 2:
6890
 
      return false;
6891
 
      break;
6892
 
    }
6893
 
    return false;
6894
 
}
6895
 
 
6896
 
/// Initialize dof map for mesh (return true iff init_cell() is needed)
6897
 
bool UFC_CahnHilliard2DBilinearForm_dof_map_2_1::init_mesh(const ufc::mesh& m)
6898
 
{
6899
 
    __global_dimension = m.num_entities[0];
6900
 
    return false;
6901
 
}
6902
 
 
6903
 
/// Initialize dof map for given cell
6904
 
void UFC_CahnHilliard2DBilinearForm_dof_map_2_1::init_cell(const ufc::mesh& m,
6905
 
                              const ufc::cell& c)
6906
 
{
6907
 
    // Do nothing
6908
 
}
6909
 
 
6910
 
/// Finish initialization of dof map for cells
6911
 
void UFC_CahnHilliard2DBilinearForm_dof_map_2_1::init_cell_finalize()
6912
 
{
6913
 
    // Do nothing
6914
 
}
6915
 
 
6916
 
/// Return the dimension of the global finite element function space
6917
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2_1::global_dimension() const
6918
 
{
6919
 
    return __global_dimension;
6920
 
}
6921
 
 
6922
 
/// Return the dimension of the local finite element function space
6923
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2_1::local_dimension() const
6924
 
{
6925
 
    return 3;
6926
 
}
6927
 
 
6928
 
// Return the geometric dimension of the coordinates this dof map provides
6929
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2_1::geometric_dimension() const
6930
 
{
6931
 
    return 2;
6932
 
}
6933
 
 
6934
 
/// Return the number of dofs on each cell facet
6935
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2_1::num_facet_dofs() const
6936
 
{
6937
 
    return 2;
6938
 
}
6939
 
 
6940
 
/// Return the number of dofs associated with each cell entity of dimension d
6941
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2_1::num_entity_dofs(unsigned int d) const
6942
 
{
6943
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6944
 
}
6945
 
 
6946
 
/// Tabulate the local-to-global mapping of dofs on a cell
6947
 
void UFC_CahnHilliard2DBilinearForm_dof_map_2_1::tabulate_dofs(unsigned int* dofs,
6948
 
                                  const ufc::mesh& m,
6949
 
                                  const ufc::cell& c) const
6950
 
{
6951
 
    dofs[0] = c.entity_indices[0][0];
6952
 
    dofs[1] = c.entity_indices[0][1];
6953
 
    dofs[2] = c.entity_indices[0][2];
6954
 
}
6955
 
 
6956
 
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
6957
 
void UFC_CahnHilliard2DBilinearForm_dof_map_2_1::tabulate_facet_dofs(unsigned int* dofs,
6958
 
                                        unsigned int facet) const
6959
 
{
6960
 
    switch ( facet )
6961
 
    {
6962
 
    case 0:
6963
 
      dofs[0] = 1;
6964
 
      dofs[1] = 2;
6965
 
      break;
6966
 
    case 1:
6967
 
      dofs[0] = 0;
6968
 
      dofs[1] = 2;
6969
 
      break;
6970
 
    case 2:
6971
 
      dofs[0] = 0;
6972
 
      dofs[1] = 1;
6973
 
      break;
6974
 
    }
6975
 
}
6976
 
 
6977
 
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
6978
 
void UFC_CahnHilliard2DBilinearForm_dof_map_2_1::tabulate_entity_dofs(unsigned int* dofs,
6979
 
                                  unsigned int d, unsigned int i) const
6980
 
{
6981
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
6982
 
}
6983
 
 
6984
 
/// Tabulate the coordinates of all dofs on a cell
6985
 
void UFC_CahnHilliard2DBilinearForm_dof_map_2_1::tabulate_coordinates(double** coordinates,
6986
 
                                         const ufc::cell& c) const
6987
 
{
6988
 
    const double * const * x = c.coordinates;
6989
 
    coordinates[0][0] = x[0][0];
6990
 
    coordinates[0][1] = x[0][1];
6991
 
    coordinates[1][0] = x[1][0];
6992
 
    coordinates[1][1] = x[1][1];
6993
 
    coordinates[2][0] = x[2][0];
6994
 
    coordinates[2][1] = x[2][1];
6995
 
}
6996
 
 
6997
 
/// Return the number of sub dof maps (for a mixed element)
6998
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2_1::num_sub_dof_maps() const
6999
 
{
7000
 
    return 1;
7001
 
}
7002
 
 
7003
 
/// Create a new dof_map for sub dof map i (for a mixed element)
7004
 
ufc::dof_map* UFC_CahnHilliard2DBilinearForm_dof_map_2_1::create_sub_dof_map(unsigned int i) const
7005
 
{
7006
 
    return new UFC_CahnHilliard2DBilinearForm_dof_map_2_1();
7007
 
}
7008
 
 
7009
 
 
7010
 
/// Constructor
7011
 
UFC_CahnHilliard2DBilinearForm_dof_map_2::UFC_CahnHilliard2DBilinearForm_dof_map_2() : ufc::dof_map()
7012
 
{
7013
 
    __global_dimension = 0;
7014
 
}
7015
 
 
7016
 
/// Destructor
7017
 
UFC_CahnHilliard2DBilinearForm_dof_map_2::~UFC_CahnHilliard2DBilinearForm_dof_map_2()
7018
 
{
7019
 
    // Do nothing
7020
 
}
7021
 
 
7022
 
/// Return a string identifying the dof map
7023
 
const char* UFC_CahnHilliard2DBilinearForm_dof_map_2::signature() const
7024
 
{
7025
 
    return "FFC dof map for MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
7026
 
}
7027
 
 
7028
 
/// Return true iff mesh entities of topological dimension d are needed
7029
 
bool UFC_CahnHilliard2DBilinearForm_dof_map_2::needs_mesh_entities(unsigned int d) const
7030
 
{
7031
 
    switch ( d )
7032
 
    {
7033
 
    case 0:
7034
 
      return true;
7035
 
      break;
7036
 
    case 1:
7037
 
      return false;
7038
 
      break;
7039
 
    case 2:
7040
 
      return false;
7041
 
      break;
7042
 
    }
7043
 
    return false;
7044
 
}
7045
 
 
7046
 
/// Initialize dof map for mesh (return true iff init_cell() is needed)
7047
 
bool UFC_CahnHilliard2DBilinearForm_dof_map_2::init_mesh(const ufc::mesh& m)
7048
 
{
7049
 
    __global_dimension = 2*m.num_entities[0];
7050
 
    return false;
7051
 
}
7052
 
 
7053
 
/// Initialize dof map for given cell
7054
 
void UFC_CahnHilliard2DBilinearForm_dof_map_2::init_cell(const ufc::mesh& m,
7055
 
                              const ufc::cell& c)
7056
 
{
7057
 
    // Do nothing
7058
 
}
7059
 
 
7060
 
/// Finish initialization of dof map for cells
7061
 
void UFC_CahnHilliard2DBilinearForm_dof_map_2::init_cell_finalize()
7062
 
{
7063
 
    // Do nothing
7064
 
}
7065
 
 
7066
 
/// Return the dimension of the global finite element function space
7067
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2::global_dimension() const
7068
 
{
7069
 
    return __global_dimension;
7070
 
}
7071
 
 
7072
 
/// Return the dimension of the local finite element function space
7073
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2::local_dimension() const
7074
 
{
7075
 
    return 6;
7076
 
}
7077
 
 
7078
 
// Return the geometric dimension of the coordinates this dof map provides
7079
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2::geometric_dimension() const
7080
 
{
7081
 
    return 2;
7082
 
}
7083
 
 
7084
 
/// Return the number of dofs on each cell facet
7085
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2::num_facet_dofs() const
7086
 
{
7087
 
    return 4;
7088
 
}
7089
 
 
7090
 
/// Return the number of dofs associated with each cell entity of dimension d
7091
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2::num_entity_dofs(unsigned int d) const
7092
 
{
7093
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7094
 
}
7095
 
 
7096
 
/// Tabulate the local-to-global mapping of dofs on a cell
7097
 
void UFC_CahnHilliard2DBilinearForm_dof_map_2::tabulate_dofs(unsigned int* dofs,
7098
 
                                  const ufc::mesh& m,
7099
 
                                  const ufc::cell& c) const
7100
 
{
7101
 
    dofs[0] = c.entity_indices[0][0];
7102
 
    dofs[1] = c.entity_indices[0][1];
7103
 
    dofs[2] = c.entity_indices[0][2];
7104
 
    unsigned int offset = m.num_entities[0];
7105
 
    dofs[3] = offset + c.entity_indices[0][0];
7106
 
    dofs[4] = offset + c.entity_indices[0][1];
7107
 
    dofs[5] = offset + c.entity_indices[0][2];
7108
 
}
7109
 
 
7110
 
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
7111
 
void UFC_CahnHilliard2DBilinearForm_dof_map_2::tabulate_facet_dofs(unsigned int* dofs,
7112
 
                                        unsigned int facet) const
7113
 
{
7114
 
    switch ( facet )
7115
 
    {
7116
 
    case 0:
7117
 
      dofs[0] = 1;
7118
 
      dofs[1] = 2;
7119
 
      dofs[2] = 4;
7120
 
      dofs[3] = 5;
7121
 
      break;
7122
 
    case 1:
7123
 
      dofs[0] = 0;
7124
 
      dofs[1] = 2;
7125
 
      dofs[2] = 3;
7126
 
      dofs[3] = 5;
7127
 
      break;
7128
 
    case 2:
7129
 
      dofs[0] = 0;
7130
 
      dofs[1] = 1;
7131
 
      dofs[2] = 3;
7132
 
      dofs[3] = 4;
7133
 
      break;
7134
 
    }
7135
 
}
7136
 
 
7137
 
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
7138
 
void UFC_CahnHilliard2DBilinearForm_dof_map_2::tabulate_entity_dofs(unsigned int* dofs,
7139
 
                                  unsigned int d, unsigned int i) const
7140
 
{
7141
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7142
 
}
7143
 
 
7144
 
/// Tabulate the coordinates of all dofs on a cell
7145
 
void UFC_CahnHilliard2DBilinearForm_dof_map_2::tabulate_coordinates(double** coordinates,
7146
 
                                         const ufc::cell& c) const
7147
 
{
7148
 
    const double * const * x = c.coordinates;
7149
 
    coordinates[0][0] = x[0][0];
7150
 
    coordinates[0][1] = x[0][1];
7151
 
    coordinates[1][0] = x[1][0];
7152
 
    coordinates[1][1] = x[1][1];
7153
 
    coordinates[2][0] = x[2][0];
7154
 
    coordinates[2][1] = x[2][1];
7155
 
    coordinates[3][0] = x[0][0];
7156
 
    coordinates[3][1] = x[0][1];
7157
 
    coordinates[4][0] = x[1][0];
7158
 
    coordinates[4][1] = x[1][1];
7159
 
    coordinates[5][0] = x[2][0];
7160
 
    coordinates[5][1] = x[2][1];
7161
 
}
7162
 
 
7163
 
/// Return the number of sub dof maps (for a mixed element)
7164
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_2::num_sub_dof_maps() const
7165
 
{
7166
 
    return 2;
7167
 
}
7168
 
 
7169
 
/// Create a new dof_map for sub dof map i (for a mixed element)
7170
 
ufc::dof_map* UFC_CahnHilliard2DBilinearForm_dof_map_2::create_sub_dof_map(unsigned int i) const
7171
 
{
7172
 
    switch ( i )
7173
 
    {
7174
 
    case 0:
7175
 
      return new UFC_CahnHilliard2DBilinearForm_dof_map_2_0();
7176
 
      break;
7177
 
    case 1:
7178
 
      return new UFC_CahnHilliard2DBilinearForm_dof_map_2_1();
7179
 
      break;
7180
 
    }
7181
 
    return 0;
7182
 
}
7183
 
 
7184
 
 
7185
 
/// Constructor
7186
 
UFC_CahnHilliard2DBilinearForm_dof_map_3::UFC_CahnHilliard2DBilinearForm_dof_map_3() : ufc::dof_map()
7187
 
{
7188
 
    __global_dimension = 0;
7189
 
}
7190
 
 
7191
 
/// Destructor
7192
 
UFC_CahnHilliard2DBilinearForm_dof_map_3::~UFC_CahnHilliard2DBilinearForm_dof_map_3()
7193
 
{
7194
 
    // Do nothing
7195
 
}
7196
 
 
7197
 
/// Return a string identifying the dof map
7198
 
const char* UFC_CahnHilliard2DBilinearForm_dof_map_3::signature() const
7199
 
{
7200
 
    return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
7201
 
}
7202
 
 
7203
 
/// Return true iff mesh entities of topological dimension d are needed
7204
 
bool UFC_CahnHilliard2DBilinearForm_dof_map_3::needs_mesh_entities(unsigned int d) const
7205
 
{
7206
 
    switch ( d )
7207
 
    {
7208
 
    case 0:
7209
 
      return false;
7210
 
      break;
7211
 
    case 1:
7212
 
      return false;
7213
 
      break;
7214
 
    case 2:
7215
 
      return true;
7216
 
      break;
7217
 
    }
7218
 
    return false;
7219
 
}
7220
 
 
7221
 
/// Initialize dof map for mesh (return true iff init_cell() is needed)
7222
 
bool UFC_CahnHilliard2DBilinearForm_dof_map_3::init_mesh(const ufc::mesh& m)
7223
 
{
7224
 
    __global_dimension = m.num_entities[2];
7225
 
    return false;
7226
 
}
7227
 
 
7228
 
/// Initialize dof map for given cell
7229
 
void UFC_CahnHilliard2DBilinearForm_dof_map_3::init_cell(const ufc::mesh& m,
7230
 
                              const ufc::cell& c)
7231
 
{
7232
 
    // Do nothing
7233
 
}
7234
 
 
7235
 
/// Finish initialization of dof map for cells
7236
 
void UFC_CahnHilliard2DBilinearForm_dof_map_3::init_cell_finalize()
7237
 
{
7238
 
    // Do nothing
7239
 
}
7240
 
 
7241
 
/// Return the dimension of the global finite element function space
7242
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_3::global_dimension() const
7243
 
{
7244
 
    return __global_dimension;
7245
 
}
7246
 
 
7247
 
/// Return the dimension of the local finite element function space
7248
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_3::local_dimension() const
7249
 
{
7250
 
    return 1;
7251
 
}
7252
 
 
7253
 
// Return the geometric dimension of the coordinates this dof map provides
7254
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_3::geometric_dimension() const
7255
 
{
7256
 
    return 2;
7257
 
}
7258
 
 
7259
 
/// Return the number of dofs on each cell facet
7260
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_3::num_facet_dofs() const
7261
 
{
7262
 
    return 0;
7263
 
}
7264
 
 
7265
 
/// Return the number of dofs associated with each cell entity of dimension d
7266
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_3::num_entity_dofs(unsigned int d) const
7267
 
{
7268
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7269
 
}
7270
 
 
7271
 
/// Tabulate the local-to-global mapping of dofs on a cell
7272
 
void UFC_CahnHilliard2DBilinearForm_dof_map_3::tabulate_dofs(unsigned int* dofs,
7273
 
                                  const ufc::mesh& m,
7274
 
                                  const ufc::cell& c) const
7275
 
{
7276
 
    dofs[0] = c.entity_indices[2][0];
7277
 
}
7278
 
 
7279
 
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
7280
 
void UFC_CahnHilliard2DBilinearForm_dof_map_3::tabulate_facet_dofs(unsigned int* dofs,
7281
 
                                        unsigned int facet) const
7282
 
{
7283
 
    switch ( facet )
7284
 
    {
7285
 
    case 0:
7286
 
      
7287
 
      break;
7288
 
    case 1:
7289
 
      
7290
 
      break;
7291
 
    case 2:
7292
 
      
7293
 
      break;
7294
 
    }
7295
 
}
7296
 
 
7297
 
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
7298
 
void UFC_CahnHilliard2DBilinearForm_dof_map_3::tabulate_entity_dofs(unsigned int* dofs,
7299
 
                                  unsigned int d, unsigned int i) const
7300
 
{
7301
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7302
 
}
7303
 
 
7304
 
/// Tabulate the coordinates of all dofs on a cell
7305
 
void UFC_CahnHilliard2DBilinearForm_dof_map_3::tabulate_coordinates(double** coordinates,
7306
 
                                         const ufc::cell& c) const
7307
 
{
7308
 
    const double * const * x = c.coordinates;
7309
 
    coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
7310
 
    coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
7311
 
}
7312
 
 
7313
 
/// Return the number of sub dof maps (for a mixed element)
7314
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_3::num_sub_dof_maps() const
7315
 
{
7316
 
    return 1;
7317
 
}
7318
 
 
7319
 
/// Create a new dof_map for sub dof map i (for a mixed element)
7320
 
ufc::dof_map* UFC_CahnHilliard2DBilinearForm_dof_map_3::create_sub_dof_map(unsigned int i) const
7321
 
{
7322
 
    return new UFC_CahnHilliard2DBilinearForm_dof_map_3();
7323
 
}
7324
 
 
7325
 
 
7326
 
/// Constructor
7327
 
UFC_CahnHilliard2DBilinearForm_dof_map_4::UFC_CahnHilliard2DBilinearForm_dof_map_4() : ufc::dof_map()
7328
 
{
7329
 
    __global_dimension = 0;
7330
 
}
7331
 
 
7332
 
/// Destructor
7333
 
UFC_CahnHilliard2DBilinearForm_dof_map_4::~UFC_CahnHilliard2DBilinearForm_dof_map_4()
7334
 
{
7335
 
    // Do nothing
7336
 
}
7337
 
 
7338
 
/// Return a string identifying the dof map
7339
 
const char* UFC_CahnHilliard2DBilinearForm_dof_map_4::signature() const
7340
 
{
7341
 
    return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
7342
 
}
7343
 
 
7344
 
/// Return true iff mesh entities of topological dimension d are needed
7345
 
bool UFC_CahnHilliard2DBilinearForm_dof_map_4::needs_mesh_entities(unsigned int d) const
7346
 
{
7347
 
    switch ( d )
7348
 
    {
7349
 
    case 0:
7350
 
      return false;
7351
 
      break;
7352
 
    case 1:
7353
 
      return false;
7354
 
      break;
7355
 
    case 2:
7356
 
      return true;
7357
 
      break;
7358
 
    }
7359
 
    return false;
7360
 
}
7361
 
 
7362
 
/// Initialize dof map for mesh (return true iff init_cell() is needed)
7363
 
bool UFC_CahnHilliard2DBilinearForm_dof_map_4::init_mesh(const ufc::mesh& m)
7364
 
{
7365
 
    __global_dimension = m.num_entities[2];
7366
 
    return false;
7367
 
}
7368
 
 
7369
 
/// Initialize dof map for given cell
7370
 
void UFC_CahnHilliard2DBilinearForm_dof_map_4::init_cell(const ufc::mesh& m,
7371
 
                              const ufc::cell& c)
7372
 
{
7373
 
    // Do nothing
7374
 
}
7375
 
 
7376
 
/// Finish initialization of dof map for cells
7377
 
void UFC_CahnHilliard2DBilinearForm_dof_map_4::init_cell_finalize()
7378
 
{
7379
 
    // Do nothing
7380
 
}
7381
 
 
7382
 
/// Return the dimension of the global finite element function space
7383
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_4::global_dimension() const
7384
 
{
7385
 
    return __global_dimension;
7386
 
}
7387
 
 
7388
 
/// Return the dimension of the local finite element function space
7389
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_4::local_dimension() const
7390
 
{
7391
 
    return 1;
7392
 
}
7393
 
 
7394
 
// Return the geometric dimension of the coordinates this dof map provides
7395
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_4::geometric_dimension() const
7396
 
{
7397
 
    return 2;
7398
 
}
7399
 
 
7400
 
/// Return the number of dofs on each cell facet
7401
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_4::num_facet_dofs() const
7402
 
{
7403
 
    return 0;
7404
 
}
7405
 
 
7406
 
/// Return the number of dofs associated with each cell entity of dimension d
7407
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_4::num_entity_dofs(unsigned int d) const
7408
 
{
7409
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7410
 
}
7411
 
 
7412
 
/// Tabulate the local-to-global mapping of dofs on a cell
7413
 
void UFC_CahnHilliard2DBilinearForm_dof_map_4::tabulate_dofs(unsigned int* dofs,
7414
 
                                  const ufc::mesh& m,
7415
 
                                  const ufc::cell& c) const
7416
 
{
7417
 
    dofs[0] = c.entity_indices[2][0];
7418
 
}
7419
 
 
7420
 
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
7421
 
void UFC_CahnHilliard2DBilinearForm_dof_map_4::tabulate_facet_dofs(unsigned int* dofs,
7422
 
                                        unsigned int facet) const
7423
 
{
7424
 
    switch ( facet )
7425
 
    {
7426
 
    case 0:
7427
 
      
7428
 
      break;
7429
 
    case 1:
7430
 
      
7431
 
      break;
7432
 
    case 2:
7433
 
      
7434
 
      break;
7435
 
    }
7436
 
}
7437
 
 
7438
 
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
7439
 
void UFC_CahnHilliard2DBilinearForm_dof_map_4::tabulate_entity_dofs(unsigned int* dofs,
7440
 
                                  unsigned int d, unsigned int i) const
7441
 
{
7442
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7443
 
}
7444
 
 
7445
 
/// Tabulate the coordinates of all dofs on a cell
7446
 
void UFC_CahnHilliard2DBilinearForm_dof_map_4::tabulate_coordinates(double** coordinates,
7447
 
                                         const ufc::cell& c) const
7448
 
{
7449
 
    const double * const * x = c.coordinates;
7450
 
    coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
7451
 
    coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
7452
 
}
7453
 
 
7454
 
/// Return the number of sub dof maps (for a mixed element)
7455
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_4::num_sub_dof_maps() const
7456
 
{
7457
 
    return 1;
7458
 
}
7459
 
 
7460
 
/// Create a new dof_map for sub dof map i (for a mixed element)
7461
 
ufc::dof_map* UFC_CahnHilliard2DBilinearForm_dof_map_4::create_sub_dof_map(unsigned int i) const
7462
 
{
7463
 
    return new UFC_CahnHilliard2DBilinearForm_dof_map_4();
7464
 
}
7465
 
 
7466
 
 
7467
 
/// Constructor
7468
 
UFC_CahnHilliard2DBilinearForm_dof_map_5::UFC_CahnHilliard2DBilinearForm_dof_map_5() : ufc::dof_map()
7469
 
{
7470
 
    __global_dimension = 0;
7471
 
}
7472
 
 
7473
 
/// Destructor
7474
 
UFC_CahnHilliard2DBilinearForm_dof_map_5::~UFC_CahnHilliard2DBilinearForm_dof_map_5()
7475
 
{
7476
 
    // Do nothing
7477
 
}
7478
 
 
7479
 
/// Return a string identifying the dof map
7480
 
const char* UFC_CahnHilliard2DBilinearForm_dof_map_5::signature() const
7481
 
{
7482
 
    return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
7483
 
}
7484
 
 
7485
 
/// Return true iff mesh entities of topological dimension d are needed
7486
 
bool UFC_CahnHilliard2DBilinearForm_dof_map_5::needs_mesh_entities(unsigned int d) const
7487
 
{
7488
 
    switch ( d )
7489
 
    {
7490
 
    case 0:
7491
 
      return false;
7492
 
      break;
7493
 
    case 1:
7494
 
      return false;
7495
 
      break;
7496
 
    case 2:
7497
 
      return true;
7498
 
      break;
7499
 
    }
7500
 
    return false;
7501
 
}
7502
 
 
7503
 
/// Initialize dof map for mesh (return true iff init_cell() is needed)
7504
 
bool UFC_CahnHilliard2DBilinearForm_dof_map_5::init_mesh(const ufc::mesh& m)
7505
 
{
7506
 
    __global_dimension = m.num_entities[2];
7507
 
    return false;
7508
 
}
7509
 
 
7510
 
/// Initialize dof map for given cell
7511
 
void UFC_CahnHilliard2DBilinearForm_dof_map_5::init_cell(const ufc::mesh& m,
7512
 
                              const ufc::cell& c)
7513
 
{
7514
 
    // Do nothing
7515
 
}
7516
 
 
7517
 
/// Finish initialization of dof map for cells
7518
 
void UFC_CahnHilliard2DBilinearForm_dof_map_5::init_cell_finalize()
7519
 
{
7520
 
    // Do nothing
7521
 
}
7522
 
 
7523
 
/// Return the dimension of the global finite element function space
7524
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_5::global_dimension() const
7525
 
{
7526
 
    return __global_dimension;
7527
 
}
7528
 
 
7529
 
/// Return the dimension of the local finite element function space
7530
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_5::local_dimension() const
7531
 
{
7532
 
    return 1;
7533
 
}
7534
 
 
7535
 
// Return the geometric dimension of the coordinates this dof map provides
7536
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_5::geometric_dimension() const
7537
 
{
7538
 
    return 2;
7539
 
}
7540
 
 
7541
 
/// Return the number of dofs on each cell facet
7542
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_5::num_facet_dofs() const
7543
 
{
7544
 
    return 0;
7545
 
}
7546
 
 
7547
 
/// Return the number of dofs associated with each cell entity of dimension d
7548
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_5::num_entity_dofs(unsigned int d) const
7549
 
{
7550
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7551
 
}
7552
 
 
7553
 
/// Tabulate the local-to-global mapping of dofs on a cell
7554
 
void UFC_CahnHilliard2DBilinearForm_dof_map_5::tabulate_dofs(unsigned int* dofs,
7555
 
                                  const ufc::mesh& m,
7556
 
                                  const ufc::cell& c) const
7557
 
{
7558
 
    dofs[0] = c.entity_indices[2][0];
7559
 
}
7560
 
 
7561
 
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
7562
 
void UFC_CahnHilliard2DBilinearForm_dof_map_5::tabulate_facet_dofs(unsigned int* dofs,
7563
 
                                        unsigned int facet) const
7564
 
{
7565
 
    switch ( facet )
7566
 
    {
7567
 
    case 0:
7568
 
      
7569
 
      break;
7570
 
    case 1:
7571
 
      
7572
 
      break;
7573
 
    case 2:
7574
 
      
7575
 
      break;
7576
 
    }
7577
 
}
7578
 
 
7579
 
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
7580
 
void UFC_CahnHilliard2DBilinearForm_dof_map_5::tabulate_entity_dofs(unsigned int* dofs,
7581
 
                                  unsigned int d, unsigned int i) const
7582
 
{
7583
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7584
 
}
7585
 
 
7586
 
/// Tabulate the coordinates of all dofs on a cell
7587
 
void UFC_CahnHilliard2DBilinearForm_dof_map_5::tabulate_coordinates(double** coordinates,
7588
 
                                         const ufc::cell& c) const
7589
 
{
7590
 
    const double * const * x = c.coordinates;
7591
 
    coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
7592
 
    coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
7593
 
}
7594
 
 
7595
 
/// Return the number of sub dof maps (for a mixed element)
7596
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_5::num_sub_dof_maps() const
7597
 
{
7598
 
    return 1;
7599
 
}
7600
 
 
7601
 
/// Create a new dof_map for sub dof map i (for a mixed element)
7602
 
ufc::dof_map* UFC_CahnHilliard2DBilinearForm_dof_map_5::create_sub_dof_map(unsigned int i) const
7603
 
{
7604
 
    return new UFC_CahnHilliard2DBilinearForm_dof_map_5();
7605
 
}
7606
 
 
7607
 
 
7608
 
/// Constructor
7609
 
UFC_CahnHilliard2DBilinearForm_dof_map_6::UFC_CahnHilliard2DBilinearForm_dof_map_6() : ufc::dof_map()
7610
 
{
7611
 
    __global_dimension = 0;
7612
 
}
7613
 
 
7614
 
/// Destructor
7615
 
UFC_CahnHilliard2DBilinearForm_dof_map_6::~UFC_CahnHilliard2DBilinearForm_dof_map_6()
7616
 
{
7617
 
    // Do nothing
7618
 
}
7619
 
 
7620
 
/// Return a string identifying the dof map
7621
 
const char* UFC_CahnHilliard2DBilinearForm_dof_map_6::signature() const
7622
 
{
7623
 
    return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
7624
 
}
7625
 
 
7626
 
/// Return true iff mesh entities of topological dimension d are needed
7627
 
bool UFC_CahnHilliard2DBilinearForm_dof_map_6::needs_mesh_entities(unsigned int d) const
7628
 
{
7629
 
    switch ( d )
7630
 
    {
7631
 
    case 0:
7632
 
      return false;
7633
 
      break;
7634
 
    case 1:
7635
 
      return false;
7636
 
      break;
7637
 
    case 2:
7638
 
      return true;
7639
 
      break;
7640
 
    }
7641
 
    return false;
7642
 
}
7643
 
 
7644
 
/// Initialize dof map for mesh (return true iff init_cell() is needed)
7645
 
bool UFC_CahnHilliard2DBilinearForm_dof_map_6::init_mesh(const ufc::mesh& m)
7646
 
{
7647
 
    __global_dimension = m.num_entities[2];
7648
 
    return false;
7649
 
}
7650
 
 
7651
 
/// Initialize dof map for given cell
7652
 
void UFC_CahnHilliard2DBilinearForm_dof_map_6::init_cell(const ufc::mesh& m,
7653
 
                              const ufc::cell& c)
7654
 
{
7655
 
    // Do nothing
7656
 
}
7657
 
 
7658
 
/// Finish initialization of dof map for cells
7659
 
void UFC_CahnHilliard2DBilinearForm_dof_map_6::init_cell_finalize()
7660
 
{
7661
 
    // Do nothing
7662
 
}
7663
 
 
7664
 
/// Return the dimension of the global finite element function space
7665
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_6::global_dimension() const
7666
 
{
7667
 
    return __global_dimension;
7668
 
}
7669
 
 
7670
 
/// Return the dimension of the local finite element function space
7671
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_6::local_dimension() const
7672
 
{
7673
 
    return 1;
7674
 
}
7675
 
 
7676
 
// Return the geometric dimension of the coordinates this dof map provides
7677
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_6::geometric_dimension() const
7678
 
{
7679
 
    return 2;
7680
 
}
7681
 
 
7682
 
/// Return the number of dofs on each cell facet
7683
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_6::num_facet_dofs() const
7684
 
{
7685
 
    return 0;
7686
 
}
7687
 
 
7688
 
/// Return the number of dofs associated with each cell entity of dimension d
7689
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_6::num_entity_dofs(unsigned int d) const
7690
 
{
7691
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7692
 
}
7693
 
 
7694
 
/// Tabulate the local-to-global mapping of dofs on a cell
7695
 
void UFC_CahnHilliard2DBilinearForm_dof_map_6::tabulate_dofs(unsigned int* dofs,
7696
 
                                  const ufc::mesh& m,
7697
 
                                  const ufc::cell& c) const
7698
 
{
7699
 
    dofs[0] = c.entity_indices[2][0];
7700
 
}
7701
 
 
7702
 
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
7703
 
void UFC_CahnHilliard2DBilinearForm_dof_map_6::tabulate_facet_dofs(unsigned int* dofs,
7704
 
                                        unsigned int facet) const
7705
 
{
7706
 
    switch ( facet )
7707
 
    {
7708
 
    case 0:
7709
 
      
7710
 
      break;
7711
 
    case 1:
7712
 
      
7713
 
      break;
7714
 
    case 2:
7715
 
      
7716
 
      break;
7717
 
    }
7718
 
}
7719
 
 
7720
 
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
7721
 
void UFC_CahnHilliard2DBilinearForm_dof_map_6::tabulate_entity_dofs(unsigned int* dofs,
7722
 
                                  unsigned int d, unsigned int i) const
7723
 
{
7724
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
7725
 
}
7726
 
 
7727
 
/// Tabulate the coordinates of all dofs on a cell
7728
 
void UFC_CahnHilliard2DBilinearForm_dof_map_6::tabulate_coordinates(double** coordinates,
7729
 
                                         const ufc::cell& c) const
7730
 
{
7731
 
    const double * const * x = c.coordinates;
7732
 
    coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
7733
 
    coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
7734
 
}
7735
 
 
7736
 
/// Return the number of sub dof maps (for a mixed element)
7737
 
unsigned int UFC_CahnHilliard2DBilinearForm_dof_map_6::num_sub_dof_maps() const
7738
 
{
7739
 
    return 1;
7740
 
}
7741
 
 
7742
 
/// Create a new dof_map for sub dof map i (for a mixed element)
7743
 
ufc::dof_map* UFC_CahnHilliard2DBilinearForm_dof_map_6::create_sub_dof_map(unsigned int i) const
7744
 
{
7745
 
    return new UFC_CahnHilliard2DBilinearForm_dof_map_6();
7746
 
}
7747
 
 
7748
 
 
7749
 
/// Constructor
7750
 
UFC_CahnHilliard2DBilinearForm_cell_integral_0::UFC_CahnHilliard2DBilinearForm_cell_integral_0() : ufc::cell_integral()
7751
 
{
7752
 
    // Do nothing
7753
 
}
7754
 
 
7755
 
/// Destructor
7756
 
UFC_CahnHilliard2DBilinearForm_cell_integral_0::~UFC_CahnHilliard2DBilinearForm_cell_integral_0()
 
2
 
 
3
/// Constructor
 
4
cahnhilliard2d_0_finite_element_0_0::cahnhilliard2d_0_finite_element_0_0() : ufc::finite_element()
 
5
{
 
6
    // Do nothing
 
7
}
 
8
 
 
9
/// Destructor
 
10
cahnhilliard2d_0_finite_element_0_0::~cahnhilliard2d_0_finite_element_0_0()
 
11
{
 
12
    // Do nothing
 
13
}
 
14
 
 
15
/// Return a string identifying the finite element
 
16
const char* cahnhilliard2d_0_finite_element_0_0::signature() const
 
17
{
 
18
    return "FiniteElement('Lagrange', 'triangle', 1)";
 
19
}
 
20
 
 
21
/// Return the cell shape
 
22
ufc::shape cahnhilliard2d_0_finite_element_0_0::cell_shape() const
 
23
{
 
24
    return ufc::triangle;
 
25
}
 
26
 
 
27
/// Return the dimension of the finite element function space
 
28
unsigned int cahnhilliard2d_0_finite_element_0_0::space_dimension() const
 
29
{
 
30
    return 3;
 
31
}
 
32
 
 
33
/// Return the rank of the value space
 
34
unsigned int cahnhilliard2d_0_finite_element_0_0::value_rank() const
 
35
{
 
36
    return 0;
 
37
}
 
38
 
 
39
/// Return the dimension of the value space for axis i
 
40
unsigned int cahnhilliard2d_0_finite_element_0_0::value_dimension(unsigned int i) const
 
41
{
 
42
    return 1;
 
43
}
 
44
 
 
45
/// Evaluate basis function i at given point in cell
 
46
void cahnhilliard2d_0_finite_element_0_0::evaluate_basis(unsigned int i,
 
47
                                   double* values,
 
48
                                   const double* coordinates,
 
49
                                   const ufc::cell& c) const
 
50
{
 
51
    // Extract vertex coordinates
 
52
    const double * const * element_coordinates = c.coordinates;
 
53
    
 
54
    // Compute Jacobian of affine map from reference cell
 
55
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
56
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
57
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
58
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
59
    
 
60
    // Compute determinant of Jacobian
 
61
    const double detJ = J_00*J_11 - J_01*J_10;
 
62
    
 
63
    // Compute inverse of Jacobian
 
64
    
 
65
    // Get coordinates and map to the reference (UFC) element
 
66
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
67
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
68
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
69
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
70
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
71
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
72
    
 
73
    // Map coordinates to the reference square
 
74
    if (std::abs(y - 1.0) < 1e-14)
 
75
      x = -1.0;
 
76
    else
 
77
      x = 2.0 *x/(1.0 - y) - 1.0;
 
78
    y = 2.0*y - 1.0;
 
79
    
 
80
    // Reset values
 
81
    *values = 0;
 
82
    
 
83
    // Map degree of freedom to element degree of freedom
 
84
    const unsigned int dof = i;
 
85
    
 
86
    // Generate scalings
 
87
    const double scalings_y_0 = 1;
 
88
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
89
    
 
90
    // Compute psitilde_a
 
91
    const double psitilde_a_0 = 1;
 
92
    const double psitilde_a_1 = x;
 
93
    
 
94
    // Compute psitilde_bs
 
95
    const double psitilde_bs_0_0 = 1;
 
96
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
97
    const double psitilde_bs_1_0 = 1;
 
98
    
 
99
    // Compute basisvalues
 
100
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
101
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
102
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
103
    
 
104
    // Table(s) of coefficients
 
105
    static const double coefficients0[3][3] = \
 
106
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
107
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
108
    {0.471404520791032, 0, 0.333333333333333}};
 
109
    
 
110
    // Extract relevant coefficients
 
111
    const double coeff0_0 = coefficients0[dof][0];
 
112
    const double coeff0_1 = coefficients0[dof][1];
 
113
    const double coeff0_2 = coefficients0[dof][2];
 
114
    
 
115
    // Compute value(s)
 
116
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
117
}
 
118
 
 
119
/// Evaluate all basis functions at given point in cell
 
120
void cahnhilliard2d_0_finite_element_0_0::evaluate_basis_all(double* values,
 
121
                                       const double* coordinates,
 
122
                                       const ufc::cell& c) const
 
123
{
 
124
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
125
}
 
126
 
 
127
/// Evaluate order n derivatives of basis function i at given point in cell
 
128
void cahnhilliard2d_0_finite_element_0_0::evaluate_basis_derivatives(unsigned int i,
 
129
                                               unsigned int n,
 
130
                                               double* values,
 
131
                                               const double* coordinates,
 
132
                                               const ufc::cell& c) const
 
133
{
 
134
    // Extract vertex coordinates
 
135
    const double * const * element_coordinates = c.coordinates;
 
136
    
 
137
    // Compute Jacobian of affine map from reference cell
 
138
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
139
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
140
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
141
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
142
    
 
143
    // Compute determinant of Jacobian
 
144
    const double detJ = J_00*J_11 - J_01*J_10;
 
145
    
 
146
    // Compute inverse of Jacobian
 
147
    
 
148
    // Get coordinates and map to the reference (UFC) element
 
149
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
150
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
151
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
152
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
153
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
154
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
155
    
 
156
    // Map coordinates to the reference square
 
157
    if (std::abs(y - 1.0) < 1e-14)
 
158
      x = -1.0;
 
159
    else
 
160
      x = 2.0 *x/(1.0 - y) - 1.0;
 
161
    y = 2.0*y - 1.0;
 
162
    
 
163
    // Compute number of derivatives
 
164
    unsigned int num_derivatives = 1;
 
165
    
 
166
    for (unsigned int j = 0; j < n; j++)
 
167
      num_derivatives *= 2;
 
168
    
 
169
    
 
170
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
171
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
172
    
 
173
    for (unsigned int j = 0; j < num_derivatives; j++)
 
174
    {
 
175
      combinations[j] = new unsigned int [n];
 
176
      for (unsigned int k = 0; k < n; k++)
 
177
        combinations[j][k] = 0;
 
178
    }
 
179
    
 
180
    // Generate combinations of derivatives
 
181
    for (unsigned int row = 1; row < num_derivatives; row++)
 
182
    {
 
183
      for (unsigned int num = 0; num < row; num++)
 
184
      {
 
185
        for (unsigned int col = n-1; col+1 > 0; col--)
 
186
        {
 
187
          if (combinations[row][col] + 1 > 1)
 
188
            combinations[row][col] = 0;
 
189
          else
 
190
          {
 
191
            combinations[row][col] += 1;
 
192
            break;
 
193
          }
 
194
        }
 
195
      }
 
196
    }
 
197
    
 
198
    // Compute inverse of Jacobian
 
199
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
200
    
 
201
    // Declare transformation matrix
 
202
    // Declare pointer to two dimensional array and initialise
 
203
    double **transform = new double *[num_derivatives];
 
204
    
 
205
    for (unsigned int j = 0; j < num_derivatives; j++)
 
206
    {
 
207
      transform[j] = new double [num_derivatives];
 
208
      for (unsigned int k = 0; k < num_derivatives; k++)
 
209
        transform[j][k] = 1;
 
210
    }
 
211
    
 
212
    // Construct transformation matrix
 
213
    for (unsigned int row = 0; row < num_derivatives; row++)
 
214
    {
 
215
      for (unsigned int col = 0; col < num_derivatives; col++)
 
216
      {
 
217
        for (unsigned int k = 0; k < n; k++)
 
218
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
219
      }
 
220
    }
 
221
    
 
222
    // Reset values
 
223
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
 
224
      values[j] = 0;
 
225
    
 
226
    // Map degree of freedom to element degree of freedom
 
227
    const unsigned int dof = i;
 
228
    
 
229
    // Generate scalings
 
230
    const double scalings_y_0 = 1;
 
231
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
232
    
 
233
    // Compute psitilde_a
 
234
    const double psitilde_a_0 = 1;
 
235
    const double psitilde_a_1 = x;
 
236
    
 
237
    // Compute psitilde_bs
 
238
    const double psitilde_bs_0_0 = 1;
 
239
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
240
    const double psitilde_bs_1_0 = 1;
 
241
    
 
242
    // Compute basisvalues
 
243
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
244
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
245
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
246
    
 
247
    // Table(s) of coefficients
 
248
    static const double coefficients0[3][3] = \
 
249
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
250
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
251
    {0.471404520791032, 0, 0.333333333333333}};
 
252
    
 
253
    // Interesting (new) part
 
254
    // Tables of derivatives of the polynomial base (transpose)
 
255
    static const double dmats0[3][3] = \
 
256
    {{0, 0, 0},
 
257
    {4.89897948556636, 0, 0},
 
258
    {0, 0, 0}};
 
259
    
 
260
    static const double dmats1[3][3] = \
 
261
    {{0, 0, 0},
 
262
    {2.44948974278318, 0, 0},
 
263
    {4.24264068711928, 0, 0}};
 
264
    
 
265
    // Compute reference derivatives
 
266
    // Declare pointer to array of derivatives on FIAT element
 
267
    double *derivatives = new double [num_derivatives];
 
268
    
 
269
    // Declare coefficients
 
270
    double coeff0_0 = 0;
 
271
    double coeff0_1 = 0;
 
272
    double coeff0_2 = 0;
 
273
    
 
274
    // Declare new coefficients
 
275
    double new_coeff0_0 = 0;
 
276
    double new_coeff0_1 = 0;
 
277
    double new_coeff0_2 = 0;
 
278
    
 
279
    // Loop possible derivatives
 
280
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
281
    {
 
282
      // Get values from coefficients array
 
283
      new_coeff0_0 = coefficients0[dof][0];
 
284
      new_coeff0_1 = coefficients0[dof][1];
 
285
      new_coeff0_2 = coefficients0[dof][2];
 
286
    
 
287
      // Loop derivative order
 
288
      for (unsigned int j = 0; j < n; j++)
 
289
      {
 
290
        // Update old coefficients
 
291
        coeff0_0 = new_coeff0_0;
 
292
        coeff0_1 = new_coeff0_1;
 
293
        coeff0_2 = new_coeff0_2;
 
294
    
 
295
        if(combinations[deriv_num][j] == 0)
 
296
        {
 
297
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
298
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
299
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
300
        }
 
301
        if(combinations[deriv_num][j] == 1)
 
302
        {
 
303
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
304
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
305
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
306
        }
 
307
    
 
308
      }
 
309
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
310
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
311
    }
 
312
    
 
313
    // Transform derivatives back to physical element
 
314
    for (unsigned int row = 0; row < num_derivatives; row++)
 
315
    {
 
316
      for (unsigned int col = 0; col < num_derivatives; col++)
 
317
      {
 
318
        values[row] += transform[row][col]*derivatives[col];
 
319
      }
 
320
    }
 
321
    // Delete pointer to array of derivatives on FIAT element
 
322
    delete [] derivatives;
 
323
    
 
324
    // Delete pointer to array of combinations of derivatives and transform
 
325
    for (unsigned int row = 0; row < num_derivatives; row++)
 
326
    {
 
327
      delete [] combinations[row];
 
328
      delete [] transform[row];
 
329
    }
 
330
    
 
331
    delete [] combinations;
 
332
    delete [] transform;
 
333
}
 
334
 
 
335
/// Evaluate order n derivatives of all basis functions at given point in cell
 
336
void cahnhilliard2d_0_finite_element_0_0::evaluate_basis_derivatives_all(unsigned int n,
 
337
                                                   double* values,
 
338
                                                   const double* coordinates,
 
339
                                                   const ufc::cell& c) const
 
340
{
 
341
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
342
}
 
343
 
 
344
/// Evaluate linear functional for dof i on the function f
 
345
double cahnhilliard2d_0_finite_element_0_0::evaluate_dof(unsigned int i,
 
346
                                   const ufc::function& f,
 
347
                                   const ufc::cell& c) const
 
348
{
 
349
    // The reference points, direction and weights:
 
350
    static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
 
351
    static const double W[3][1] = {{1}, {1}, {1}};
 
352
    static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
 
353
    
 
354
    const double * const * x = c.coordinates;
 
355
    double result = 0.0;
 
356
    // Iterate over the points:
 
357
    // Evaluate basis functions for affine mapping
 
358
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
359
    const double w1 = X[i][0][0];
 
360
    const double w2 = X[i][0][1];
 
361
    
 
362
    // Compute affine mapping y = F(X)
 
363
    double y[2];
 
364
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
365
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
366
    
 
367
    // Evaluate function at physical points
 
368
    double values[1];
 
369
    f.evaluate(values, y, c);
 
370
    
 
371
    // Map function values using appropriate mapping
 
372
    // Affine map: Do nothing
 
373
    
 
374
    // Note that we do not map the weights (yet).
 
375
    
 
376
    // Take directional components
 
377
    for(int k = 0; k < 1; k++)
 
378
      result += values[k]*D[i][0][k];
 
379
    // Multiply by weights
 
380
    result *= W[i][0];
 
381
    
 
382
    return result;
 
383
}
 
384
 
 
385
/// Evaluate linear functionals for all dofs on the function f
 
386
void cahnhilliard2d_0_finite_element_0_0::evaluate_dofs(double* values,
 
387
                                  const ufc::function& f,
 
388
                                  const ufc::cell& c) const
 
389
{
 
390
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
391
}
 
392
 
 
393
/// Interpolate vertex values from dof values
 
394
void cahnhilliard2d_0_finite_element_0_0::interpolate_vertex_values(double* vertex_values,
 
395
                                              const double* dof_values,
 
396
                                              const ufc::cell& c) const
 
397
{
 
398
    // Evaluate at vertices and use affine mapping
 
399
    vertex_values[0] = dof_values[0];
 
400
    vertex_values[1] = dof_values[1];
 
401
    vertex_values[2] = dof_values[2];
 
402
}
 
403
 
 
404
/// Return the number of sub elements (for a mixed element)
 
405
unsigned int cahnhilliard2d_0_finite_element_0_0::num_sub_elements() const
 
406
{
 
407
    return 1;
 
408
}
 
409
 
 
410
/// Create a new finite element for sub element i (for a mixed element)
 
411
ufc::finite_element* cahnhilliard2d_0_finite_element_0_0::create_sub_element(unsigned int i) const
 
412
{
 
413
    return new cahnhilliard2d_0_finite_element_0_0();
 
414
}
 
415
 
 
416
 
 
417
/// Constructor
 
418
cahnhilliard2d_0_finite_element_0_1::cahnhilliard2d_0_finite_element_0_1() : ufc::finite_element()
 
419
{
 
420
    // Do nothing
 
421
}
 
422
 
 
423
/// Destructor
 
424
cahnhilliard2d_0_finite_element_0_1::~cahnhilliard2d_0_finite_element_0_1()
 
425
{
 
426
    // Do nothing
 
427
}
 
428
 
 
429
/// Return a string identifying the finite element
 
430
const char* cahnhilliard2d_0_finite_element_0_1::signature() const
 
431
{
 
432
    return "FiniteElement('Lagrange', 'triangle', 1)";
 
433
}
 
434
 
 
435
/// Return the cell shape
 
436
ufc::shape cahnhilliard2d_0_finite_element_0_1::cell_shape() const
 
437
{
 
438
    return ufc::triangle;
 
439
}
 
440
 
 
441
/// Return the dimension of the finite element function space
 
442
unsigned int cahnhilliard2d_0_finite_element_0_1::space_dimension() const
 
443
{
 
444
    return 3;
 
445
}
 
446
 
 
447
/// Return the rank of the value space
 
448
unsigned int cahnhilliard2d_0_finite_element_0_1::value_rank() const
 
449
{
 
450
    return 0;
 
451
}
 
452
 
 
453
/// Return the dimension of the value space for axis i
 
454
unsigned int cahnhilliard2d_0_finite_element_0_1::value_dimension(unsigned int i) const
 
455
{
 
456
    return 1;
 
457
}
 
458
 
 
459
/// Evaluate basis function i at given point in cell
 
460
void cahnhilliard2d_0_finite_element_0_1::evaluate_basis(unsigned int i,
 
461
                                   double* values,
 
462
                                   const double* coordinates,
 
463
                                   const ufc::cell& c) const
 
464
{
 
465
    // Extract vertex coordinates
 
466
    const double * const * element_coordinates = c.coordinates;
 
467
    
 
468
    // Compute Jacobian of affine map from reference cell
 
469
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
470
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
471
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
472
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
473
    
 
474
    // Compute determinant of Jacobian
 
475
    const double detJ = J_00*J_11 - J_01*J_10;
 
476
    
 
477
    // Compute inverse of Jacobian
 
478
    
 
479
    // Get coordinates and map to the reference (UFC) element
 
480
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
481
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
482
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
483
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
484
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
485
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
486
    
 
487
    // Map coordinates to the reference square
 
488
    if (std::abs(y - 1.0) < 1e-14)
 
489
      x = -1.0;
 
490
    else
 
491
      x = 2.0 *x/(1.0 - y) - 1.0;
 
492
    y = 2.0*y - 1.0;
 
493
    
 
494
    // Reset values
 
495
    *values = 0;
 
496
    
 
497
    // Map degree of freedom to element degree of freedom
 
498
    const unsigned int dof = i;
 
499
    
 
500
    // Generate scalings
 
501
    const double scalings_y_0 = 1;
 
502
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
503
    
 
504
    // Compute psitilde_a
 
505
    const double psitilde_a_0 = 1;
 
506
    const double psitilde_a_1 = x;
 
507
    
 
508
    // Compute psitilde_bs
 
509
    const double psitilde_bs_0_0 = 1;
 
510
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
511
    const double psitilde_bs_1_0 = 1;
 
512
    
 
513
    // Compute basisvalues
 
514
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
515
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
516
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
517
    
 
518
    // Table(s) of coefficients
 
519
    static const double coefficients0[3][3] = \
 
520
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
521
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
522
    {0.471404520791032, 0, 0.333333333333333}};
 
523
    
 
524
    // Extract relevant coefficients
 
525
    const double coeff0_0 = coefficients0[dof][0];
 
526
    const double coeff0_1 = coefficients0[dof][1];
 
527
    const double coeff0_2 = coefficients0[dof][2];
 
528
    
 
529
    // Compute value(s)
 
530
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
531
}
 
532
 
 
533
/// Evaluate all basis functions at given point in cell
 
534
void cahnhilliard2d_0_finite_element_0_1::evaluate_basis_all(double* values,
 
535
                                       const double* coordinates,
 
536
                                       const ufc::cell& c) const
 
537
{
 
538
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
539
}
 
540
 
 
541
/// Evaluate order n derivatives of basis function i at given point in cell
 
542
void cahnhilliard2d_0_finite_element_0_1::evaluate_basis_derivatives(unsigned int i,
 
543
                                               unsigned int n,
 
544
                                               double* values,
 
545
                                               const double* coordinates,
 
546
                                               const ufc::cell& c) const
 
547
{
 
548
    // Extract vertex coordinates
 
549
    const double * const * element_coordinates = c.coordinates;
 
550
    
 
551
    // Compute Jacobian of affine map from reference cell
 
552
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
553
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
554
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
555
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
556
    
 
557
    // Compute determinant of Jacobian
 
558
    const double detJ = J_00*J_11 - J_01*J_10;
 
559
    
 
560
    // Compute inverse of Jacobian
 
561
    
 
562
    // Get coordinates and map to the reference (UFC) element
 
563
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
564
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
565
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
566
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
567
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
568
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
569
    
 
570
    // Map coordinates to the reference square
 
571
    if (std::abs(y - 1.0) < 1e-14)
 
572
      x = -1.0;
 
573
    else
 
574
      x = 2.0 *x/(1.0 - y) - 1.0;
 
575
    y = 2.0*y - 1.0;
 
576
    
 
577
    // Compute number of derivatives
 
578
    unsigned int num_derivatives = 1;
 
579
    
 
580
    for (unsigned int j = 0; j < n; j++)
 
581
      num_derivatives *= 2;
 
582
    
 
583
    
 
584
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
585
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
586
    
 
587
    for (unsigned int j = 0; j < num_derivatives; j++)
 
588
    {
 
589
      combinations[j] = new unsigned int [n];
 
590
      for (unsigned int k = 0; k < n; k++)
 
591
        combinations[j][k] = 0;
 
592
    }
 
593
    
 
594
    // Generate combinations of derivatives
 
595
    for (unsigned int row = 1; row < num_derivatives; row++)
 
596
    {
 
597
      for (unsigned int num = 0; num < row; num++)
 
598
      {
 
599
        for (unsigned int col = n-1; col+1 > 0; col--)
 
600
        {
 
601
          if (combinations[row][col] + 1 > 1)
 
602
            combinations[row][col] = 0;
 
603
          else
 
604
          {
 
605
            combinations[row][col] += 1;
 
606
            break;
 
607
          }
 
608
        }
 
609
      }
 
610
    }
 
611
    
 
612
    // Compute inverse of Jacobian
 
613
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
614
    
 
615
    // Declare transformation matrix
 
616
    // Declare pointer to two dimensional array and initialise
 
617
    double **transform = new double *[num_derivatives];
 
618
    
 
619
    for (unsigned int j = 0; j < num_derivatives; j++)
 
620
    {
 
621
      transform[j] = new double [num_derivatives];
 
622
      for (unsigned int k = 0; k < num_derivatives; k++)
 
623
        transform[j][k] = 1;
 
624
    }
 
625
    
 
626
    // Construct transformation matrix
 
627
    for (unsigned int row = 0; row < num_derivatives; row++)
 
628
    {
 
629
      for (unsigned int col = 0; col < num_derivatives; col++)
 
630
      {
 
631
        for (unsigned int k = 0; k < n; k++)
 
632
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
633
      }
 
634
    }
 
635
    
 
636
    // Reset values
 
637
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
 
638
      values[j] = 0;
 
639
    
 
640
    // Map degree of freedom to element degree of freedom
 
641
    const unsigned int dof = i;
 
642
    
 
643
    // Generate scalings
 
644
    const double scalings_y_0 = 1;
 
645
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
646
    
 
647
    // Compute psitilde_a
 
648
    const double psitilde_a_0 = 1;
 
649
    const double psitilde_a_1 = x;
 
650
    
 
651
    // Compute psitilde_bs
 
652
    const double psitilde_bs_0_0 = 1;
 
653
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
654
    const double psitilde_bs_1_0 = 1;
 
655
    
 
656
    // Compute basisvalues
 
657
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
658
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
659
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
660
    
 
661
    // Table(s) of coefficients
 
662
    static const double coefficients0[3][3] = \
 
663
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
664
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
665
    {0.471404520791032, 0, 0.333333333333333}};
 
666
    
 
667
    // Interesting (new) part
 
668
    // Tables of derivatives of the polynomial base (transpose)
 
669
    static const double dmats0[3][3] = \
 
670
    {{0, 0, 0},
 
671
    {4.89897948556636, 0, 0},
 
672
    {0, 0, 0}};
 
673
    
 
674
    static const double dmats1[3][3] = \
 
675
    {{0, 0, 0},
 
676
    {2.44948974278318, 0, 0},
 
677
    {4.24264068711928, 0, 0}};
 
678
    
 
679
    // Compute reference derivatives
 
680
    // Declare pointer to array of derivatives on FIAT element
 
681
    double *derivatives = new double [num_derivatives];
 
682
    
 
683
    // Declare coefficients
 
684
    double coeff0_0 = 0;
 
685
    double coeff0_1 = 0;
 
686
    double coeff0_2 = 0;
 
687
    
 
688
    // Declare new coefficients
 
689
    double new_coeff0_0 = 0;
 
690
    double new_coeff0_1 = 0;
 
691
    double new_coeff0_2 = 0;
 
692
    
 
693
    // Loop possible derivatives
 
694
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
695
    {
 
696
      // Get values from coefficients array
 
697
      new_coeff0_0 = coefficients0[dof][0];
 
698
      new_coeff0_1 = coefficients0[dof][1];
 
699
      new_coeff0_2 = coefficients0[dof][2];
 
700
    
 
701
      // Loop derivative order
 
702
      for (unsigned int j = 0; j < n; j++)
 
703
      {
 
704
        // Update old coefficients
 
705
        coeff0_0 = new_coeff0_0;
 
706
        coeff0_1 = new_coeff0_1;
 
707
        coeff0_2 = new_coeff0_2;
 
708
    
 
709
        if(combinations[deriv_num][j] == 0)
 
710
        {
 
711
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
712
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
713
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
714
        }
 
715
        if(combinations[deriv_num][j] == 1)
 
716
        {
 
717
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
718
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
719
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
720
        }
 
721
    
 
722
      }
 
723
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
724
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
725
    }
 
726
    
 
727
    // Transform derivatives back to physical element
 
728
    for (unsigned int row = 0; row < num_derivatives; row++)
 
729
    {
 
730
      for (unsigned int col = 0; col < num_derivatives; col++)
 
731
      {
 
732
        values[row] += transform[row][col]*derivatives[col];
 
733
      }
 
734
    }
 
735
    // Delete pointer to array of derivatives on FIAT element
 
736
    delete [] derivatives;
 
737
    
 
738
    // Delete pointer to array of combinations of derivatives and transform
 
739
    for (unsigned int row = 0; row < num_derivatives; row++)
 
740
    {
 
741
      delete [] combinations[row];
 
742
      delete [] transform[row];
 
743
    }
 
744
    
 
745
    delete [] combinations;
 
746
    delete [] transform;
 
747
}
 
748
 
 
749
/// Evaluate order n derivatives of all basis functions at given point in cell
 
750
void cahnhilliard2d_0_finite_element_0_1::evaluate_basis_derivatives_all(unsigned int n,
 
751
                                                   double* values,
 
752
                                                   const double* coordinates,
 
753
                                                   const ufc::cell& c) const
 
754
{
 
755
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
756
}
 
757
 
 
758
/// Evaluate linear functional for dof i on the function f
 
759
double cahnhilliard2d_0_finite_element_0_1::evaluate_dof(unsigned int i,
 
760
                                   const ufc::function& f,
 
761
                                   const ufc::cell& c) const
 
762
{
 
763
    // The reference points, direction and weights:
 
764
    static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
 
765
    static const double W[3][1] = {{1}, {1}, {1}};
 
766
    static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
 
767
    
 
768
    const double * const * x = c.coordinates;
 
769
    double result = 0.0;
 
770
    // Iterate over the points:
 
771
    // Evaluate basis functions for affine mapping
 
772
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
773
    const double w1 = X[i][0][0];
 
774
    const double w2 = X[i][0][1];
 
775
    
 
776
    // Compute affine mapping y = F(X)
 
777
    double y[2];
 
778
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
779
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
780
    
 
781
    // Evaluate function at physical points
 
782
    double values[1];
 
783
    f.evaluate(values, y, c);
 
784
    
 
785
    // Map function values using appropriate mapping
 
786
    // Affine map: Do nothing
 
787
    
 
788
    // Note that we do not map the weights (yet).
 
789
    
 
790
    // Take directional components
 
791
    for(int k = 0; k < 1; k++)
 
792
      result += values[k]*D[i][0][k];
 
793
    // Multiply by weights
 
794
    result *= W[i][0];
 
795
    
 
796
    return result;
 
797
}
 
798
 
 
799
/// Evaluate linear functionals for all dofs on the function f
 
800
void cahnhilliard2d_0_finite_element_0_1::evaluate_dofs(double* values,
 
801
                                  const ufc::function& f,
 
802
                                  const ufc::cell& c) const
 
803
{
 
804
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
805
}
 
806
 
 
807
/// Interpolate vertex values from dof values
 
808
void cahnhilliard2d_0_finite_element_0_1::interpolate_vertex_values(double* vertex_values,
 
809
                                              const double* dof_values,
 
810
                                              const ufc::cell& c) const
 
811
{
 
812
    // Evaluate at vertices and use affine mapping
 
813
    vertex_values[0] = dof_values[0];
 
814
    vertex_values[1] = dof_values[1];
 
815
    vertex_values[2] = dof_values[2];
 
816
}
 
817
 
 
818
/// Return the number of sub elements (for a mixed element)
 
819
unsigned int cahnhilliard2d_0_finite_element_0_1::num_sub_elements() const
 
820
{
 
821
    return 1;
 
822
}
 
823
 
 
824
/// Create a new finite element for sub element i (for a mixed element)
 
825
ufc::finite_element* cahnhilliard2d_0_finite_element_0_1::create_sub_element(unsigned int i) const
 
826
{
 
827
    return new cahnhilliard2d_0_finite_element_0_1();
 
828
}
 
829
 
 
830
 
 
831
/// Constructor
 
832
cahnhilliard2d_0_finite_element_0::cahnhilliard2d_0_finite_element_0() : ufc::finite_element()
 
833
{
 
834
    // Do nothing
 
835
}
 
836
 
 
837
/// Destructor
 
838
cahnhilliard2d_0_finite_element_0::~cahnhilliard2d_0_finite_element_0()
 
839
{
 
840
    // Do nothing
 
841
}
 
842
 
 
843
/// Return a string identifying the finite element
 
844
const char* cahnhilliard2d_0_finite_element_0::signature() const
 
845
{
 
846
    return "MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
 
847
}
 
848
 
 
849
/// Return the cell shape
 
850
ufc::shape cahnhilliard2d_0_finite_element_0::cell_shape() const
 
851
{
 
852
    return ufc::triangle;
 
853
}
 
854
 
 
855
/// Return the dimension of the finite element function space
 
856
unsigned int cahnhilliard2d_0_finite_element_0::space_dimension() const
 
857
{
 
858
    return 6;
 
859
}
 
860
 
 
861
/// Return the rank of the value space
 
862
unsigned int cahnhilliard2d_0_finite_element_0::value_rank() const
 
863
{
 
864
    return 1;
 
865
}
 
866
 
 
867
/// Return the dimension of the value space for axis i
 
868
unsigned int cahnhilliard2d_0_finite_element_0::value_dimension(unsigned int i) const
 
869
{
 
870
    return 2;
 
871
}
 
872
 
 
873
/// Evaluate basis function i at given point in cell
 
874
void cahnhilliard2d_0_finite_element_0::evaluate_basis(unsigned int i,
 
875
                                   double* values,
 
876
                                   const double* coordinates,
 
877
                                   const ufc::cell& c) const
 
878
{
 
879
    // Extract vertex coordinates
 
880
    const double * const * element_coordinates = c.coordinates;
 
881
    
 
882
    // Compute Jacobian of affine map from reference cell
 
883
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
884
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
885
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
886
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
887
    
 
888
    // Compute determinant of Jacobian
 
889
    const double detJ = J_00*J_11 - J_01*J_10;
 
890
    
 
891
    // Compute inverse of Jacobian
 
892
    
 
893
    // Get coordinates and map to the reference (UFC) element
 
894
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
895
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
896
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
897
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
898
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
899
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
900
    
 
901
    // Map coordinates to the reference square
 
902
    if (std::abs(y - 1.0) < 1e-14)
 
903
      x = -1.0;
 
904
    else
 
905
      x = 2.0 *x/(1.0 - y) - 1.0;
 
906
    y = 2.0*y - 1.0;
 
907
    
 
908
    // Reset values
 
909
    values[0] = 0;
 
910
    values[1] = 0;
 
911
    
 
912
    if (0 <= i && i <= 2)
 
913
    {
 
914
      // Map degree of freedom to element degree of freedom
 
915
      const unsigned int dof = i;
 
916
    
 
917
      // Generate scalings
 
918
      const double scalings_y_0 = 1;
 
919
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
920
    
 
921
      // Compute psitilde_a
 
922
      const double psitilde_a_0 = 1;
 
923
      const double psitilde_a_1 = x;
 
924
    
 
925
      // Compute psitilde_bs
 
926
      const double psitilde_bs_0_0 = 1;
 
927
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
928
      const double psitilde_bs_1_0 = 1;
 
929
    
 
930
      // Compute basisvalues
 
931
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
932
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
933
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
934
    
 
935
      // Table(s) of coefficients
 
936
      static const double coefficients0[3][3] =   \
 
937
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
938
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
939
      {0.471404520791032, 0, 0.333333333333333}};
 
940
    
 
941
      // Extract relevant coefficients
 
942
      const double coeff0_0 =   coefficients0[dof][0];
 
943
      const double coeff0_1 =   coefficients0[dof][1];
 
944
      const double coeff0_2 =   coefficients0[dof][2];
 
945
    
 
946
      // Compute value(s)
 
947
      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
948
    }
 
949
    
 
950
    if (3 <= i && i <= 5)
 
951
    {
 
952
      // Map degree of freedom to element degree of freedom
 
953
      const unsigned int dof = i - 3;
 
954
    
 
955
      // Generate scalings
 
956
      const double scalings_y_0 = 1;
 
957
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
958
    
 
959
      // Compute psitilde_a
 
960
      const double psitilde_a_0 = 1;
 
961
      const double psitilde_a_1 = x;
 
962
    
 
963
      // Compute psitilde_bs
 
964
      const double psitilde_bs_0_0 = 1;
 
965
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
966
      const double psitilde_bs_1_0 = 1;
 
967
    
 
968
      // Compute basisvalues
 
969
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
970
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
971
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
972
    
 
973
      // Table(s) of coefficients
 
974
      static const double coefficients0[3][3] =   \
 
975
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
976
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
977
      {0.471404520791032, 0, 0.333333333333333}};
 
978
    
 
979
      // Extract relevant coefficients
 
980
      const double coeff0_0 =   coefficients0[dof][0];
 
981
      const double coeff0_1 =   coefficients0[dof][1];
 
982
      const double coeff0_2 =   coefficients0[dof][2];
 
983
    
 
984
      // Compute value(s)
 
985
      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
986
    }
 
987
    
 
988
}
 
989
 
 
990
/// Evaluate all basis functions at given point in cell
 
991
void cahnhilliard2d_0_finite_element_0::evaluate_basis_all(double* values,
 
992
                                       const double* coordinates,
 
993
                                       const ufc::cell& c) const
 
994
{
 
995
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
996
}
 
997
 
 
998
/// Evaluate order n derivatives of basis function i at given point in cell
 
999
void cahnhilliard2d_0_finite_element_0::evaluate_basis_derivatives(unsigned int i,
 
1000
                                               unsigned int n,
 
1001
                                               double* values,
 
1002
                                               const double* coordinates,
 
1003
                                               const ufc::cell& c) const
 
1004
{
 
1005
    // Extract vertex coordinates
 
1006
    const double * const * element_coordinates = c.coordinates;
 
1007
    
 
1008
    // Compute Jacobian of affine map from reference cell
 
1009
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
1010
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
1011
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
1012
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
1013
    
 
1014
    // Compute determinant of Jacobian
 
1015
    const double detJ = J_00*J_11 - J_01*J_10;
 
1016
    
 
1017
    // Compute inverse of Jacobian
 
1018
    
 
1019
    // Get coordinates and map to the reference (UFC) element
 
1020
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
1021
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
1022
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
1023
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
1024
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
1025
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
1026
    
 
1027
    // Map coordinates to the reference square
 
1028
    if (std::abs(y - 1.0) < 1e-14)
 
1029
      x = -1.0;
 
1030
    else
 
1031
      x = 2.0 *x/(1.0 - y) - 1.0;
 
1032
    y = 2.0*y - 1.0;
 
1033
    
 
1034
    // Compute number of derivatives
 
1035
    unsigned int num_derivatives = 1;
 
1036
    
 
1037
    for (unsigned int j = 0; j < n; j++)
 
1038
      num_derivatives *= 2;
 
1039
    
 
1040
    
 
1041
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
1042
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
1043
    
 
1044
    for (unsigned int j = 0; j < num_derivatives; j++)
 
1045
    {
 
1046
      combinations[j] = new unsigned int [n];
 
1047
      for (unsigned int k = 0; k < n; k++)
 
1048
        combinations[j][k] = 0;
 
1049
    }
 
1050
    
 
1051
    // Generate combinations of derivatives
 
1052
    for (unsigned int row = 1; row < num_derivatives; row++)
 
1053
    {
 
1054
      for (unsigned int num = 0; num < row; num++)
 
1055
      {
 
1056
        for (unsigned int col = n-1; col+1 > 0; col--)
 
1057
        {
 
1058
          if (combinations[row][col] + 1 > 1)
 
1059
            combinations[row][col] = 0;
 
1060
          else
 
1061
          {
 
1062
            combinations[row][col] += 1;
 
1063
            break;
 
1064
          }
 
1065
        }
 
1066
      }
 
1067
    }
 
1068
    
 
1069
    // Compute inverse of Jacobian
 
1070
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
1071
    
 
1072
    // Declare transformation matrix
 
1073
    // Declare pointer to two dimensional array and initialise
 
1074
    double **transform = new double *[num_derivatives];
 
1075
    
 
1076
    for (unsigned int j = 0; j < num_derivatives; j++)
 
1077
    {
 
1078
      transform[j] = new double [num_derivatives];
 
1079
      for (unsigned int k = 0; k < num_derivatives; k++)
 
1080
        transform[j][k] = 1;
 
1081
    }
 
1082
    
 
1083
    // Construct transformation matrix
 
1084
    for (unsigned int row = 0; row < num_derivatives; row++)
 
1085
    {
 
1086
      for (unsigned int col = 0; col < num_derivatives; col++)
 
1087
      {
 
1088
        for (unsigned int k = 0; k < n; k++)
 
1089
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
1090
      }
 
1091
    }
 
1092
    
 
1093
    // Reset values
 
1094
    for (unsigned int j = 0; j < 2*num_derivatives; j++)
 
1095
      values[j] = 0;
 
1096
    
 
1097
    if (0 <= i && i <= 2)
 
1098
    {
 
1099
      // Map degree of freedom to element degree of freedom
 
1100
      const unsigned int dof = i;
 
1101
    
 
1102
      // Generate scalings
 
1103
      const double scalings_y_0 = 1;
 
1104
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
1105
    
 
1106
      // Compute psitilde_a
 
1107
      const double psitilde_a_0 = 1;
 
1108
      const double psitilde_a_1 = x;
 
1109
    
 
1110
      // Compute psitilde_bs
 
1111
      const double psitilde_bs_0_0 = 1;
 
1112
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
1113
      const double psitilde_bs_1_0 = 1;
 
1114
    
 
1115
      // Compute basisvalues
 
1116
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
1117
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
1118
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
1119
    
 
1120
      // Table(s) of coefficients
 
1121
      static const double coefficients0[3][3] =   \
 
1122
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
1123
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
1124
      {0.471404520791032, 0, 0.333333333333333}};
 
1125
    
 
1126
      // Interesting (new) part
 
1127
      // Tables of derivatives of the polynomial base (transpose)
 
1128
      static const double dmats0[3][3] =   \
 
1129
      {{0, 0, 0},
 
1130
      {4.89897948556636, 0, 0},
 
1131
      {0, 0, 0}};
 
1132
    
 
1133
      static const double dmats1[3][3] =   \
 
1134
      {{0, 0, 0},
 
1135
      {2.44948974278318, 0, 0},
 
1136
      {4.24264068711928, 0, 0}};
 
1137
    
 
1138
      // Compute reference derivatives
 
1139
      // Declare pointer to array of derivatives on FIAT element
 
1140
      double *derivatives = new double [num_derivatives];
 
1141
    
 
1142
      // Declare coefficients
 
1143
      double coeff0_0 = 0;
 
1144
      double coeff0_1 = 0;
 
1145
      double coeff0_2 = 0;
 
1146
    
 
1147
      // Declare new coefficients
 
1148
      double new_coeff0_0 = 0;
 
1149
      double new_coeff0_1 = 0;
 
1150
      double new_coeff0_2 = 0;
 
1151
    
 
1152
      // Loop possible derivatives
 
1153
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
1154
      {
 
1155
        // Get values from coefficients array
 
1156
        new_coeff0_0 = coefficients0[dof][0];
 
1157
        new_coeff0_1 = coefficients0[dof][1];
 
1158
        new_coeff0_2 = coefficients0[dof][2];
 
1159
    
 
1160
        // Loop derivative order
 
1161
        for (unsigned int j = 0; j < n; j++)
 
1162
        {
 
1163
          // Update old coefficients
 
1164
          coeff0_0 = new_coeff0_0;
 
1165
          coeff0_1 = new_coeff0_1;
 
1166
          coeff0_2 = new_coeff0_2;
 
1167
    
 
1168
          if(combinations[deriv_num][j] == 0)
 
1169
          {
 
1170
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
1171
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
1172
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
1173
          }
 
1174
          if(combinations[deriv_num][j] == 1)
 
1175
          {
 
1176
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
1177
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
1178
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
1179
          }
 
1180
    
 
1181
        }
 
1182
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
1183
        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
1184
      }
 
1185
    
 
1186
      // Transform derivatives back to physical element
 
1187
      for (unsigned int row = 0; row < num_derivatives; row++)
 
1188
      {
 
1189
        for (unsigned int col = 0; col < num_derivatives; col++)
 
1190
        {
 
1191
          values[row] += transform[row][col]*derivatives[col];
 
1192
        }
 
1193
      }
 
1194
      // Delete pointer to array of derivatives on FIAT element
 
1195
      delete [] derivatives;
 
1196
    
 
1197
      // Delete pointer to array of combinations of derivatives and transform
 
1198
      for (unsigned int row = 0; row < num_derivatives; row++)
 
1199
      {
 
1200
        delete [] combinations[row];
 
1201
        delete [] transform[row];
 
1202
      }
 
1203
    
 
1204
      delete [] combinations;
 
1205
      delete [] transform;
 
1206
    }
 
1207
    
 
1208
    if (3 <= i && i <= 5)
 
1209
    {
 
1210
      // Map degree of freedom to element degree of freedom
 
1211
      const unsigned int dof = i - 3;
 
1212
    
 
1213
      // Generate scalings
 
1214
      const double scalings_y_0 = 1;
 
1215
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
1216
    
 
1217
      // Compute psitilde_a
 
1218
      const double psitilde_a_0 = 1;
 
1219
      const double psitilde_a_1 = x;
 
1220
    
 
1221
      // Compute psitilde_bs
 
1222
      const double psitilde_bs_0_0 = 1;
 
1223
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
1224
      const double psitilde_bs_1_0 = 1;
 
1225
    
 
1226
      // Compute basisvalues
 
1227
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
1228
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
1229
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
1230
    
 
1231
      // Table(s) of coefficients
 
1232
      static const double coefficients0[3][3] =   \
 
1233
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
1234
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
1235
      {0.471404520791032, 0, 0.333333333333333}};
 
1236
    
 
1237
      // Interesting (new) part
 
1238
      // Tables of derivatives of the polynomial base (transpose)
 
1239
      static const double dmats0[3][3] =   \
 
1240
      {{0, 0, 0},
 
1241
      {4.89897948556636, 0, 0},
 
1242
      {0, 0, 0}};
 
1243
    
 
1244
      static const double dmats1[3][3] =   \
 
1245
      {{0, 0, 0},
 
1246
      {2.44948974278318, 0, 0},
 
1247
      {4.24264068711928, 0, 0}};
 
1248
    
 
1249
      // Compute reference derivatives
 
1250
      // Declare pointer to array of derivatives on FIAT element
 
1251
      double *derivatives = new double [num_derivatives];
 
1252
    
 
1253
      // Declare coefficients
 
1254
      double coeff0_0 = 0;
 
1255
      double coeff0_1 = 0;
 
1256
      double coeff0_2 = 0;
 
1257
    
 
1258
      // Declare new coefficients
 
1259
      double new_coeff0_0 = 0;
 
1260
      double new_coeff0_1 = 0;
 
1261
      double new_coeff0_2 = 0;
 
1262
    
 
1263
      // Loop possible derivatives
 
1264
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
1265
      {
 
1266
        // Get values from coefficients array
 
1267
        new_coeff0_0 = coefficients0[dof][0];
 
1268
        new_coeff0_1 = coefficients0[dof][1];
 
1269
        new_coeff0_2 = coefficients0[dof][2];
 
1270
    
 
1271
        // Loop derivative order
 
1272
        for (unsigned int j = 0; j < n; j++)
 
1273
        {
 
1274
          // Update old coefficients
 
1275
          coeff0_0 = new_coeff0_0;
 
1276
          coeff0_1 = new_coeff0_1;
 
1277
          coeff0_2 = new_coeff0_2;
 
1278
    
 
1279
          if(combinations[deriv_num][j] == 0)
 
1280
          {
 
1281
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
1282
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
1283
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
1284
          }
 
1285
          if(combinations[deriv_num][j] == 1)
 
1286
          {
 
1287
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
1288
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
1289
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
1290
          }
 
1291
    
 
1292
        }
 
1293
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
1294
        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
1295
      }
 
1296
    
 
1297
      // Transform derivatives back to physical element
 
1298
      for (unsigned int row = 0; row < num_derivatives; row++)
 
1299
      {
 
1300
        for (unsigned int col = 0; col < num_derivatives; col++)
 
1301
        {
 
1302
          values[num_derivatives + row] += transform[row][col]*derivatives[col];
 
1303
        }
 
1304
      }
 
1305
      // Delete pointer to array of derivatives on FIAT element
 
1306
      delete [] derivatives;
 
1307
    
 
1308
      // Delete pointer to array of combinations of derivatives and transform
 
1309
      for (unsigned int row = 0; row < num_derivatives; row++)
 
1310
      {
 
1311
        delete [] combinations[row];
 
1312
        delete [] transform[row];
 
1313
      }
 
1314
    
 
1315
      delete [] combinations;
 
1316
      delete [] transform;
 
1317
    }
 
1318
    
 
1319
}
 
1320
 
 
1321
/// Evaluate order n derivatives of all basis functions at given point in cell
 
1322
void cahnhilliard2d_0_finite_element_0::evaluate_basis_derivatives_all(unsigned int n,
 
1323
                                                   double* values,
 
1324
                                                   const double* coordinates,
 
1325
                                                   const ufc::cell& c) const
 
1326
{
 
1327
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
1328
}
 
1329
 
 
1330
/// Evaluate linear functional for dof i on the function f
 
1331
double cahnhilliard2d_0_finite_element_0::evaluate_dof(unsigned int i,
 
1332
                                   const ufc::function& f,
 
1333
                                   const ufc::cell& c) const
 
1334
{
 
1335
    // The reference points, direction and weights:
 
1336
    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
 
1337
    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
 
1338
    static const double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
 
1339
    
 
1340
    const double * const * x = c.coordinates;
 
1341
    double result = 0.0;
 
1342
    // Iterate over the points:
 
1343
    // Evaluate basis functions for affine mapping
 
1344
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
1345
    const double w1 = X[i][0][0];
 
1346
    const double w2 = X[i][0][1];
 
1347
    
 
1348
    // Compute affine mapping y = F(X)
 
1349
    double y[2];
 
1350
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
1351
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
1352
    
 
1353
    // Evaluate function at physical points
 
1354
    double values[2];
 
1355
    f.evaluate(values, y, c);
 
1356
    
 
1357
    // Map function values using appropriate mapping
 
1358
    // Affine map: Do nothing
 
1359
    
 
1360
    // Note that we do not map the weights (yet).
 
1361
    
 
1362
    // Take directional components
 
1363
    for(int k = 0; k < 2; k++)
 
1364
      result += values[k]*D[i][0][k];
 
1365
    // Multiply by weights
 
1366
    result *= W[i][0];
 
1367
    
 
1368
    return result;
 
1369
}
 
1370
 
 
1371
/// Evaluate linear functionals for all dofs on the function f
 
1372
void cahnhilliard2d_0_finite_element_0::evaluate_dofs(double* values,
 
1373
                                  const ufc::function& f,
 
1374
                                  const ufc::cell& c) const
 
1375
{
 
1376
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
1377
}
 
1378
 
 
1379
/// Interpolate vertex values from dof values
 
1380
void cahnhilliard2d_0_finite_element_0::interpolate_vertex_values(double* vertex_values,
 
1381
                                              const double* dof_values,
 
1382
                                              const ufc::cell& c) const
 
1383
{
 
1384
    // Evaluate at vertices and use affine mapping
 
1385
    vertex_values[0] = dof_values[0];
 
1386
    vertex_values[2] = dof_values[1];
 
1387
    vertex_values[4] = dof_values[2];
 
1388
    // Evaluate at vertices and use affine mapping
 
1389
    vertex_values[1] = dof_values[3];
 
1390
    vertex_values[3] = dof_values[4];
 
1391
    vertex_values[5] = dof_values[5];
 
1392
}
 
1393
 
 
1394
/// Return the number of sub elements (for a mixed element)
 
1395
unsigned int cahnhilliard2d_0_finite_element_0::num_sub_elements() const
 
1396
{
 
1397
    return 2;
 
1398
}
 
1399
 
 
1400
/// Create a new finite element for sub element i (for a mixed element)
 
1401
ufc::finite_element* cahnhilliard2d_0_finite_element_0::create_sub_element(unsigned int i) const
 
1402
{
 
1403
    switch ( i )
 
1404
    {
 
1405
    case 0:
 
1406
      return new cahnhilliard2d_0_finite_element_0_0();
 
1407
      break;
 
1408
    case 1:
 
1409
      return new cahnhilliard2d_0_finite_element_0_1();
 
1410
      break;
 
1411
    }
 
1412
    return 0;
 
1413
}
 
1414
 
 
1415
 
 
1416
/// Constructor
 
1417
cahnhilliard2d_0_finite_element_1_0::cahnhilliard2d_0_finite_element_1_0() : ufc::finite_element()
 
1418
{
 
1419
    // Do nothing
 
1420
}
 
1421
 
 
1422
/// Destructor
 
1423
cahnhilliard2d_0_finite_element_1_0::~cahnhilliard2d_0_finite_element_1_0()
 
1424
{
 
1425
    // Do nothing
 
1426
}
 
1427
 
 
1428
/// Return a string identifying the finite element
 
1429
const char* cahnhilliard2d_0_finite_element_1_0::signature() const
 
1430
{
 
1431
    return "FiniteElement('Lagrange', 'triangle', 1)";
 
1432
}
 
1433
 
 
1434
/// Return the cell shape
 
1435
ufc::shape cahnhilliard2d_0_finite_element_1_0::cell_shape() const
 
1436
{
 
1437
    return ufc::triangle;
 
1438
}
 
1439
 
 
1440
/// Return the dimension of the finite element function space
 
1441
unsigned int cahnhilliard2d_0_finite_element_1_0::space_dimension() const
 
1442
{
 
1443
    return 3;
 
1444
}
 
1445
 
 
1446
/// Return the rank of the value space
 
1447
unsigned int cahnhilliard2d_0_finite_element_1_0::value_rank() const
 
1448
{
 
1449
    return 0;
 
1450
}
 
1451
 
 
1452
/// Return the dimension of the value space for axis i
 
1453
unsigned int cahnhilliard2d_0_finite_element_1_0::value_dimension(unsigned int i) const
 
1454
{
 
1455
    return 1;
 
1456
}
 
1457
 
 
1458
/// Evaluate basis function i at given point in cell
 
1459
void cahnhilliard2d_0_finite_element_1_0::evaluate_basis(unsigned int i,
 
1460
                                   double* values,
 
1461
                                   const double* coordinates,
 
1462
                                   const ufc::cell& c) const
 
1463
{
 
1464
    // Extract vertex coordinates
 
1465
    const double * const * element_coordinates = c.coordinates;
 
1466
    
 
1467
    // Compute Jacobian of affine map from reference cell
 
1468
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
1469
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
1470
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
1471
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
1472
    
 
1473
    // Compute determinant of Jacobian
 
1474
    const double detJ = J_00*J_11 - J_01*J_10;
 
1475
    
 
1476
    // Compute inverse of Jacobian
 
1477
    
 
1478
    // Get coordinates and map to the reference (UFC) element
 
1479
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
1480
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
1481
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
1482
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
1483
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
1484
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
1485
    
 
1486
    // Map coordinates to the reference square
 
1487
    if (std::abs(y - 1.0) < 1e-14)
 
1488
      x = -1.0;
 
1489
    else
 
1490
      x = 2.0 *x/(1.0 - y) - 1.0;
 
1491
    y = 2.0*y - 1.0;
 
1492
    
 
1493
    // Reset values
 
1494
    *values = 0;
 
1495
    
 
1496
    // Map degree of freedom to element degree of freedom
 
1497
    const unsigned int dof = i;
 
1498
    
 
1499
    // Generate scalings
 
1500
    const double scalings_y_0 = 1;
 
1501
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
1502
    
 
1503
    // Compute psitilde_a
 
1504
    const double psitilde_a_0 = 1;
 
1505
    const double psitilde_a_1 = x;
 
1506
    
 
1507
    // Compute psitilde_bs
 
1508
    const double psitilde_bs_0_0 = 1;
 
1509
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
1510
    const double psitilde_bs_1_0 = 1;
 
1511
    
 
1512
    // Compute basisvalues
 
1513
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
1514
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
1515
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
1516
    
 
1517
    // Table(s) of coefficients
 
1518
    static const double coefficients0[3][3] = \
 
1519
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
1520
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
1521
    {0.471404520791032, 0, 0.333333333333333}};
 
1522
    
 
1523
    // Extract relevant coefficients
 
1524
    const double coeff0_0 = coefficients0[dof][0];
 
1525
    const double coeff0_1 = coefficients0[dof][1];
 
1526
    const double coeff0_2 = coefficients0[dof][2];
 
1527
    
 
1528
    // Compute value(s)
 
1529
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
1530
}
 
1531
 
 
1532
/// Evaluate all basis functions at given point in cell
 
1533
void cahnhilliard2d_0_finite_element_1_0::evaluate_basis_all(double* values,
 
1534
                                       const double* coordinates,
 
1535
                                       const ufc::cell& c) const
 
1536
{
 
1537
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
1538
}
 
1539
 
 
1540
/// Evaluate order n derivatives of basis function i at given point in cell
 
1541
void cahnhilliard2d_0_finite_element_1_0::evaluate_basis_derivatives(unsigned int i,
 
1542
                                               unsigned int n,
 
1543
                                               double* values,
 
1544
                                               const double* coordinates,
 
1545
                                               const ufc::cell& c) const
 
1546
{
 
1547
    // Extract vertex coordinates
 
1548
    const double * const * element_coordinates = c.coordinates;
 
1549
    
 
1550
    // Compute Jacobian of affine map from reference cell
 
1551
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
1552
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
1553
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
1554
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
1555
    
 
1556
    // Compute determinant of Jacobian
 
1557
    const double detJ = J_00*J_11 - J_01*J_10;
 
1558
    
 
1559
    // Compute inverse of Jacobian
 
1560
    
 
1561
    // Get coordinates and map to the reference (UFC) element
 
1562
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
1563
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
1564
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
1565
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
1566
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
1567
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
1568
    
 
1569
    // Map coordinates to the reference square
 
1570
    if (std::abs(y - 1.0) < 1e-14)
 
1571
      x = -1.0;
 
1572
    else
 
1573
      x = 2.0 *x/(1.0 - y) - 1.0;
 
1574
    y = 2.0*y - 1.0;
 
1575
    
 
1576
    // Compute number of derivatives
 
1577
    unsigned int num_derivatives = 1;
 
1578
    
 
1579
    for (unsigned int j = 0; j < n; j++)
 
1580
      num_derivatives *= 2;
 
1581
    
 
1582
    
 
1583
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
1584
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
1585
    
 
1586
    for (unsigned int j = 0; j < num_derivatives; j++)
 
1587
    {
 
1588
      combinations[j] = new unsigned int [n];
 
1589
      for (unsigned int k = 0; k < n; k++)
 
1590
        combinations[j][k] = 0;
 
1591
    }
 
1592
    
 
1593
    // Generate combinations of derivatives
 
1594
    for (unsigned int row = 1; row < num_derivatives; row++)
 
1595
    {
 
1596
      for (unsigned int num = 0; num < row; num++)
 
1597
      {
 
1598
        for (unsigned int col = n-1; col+1 > 0; col--)
 
1599
        {
 
1600
          if (combinations[row][col] + 1 > 1)
 
1601
            combinations[row][col] = 0;
 
1602
          else
 
1603
          {
 
1604
            combinations[row][col] += 1;
 
1605
            break;
 
1606
          }
 
1607
        }
 
1608
      }
 
1609
    }
 
1610
    
 
1611
    // Compute inverse of Jacobian
 
1612
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
1613
    
 
1614
    // Declare transformation matrix
 
1615
    // Declare pointer to two dimensional array and initialise
 
1616
    double **transform = new double *[num_derivatives];
 
1617
    
 
1618
    for (unsigned int j = 0; j < num_derivatives; j++)
 
1619
    {
 
1620
      transform[j] = new double [num_derivatives];
 
1621
      for (unsigned int k = 0; k < num_derivatives; k++)
 
1622
        transform[j][k] = 1;
 
1623
    }
 
1624
    
 
1625
    // Construct transformation matrix
 
1626
    for (unsigned int row = 0; row < num_derivatives; row++)
 
1627
    {
 
1628
      for (unsigned int col = 0; col < num_derivatives; col++)
 
1629
      {
 
1630
        for (unsigned int k = 0; k < n; k++)
 
1631
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
1632
      }
 
1633
    }
 
1634
    
 
1635
    // Reset values
 
1636
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
 
1637
      values[j] = 0;
 
1638
    
 
1639
    // Map degree of freedom to element degree of freedom
 
1640
    const unsigned int dof = i;
 
1641
    
 
1642
    // Generate scalings
 
1643
    const double scalings_y_0 = 1;
 
1644
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
1645
    
 
1646
    // Compute psitilde_a
 
1647
    const double psitilde_a_0 = 1;
 
1648
    const double psitilde_a_1 = x;
 
1649
    
 
1650
    // Compute psitilde_bs
 
1651
    const double psitilde_bs_0_0 = 1;
 
1652
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
1653
    const double psitilde_bs_1_0 = 1;
 
1654
    
 
1655
    // Compute basisvalues
 
1656
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
1657
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
1658
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
1659
    
 
1660
    // Table(s) of coefficients
 
1661
    static const double coefficients0[3][3] = \
 
1662
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
1663
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
1664
    {0.471404520791032, 0, 0.333333333333333}};
 
1665
    
 
1666
    // Interesting (new) part
 
1667
    // Tables of derivatives of the polynomial base (transpose)
 
1668
    static const double dmats0[3][3] = \
 
1669
    {{0, 0, 0},
 
1670
    {4.89897948556636, 0, 0},
 
1671
    {0, 0, 0}};
 
1672
    
 
1673
    static const double dmats1[3][3] = \
 
1674
    {{0, 0, 0},
 
1675
    {2.44948974278318, 0, 0},
 
1676
    {4.24264068711928, 0, 0}};
 
1677
    
 
1678
    // Compute reference derivatives
 
1679
    // Declare pointer to array of derivatives on FIAT element
 
1680
    double *derivatives = new double [num_derivatives];
 
1681
    
 
1682
    // Declare coefficients
 
1683
    double coeff0_0 = 0;
 
1684
    double coeff0_1 = 0;
 
1685
    double coeff0_2 = 0;
 
1686
    
 
1687
    // Declare new coefficients
 
1688
    double new_coeff0_0 = 0;
 
1689
    double new_coeff0_1 = 0;
 
1690
    double new_coeff0_2 = 0;
 
1691
    
 
1692
    // Loop possible derivatives
 
1693
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
1694
    {
 
1695
      // Get values from coefficients array
 
1696
      new_coeff0_0 = coefficients0[dof][0];
 
1697
      new_coeff0_1 = coefficients0[dof][1];
 
1698
      new_coeff0_2 = coefficients0[dof][2];
 
1699
    
 
1700
      // Loop derivative order
 
1701
      for (unsigned int j = 0; j < n; j++)
 
1702
      {
 
1703
        // Update old coefficients
 
1704
        coeff0_0 = new_coeff0_0;
 
1705
        coeff0_1 = new_coeff0_1;
 
1706
        coeff0_2 = new_coeff0_2;
 
1707
    
 
1708
        if(combinations[deriv_num][j] == 0)
 
1709
        {
 
1710
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
1711
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
1712
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
1713
        }
 
1714
        if(combinations[deriv_num][j] == 1)
 
1715
        {
 
1716
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
1717
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
1718
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
1719
        }
 
1720
    
 
1721
      }
 
1722
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
1723
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
1724
    }
 
1725
    
 
1726
    // Transform derivatives back to physical element
 
1727
    for (unsigned int row = 0; row < num_derivatives; row++)
 
1728
    {
 
1729
      for (unsigned int col = 0; col < num_derivatives; col++)
 
1730
      {
 
1731
        values[row] += transform[row][col]*derivatives[col];
 
1732
      }
 
1733
    }
 
1734
    // Delete pointer to array of derivatives on FIAT element
 
1735
    delete [] derivatives;
 
1736
    
 
1737
    // Delete pointer to array of combinations of derivatives and transform
 
1738
    for (unsigned int row = 0; row < num_derivatives; row++)
 
1739
    {
 
1740
      delete [] combinations[row];
 
1741
      delete [] transform[row];
 
1742
    }
 
1743
    
 
1744
    delete [] combinations;
 
1745
    delete [] transform;
 
1746
}
 
1747
 
 
1748
/// Evaluate order n derivatives of all basis functions at given point in cell
 
1749
void cahnhilliard2d_0_finite_element_1_0::evaluate_basis_derivatives_all(unsigned int n,
 
1750
                                                   double* values,
 
1751
                                                   const double* coordinates,
 
1752
                                                   const ufc::cell& c) const
 
1753
{
 
1754
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
1755
}
 
1756
 
 
1757
/// Evaluate linear functional for dof i on the function f
 
1758
double cahnhilliard2d_0_finite_element_1_0::evaluate_dof(unsigned int i,
 
1759
                                   const ufc::function& f,
 
1760
                                   const ufc::cell& c) const
 
1761
{
 
1762
    // The reference points, direction and weights:
 
1763
    static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
 
1764
    static const double W[3][1] = {{1}, {1}, {1}};
 
1765
    static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
 
1766
    
 
1767
    const double * const * x = c.coordinates;
 
1768
    double result = 0.0;
 
1769
    // Iterate over the points:
 
1770
    // Evaluate basis functions for affine mapping
 
1771
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
1772
    const double w1 = X[i][0][0];
 
1773
    const double w2 = X[i][0][1];
 
1774
    
 
1775
    // Compute affine mapping y = F(X)
 
1776
    double y[2];
 
1777
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
1778
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
1779
    
 
1780
    // Evaluate function at physical points
 
1781
    double values[1];
 
1782
    f.evaluate(values, y, c);
 
1783
    
 
1784
    // Map function values using appropriate mapping
 
1785
    // Affine map: Do nothing
 
1786
    
 
1787
    // Note that we do not map the weights (yet).
 
1788
    
 
1789
    // Take directional components
 
1790
    for(int k = 0; k < 1; k++)
 
1791
      result += values[k]*D[i][0][k];
 
1792
    // Multiply by weights
 
1793
    result *= W[i][0];
 
1794
    
 
1795
    return result;
 
1796
}
 
1797
 
 
1798
/// Evaluate linear functionals for all dofs on the function f
 
1799
void cahnhilliard2d_0_finite_element_1_0::evaluate_dofs(double* values,
 
1800
                                  const ufc::function& f,
 
1801
                                  const ufc::cell& c) const
 
1802
{
 
1803
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
1804
}
 
1805
 
 
1806
/// Interpolate vertex values from dof values
 
1807
void cahnhilliard2d_0_finite_element_1_0::interpolate_vertex_values(double* vertex_values,
 
1808
                                              const double* dof_values,
 
1809
                                              const ufc::cell& c) const
 
1810
{
 
1811
    // Evaluate at vertices and use affine mapping
 
1812
    vertex_values[0] = dof_values[0];
 
1813
    vertex_values[1] = dof_values[1];
 
1814
    vertex_values[2] = dof_values[2];
 
1815
}
 
1816
 
 
1817
/// Return the number of sub elements (for a mixed element)
 
1818
unsigned int cahnhilliard2d_0_finite_element_1_0::num_sub_elements() const
 
1819
{
 
1820
    return 1;
 
1821
}
 
1822
 
 
1823
/// Create a new finite element for sub element i (for a mixed element)
 
1824
ufc::finite_element* cahnhilliard2d_0_finite_element_1_0::create_sub_element(unsigned int i) const
 
1825
{
 
1826
    return new cahnhilliard2d_0_finite_element_1_0();
 
1827
}
 
1828
 
 
1829
 
 
1830
/// Constructor
 
1831
cahnhilliard2d_0_finite_element_1_1::cahnhilliard2d_0_finite_element_1_1() : ufc::finite_element()
 
1832
{
 
1833
    // Do nothing
 
1834
}
 
1835
 
 
1836
/// Destructor
 
1837
cahnhilliard2d_0_finite_element_1_1::~cahnhilliard2d_0_finite_element_1_1()
 
1838
{
 
1839
    // Do nothing
 
1840
}
 
1841
 
 
1842
/// Return a string identifying the finite element
 
1843
const char* cahnhilliard2d_0_finite_element_1_1::signature() const
 
1844
{
 
1845
    return "FiniteElement('Lagrange', 'triangle', 1)";
 
1846
}
 
1847
 
 
1848
/// Return the cell shape
 
1849
ufc::shape cahnhilliard2d_0_finite_element_1_1::cell_shape() const
 
1850
{
 
1851
    return ufc::triangle;
 
1852
}
 
1853
 
 
1854
/// Return the dimension of the finite element function space
 
1855
unsigned int cahnhilliard2d_0_finite_element_1_1::space_dimension() const
 
1856
{
 
1857
    return 3;
 
1858
}
 
1859
 
 
1860
/// Return the rank of the value space
 
1861
unsigned int cahnhilliard2d_0_finite_element_1_1::value_rank() const
 
1862
{
 
1863
    return 0;
 
1864
}
 
1865
 
 
1866
/// Return the dimension of the value space for axis i
 
1867
unsigned int cahnhilliard2d_0_finite_element_1_1::value_dimension(unsigned int i) const
 
1868
{
 
1869
    return 1;
 
1870
}
 
1871
 
 
1872
/// Evaluate basis function i at given point in cell
 
1873
void cahnhilliard2d_0_finite_element_1_1::evaluate_basis(unsigned int i,
 
1874
                                   double* values,
 
1875
                                   const double* coordinates,
 
1876
                                   const ufc::cell& c) const
 
1877
{
 
1878
    // Extract vertex coordinates
 
1879
    const double * const * element_coordinates = c.coordinates;
 
1880
    
 
1881
    // Compute Jacobian of affine map from reference cell
 
1882
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
1883
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
1884
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
1885
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
1886
    
 
1887
    // Compute determinant of Jacobian
 
1888
    const double detJ = J_00*J_11 - J_01*J_10;
 
1889
    
 
1890
    // Compute inverse of Jacobian
 
1891
    
 
1892
    // Get coordinates and map to the reference (UFC) element
 
1893
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
1894
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
1895
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
1896
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
1897
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
1898
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
1899
    
 
1900
    // Map coordinates to the reference square
 
1901
    if (std::abs(y - 1.0) < 1e-14)
 
1902
      x = -1.0;
 
1903
    else
 
1904
      x = 2.0 *x/(1.0 - y) - 1.0;
 
1905
    y = 2.0*y - 1.0;
 
1906
    
 
1907
    // Reset values
 
1908
    *values = 0;
 
1909
    
 
1910
    // Map degree of freedom to element degree of freedom
 
1911
    const unsigned int dof = i;
 
1912
    
 
1913
    // Generate scalings
 
1914
    const double scalings_y_0 = 1;
 
1915
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
1916
    
 
1917
    // Compute psitilde_a
 
1918
    const double psitilde_a_0 = 1;
 
1919
    const double psitilde_a_1 = x;
 
1920
    
 
1921
    // Compute psitilde_bs
 
1922
    const double psitilde_bs_0_0 = 1;
 
1923
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
1924
    const double psitilde_bs_1_0 = 1;
 
1925
    
 
1926
    // Compute basisvalues
 
1927
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
1928
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
1929
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
1930
    
 
1931
    // Table(s) of coefficients
 
1932
    static const double coefficients0[3][3] = \
 
1933
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
1934
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
1935
    {0.471404520791032, 0, 0.333333333333333}};
 
1936
    
 
1937
    // Extract relevant coefficients
 
1938
    const double coeff0_0 = coefficients0[dof][0];
 
1939
    const double coeff0_1 = coefficients0[dof][1];
 
1940
    const double coeff0_2 = coefficients0[dof][2];
 
1941
    
 
1942
    // Compute value(s)
 
1943
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
1944
}
 
1945
 
 
1946
/// Evaluate all basis functions at given point in cell
 
1947
void cahnhilliard2d_0_finite_element_1_1::evaluate_basis_all(double* values,
 
1948
                                       const double* coordinates,
 
1949
                                       const ufc::cell& c) const
 
1950
{
 
1951
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
1952
}
 
1953
 
 
1954
/// Evaluate order n derivatives of basis function i at given point in cell
 
1955
void cahnhilliard2d_0_finite_element_1_1::evaluate_basis_derivatives(unsigned int i,
 
1956
                                               unsigned int n,
 
1957
                                               double* values,
 
1958
                                               const double* coordinates,
 
1959
                                               const ufc::cell& c) const
 
1960
{
 
1961
    // Extract vertex coordinates
 
1962
    const double * const * element_coordinates = c.coordinates;
 
1963
    
 
1964
    // Compute Jacobian of affine map from reference cell
 
1965
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
1966
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
1967
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
1968
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
1969
    
 
1970
    // Compute determinant of Jacobian
 
1971
    const double detJ = J_00*J_11 - J_01*J_10;
 
1972
    
 
1973
    // Compute inverse of Jacobian
 
1974
    
 
1975
    // Get coordinates and map to the reference (UFC) element
 
1976
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
1977
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
1978
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
1979
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
1980
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
1981
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
1982
    
 
1983
    // Map coordinates to the reference square
 
1984
    if (std::abs(y - 1.0) < 1e-14)
 
1985
      x = -1.0;
 
1986
    else
 
1987
      x = 2.0 *x/(1.0 - y) - 1.0;
 
1988
    y = 2.0*y - 1.0;
 
1989
    
 
1990
    // Compute number of derivatives
 
1991
    unsigned int num_derivatives = 1;
 
1992
    
 
1993
    for (unsigned int j = 0; j < n; j++)
 
1994
      num_derivatives *= 2;
 
1995
    
 
1996
    
 
1997
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
1998
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
1999
    
 
2000
    for (unsigned int j = 0; j < num_derivatives; j++)
 
2001
    {
 
2002
      combinations[j] = new unsigned int [n];
 
2003
      for (unsigned int k = 0; k < n; k++)
 
2004
        combinations[j][k] = 0;
 
2005
    }
 
2006
    
 
2007
    // Generate combinations of derivatives
 
2008
    for (unsigned int row = 1; row < num_derivatives; row++)
 
2009
    {
 
2010
      for (unsigned int num = 0; num < row; num++)
 
2011
      {
 
2012
        for (unsigned int col = n-1; col+1 > 0; col--)
 
2013
        {
 
2014
          if (combinations[row][col] + 1 > 1)
 
2015
            combinations[row][col] = 0;
 
2016
          else
 
2017
          {
 
2018
            combinations[row][col] += 1;
 
2019
            break;
 
2020
          }
 
2021
        }
 
2022
      }
 
2023
    }
 
2024
    
 
2025
    // Compute inverse of Jacobian
 
2026
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
2027
    
 
2028
    // Declare transformation matrix
 
2029
    // Declare pointer to two dimensional array and initialise
 
2030
    double **transform = new double *[num_derivatives];
 
2031
    
 
2032
    for (unsigned int j = 0; j < num_derivatives; j++)
 
2033
    {
 
2034
      transform[j] = new double [num_derivatives];
 
2035
      for (unsigned int k = 0; k < num_derivatives; k++)
 
2036
        transform[j][k] = 1;
 
2037
    }
 
2038
    
 
2039
    // Construct transformation matrix
 
2040
    for (unsigned int row = 0; row < num_derivatives; row++)
 
2041
    {
 
2042
      for (unsigned int col = 0; col < num_derivatives; col++)
 
2043
      {
 
2044
        for (unsigned int k = 0; k < n; k++)
 
2045
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
2046
      }
 
2047
    }
 
2048
    
 
2049
    // Reset values
 
2050
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
 
2051
      values[j] = 0;
 
2052
    
 
2053
    // Map degree of freedom to element degree of freedom
 
2054
    const unsigned int dof = i;
 
2055
    
 
2056
    // Generate scalings
 
2057
    const double scalings_y_0 = 1;
 
2058
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
2059
    
 
2060
    // Compute psitilde_a
 
2061
    const double psitilde_a_0 = 1;
 
2062
    const double psitilde_a_1 = x;
 
2063
    
 
2064
    // Compute psitilde_bs
 
2065
    const double psitilde_bs_0_0 = 1;
 
2066
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
2067
    const double psitilde_bs_1_0 = 1;
 
2068
    
 
2069
    // Compute basisvalues
 
2070
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
2071
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
2072
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
2073
    
 
2074
    // Table(s) of coefficients
 
2075
    static const double coefficients0[3][3] = \
 
2076
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
2077
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
2078
    {0.471404520791032, 0, 0.333333333333333}};
 
2079
    
 
2080
    // Interesting (new) part
 
2081
    // Tables of derivatives of the polynomial base (transpose)
 
2082
    static const double dmats0[3][3] = \
 
2083
    {{0, 0, 0},
 
2084
    {4.89897948556636, 0, 0},
 
2085
    {0, 0, 0}};
 
2086
    
 
2087
    static const double dmats1[3][3] = \
 
2088
    {{0, 0, 0},
 
2089
    {2.44948974278318, 0, 0},
 
2090
    {4.24264068711928, 0, 0}};
 
2091
    
 
2092
    // Compute reference derivatives
 
2093
    // Declare pointer to array of derivatives on FIAT element
 
2094
    double *derivatives = new double [num_derivatives];
 
2095
    
 
2096
    // Declare coefficients
 
2097
    double coeff0_0 = 0;
 
2098
    double coeff0_1 = 0;
 
2099
    double coeff0_2 = 0;
 
2100
    
 
2101
    // Declare new coefficients
 
2102
    double new_coeff0_0 = 0;
 
2103
    double new_coeff0_1 = 0;
 
2104
    double new_coeff0_2 = 0;
 
2105
    
 
2106
    // Loop possible derivatives
 
2107
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
2108
    {
 
2109
      // Get values from coefficients array
 
2110
      new_coeff0_0 = coefficients0[dof][0];
 
2111
      new_coeff0_1 = coefficients0[dof][1];
 
2112
      new_coeff0_2 = coefficients0[dof][2];
 
2113
    
 
2114
      // Loop derivative order
 
2115
      for (unsigned int j = 0; j < n; j++)
 
2116
      {
 
2117
        // Update old coefficients
 
2118
        coeff0_0 = new_coeff0_0;
 
2119
        coeff0_1 = new_coeff0_1;
 
2120
        coeff0_2 = new_coeff0_2;
 
2121
    
 
2122
        if(combinations[deriv_num][j] == 0)
 
2123
        {
 
2124
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
2125
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
2126
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
2127
        }
 
2128
        if(combinations[deriv_num][j] == 1)
 
2129
        {
 
2130
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
2131
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
2132
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
2133
        }
 
2134
    
 
2135
      }
 
2136
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
2137
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
2138
    }
 
2139
    
 
2140
    // Transform derivatives back to physical element
 
2141
    for (unsigned int row = 0; row < num_derivatives; row++)
 
2142
    {
 
2143
      for (unsigned int col = 0; col < num_derivatives; col++)
 
2144
      {
 
2145
        values[row] += transform[row][col]*derivatives[col];
 
2146
      }
 
2147
    }
 
2148
    // Delete pointer to array of derivatives on FIAT element
 
2149
    delete [] derivatives;
 
2150
    
 
2151
    // Delete pointer to array of combinations of derivatives and transform
 
2152
    for (unsigned int row = 0; row < num_derivatives; row++)
 
2153
    {
 
2154
      delete [] combinations[row];
 
2155
      delete [] transform[row];
 
2156
    }
 
2157
    
 
2158
    delete [] combinations;
 
2159
    delete [] transform;
 
2160
}
 
2161
 
 
2162
/// Evaluate order n derivatives of all basis functions at given point in cell
 
2163
void cahnhilliard2d_0_finite_element_1_1::evaluate_basis_derivatives_all(unsigned int n,
 
2164
                                                   double* values,
 
2165
                                                   const double* coordinates,
 
2166
                                                   const ufc::cell& c) const
 
2167
{
 
2168
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
2169
}
 
2170
 
 
2171
/// Evaluate linear functional for dof i on the function f
 
2172
double cahnhilliard2d_0_finite_element_1_1::evaluate_dof(unsigned int i,
 
2173
                                   const ufc::function& f,
 
2174
                                   const ufc::cell& c) const
 
2175
{
 
2176
    // The reference points, direction and weights:
 
2177
    static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
 
2178
    static const double W[3][1] = {{1}, {1}, {1}};
 
2179
    static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
 
2180
    
 
2181
    const double * const * x = c.coordinates;
 
2182
    double result = 0.0;
 
2183
    // Iterate over the points:
 
2184
    // Evaluate basis functions for affine mapping
 
2185
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
2186
    const double w1 = X[i][0][0];
 
2187
    const double w2 = X[i][0][1];
 
2188
    
 
2189
    // Compute affine mapping y = F(X)
 
2190
    double y[2];
 
2191
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
2192
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
2193
    
 
2194
    // Evaluate function at physical points
 
2195
    double values[1];
 
2196
    f.evaluate(values, y, c);
 
2197
    
 
2198
    // Map function values using appropriate mapping
 
2199
    // Affine map: Do nothing
 
2200
    
 
2201
    // Note that we do not map the weights (yet).
 
2202
    
 
2203
    // Take directional components
 
2204
    for(int k = 0; k < 1; k++)
 
2205
      result += values[k]*D[i][0][k];
 
2206
    // Multiply by weights
 
2207
    result *= W[i][0];
 
2208
    
 
2209
    return result;
 
2210
}
 
2211
 
 
2212
/// Evaluate linear functionals for all dofs on the function f
 
2213
void cahnhilliard2d_0_finite_element_1_1::evaluate_dofs(double* values,
 
2214
                                  const ufc::function& f,
 
2215
                                  const ufc::cell& c) const
 
2216
{
 
2217
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
2218
}
 
2219
 
 
2220
/// Interpolate vertex values from dof values
 
2221
void cahnhilliard2d_0_finite_element_1_1::interpolate_vertex_values(double* vertex_values,
 
2222
                                              const double* dof_values,
 
2223
                                              const ufc::cell& c) const
 
2224
{
 
2225
    // Evaluate at vertices and use affine mapping
 
2226
    vertex_values[0] = dof_values[0];
 
2227
    vertex_values[1] = dof_values[1];
 
2228
    vertex_values[2] = dof_values[2];
 
2229
}
 
2230
 
 
2231
/// Return the number of sub elements (for a mixed element)
 
2232
unsigned int cahnhilliard2d_0_finite_element_1_1::num_sub_elements() const
 
2233
{
 
2234
    return 1;
 
2235
}
 
2236
 
 
2237
/// Create a new finite element for sub element i (for a mixed element)
 
2238
ufc::finite_element* cahnhilliard2d_0_finite_element_1_1::create_sub_element(unsigned int i) const
 
2239
{
 
2240
    return new cahnhilliard2d_0_finite_element_1_1();
 
2241
}
 
2242
 
 
2243
 
 
2244
/// Constructor
 
2245
cahnhilliard2d_0_finite_element_1::cahnhilliard2d_0_finite_element_1() : ufc::finite_element()
 
2246
{
 
2247
    // Do nothing
 
2248
}
 
2249
 
 
2250
/// Destructor
 
2251
cahnhilliard2d_0_finite_element_1::~cahnhilliard2d_0_finite_element_1()
 
2252
{
 
2253
    // Do nothing
 
2254
}
 
2255
 
 
2256
/// Return a string identifying the finite element
 
2257
const char* cahnhilliard2d_0_finite_element_1::signature() const
 
2258
{
 
2259
    return "MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
 
2260
}
 
2261
 
 
2262
/// Return the cell shape
 
2263
ufc::shape cahnhilliard2d_0_finite_element_1::cell_shape() const
 
2264
{
 
2265
    return ufc::triangle;
 
2266
}
 
2267
 
 
2268
/// Return the dimension of the finite element function space
 
2269
unsigned int cahnhilliard2d_0_finite_element_1::space_dimension() const
 
2270
{
 
2271
    return 6;
 
2272
}
 
2273
 
 
2274
/// Return the rank of the value space
 
2275
unsigned int cahnhilliard2d_0_finite_element_1::value_rank() const
 
2276
{
 
2277
    return 1;
 
2278
}
 
2279
 
 
2280
/// Return the dimension of the value space for axis i
 
2281
unsigned int cahnhilliard2d_0_finite_element_1::value_dimension(unsigned int i) const
 
2282
{
 
2283
    return 2;
 
2284
}
 
2285
 
 
2286
/// Evaluate basis function i at given point in cell
 
2287
void cahnhilliard2d_0_finite_element_1::evaluate_basis(unsigned int i,
 
2288
                                   double* values,
 
2289
                                   const double* coordinates,
 
2290
                                   const ufc::cell& c) const
 
2291
{
 
2292
    // Extract vertex coordinates
 
2293
    const double * const * element_coordinates = c.coordinates;
 
2294
    
 
2295
    // Compute Jacobian of affine map from reference cell
 
2296
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
2297
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
2298
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
2299
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
2300
    
 
2301
    // Compute determinant of Jacobian
 
2302
    const double detJ = J_00*J_11 - J_01*J_10;
 
2303
    
 
2304
    // Compute inverse of Jacobian
 
2305
    
 
2306
    // Get coordinates and map to the reference (UFC) element
 
2307
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
2308
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
2309
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
2310
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
2311
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
2312
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
2313
    
 
2314
    // Map coordinates to the reference square
 
2315
    if (std::abs(y - 1.0) < 1e-14)
 
2316
      x = -1.0;
 
2317
    else
 
2318
      x = 2.0 *x/(1.0 - y) - 1.0;
 
2319
    y = 2.0*y - 1.0;
 
2320
    
 
2321
    // Reset values
 
2322
    values[0] = 0;
 
2323
    values[1] = 0;
 
2324
    
 
2325
    if (0 <= i && i <= 2)
 
2326
    {
 
2327
      // Map degree of freedom to element degree of freedom
 
2328
      const unsigned int dof = i;
 
2329
    
 
2330
      // Generate scalings
 
2331
      const double scalings_y_0 = 1;
 
2332
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
2333
    
 
2334
      // Compute psitilde_a
 
2335
      const double psitilde_a_0 = 1;
 
2336
      const double psitilde_a_1 = x;
 
2337
    
 
2338
      // Compute psitilde_bs
 
2339
      const double psitilde_bs_0_0 = 1;
 
2340
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
2341
      const double psitilde_bs_1_0 = 1;
 
2342
    
 
2343
      // Compute basisvalues
 
2344
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
2345
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
2346
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
2347
    
 
2348
      // Table(s) of coefficients
 
2349
      static const double coefficients0[3][3] =   \
 
2350
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
2351
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
2352
      {0.471404520791032, 0, 0.333333333333333}};
 
2353
    
 
2354
      // Extract relevant coefficients
 
2355
      const double coeff0_0 =   coefficients0[dof][0];
 
2356
      const double coeff0_1 =   coefficients0[dof][1];
 
2357
      const double coeff0_2 =   coefficients0[dof][2];
 
2358
    
 
2359
      // Compute value(s)
 
2360
      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
2361
    }
 
2362
    
 
2363
    if (3 <= i && i <= 5)
 
2364
    {
 
2365
      // Map degree of freedom to element degree of freedom
 
2366
      const unsigned int dof = i - 3;
 
2367
    
 
2368
      // Generate scalings
 
2369
      const double scalings_y_0 = 1;
 
2370
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
2371
    
 
2372
      // Compute psitilde_a
 
2373
      const double psitilde_a_0 = 1;
 
2374
      const double psitilde_a_1 = x;
 
2375
    
 
2376
      // Compute psitilde_bs
 
2377
      const double psitilde_bs_0_0 = 1;
 
2378
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
2379
      const double psitilde_bs_1_0 = 1;
 
2380
    
 
2381
      // Compute basisvalues
 
2382
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
2383
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
2384
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
2385
    
 
2386
      // Table(s) of coefficients
 
2387
      static const double coefficients0[3][3] =   \
 
2388
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
2389
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
2390
      {0.471404520791032, 0, 0.333333333333333}};
 
2391
    
 
2392
      // Extract relevant coefficients
 
2393
      const double coeff0_0 =   coefficients0[dof][0];
 
2394
      const double coeff0_1 =   coefficients0[dof][1];
 
2395
      const double coeff0_2 =   coefficients0[dof][2];
 
2396
    
 
2397
      // Compute value(s)
 
2398
      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
2399
    }
 
2400
    
 
2401
}
 
2402
 
 
2403
/// Evaluate all basis functions at given point in cell
 
2404
void cahnhilliard2d_0_finite_element_1::evaluate_basis_all(double* values,
 
2405
                                       const double* coordinates,
 
2406
                                       const ufc::cell& c) const
 
2407
{
 
2408
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
2409
}
 
2410
 
 
2411
/// Evaluate order n derivatives of basis function i at given point in cell
 
2412
void cahnhilliard2d_0_finite_element_1::evaluate_basis_derivatives(unsigned int i,
 
2413
                                               unsigned int n,
 
2414
                                               double* values,
 
2415
                                               const double* coordinates,
 
2416
                                               const ufc::cell& c) const
 
2417
{
 
2418
    // Extract vertex coordinates
 
2419
    const double * const * element_coordinates = c.coordinates;
 
2420
    
 
2421
    // Compute Jacobian of affine map from reference cell
 
2422
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
2423
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
2424
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
2425
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
2426
    
 
2427
    // Compute determinant of Jacobian
 
2428
    const double detJ = J_00*J_11 - J_01*J_10;
 
2429
    
 
2430
    // Compute inverse of Jacobian
 
2431
    
 
2432
    // Get coordinates and map to the reference (UFC) element
 
2433
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
2434
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
2435
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
2436
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
2437
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
2438
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
2439
    
 
2440
    // Map coordinates to the reference square
 
2441
    if (std::abs(y - 1.0) < 1e-14)
 
2442
      x = -1.0;
 
2443
    else
 
2444
      x = 2.0 *x/(1.0 - y) - 1.0;
 
2445
    y = 2.0*y - 1.0;
 
2446
    
 
2447
    // Compute number of derivatives
 
2448
    unsigned int num_derivatives = 1;
 
2449
    
 
2450
    for (unsigned int j = 0; j < n; j++)
 
2451
      num_derivatives *= 2;
 
2452
    
 
2453
    
 
2454
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
2455
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
2456
    
 
2457
    for (unsigned int j = 0; j < num_derivatives; j++)
 
2458
    {
 
2459
      combinations[j] = new unsigned int [n];
 
2460
      for (unsigned int k = 0; k < n; k++)
 
2461
        combinations[j][k] = 0;
 
2462
    }
 
2463
    
 
2464
    // Generate combinations of derivatives
 
2465
    for (unsigned int row = 1; row < num_derivatives; row++)
 
2466
    {
 
2467
      for (unsigned int num = 0; num < row; num++)
 
2468
      {
 
2469
        for (unsigned int col = n-1; col+1 > 0; col--)
 
2470
        {
 
2471
          if (combinations[row][col] + 1 > 1)
 
2472
            combinations[row][col] = 0;
 
2473
          else
 
2474
          {
 
2475
            combinations[row][col] += 1;
 
2476
            break;
 
2477
          }
 
2478
        }
 
2479
      }
 
2480
    }
 
2481
    
 
2482
    // Compute inverse of Jacobian
 
2483
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
2484
    
 
2485
    // Declare transformation matrix
 
2486
    // Declare pointer to two dimensional array and initialise
 
2487
    double **transform = new double *[num_derivatives];
 
2488
    
 
2489
    for (unsigned int j = 0; j < num_derivatives; j++)
 
2490
    {
 
2491
      transform[j] = new double [num_derivatives];
 
2492
      for (unsigned int k = 0; k < num_derivatives; k++)
 
2493
        transform[j][k] = 1;
 
2494
    }
 
2495
    
 
2496
    // Construct transformation matrix
 
2497
    for (unsigned int row = 0; row < num_derivatives; row++)
 
2498
    {
 
2499
      for (unsigned int col = 0; col < num_derivatives; col++)
 
2500
      {
 
2501
        for (unsigned int k = 0; k < n; k++)
 
2502
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
2503
      }
 
2504
    }
 
2505
    
 
2506
    // Reset values
 
2507
    for (unsigned int j = 0; j < 2*num_derivatives; j++)
 
2508
      values[j] = 0;
 
2509
    
 
2510
    if (0 <= i && i <= 2)
 
2511
    {
 
2512
      // Map degree of freedom to element degree of freedom
 
2513
      const unsigned int dof = i;
 
2514
    
 
2515
      // Generate scalings
 
2516
      const double scalings_y_0 = 1;
 
2517
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
2518
    
 
2519
      // Compute psitilde_a
 
2520
      const double psitilde_a_0 = 1;
 
2521
      const double psitilde_a_1 = x;
 
2522
    
 
2523
      // Compute psitilde_bs
 
2524
      const double psitilde_bs_0_0 = 1;
 
2525
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
2526
      const double psitilde_bs_1_0 = 1;
 
2527
    
 
2528
      // Compute basisvalues
 
2529
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
2530
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
2531
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
2532
    
 
2533
      // Table(s) of coefficients
 
2534
      static const double coefficients0[3][3] =   \
 
2535
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
2536
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
2537
      {0.471404520791032, 0, 0.333333333333333}};
 
2538
    
 
2539
      // Interesting (new) part
 
2540
      // Tables of derivatives of the polynomial base (transpose)
 
2541
      static const double dmats0[3][3] =   \
 
2542
      {{0, 0, 0},
 
2543
      {4.89897948556636, 0, 0},
 
2544
      {0, 0, 0}};
 
2545
    
 
2546
      static const double dmats1[3][3] =   \
 
2547
      {{0, 0, 0},
 
2548
      {2.44948974278318, 0, 0},
 
2549
      {4.24264068711928, 0, 0}};
 
2550
    
 
2551
      // Compute reference derivatives
 
2552
      // Declare pointer to array of derivatives on FIAT element
 
2553
      double *derivatives = new double [num_derivatives];
 
2554
    
 
2555
      // Declare coefficients
 
2556
      double coeff0_0 = 0;
 
2557
      double coeff0_1 = 0;
 
2558
      double coeff0_2 = 0;
 
2559
    
 
2560
      // Declare new coefficients
 
2561
      double new_coeff0_0 = 0;
 
2562
      double new_coeff0_1 = 0;
 
2563
      double new_coeff0_2 = 0;
 
2564
    
 
2565
      // Loop possible derivatives
 
2566
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
2567
      {
 
2568
        // Get values from coefficients array
 
2569
        new_coeff0_0 = coefficients0[dof][0];
 
2570
        new_coeff0_1 = coefficients0[dof][1];
 
2571
        new_coeff0_2 = coefficients0[dof][2];
 
2572
    
 
2573
        // Loop derivative order
 
2574
        for (unsigned int j = 0; j < n; j++)
 
2575
        {
 
2576
          // Update old coefficients
 
2577
          coeff0_0 = new_coeff0_0;
 
2578
          coeff0_1 = new_coeff0_1;
 
2579
          coeff0_2 = new_coeff0_2;
 
2580
    
 
2581
          if(combinations[deriv_num][j] == 0)
 
2582
          {
 
2583
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
2584
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
2585
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
2586
          }
 
2587
          if(combinations[deriv_num][j] == 1)
 
2588
          {
 
2589
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
2590
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
2591
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
2592
          }
 
2593
    
 
2594
        }
 
2595
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
2596
        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
2597
      }
 
2598
    
 
2599
      // Transform derivatives back to physical element
 
2600
      for (unsigned int row = 0; row < num_derivatives; row++)
 
2601
      {
 
2602
        for (unsigned int col = 0; col < num_derivatives; col++)
 
2603
        {
 
2604
          values[row] += transform[row][col]*derivatives[col];
 
2605
        }
 
2606
      }
 
2607
      // Delete pointer to array of derivatives on FIAT element
 
2608
      delete [] derivatives;
 
2609
    
 
2610
      // Delete pointer to array of combinations of derivatives and transform
 
2611
      for (unsigned int row = 0; row < num_derivatives; row++)
 
2612
      {
 
2613
        delete [] combinations[row];
 
2614
        delete [] transform[row];
 
2615
      }
 
2616
    
 
2617
      delete [] combinations;
 
2618
      delete [] transform;
 
2619
    }
 
2620
    
 
2621
    if (3 <= i && i <= 5)
 
2622
    {
 
2623
      // Map degree of freedom to element degree of freedom
 
2624
      const unsigned int dof = i - 3;
 
2625
    
 
2626
      // Generate scalings
 
2627
      const double scalings_y_0 = 1;
 
2628
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
2629
    
 
2630
      // Compute psitilde_a
 
2631
      const double psitilde_a_0 = 1;
 
2632
      const double psitilde_a_1 = x;
 
2633
    
 
2634
      // Compute psitilde_bs
 
2635
      const double psitilde_bs_0_0 = 1;
 
2636
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
2637
      const double psitilde_bs_1_0 = 1;
 
2638
    
 
2639
      // Compute basisvalues
 
2640
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
2641
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
2642
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
2643
    
 
2644
      // Table(s) of coefficients
 
2645
      static const double coefficients0[3][3] =   \
 
2646
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
2647
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
2648
      {0.471404520791032, 0, 0.333333333333333}};
 
2649
    
 
2650
      // Interesting (new) part
 
2651
      // Tables of derivatives of the polynomial base (transpose)
 
2652
      static const double dmats0[3][3] =   \
 
2653
      {{0, 0, 0},
 
2654
      {4.89897948556636, 0, 0},
 
2655
      {0, 0, 0}};
 
2656
    
 
2657
      static const double dmats1[3][3] =   \
 
2658
      {{0, 0, 0},
 
2659
      {2.44948974278318, 0, 0},
 
2660
      {4.24264068711928, 0, 0}};
 
2661
    
 
2662
      // Compute reference derivatives
 
2663
      // Declare pointer to array of derivatives on FIAT element
 
2664
      double *derivatives = new double [num_derivatives];
 
2665
    
 
2666
      // Declare coefficients
 
2667
      double coeff0_0 = 0;
 
2668
      double coeff0_1 = 0;
 
2669
      double coeff0_2 = 0;
 
2670
    
 
2671
      // Declare new coefficients
 
2672
      double new_coeff0_0 = 0;
 
2673
      double new_coeff0_1 = 0;
 
2674
      double new_coeff0_2 = 0;
 
2675
    
 
2676
      // Loop possible derivatives
 
2677
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
2678
      {
 
2679
        // Get values from coefficients array
 
2680
        new_coeff0_0 = coefficients0[dof][0];
 
2681
        new_coeff0_1 = coefficients0[dof][1];
 
2682
        new_coeff0_2 = coefficients0[dof][2];
 
2683
    
 
2684
        // Loop derivative order
 
2685
        for (unsigned int j = 0; j < n; j++)
 
2686
        {
 
2687
          // Update old coefficients
 
2688
          coeff0_0 = new_coeff0_0;
 
2689
          coeff0_1 = new_coeff0_1;
 
2690
          coeff0_2 = new_coeff0_2;
 
2691
    
 
2692
          if(combinations[deriv_num][j] == 0)
 
2693
          {
 
2694
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
2695
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
2696
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
2697
          }
 
2698
          if(combinations[deriv_num][j] == 1)
 
2699
          {
 
2700
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
2701
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
2702
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
2703
          }
 
2704
    
 
2705
        }
 
2706
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
2707
        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
2708
      }
 
2709
    
 
2710
      // Transform derivatives back to physical element
 
2711
      for (unsigned int row = 0; row < num_derivatives; row++)
 
2712
      {
 
2713
        for (unsigned int col = 0; col < num_derivatives; col++)
 
2714
        {
 
2715
          values[num_derivatives + row] += transform[row][col]*derivatives[col];
 
2716
        }
 
2717
      }
 
2718
      // Delete pointer to array of derivatives on FIAT element
 
2719
      delete [] derivatives;
 
2720
    
 
2721
      // Delete pointer to array of combinations of derivatives and transform
 
2722
      for (unsigned int row = 0; row < num_derivatives; row++)
 
2723
      {
 
2724
        delete [] combinations[row];
 
2725
        delete [] transform[row];
 
2726
      }
 
2727
    
 
2728
      delete [] combinations;
 
2729
      delete [] transform;
 
2730
    }
 
2731
    
 
2732
}
 
2733
 
 
2734
/// Evaluate order n derivatives of all basis functions at given point in cell
 
2735
void cahnhilliard2d_0_finite_element_1::evaluate_basis_derivatives_all(unsigned int n,
 
2736
                                                   double* values,
 
2737
                                                   const double* coordinates,
 
2738
                                                   const ufc::cell& c) const
 
2739
{
 
2740
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
2741
}
 
2742
 
 
2743
/// Evaluate linear functional for dof i on the function f
 
2744
double cahnhilliard2d_0_finite_element_1::evaluate_dof(unsigned int i,
 
2745
                                   const ufc::function& f,
 
2746
                                   const ufc::cell& c) const
 
2747
{
 
2748
    // The reference points, direction and weights:
 
2749
    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
 
2750
    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
 
2751
    static const double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
 
2752
    
 
2753
    const double * const * x = c.coordinates;
 
2754
    double result = 0.0;
 
2755
    // Iterate over the points:
 
2756
    // Evaluate basis functions for affine mapping
 
2757
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
2758
    const double w1 = X[i][0][0];
 
2759
    const double w2 = X[i][0][1];
 
2760
    
 
2761
    // Compute affine mapping y = F(X)
 
2762
    double y[2];
 
2763
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
2764
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
2765
    
 
2766
    // Evaluate function at physical points
 
2767
    double values[2];
 
2768
    f.evaluate(values, y, c);
 
2769
    
 
2770
    // Map function values using appropriate mapping
 
2771
    // Affine map: Do nothing
 
2772
    
 
2773
    // Note that we do not map the weights (yet).
 
2774
    
 
2775
    // Take directional components
 
2776
    for(int k = 0; k < 2; k++)
 
2777
      result += values[k]*D[i][0][k];
 
2778
    // Multiply by weights
 
2779
    result *= W[i][0];
 
2780
    
 
2781
    return result;
 
2782
}
 
2783
 
 
2784
/// Evaluate linear functionals for all dofs on the function f
 
2785
void cahnhilliard2d_0_finite_element_1::evaluate_dofs(double* values,
 
2786
                                  const ufc::function& f,
 
2787
                                  const ufc::cell& c) const
 
2788
{
 
2789
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
2790
}
 
2791
 
 
2792
/// Interpolate vertex values from dof values
 
2793
void cahnhilliard2d_0_finite_element_1::interpolate_vertex_values(double* vertex_values,
 
2794
                                              const double* dof_values,
 
2795
                                              const ufc::cell& c) const
 
2796
{
 
2797
    // Evaluate at vertices and use affine mapping
 
2798
    vertex_values[0] = dof_values[0];
 
2799
    vertex_values[2] = dof_values[1];
 
2800
    vertex_values[4] = dof_values[2];
 
2801
    // Evaluate at vertices and use affine mapping
 
2802
    vertex_values[1] = dof_values[3];
 
2803
    vertex_values[3] = dof_values[4];
 
2804
    vertex_values[5] = dof_values[5];
 
2805
}
 
2806
 
 
2807
/// Return the number of sub elements (for a mixed element)
 
2808
unsigned int cahnhilliard2d_0_finite_element_1::num_sub_elements() const
 
2809
{
 
2810
    return 2;
 
2811
}
 
2812
 
 
2813
/// Create a new finite element for sub element i (for a mixed element)
 
2814
ufc::finite_element* cahnhilliard2d_0_finite_element_1::create_sub_element(unsigned int i) const
 
2815
{
 
2816
    switch ( i )
 
2817
    {
 
2818
    case 0:
 
2819
      return new cahnhilliard2d_0_finite_element_1_0();
 
2820
      break;
 
2821
    case 1:
 
2822
      return new cahnhilliard2d_0_finite_element_1_1();
 
2823
      break;
 
2824
    }
 
2825
    return 0;
 
2826
}
 
2827
 
 
2828
 
 
2829
/// Constructor
 
2830
cahnhilliard2d_0_finite_element_2_0::cahnhilliard2d_0_finite_element_2_0() : ufc::finite_element()
 
2831
{
 
2832
    // Do nothing
 
2833
}
 
2834
 
 
2835
/// Destructor
 
2836
cahnhilliard2d_0_finite_element_2_0::~cahnhilliard2d_0_finite_element_2_0()
 
2837
{
 
2838
    // Do nothing
 
2839
}
 
2840
 
 
2841
/// Return a string identifying the finite element
 
2842
const char* cahnhilliard2d_0_finite_element_2_0::signature() const
 
2843
{
 
2844
    return "FiniteElement('Lagrange', 'triangle', 1)";
 
2845
}
 
2846
 
 
2847
/// Return the cell shape
 
2848
ufc::shape cahnhilliard2d_0_finite_element_2_0::cell_shape() const
 
2849
{
 
2850
    return ufc::triangle;
 
2851
}
 
2852
 
 
2853
/// Return the dimension of the finite element function space
 
2854
unsigned int cahnhilliard2d_0_finite_element_2_0::space_dimension() const
 
2855
{
 
2856
    return 3;
 
2857
}
 
2858
 
 
2859
/// Return the rank of the value space
 
2860
unsigned int cahnhilliard2d_0_finite_element_2_0::value_rank() const
 
2861
{
 
2862
    return 0;
 
2863
}
 
2864
 
 
2865
/// Return the dimension of the value space for axis i
 
2866
unsigned int cahnhilliard2d_0_finite_element_2_0::value_dimension(unsigned int i) const
 
2867
{
 
2868
    return 1;
 
2869
}
 
2870
 
 
2871
/// Evaluate basis function i at given point in cell
 
2872
void cahnhilliard2d_0_finite_element_2_0::evaluate_basis(unsigned int i,
 
2873
                                   double* values,
 
2874
                                   const double* coordinates,
 
2875
                                   const ufc::cell& c) const
 
2876
{
 
2877
    // Extract vertex coordinates
 
2878
    const double * const * element_coordinates = c.coordinates;
 
2879
    
 
2880
    // Compute Jacobian of affine map from reference cell
 
2881
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
2882
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
2883
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
2884
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
2885
    
 
2886
    // Compute determinant of Jacobian
 
2887
    const double detJ = J_00*J_11 - J_01*J_10;
 
2888
    
 
2889
    // Compute inverse of Jacobian
 
2890
    
 
2891
    // Get coordinates and map to the reference (UFC) element
 
2892
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
2893
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
2894
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
2895
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
2896
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
2897
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
2898
    
 
2899
    // Map coordinates to the reference square
 
2900
    if (std::abs(y - 1.0) < 1e-14)
 
2901
      x = -1.0;
 
2902
    else
 
2903
      x = 2.0 *x/(1.0 - y) - 1.0;
 
2904
    y = 2.0*y - 1.0;
 
2905
    
 
2906
    // Reset values
 
2907
    *values = 0;
 
2908
    
 
2909
    // Map degree of freedom to element degree of freedom
 
2910
    const unsigned int dof = i;
 
2911
    
 
2912
    // Generate scalings
 
2913
    const double scalings_y_0 = 1;
 
2914
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
2915
    
 
2916
    // Compute psitilde_a
 
2917
    const double psitilde_a_0 = 1;
 
2918
    const double psitilde_a_1 = x;
 
2919
    
 
2920
    // Compute psitilde_bs
 
2921
    const double psitilde_bs_0_0 = 1;
 
2922
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
2923
    const double psitilde_bs_1_0 = 1;
 
2924
    
 
2925
    // Compute basisvalues
 
2926
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
2927
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
2928
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
2929
    
 
2930
    // Table(s) of coefficients
 
2931
    static const double coefficients0[3][3] = \
 
2932
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
2933
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
2934
    {0.471404520791032, 0, 0.333333333333333}};
 
2935
    
 
2936
    // Extract relevant coefficients
 
2937
    const double coeff0_0 = coefficients0[dof][0];
 
2938
    const double coeff0_1 = coefficients0[dof][1];
 
2939
    const double coeff0_2 = coefficients0[dof][2];
 
2940
    
 
2941
    // Compute value(s)
 
2942
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
2943
}
 
2944
 
 
2945
/// Evaluate all basis functions at given point in cell
 
2946
void cahnhilliard2d_0_finite_element_2_0::evaluate_basis_all(double* values,
 
2947
                                       const double* coordinates,
 
2948
                                       const ufc::cell& c) const
 
2949
{
 
2950
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
2951
}
 
2952
 
 
2953
/// Evaluate order n derivatives of basis function i at given point in cell
 
2954
void cahnhilliard2d_0_finite_element_2_0::evaluate_basis_derivatives(unsigned int i,
 
2955
                                               unsigned int n,
 
2956
                                               double* values,
 
2957
                                               const double* coordinates,
 
2958
                                               const ufc::cell& c) const
 
2959
{
 
2960
    // Extract vertex coordinates
 
2961
    const double * const * element_coordinates = c.coordinates;
 
2962
    
 
2963
    // Compute Jacobian of affine map from reference cell
 
2964
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
2965
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
2966
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
2967
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
2968
    
 
2969
    // Compute determinant of Jacobian
 
2970
    const double detJ = J_00*J_11 - J_01*J_10;
 
2971
    
 
2972
    // Compute inverse of Jacobian
 
2973
    
 
2974
    // Get coordinates and map to the reference (UFC) element
 
2975
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
2976
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
2977
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
2978
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
2979
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
2980
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
2981
    
 
2982
    // Map coordinates to the reference square
 
2983
    if (std::abs(y - 1.0) < 1e-14)
 
2984
      x = -1.0;
 
2985
    else
 
2986
      x = 2.0 *x/(1.0 - y) - 1.0;
 
2987
    y = 2.0*y - 1.0;
 
2988
    
 
2989
    // Compute number of derivatives
 
2990
    unsigned int num_derivatives = 1;
 
2991
    
 
2992
    for (unsigned int j = 0; j < n; j++)
 
2993
      num_derivatives *= 2;
 
2994
    
 
2995
    
 
2996
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
2997
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
2998
    
 
2999
    for (unsigned int j = 0; j < num_derivatives; j++)
 
3000
    {
 
3001
      combinations[j] = new unsigned int [n];
 
3002
      for (unsigned int k = 0; k < n; k++)
 
3003
        combinations[j][k] = 0;
 
3004
    }
 
3005
    
 
3006
    // Generate combinations of derivatives
 
3007
    for (unsigned int row = 1; row < num_derivatives; row++)
 
3008
    {
 
3009
      for (unsigned int num = 0; num < row; num++)
 
3010
      {
 
3011
        for (unsigned int col = n-1; col+1 > 0; col--)
 
3012
        {
 
3013
          if (combinations[row][col] + 1 > 1)
 
3014
            combinations[row][col] = 0;
 
3015
          else
 
3016
          {
 
3017
            combinations[row][col] += 1;
 
3018
            break;
 
3019
          }
 
3020
        }
 
3021
      }
 
3022
    }
 
3023
    
 
3024
    // Compute inverse of Jacobian
 
3025
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
3026
    
 
3027
    // Declare transformation matrix
 
3028
    // Declare pointer to two dimensional array and initialise
 
3029
    double **transform = new double *[num_derivatives];
 
3030
    
 
3031
    for (unsigned int j = 0; j < num_derivatives; j++)
 
3032
    {
 
3033
      transform[j] = new double [num_derivatives];
 
3034
      for (unsigned int k = 0; k < num_derivatives; k++)
 
3035
        transform[j][k] = 1;
 
3036
    }
 
3037
    
 
3038
    // Construct transformation matrix
 
3039
    for (unsigned int row = 0; row < num_derivatives; row++)
 
3040
    {
 
3041
      for (unsigned int col = 0; col < num_derivatives; col++)
 
3042
      {
 
3043
        for (unsigned int k = 0; k < n; k++)
 
3044
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
3045
      }
 
3046
    }
 
3047
    
 
3048
    // Reset values
 
3049
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
 
3050
      values[j] = 0;
 
3051
    
 
3052
    // Map degree of freedom to element degree of freedom
 
3053
    const unsigned int dof = i;
 
3054
    
 
3055
    // Generate scalings
 
3056
    const double scalings_y_0 = 1;
 
3057
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
3058
    
 
3059
    // Compute psitilde_a
 
3060
    const double psitilde_a_0 = 1;
 
3061
    const double psitilde_a_1 = x;
 
3062
    
 
3063
    // Compute psitilde_bs
 
3064
    const double psitilde_bs_0_0 = 1;
 
3065
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
3066
    const double psitilde_bs_1_0 = 1;
 
3067
    
 
3068
    // Compute basisvalues
 
3069
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
3070
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
3071
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
3072
    
 
3073
    // Table(s) of coefficients
 
3074
    static const double coefficients0[3][3] = \
 
3075
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
3076
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
3077
    {0.471404520791032, 0, 0.333333333333333}};
 
3078
    
 
3079
    // Interesting (new) part
 
3080
    // Tables of derivatives of the polynomial base (transpose)
 
3081
    static const double dmats0[3][3] = \
 
3082
    {{0, 0, 0},
 
3083
    {4.89897948556636, 0, 0},
 
3084
    {0, 0, 0}};
 
3085
    
 
3086
    static const double dmats1[3][3] = \
 
3087
    {{0, 0, 0},
 
3088
    {2.44948974278318, 0, 0},
 
3089
    {4.24264068711928, 0, 0}};
 
3090
    
 
3091
    // Compute reference derivatives
 
3092
    // Declare pointer to array of derivatives on FIAT element
 
3093
    double *derivatives = new double [num_derivatives];
 
3094
    
 
3095
    // Declare coefficients
 
3096
    double coeff0_0 = 0;
 
3097
    double coeff0_1 = 0;
 
3098
    double coeff0_2 = 0;
 
3099
    
 
3100
    // Declare new coefficients
 
3101
    double new_coeff0_0 = 0;
 
3102
    double new_coeff0_1 = 0;
 
3103
    double new_coeff0_2 = 0;
 
3104
    
 
3105
    // Loop possible derivatives
 
3106
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
3107
    {
 
3108
      // Get values from coefficients array
 
3109
      new_coeff0_0 = coefficients0[dof][0];
 
3110
      new_coeff0_1 = coefficients0[dof][1];
 
3111
      new_coeff0_2 = coefficients0[dof][2];
 
3112
    
 
3113
      // Loop derivative order
 
3114
      for (unsigned int j = 0; j < n; j++)
 
3115
      {
 
3116
        // Update old coefficients
 
3117
        coeff0_0 = new_coeff0_0;
 
3118
        coeff0_1 = new_coeff0_1;
 
3119
        coeff0_2 = new_coeff0_2;
 
3120
    
 
3121
        if(combinations[deriv_num][j] == 0)
 
3122
        {
 
3123
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
3124
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
3125
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
3126
        }
 
3127
        if(combinations[deriv_num][j] == 1)
 
3128
        {
 
3129
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
3130
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
3131
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
3132
        }
 
3133
    
 
3134
      }
 
3135
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
3136
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
3137
    }
 
3138
    
 
3139
    // Transform derivatives back to physical element
 
3140
    for (unsigned int row = 0; row < num_derivatives; row++)
 
3141
    {
 
3142
      for (unsigned int col = 0; col < num_derivatives; col++)
 
3143
      {
 
3144
        values[row] += transform[row][col]*derivatives[col];
 
3145
      }
 
3146
    }
 
3147
    // Delete pointer to array of derivatives on FIAT element
 
3148
    delete [] derivatives;
 
3149
    
 
3150
    // Delete pointer to array of combinations of derivatives and transform
 
3151
    for (unsigned int row = 0; row < num_derivatives; row++)
 
3152
    {
 
3153
      delete [] combinations[row];
 
3154
      delete [] transform[row];
 
3155
    }
 
3156
    
 
3157
    delete [] combinations;
 
3158
    delete [] transform;
 
3159
}
 
3160
 
 
3161
/// Evaluate order n derivatives of all basis functions at given point in cell
 
3162
void cahnhilliard2d_0_finite_element_2_0::evaluate_basis_derivatives_all(unsigned int n,
 
3163
                                                   double* values,
 
3164
                                                   const double* coordinates,
 
3165
                                                   const ufc::cell& c) const
 
3166
{
 
3167
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
3168
}
 
3169
 
 
3170
/// Evaluate linear functional for dof i on the function f
 
3171
double cahnhilliard2d_0_finite_element_2_0::evaluate_dof(unsigned int i,
 
3172
                                   const ufc::function& f,
 
3173
                                   const ufc::cell& c) const
 
3174
{
 
3175
    // The reference points, direction and weights:
 
3176
    static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
 
3177
    static const double W[3][1] = {{1}, {1}, {1}};
 
3178
    static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
 
3179
    
 
3180
    const double * const * x = c.coordinates;
 
3181
    double result = 0.0;
 
3182
    // Iterate over the points:
 
3183
    // Evaluate basis functions for affine mapping
 
3184
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
3185
    const double w1 = X[i][0][0];
 
3186
    const double w2 = X[i][0][1];
 
3187
    
 
3188
    // Compute affine mapping y = F(X)
 
3189
    double y[2];
 
3190
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
3191
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
3192
    
 
3193
    // Evaluate function at physical points
 
3194
    double values[1];
 
3195
    f.evaluate(values, y, c);
 
3196
    
 
3197
    // Map function values using appropriate mapping
 
3198
    // Affine map: Do nothing
 
3199
    
 
3200
    // Note that we do not map the weights (yet).
 
3201
    
 
3202
    // Take directional components
 
3203
    for(int k = 0; k < 1; k++)
 
3204
      result += values[k]*D[i][0][k];
 
3205
    // Multiply by weights
 
3206
    result *= W[i][0];
 
3207
    
 
3208
    return result;
 
3209
}
 
3210
 
 
3211
/// Evaluate linear functionals for all dofs on the function f
 
3212
void cahnhilliard2d_0_finite_element_2_0::evaluate_dofs(double* values,
 
3213
                                  const ufc::function& f,
 
3214
                                  const ufc::cell& c) const
 
3215
{
 
3216
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
3217
}
 
3218
 
 
3219
/// Interpolate vertex values from dof values
 
3220
void cahnhilliard2d_0_finite_element_2_0::interpolate_vertex_values(double* vertex_values,
 
3221
                                              const double* dof_values,
 
3222
                                              const ufc::cell& c) const
 
3223
{
 
3224
    // Evaluate at vertices and use affine mapping
 
3225
    vertex_values[0] = dof_values[0];
 
3226
    vertex_values[1] = dof_values[1];
 
3227
    vertex_values[2] = dof_values[2];
 
3228
}
 
3229
 
 
3230
/// Return the number of sub elements (for a mixed element)
 
3231
unsigned int cahnhilliard2d_0_finite_element_2_0::num_sub_elements() const
 
3232
{
 
3233
    return 1;
 
3234
}
 
3235
 
 
3236
/// Create a new finite element for sub element i (for a mixed element)
 
3237
ufc::finite_element* cahnhilliard2d_0_finite_element_2_0::create_sub_element(unsigned int i) const
 
3238
{
 
3239
    return new cahnhilliard2d_0_finite_element_2_0();
 
3240
}
 
3241
 
 
3242
 
 
3243
/// Constructor
 
3244
cahnhilliard2d_0_finite_element_2_1::cahnhilliard2d_0_finite_element_2_1() : ufc::finite_element()
 
3245
{
 
3246
    // Do nothing
 
3247
}
 
3248
 
 
3249
/// Destructor
 
3250
cahnhilliard2d_0_finite_element_2_1::~cahnhilliard2d_0_finite_element_2_1()
 
3251
{
 
3252
    // Do nothing
 
3253
}
 
3254
 
 
3255
/// Return a string identifying the finite element
 
3256
const char* cahnhilliard2d_0_finite_element_2_1::signature() const
 
3257
{
 
3258
    return "FiniteElement('Lagrange', 'triangle', 1)";
 
3259
}
 
3260
 
 
3261
/// Return the cell shape
 
3262
ufc::shape cahnhilliard2d_0_finite_element_2_1::cell_shape() const
 
3263
{
 
3264
    return ufc::triangle;
 
3265
}
 
3266
 
 
3267
/// Return the dimension of the finite element function space
 
3268
unsigned int cahnhilliard2d_0_finite_element_2_1::space_dimension() const
 
3269
{
 
3270
    return 3;
 
3271
}
 
3272
 
 
3273
/// Return the rank of the value space
 
3274
unsigned int cahnhilliard2d_0_finite_element_2_1::value_rank() const
 
3275
{
 
3276
    return 0;
 
3277
}
 
3278
 
 
3279
/// Return the dimension of the value space for axis i
 
3280
unsigned int cahnhilliard2d_0_finite_element_2_1::value_dimension(unsigned int i) const
 
3281
{
 
3282
    return 1;
 
3283
}
 
3284
 
 
3285
/// Evaluate basis function i at given point in cell
 
3286
void cahnhilliard2d_0_finite_element_2_1::evaluate_basis(unsigned int i,
 
3287
                                   double* values,
 
3288
                                   const double* coordinates,
 
3289
                                   const ufc::cell& c) const
 
3290
{
 
3291
    // Extract vertex coordinates
 
3292
    const double * const * element_coordinates = c.coordinates;
 
3293
    
 
3294
    // Compute Jacobian of affine map from reference cell
 
3295
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
3296
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
3297
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
3298
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
3299
    
 
3300
    // Compute determinant of Jacobian
 
3301
    const double detJ = J_00*J_11 - J_01*J_10;
 
3302
    
 
3303
    // Compute inverse of Jacobian
 
3304
    
 
3305
    // Get coordinates and map to the reference (UFC) element
 
3306
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
3307
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
3308
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
3309
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
3310
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
3311
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
3312
    
 
3313
    // Map coordinates to the reference square
 
3314
    if (std::abs(y - 1.0) < 1e-14)
 
3315
      x = -1.0;
 
3316
    else
 
3317
      x = 2.0 *x/(1.0 - y) - 1.0;
 
3318
    y = 2.0*y - 1.0;
 
3319
    
 
3320
    // Reset values
 
3321
    *values = 0;
 
3322
    
 
3323
    // Map degree of freedom to element degree of freedom
 
3324
    const unsigned int dof = i;
 
3325
    
 
3326
    // Generate scalings
 
3327
    const double scalings_y_0 = 1;
 
3328
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
3329
    
 
3330
    // Compute psitilde_a
 
3331
    const double psitilde_a_0 = 1;
 
3332
    const double psitilde_a_1 = x;
 
3333
    
 
3334
    // Compute psitilde_bs
 
3335
    const double psitilde_bs_0_0 = 1;
 
3336
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
3337
    const double psitilde_bs_1_0 = 1;
 
3338
    
 
3339
    // Compute basisvalues
 
3340
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
3341
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
3342
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
3343
    
 
3344
    // Table(s) of coefficients
 
3345
    static const double coefficients0[3][3] = \
 
3346
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
3347
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
3348
    {0.471404520791032, 0, 0.333333333333333}};
 
3349
    
 
3350
    // Extract relevant coefficients
 
3351
    const double coeff0_0 = coefficients0[dof][0];
 
3352
    const double coeff0_1 = coefficients0[dof][1];
 
3353
    const double coeff0_2 = coefficients0[dof][2];
 
3354
    
 
3355
    // Compute value(s)
 
3356
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
3357
}
 
3358
 
 
3359
/// Evaluate all basis functions at given point in cell
 
3360
void cahnhilliard2d_0_finite_element_2_1::evaluate_basis_all(double* values,
 
3361
                                       const double* coordinates,
 
3362
                                       const ufc::cell& c) const
 
3363
{
 
3364
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
3365
}
 
3366
 
 
3367
/// Evaluate order n derivatives of basis function i at given point in cell
 
3368
void cahnhilliard2d_0_finite_element_2_1::evaluate_basis_derivatives(unsigned int i,
 
3369
                                               unsigned int n,
 
3370
                                               double* values,
 
3371
                                               const double* coordinates,
 
3372
                                               const ufc::cell& c) const
 
3373
{
 
3374
    // Extract vertex coordinates
 
3375
    const double * const * element_coordinates = c.coordinates;
 
3376
    
 
3377
    // Compute Jacobian of affine map from reference cell
 
3378
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
3379
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
3380
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
3381
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
3382
    
 
3383
    // Compute determinant of Jacobian
 
3384
    const double detJ = J_00*J_11 - J_01*J_10;
 
3385
    
 
3386
    // Compute inverse of Jacobian
 
3387
    
 
3388
    // Get coordinates and map to the reference (UFC) element
 
3389
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
3390
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
3391
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
3392
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
3393
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
3394
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
3395
    
 
3396
    // Map coordinates to the reference square
 
3397
    if (std::abs(y - 1.0) < 1e-14)
 
3398
      x = -1.0;
 
3399
    else
 
3400
      x = 2.0 *x/(1.0 - y) - 1.0;
 
3401
    y = 2.0*y - 1.0;
 
3402
    
 
3403
    // Compute number of derivatives
 
3404
    unsigned int num_derivatives = 1;
 
3405
    
 
3406
    for (unsigned int j = 0; j < n; j++)
 
3407
      num_derivatives *= 2;
 
3408
    
 
3409
    
 
3410
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
3411
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
3412
    
 
3413
    for (unsigned int j = 0; j < num_derivatives; j++)
 
3414
    {
 
3415
      combinations[j] = new unsigned int [n];
 
3416
      for (unsigned int k = 0; k < n; k++)
 
3417
        combinations[j][k] = 0;
 
3418
    }
 
3419
    
 
3420
    // Generate combinations of derivatives
 
3421
    for (unsigned int row = 1; row < num_derivatives; row++)
 
3422
    {
 
3423
      for (unsigned int num = 0; num < row; num++)
 
3424
      {
 
3425
        for (unsigned int col = n-1; col+1 > 0; col--)
 
3426
        {
 
3427
          if (combinations[row][col] + 1 > 1)
 
3428
            combinations[row][col] = 0;
 
3429
          else
 
3430
          {
 
3431
            combinations[row][col] += 1;
 
3432
            break;
 
3433
          }
 
3434
        }
 
3435
      }
 
3436
    }
 
3437
    
 
3438
    // Compute inverse of Jacobian
 
3439
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
3440
    
 
3441
    // Declare transformation matrix
 
3442
    // Declare pointer to two dimensional array and initialise
 
3443
    double **transform = new double *[num_derivatives];
 
3444
    
 
3445
    for (unsigned int j = 0; j < num_derivatives; j++)
 
3446
    {
 
3447
      transform[j] = new double [num_derivatives];
 
3448
      for (unsigned int k = 0; k < num_derivatives; k++)
 
3449
        transform[j][k] = 1;
 
3450
    }
 
3451
    
 
3452
    // Construct transformation matrix
 
3453
    for (unsigned int row = 0; row < num_derivatives; row++)
 
3454
    {
 
3455
      for (unsigned int col = 0; col < num_derivatives; col++)
 
3456
      {
 
3457
        for (unsigned int k = 0; k < n; k++)
 
3458
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
3459
      }
 
3460
    }
 
3461
    
 
3462
    // Reset values
 
3463
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
 
3464
      values[j] = 0;
 
3465
    
 
3466
    // Map degree of freedom to element degree of freedom
 
3467
    const unsigned int dof = i;
 
3468
    
 
3469
    // Generate scalings
 
3470
    const double scalings_y_0 = 1;
 
3471
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
3472
    
 
3473
    // Compute psitilde_a
 
3474
    const double psitilde_a_0 = 1;
 
3475
    const double psitilde_a_1 = x;
 
3476
    
 
3477
    // Compute psitilde_bs
 
3478
    const double psitilde_bs_0_0 = 1;
 
3479
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
3480
    const double psitilde_bs_1_0 = 1;
 
3481
    
 
3482
    // Compute basisvalues
 
3483
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
3484
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
3485
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
3486
    
 
3487
    // Table(s) of coefficients
 
3488
    static const double coefficients0[3][3] = \
 
3489
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
3490
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
3491
    {0.471404520791032, 0, 0.333333333333333}};
 
3492
    
 
3493
    // Interesting (new) part
 
3494
    // Tables of derivatives of the polynomial base (transpose)
 
3495
    static const double dmats0[3][3] = \
 
3496
    {{0, 0, 0},
 
3497
    {4.89897948556636, 0, 0},
 
3498
    {0, 0, 0}};
 
3499
    
 
3500
    static const double dmats1[3][3] = \
 
3501
    {{0, 0, 0},
 
3502
    {2.44948974278318, 0, 0},
 
3503
    {4.24264068711928, 0, 0}};
 
3504
    
 
3505
    // Compute reference derivatives
 
3506
    // Declare pointer to array of derivatives on FIAT element
 
3507
    double *derivatives = new double [num_derivatives];
 
3508
    
 
3509
    // Declare coefficients
 
3510
    double coeff0_0 = 0;
 
3511
    double coeff0_1 = 0;
 
3512
    double coeff0_2 = 0;
 
3513
    
 
3514
    // Declare new coefficients
 
3515
    double new_coeff0_0 = 0;
 
3516
    double new_coeff0_1 = 0;
 
3517
    double new_coeff0_2 = 0;
 
3518
    
 
3519
    // Loop possible derivatives
 
3520
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
3521
    {
 
3522
      // Get values from coefficients array
 
3523
      new_coeff0_0 = coefficients0[dof][0];
 
3524
      new_coeff0_1 = coefficients0[dof][1];
 
3525
      new_coeff0_2 = coefficients0[dof][2];
 
3526
    
 
3527
      // Loop derivative order
 
3528
      for (unsigned int j = 0; j < n; j++)
 
3529
      {
 
3530
        // Update old coefficients
 
3531
        coeff0_0 = new_coeff0_0;
 
3532
        coeff0_1 = new_coeff0_1;
 
3533
        coeff0_2 = new_coeff0_2;
 
3534
    
 
3535
        if(combinations[deriv_num][j] == 0)
 
3536
        {
 
3537
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
3538
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
3539
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
3540
        }
 
3541
        if(combinations[deriv_num][j] == 1)
 
3542
        {
 
3543
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
3544
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
3545
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
3546
        }
 
3547
    
 
3548
      }
 
3549
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
3550
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
3551
    }
 
3552
    
 
3553
    // Transform derivatives back to physical element
 
3554
    for (unsigned int row = 0; row < num_derivatives; row++)
 
3555
    {
 
3556
      for (unsigned int col = 0; col < num_derivatives; col++)
 
3557
      {
 
3558
        values[row] += transform[row][col]*derivatives[col];
 
3559
      }
 
3560
    }
 
3561
    // Delete pointer to array of derivatives on FIAT element
 
3562
    delete [] derivatives;
 
3563
    
 
3564
    // Delete pointer to array of combinations of derivatives and transform
 
3565
    for (unsigned int row = 0; row < num_derivatives; row++)
 
3566
    {
 
3567
      delete [] combinations[row];
 
3568
      delete [] transform[row];
 
3569
    }
 
3570
    
 
3571
    delete [] combinations;
 
3572
    delete [] transform;
 
3573
}
 
3574
 
 
3575
/// Evaluate order n derivatives of all basis functions at given point in cell
 
3576
void cahnhilliard2d_0_finite_element_2_1::evaluate_basis_derivatives_all(unsigned int n,
 
3577
                                                   double* values,
 
3578
                                                   const double* coordinates,
 
3579
                                                   const ufc::cell& c) const
 
3580
{
 
3581
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
3582
}
 
3583
 
 
3584
/// Evaluate linear functional for dof i on the function f
 
3585
double cahnhilliard2d_0_finite_element_2_1::evaluate_dof(unsigned int i,
 
3586
                                   const ufc::function& f,
 
3587
                                   const ufc::cell& c) const
 
3588
{
 
3589
    // The reference points, direction and weights:
 
3590
    static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
 
3591
    static const double W[3][1] = {{1}, {1}, {1}};
 
3592
    static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
 
3593
    
 
3594
    const double * const * x = c.coordinates;
 
3595
    double result = 0.0;
 
3596
    // Iterate over the points:
 
3597
    // Evaluate basis functions for affine mapping
 
3598
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
3599
    const double w1 = X[i][0][0];
 
3600
    const double w2 = X[i][0][1];
 
3601
    
 
3602
    // Compute affine mapping y = F(X)
 
3603
    double y[2];
 
3604
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
3605
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
3606
    
 
3607
    // Evaluate function at physical points
 
3608
    double values[1];
 
3609
    f.evaluate(values, y, c);
 
3610
    
 
3611
    // Map function values using appropriate mapping
 
3612
    // Affine map: Do nothing
 
3613
    
 
3614
    // Note that we do not map the weights (yet).
 
3615
    
 
3616
    // Take directional components
 
3617
    for(int k = 0; k < 1; k++)
 
3618
      result += values[k]*D[i][0][k];
 
3619
    // Multiply by weights
 
3620
    result *= W[i][0];
 
3621
    
 
3622
    return result;
 
3623
}
 
3624
 
 
3625
/// Evaluate linear functionals for all dofs on the function f
 
3626
void cahnhilliard2d_0_finite_element_2_1::evaluate_dofs(double* values,
 
3627
                                  const ufc::function& f,
 
3628
                                  const ufc::cell& c) const
 
3629
{
 
3630
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
3631
}
 
3632
 
 
3633
/// Interpolate vertex values from dof values
 
3634
void cahnhilliard2d_0_finite_element_2_1::interpolate_vertex_values(double* vertex_values,
 
3635
                                              const double* dof_values,
 
3636
                                              const ufc::cell& c) const
 
3637
{
 
3638
    // Evaluate at vertices and use affine mapping
 
3639
    vertex_values[0] = dof_values[0];
 
3640
    vertex_values[1] = dof_values[1];
 
3641
    vertex_values[2] = dof_values[2];
 
3642
}
 
3643
 
 
3644
/// Return the number of sub elements (for a mixed element)
 
3645
unsigned int cahnhilliard2d_0_finite_element_2_1::num_sub_elements() const
 
3646
{
 
3647
    return 1;
 
3648
}
 
3649
 
 
3650
/// Create a new finite element for sub element i (for a mixed element)
 
3651
ufc::finite_element* cahnhilliard2d_0_finite_element_2_1::create_sub_element(unsigned int i) const
 
3652
{
 
3653
    return new cahnhilliard2d_0_finite_element_2_1();
 
3654
}
 
3655
 
 
3656
 
 
3657
/// Constructor
 
3658
cahnhilliard2d_0_finite_element_2::cahnhilliard2d_0_finite_element_2() : ufc::finite_element()
 
3659
{
 
3660
    // Do nothing
 
3661
}
 
3662
 
 
3663
/// Destructor
 
3664
cahnhilliard2d_0_finite_element_2::~cahnhilliard2d_0_finite_element_2()
 
3665
{
 
3666
    // Do nothing
 
3667
}
 
3668
 
 
3669
/// Return a string identifying the finite element
 
3670
const char* cahnhilliard2d_0_finite_element_2::signature() const
 
3671
{
 
3672
    return "MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
 
3673
}
 
3674
 
 
3675
/// Return the cell shape
 
3676
ufc::shape cahnhilliard2d_0_finite_element_2::cell_shape() const
 
3677
{
 
3678
    return ufc::triangle;
 
3679
}
 
3680
 
 
3681
/// Return the dimension of the finite element function space
 
3682
unsigned int cahnhilliard2d_0_finite_element_2::space_dimension() const
 
3683
{
 
3684
    return 6;
 
3685
}
 
3686
 
 
3687
/// Return the rank of the value space
 
3688
unsigned int cahnhilliard2d_0_finite_element_2::value_rank() const
 
3689
{
 
3690
    return 1;
 
3691
}
 
3692
 
 
3693
/// Return the dimension of the value space for axis i
 
3694
unsigned int cahnhilliard2d_0_finite_element_2::value_dimension(unsigned int i) const
 
3695
{
 
3696
    return 2;
 
3697
}
 
3698
 
 
3699
/// Evaluate basis function i at given point in cell
 
3700
void cahnhilliard2d_0_finite_element_2::evaluate_basis(unsigned int i,
 
3701
                                   double* values,
 
3702
                                   const double* coordinates,
 
3703
                                   const ufc::cell& c) const
 
3704
{
 
3705
    // Extract vertex coordinates
 
3706
    const double * const * element_coordinates = c.coordinates;
 
3707
    
 
3708
    // Compute Jacobian of affine map from reference cell
 
3709
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
3710
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
3711
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
3712
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
3713
    
 
3714
    // Compute determinant of Jacobian
 
3715
    const double detJ = J_00*J_11 - J_01*J_10;
 
3716
    
 
3717
    // Compute inverse of Jacobian
 
3718
    
 
3719
    // Get coordinates and map to the reference (UFC) element
 
3720
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
3721
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
3722
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
3723
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
3724
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
3725
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
3726
    
 
3727
    // Map coordinates to the reference square
 
3728
    if (std::abs(y - 1.0) < 1e-14)
 
3729
      x = -1.0;
 
3730
    else
 
3731
      x = 2.0 *x/(1.0 - y) - 1.0;
 
3732
    y = 2.0*y - 1.0;
 
3733
    
 
3734
    // Reset values
 
3735
    values[0] = 0;
 
3736
    values[1] = 0;
 
3737
    
 
3738
    if (0 <= i && i <= 2)
 
3739
    {
 
3740
      // Map degree of freedom to element degree of freedom
 
3741
      const unsigned int dof = i;
 
3742
    
 
3743
      // Generate scalings
 
3744
      const double scalings_y_0 = 1;
 
3745
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
3746
    
 
3747
      // Compute psitilde_a
 
3748
      const double psitilde_a_0 = 1;
 
3749
      const double psitilde_a_1 = x;
 
3750
    
 
3751
      // Compute psitilde_bs
 
3752
      const double psitilde_bs_0_0 = 1;
 
3753
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
3754
      const double psitilde_bs_1_0 = 1;
 
3755
    
 
3756
      // Compute basisvalues
 
3757
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
3758
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
3759
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
3760
    
 
3761
      // Table(s) of coefficients
 
3762
      static const double coefficients0[3][3] =   \
 
3763
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
3764
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
3765
      {0.471404520791032, 0, 0.333333333333333}};
 
3766
    
 
3767
      // Extract relevant coefficients
 
3768
      const double coeff0_0 =   coefficients0[dof][0];
 
3769
      const double coeff0_1 =   coefficients0[dof][1];
 
3770
      const double coeff0_2 =   coefficients0[dof][2];
 
3771
    
 
3772
      // Compute value(s)
 
3773
      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
3774
    }
 
3775
    
 
3776
    if (3 <= i && i <= 5)
 
3777
    {
 
3778
      // Map degree of freedom to element degree of freedom
 
3779
      const unsigned int dof = i - 3;
 
3780
    
 
3781
      // Generate scalings
 
3782
      const double scalings_y_0 = 1;
 
3783
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
3784
    
 
3785
      // Compute psitilde_a
 
3786
      const double psitilde_a_0 = 1;
 
3787
      const double psitilde_a_1 = x;
 
3788
    
 
3789
      // Compute psitilde_bs
 
3790
      const double psitilde_bs_0_0 = 1;
 
3791
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
3792
      const double psitilde_bs_1_0 = 1;
 
3793
    
 
3794
      // Compute basisvalues
 
3795
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
3796
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
3797
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
3798
    
 
3799
      // Table(s) of coefficients
 
3800
      static const double coefficients0[3][3] =   \
 
3801
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
3802
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
3803
      {0.471404520791032, 0, 0.333333333333333}};
 
3804
    
 
3805
      // Extract relevant coefficients
 
3806
      const double coeff0_0 =   coefficients0[dof][0];
 
3807
      const double coeff0_1 =   coefficients0[dof][1];
 
3808
      const double coeff0_2 =   coefficients0[dof][2];
 
3809
    
 
3810
      // Compute value(s)
 
3811
      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
3812
    }
 
3813
    
 
3814
}
 
3815
 
 
3816
/// Evaluate all basis functions at given point in cell
 
3817
void cahnhilliard2d_0_finite_element_2::evaluate_basis_all(double* values,
 
3818
                                       const double* coordinates,
 
3819
                                       const ufc::cell& c) const
 
3820
{
 
3821
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
3822
}
 
3823
 
 
3824
/// Evaluate order n derivatives of basis function i at given point in cell
 
3825
void cahnhilliard2d_0_finite_element_2::evaluate_basis_derivatives(unsigned int i,
 
3826
                                               unsigned int n,
 
3827
                                               double* values,
 
3828
                                               const double* coordinates,
 
3829
                                               const ufc::cell& c) const
 
3830
{
 
3831
    // Extract vertex coordinates
 
3832
    const double * const * element_coordinates = c.coordinates;
 
3833
    
 
3834
    // Compute Jacobian of affine map from reference cell
 
3835
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
3836
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
3837
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
3838
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
3839
    
 
3840
    // Compute determinant of Jacobian
 
3841
    const double detJ = J_00*J_11 - J_01*J_10;
 
3842
    
 
3843
    // Compute inverse of Jacobian
 
3844
    
 
3845
    // Get coordinates and map to the reference (UFC) element
 
3846
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
3847
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
3848
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
3849
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
3850
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
3851
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
3852
    
 
3853
    // Map coordinates to the reference square
 
3854
    if (std::abs(y - 1.0) < 1e-14)
 
3855
      x = -1.0;
 
3856
    else
 
3857
      x = 2.0 *x/(1.0 - y) - 1.0;
 
3858
    y = 2.0*y - 1.0;
 
3859
    
 
3860
    // Compute number of derivatives
 
3861
    unsigned int num_derivatives = 1;
 
3862
    
 
3863
    for (unsigned int j = 0; j < n; j++)
 
3864
      num_derivatives *= 2;
 
3865
    
 
3866
    
 
3867
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
3868
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
3869
    
 
3870
    for (unsigned int j = 0; j < num_derivatives; j++)
 
3871
    {
 
3872
      combinations[j] = new unsigned int [n];
 
3873
      for (unsigned int k = 0; k < n; k++)
 
3874
        combinations[j][k] = 0;
 
3875
    }
 
3876
    
 
3877
    // Generate combinations of derivatives
 
3878
    for (unsigned int row = 1; row < num_derivatives; row++)
 
3879
    {
 
3880
      for (unsigned int num = 0; num < row; num++)
 
3881
      {
 
3882
        for (unsigned int col = n-1; col+1 > 0; col--)
 
3883
        {
 
3884
          if (combinations[row][col] + 1 > 1)
 
3885
            combinations[row][col] = 0;
 
3886
          else
 
3887
          {
 
3888
            combinations[row][col] += 1;
 
3889
            break;
 
3890
          }
 
3891
        }
 
3892
      }
 
3893
    }
 
3894
    
 
3895
    // Compute inverse of Jacobian
 
3896
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
3897
    
 
3898
    // Declare transformation matrix
 
3899
    // Declare pointer to two dimensional array and initialise
 
3900
    double **transform = new double *[num_derivatives];
 
3901
    
 
3902
    for (unsigned int j = 0; j < num_derivatives; j++)
 
3903
    {
 
3904
      transform[j] = new double [num_derivatives];
 
3905
      for (unsigned int k = 0; k < num_derivatives; k++)
 
3906
        transform[j][k] = 1;
 
3907
    }
 
3908
    
 
3909
    // Construct transformation matrix
 
3910
    for (unsigned int row = 0; row < num_derivatives; row++)
 
3911
    {
 
3912
      for (unsigned int col = 0; col < num_derivatives; col++)
 
3913
      {
 
3914
        for (unsigned int k = 0; k < n; k++)
 
3915
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
3916
      }
 
3917
    }
 
3918
    
 
3919
    // Reset values
 
3920
    for (unsigned int j = 0; j < 2*num_derivatives; j++)
 
3921
      values[j] = 0;
 
3922
    
 
3923
    if (0 <= i && i <= 2)
 
3924
    {
 
3925
      // Map degree of freedom to element degree of freedom
 
3926
      const unsigned int dof = i;
 
3927
    
 
3928
      // Generate scalings
 
3929
      const double scalings_y_0 = 1;
 
3930
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
3931
    
 
3932
      // Compute psitilde_a
 
3933
      const double psitilde_a_0 = 1;
 
3934
      const double psitilde_a_1 = x;
 
3935
    
 
3936
      // Compute psitilde_bs
 
3937
      const double psitilde_bs_0_0 = 1;
 
3938
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
3939
      const double psitilde_bs_1_0 = 1;
 
3940
    
 
3941
      // Compute basisvalues
 
3942
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
3943
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
3944
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
3945
    
 
3946
      // Table(s) of coefficients
 
3947
      static const double coefficients0[3][3] =   \
 
3948
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
3949
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
3950
      {0.471404520791032, 0, 0.333333333333333}};
 
3951
    
 
3952
      // Interesting (new) part
 
3953
      // Tables of derivatives of the polynomial base (transpose)
 
3954
      static const double dmats0[3][3] =   \
 
3955
      {{0, 0, 0},
 
3956
      {4.89897948556636, 0, 0},
 
3957
      {0, 0, 0}};
 
3958
    
 
3959
      static const double dmats1[3][3] =   \
 
3960
      {{0, 0, 0},
 
3961
      {2.44948974278318, 0, 0},
 
3962
      {4.24264068711928, 0, 0}};
 
3963
    
 
3964
      // Compute reference derivatives
 
3965
      // Declare pointer to array of derivatives on FIAT element
 
3966
      double *derivatives = new double [num_derivatives];
 
3967
    
 
3968
      // Declare coefficients
 
3969
      double coeff0_0 = 0;
 
3970
      double coeff0_1 = 0;
 
3971
      double coeff0_2 = 0;
 
3972
    
 
3973
      // Declare new coefficients
 
3974
      double new_coeff0_0 = 0;
 
3975
      double new_coeff0_1 = 0;
 
3976
      double new_coeff0_2 = 0;
 
3977
    
 
3978
      // Loop possible derivatives
 
3979
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
3980
      {
 
3981
        // Get values from coefficients array
 
3982
        new_coeff0_0 = coefficients0[dof][0];
 
3983
        new_coeff0_1 = coefficients0[dof][1];
 
3984
        new_coeff0_2 = coefficients0[dof][2];
 
3985
    
 
3986
        // Loop derivative order
 
3987
        for (unsigned int j = 0; j < n; j++)
 
3988
        {
 
3989
          // Update old coefficients
 
3990
          coeff0_0 = new_coeff0_0;
 
3991
          coeff0_1 = new_coeff0_1;
 
3992
          coeff0_2 = new_coeff0_2;
 
3993
    
 
3994
          if(combinations[deriv_num][j] == 0)
 
3995
          {
 
3996
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
3997
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
3998
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
3999
          }
 
4000
          if(combinations[deriv_num][j] == 1)
 
4001
          {
 
4002
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
4003
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
4004
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
4005
          }
 
4006
    
 
4007
        }
 
4008
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
4009
        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
4010
      }
 
4011
    
 
4012
      // Transform derivatives back to physical element
 
4013
      for (unsigned int row = 0; row < num_derivatives; row++)
 
4014
      {
 
4015
        for (unsigned int col = 0; col < num_derivatives; col++)
 
4016
        {
 
4017
          values[row] += transform[row][col]*derivatives[col];
 
4018
        }
 
4019
      }
 
4020
      // Delete pointer to array of derivatives on FIAT element
 
4021
      delete [] derivatives;
 
4022
    
 
4023
      // Delete pointer to array of combinations of derivatives and transform
 
4024
      for (unsigned int row = 0; row < num_derivatives; row++)
 
4025
      {
 
4026
        delete [] combinations[row];
 
4027
        delete [] transform[row];
 
4028
      }
 
4029
    
 
4030
      delete [] combinations;
 
4031
      delete [] transform;
 
4032
    }
 
4033
    
 
4034
    if (3 <= i && i <= 5)
 
4035
    {
 
4036
      // Map degree of freedom to element degree of freedom
 
4037
      const unsigned int dof = i - 3;
 
4038
    
 
4039
      // Generate scalings
 
4040
      const double scalings_y_0 = 1;
 
4041
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
4042
    
 
4043
      // Compute psitilde_a
 
4044
      const double psitilde_a_0 = 1;
 
4045
      const double psitilde_a_1 = x;
 
4046
    
 
4047
      // Compute psitilde_bs
 
4048
      const double psitilde_bs_0_0 = 1;
 
4049
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
4050
      const double psitilde_bs_1_0 = 1;
 
4051
    
 
4052
      // Compute basisvalues
 
4053
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
4054
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
4055
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
4056
    
 
4057
      // Table(s) of coefficients
 
4058
      static const double coefficients0[3][3] =   \
 
4059
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
4060
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
4061
      {0.471404520791032, 0, 0.333333333333333}};
 
4062
    
 
4063
      // Interesting (new) part
 
4064
      // Tables of derivatives of the polynomial base (transpose)
 
4065
      static const double dmats0[3][3] =   \
 
4066
      {{0, 0, 0},
 
4067
      {4.89897948556636, 0, 0},
 
4068
      {0, 0, 0}};
 
4069
    
 
4070
      static const double dmats1[3][3] =   \
 
4071
      {{0, 0, 0},
 
4072
      {2.44948974278318, 0, 0},
 
4073
      {4.24264068711928, 0, 0}};
 
4074
    
 
4075
      // Compute reference derivatives
 
4076
      // Declare pointer to array of derivatives on FIAT element
 
4077
      double *derivatives = new double [num_derivatives];
 
4078
    
 
4079
      // Declare coefficients
 
4080
      double coeff0_0 = 0;
 
4081
      double coeff0_1 = 0;
 
4082
      double coeff0_2 = 0;
 
4083
    
 
4084
      // Declare new coefficients
 
4085
      double new_coeff0_0 = 0;
 
4086
      double new_coeff0_1 = 0;
 
4087
      double new_coeff0_2 = 0;
 
4088
    
 
4089
      // Loop possible derivatives
 
4090
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
4091
      {
 
4092
        // Get values from coefficients array
 
4093
        new_coeff0_0 = coefficients0[dof][0];
 
4094
        new_coeff0_1 = coefficients0[dof][1];
 
4095
        new_coeff0_2 = coefficients0[dof][2];
 
4096
    
 
4097
        // Loop derivative order
 
4098
        for (unsigned int j = 0; j < n; j++)
 
4099
        {
 
4100
          // Update old coefficients
 
4101
          coeff0_0 = new_coeff0_0;
 
4102
          coeff0_1 = new_coeff0_1;
 
4103
          coeff0_2 = new_coeff0_2;
 
4104
    
 
4105
          if(combinations[deriv_num][j] == 0)
 
4106
          {
 
4107
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
4108
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
4109
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
4110
          }
 
4111
          if(combinations[deriv_num][j] == 1)
 
4112
          {
 
4113
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
4114
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
4115
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
4116
          }
 
4117
    
 
4118
        }
 
4119
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
4120
        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
4121
      }
 
4122
    
 
4123
      // Transform derivatives back to physical element
 
4124
      for (unsigned int row = 0; row < num_derivatives; row++)
 
4125
      {
 
4126
        for (unsigned int col = 0; col < num_derivatives; col++)
 
4127
        {
 
4128
          values[num_derivatives + row] += transform[row][col]*derivatives[col];
 
4129
        }
 
4130
      }
 
4131
      // Delete pointer to array of derivatives on FIAT element
 
4132
      delete [] derivatives;
 
4133
    
 
4134
      // Delete pointer to array of combinations of derivatives and transform
 
4135
      for (unsigned int row = 0; row < num_derivatives; row++)
 
4136
      {
 
4137
        delete [] combinations[row];
 
4138
        delete [] transform[row];
 
4139
      }
 
4140
    
 
4141
      delete [] combinations;
 
4142
      delete [] transform;
 
4143
    }
 
4144
    
 
4145
}
 
4146
 
 
4147
/// Evaluate order n derivatives of all basis functions at given point in cell
 
4148
void cahnhilliard2d_0_finite_element_2::evaluate_basis_derivatives_all(unsigned int n,
 
4149
                                                   double* values,
 
4150
                                                   const double* coordinates,
 
4151
                                                   const ufc::cell& c) const
 
4152
{
 
4153
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
4154
}
 
4155
 
 
4156
/// Evaluate linear functional for dof i on the function f
 
4157
double cahnhilliard2d_0_finite_element_2::evaluate_dof(unsigned int i,
 
4158
                                   const ufc::function& f,
 
4159
                                   const ufc::cell& c) const
 
4160
{
 
4161
    // The reference points, direction and weights:
 
4162
    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
 
4163
    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
 
4164
    static const double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
 
4165
    
 
4166
    const double * const * x = c.coordinates;
 
4167
    double result = 0.0;
 
4168
    // Iterate over the points:
 
4169
    // Evaluate basis functions for affine mapping
 
4170
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
4171
    const double w1 = X[i][0][0];
 
4172
    const double w2 = X[i][0][1];
 
4173
    
 
4174
    // Compute affine mapping y = F(X)
 
4175
    double y[2];
 
4176
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
4177
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
4178
    
 
4179
    // Evaluate function at physical points
 
4180
    double values[2];
 
4181
    f.evaluate(values, y, c);
 
4182
    
 
4183
    // Map function values using appropriate mapping
 
4184
    // Affine map: Do nothing
 
4185
    
 
4186
    // Note that we do not map the weights (yet).
 
4187
    
 
4188
    // Take directional components
 
4189
    for(int k = 0; k < 2; k++)
 
4190
      result += values[k]*D[i][0][k];
 
4191
    // Multiply by weights
 
4192
    result *= W[i][0];
 
4193
    
 
4194
    return result;
 
4195
}
 
4196
 
 
4197
/// Evaluate linear functionals for all dofs on the function f
 
4198
void cahnhilliard2d_0_finite_element_2::evaluate_dofs(double* values,
 
4199
                                  const ufc::function& f,
 
4200
                                  const ufc::cell& c) const
 
4201
{
 
4202
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
4203
}
 
4204
 
 
4205
/// Interpolate vertex values from dof values
 
4206
void cahnhilliard2d_0_finite_element_2::interpolate_vertex_values(double* vertex_values,
 
4207
                                              const double* dof_values,
 
4208
                                              const ufc::cell& c) const
 
4209
{
 
4210
    // Evaluate at vertices and use affine mapping
 
4211
    vertex_values[0] = dof_values[0];
 
4212
    vertex_values[2] = dof_values[1];
 
4213
    vertex_values[4] = dof_values[2];
 
4214
    // Evaluate at vertices and use affine mapping
 
4215
    vertex_values[1] = dof_values[3];
 
4216
    vertex_values[3] = dof_values[4];
 
4217
    vertex_values[5] = dof_values[5];
 
4218
}
 
4219
 
 
4220
/// Return the number of sub elements (for a mixed element)
 
4221
unsigned int cahnhilliard2d_0_finite_element_2::num_sub_elements() const
 
4222
{
 
4223
    return 2;
 
4224
}
 
4225
 
 
4226
/// Create a new finite element for sub element i (for a mixed element)
 
4227
ufc::finite_element* cahnhilliard2d_0_finite_element_2::create_sub_element(unsigned int i) const
 
4228
{
 
4229
    switch ( i )
 
4230
    {
 
4231
    case 0:
 
4232
      return new cahnhilliard2d_0_finite_element_2_0();
 
4233
      break;
 
4234
    case 1:
 
4235
      return new cahnhilliard2d_0_finite_element_2_1();
 
4236
      break;
 
4237
    }
 
4238
    return 0;
 
4239
}
 
4240
 
 
4241
 
 
4242
/// Constructor
 
4243
cahnhilliard2d_0_finite_element_3::cahnhilliard2d_0_finite_element_3() : ufc::finite_element()
 
4244
{
 
4245
    // Do nothing
 
4246
}
 
4247
 
 
4248
/// Destructor
 
4249
cahnhilliard2d_0_finite_element_3::~cahnhilliard2d_0_finite_element_3()
 
4250
{
 
4251
    // Do nothing
 
4252
}
 
4253
 
 
4254
/// Return a string identifying the finite element
 
4255
const char* cahnhilliard2d_0_finite_element_3::signature() const
 
4256
{
 
4257
    return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
 
4258
}
 
4259
 
 
4260
/// Return the cell shape
 
4261
ufc::shape cahnhilliard2d_0_finite_element_3::cell_shape() const
 
4262
{
 
4263
    return ufc::triangle;
 
4264
}
 
4265
 
 
4266
/// Return the dimension of the finite element function space
 
4267
unsigned int cahnhilliard2d_0_finite_element_3::space_dimension() const
 
4268
{
 
4269
    return 1;
 
4270
}
 
4271
 
 
4272
/// Return the rank of the value space
 
4273
unsigned int cahnhilliard2d_0_finite_element_3::value_rank() const
 
4274
{
 
4275
    return 0;
 
4276
}
 
4277
 
 
4278
/// Return the dimension of the value space for axis i
 
4279
unsigned int cahnhilliard2d_0_finite_element_3::value_dimension(unsigned int i) const
 
4280
{
 
4281
    return 1;
 
4282
}
 
4283
 
 
4284
/// Evaluate basis function i at given point in cell
 
4285
void cahnhilliard2d_0_finite_element_3::evaluate_basis(unsigned int i,
 
4286
                                   double* values,
 
4287
                                   const double* coordinates,
 
4288
                                   const ufc::cell& c) const
 
4289
{
 
4290
    // Extract vertex coordinates
 
4291
    const double * const * element_coordinates = c.coordinates;
 
4292
    
 
4293
    // Compute Jacobian of affine map from reference cell
 
4294
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
4295
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
4296
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
4297
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
4298
    
 
4299
    // Compute determinant of Jacobian
 
4300
    const double detJ = J_00*J_11 - J_01*J_10;
 
4301
    
 
4302
    // Compute inverse of Jacobian
 
4303
    
 
4304
    // Get coordinates and map to the reference (UFC) element
 
4305
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
4306
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
4307
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
4308
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
4309
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
4310
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
4311
    
 
4312
    // Map coordinates to the reference square
 
4313
    if (std::abs(y - 1.0) < 1e-14)
 
4314
      x = -1.0;
 
4315
    else
 
4316
      x = 2.0 *x/(1.0 - y) - 1.0;
 
4317
    y = 2.0*y - 1.0;
 
4318
    
 
4319
    // Reset values
 
4320
    *values = 0;
 
4321
    
 
4322
    // Map degree of freedom to element degree of freedom
 
4323
    const unsigned int dof = i;
 
4324
    
 
4325
    // Generate scalings
 
4326
    const double scalings_y_0 = 1;
 
4327
    
 
4328
    // Compute psitilde_a
 
4329
    const double psitilde_a_0 = 1;
 
4330
    
 
4331
    // Compute psitilde_bs
 
4332
    const double psitilde_bs_0_0 = 1;
 
4333
    
 
4334
    // Compute basisvalues
 
4335
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
4336
    
 
4337
    // Table(s) of coefficients
 
4338
    static const double coefficients0[1][1] = \
 
4339
    {{1.41421356237309}};
 
4340
    
 
4341
    // Extract relevant coefficients
 
4342
    const double coeff0_0 = coefficients0[dof][0];
 
4343
    
 
4344
    // Compute value(s)
 
4345
    *values = coeff0_0*basisvalue0;
 
4346
}
 
4347
 
 
4348
/// Evaluate all basis functions at given point in cell
 
4349
void cahnhilliard2d_0_finite_element_3::evaluate_basis_all(double* values,
 
4350
                                       const double* coordinates,
 
4351
                                       const ufc::cell& c) const
 
4352
{
 
4353
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
4354
}
 
4355
 
 
4356
/// Evaluate order n derivatives of basis function i at given point in cell
 
4357
void cahnhilliard2d_0_finite_element_3::evaluate_basis_derivatives(unsigned int i,
 
4358
                                               unsigned int n,
 
4359
                                               double* values,
 
4360
                                               const double* coordinates,
 
4361
                                               const ufc::cell& c) const
 
4362
{
 
4363
    // Extract vertex coordinates
 
4364
    const double * const * element_coordinates = c.coordinates;
 
4365
    
 
4366
    // Compute Jacobian of affine map from reference cell
 
4367
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
4368
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
4369
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
4370
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
4371
    
 
4372
    // Compute determinant of Jacobian
 
4373
    const double detJ = J_00*J_11 - J_01*J_10;
 
4374
    
 
4375
    // Compute inverse of Jacobian
 
4376
    
 
4377
    // Get coordinates and map to the reference (UFC) element
 
4378
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
4379
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
4380
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
4381
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
4382
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
4383
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
4384
    
 
4385
    // Map coordinates to the reference square
 
4386
    if (std::abs(y - 1.0) < 1e-14)
 
4387
      x = -1.0;
 
4388
    else
 
4389
      x = 2.0 *x/(1.0 - y) - 1.0;
 
4390
    y = 2.0*y - 1.0;
 
4391
    
 
4392
    // Compute number of derivatives
 
4393
    unsigned int num_derivatives = 1;
 
4394
    
 
4395
    for (unsigned int j = 0; j < n; j++)
 
4396
      num_derivatives *= 2;
 
4397
    
 
4398
    
 
4399
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
4400
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
4401
    
 
4402
    for (unsigned int j = 0; j < num_derivatives; j++)
 
4403
    {
 
4404
      combinations[j] = new unsigned int [n];
 
4405
      for (unsigned int k = 0; k < n; k++)
 
4406
        combinations[j][k] = 0;
 
4407
    }
 
4408
    
 
4409
    // Generate combinations of derivatives
 
4410
    for (unsigned int row = 1; row < num_derivatives; row++)
 
4411
    {
 
4412
      for (unsigned int num = 0; num < row; num++)
 
4413
      {
 
4414
        for (unsigned int col = n-1; col+1 > 0; col--)
 
4415
        {
 
4416
          if (combinations[row][col] + 1 > 1)
 
4417
            combinations[row][col] = 0;
 
4418
          else
 
4419
          {
 
4420
            combinations[row][col] += 1;
 
4421
            break;
 
4422
          }
 
4423
        }
 
4424
      }
 
4425
    }
 
4426
    
 
4427
    // Compute inverse of Jacobian
 
4428
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
4429
    
 
4430
    // Declare transformation matrix
 
4431
    // Declare pointer to two dimensional array and initialise
 
4432
    double **transform = new double *[num_derivatives];
 
4433
    
 
4434
    for (unsigned int j = 0; j < num_derivatives; j++)
 
4435
    {
 
4436
      transform[j] = new double [num_derivatives];
 
4437
      for (unsigned int k = 0; k < num_derivatives; k++)
 
4438
        transform[j][k] = 1;
 
4439
    }
 
4440
    
 
4441
    // Construct transformation matrix
 
4442
    for (unsigned int row = 0; row < num_derivatives; row++)
 
4443
    {
 
4444
      for (unsigned int col = 0; col < num_derivatives; col++)
 
4445
      {
 
4446
        for (unsigned int k = 0; k < n; k++)
 
4447
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
4448
      }
 
4449
    }
 
4450
    
 
4451
    // Reset values
 
4452
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
 
4453
      values[j] = 0;
 
4454
    
 
4455
    // Map degree of freedom to element degree of freedom
 
4456
    const unsigned int dof = i;
 
4457
    
 
4458
    // Generate scalings
 
4459
    const double scalings_y_0 = 1;
 
4460
    
 
4461
    // Compute psitilde_a
 
4462
    const double psitilde_a_0 = 1;
 
4463
    
 
4464
    // Compute psitilde_bs
 
4465
    const double psitilde_bs_0_0 = 1;
 
4466
    
 
4467
    // Compute basisvalues
 
4468
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
4469
    
 
4470
    // Table(s) of coefficients
 
4471
    static const double coefficients0[1][1] = \
 
4472
    {{1.41421356237309}};
 
4473
    
 
4474
    // Interesting (new) part
 
4475
    // Tables of derivatives of the polynomial base (transpose)
 
4476
    static const double dmats0[1][1] = \
 
4477
    {{0}};
 
4478
    
 
4479
    static const double dmats1[1][1] = \
 
4480
    {{0}};
 
4481
    
 
4482
    // Compute reference derivatives
 
4483
    // Declare pointer to array of derivatives on FIAT element
 
4484
    double *derivatives = new double [num_derivatives];
 
4485
    
 
4486
    // Declare coefficients
 
4487
    double coeff0_0 = 0;
 
4488
    
 
4489
    // Declare new coefficients
 
4490
    double new_coeff0_0 = 0;
 
4491
    
 
4492
    // Loop possible derivatives
 
4493
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
4494
    {
 
4495
      // Get values from coefficients array
 
4496
      new_coeff0_0 = coefficients0[dof][0];
 
4497
    
 
4498
      // Loop derivative order
 
4499
      for (unsigned int j = 0; j < n; j++)
 
4500
      {
 
4501
        // Update old coefficients
 
4502
        coeff0_0 = new_coeff0_0;
 
4503
    
 
4504
        if(combinations[deriv_num][j] == 0)
 
4505
        {
 
4506
          new_coeff0_0 = coeff0_0*dmats0[0][0];
 
4507
        }
 
4508
        if(combinations[deriv_num][j] == 1)
 
4509
        {
 
4510
          new_coeff0_0 = coeff0_0*dmats1[0][0];
 
4511
        }
 
4512
    
 
4513
      }
 
4514
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
4515
      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
 
4516
    }
 
4517
    
 
4518
    // Transform derivatives back to physical element
 
4519
    for (unsigned int row = 0; row < num_derivatives; row++)
 
4520
    {
 
4521
      for (unsigned int col = 0; col < num_derivatives; col++)
 
4522
      {
 
4523
        values[row] += transform[row][col]*derivatives[col];
 
4524
      }
 
4525
    }
 
4526
    // Delete pointer to array of derivatives on FIAT element
 
4527
    delete [] derivatives;
 
4528
    
 
4529
    // Delete pointer to array of combinations of derivatives and transform
 
4530
    for (unsigned int row = 0; row < num_derivatives; row++)
 
4531
    {
 
4532
      delete [] combinations[row];
 
4533
      delete [] transform[row];
 
4534
    }
 
4535
    
 
4536
    delete [] combinations;
 
4537
    delete [] transform;
 
4538
}
 
4539
 
 
4540
/// Evaluate order n derivatives of all basis functions at given point in cell
 
4541
void cahnhilliard2d_0_finite_element_3::evaluate_basis_derivatives_all(unsigned int n,
 
4542
                                                   double* values,
 
4543
                                                   const double* coordinates,
 
4544
                                                   const ufc::cell& c) const
 
4545
{
 
4546
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
4547
}
 
4548
 
 
4549
/// Evaluate linear functional for dof i on the function f
 
4550
double cahnhilliard2d_0_finite_element_3::evaluate_dof(unsigned int i,
 
4551
                                   const ufc::function& f,
 
4552
                                   const ufc::cell& c) const
 
4553
{
 
4554
    // The reference points, direction and weights:
 
4555
    static const double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
 
4556
    static const double W[1][1] = {{1}};
 
4557
    static const double D[1][1][1] = {{{1}}};
 
4558
    
 
4559
    const double * const * x = c.coordinates;
 
4560
    double result = 0.0;
 
4561
    // Iterate over the points:
 
4562
    // Evaluate basis functions for affine mapping
 
4563
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
4564
    const double w1 = X[i][0][0];
 
4565
    const double w2 = X[i][0][1];
 
4566
    
 
4567
    // Compute affine mapping y = F(X)
 
4568
    double y[2];
 
4569
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
4570
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
4571
    
 
4572
    // Evaluate function at physical points
 
4573
    double values[1];
 
4574
    f.evaluate(values, y, c);
 
4575
    
 
4576
    // Map function values using appropriate mapping
 
4577
    // Affine map: Do nothing
 
4578
    
 
4579
    // Note that we do not map the weights (yet).
 
4580
    
 
4581
    // Take directional components
 
4582
    for(int k = 0; k < 1; k++)
 
4583
      result += values[k]*D[i][0][k];
 
4584
    // Multiply by weights
 
4585
    result *= W[i][0];
 
4586
    
 
4587
    return result;
 
4588
}
 
4589
 
 
4590
/// Evaluate linear functionals for all dofs on the function f
 
4591
void cahnhilliard2d_0_finite_element_3::evaluate_dofs(double* values,
 
4592
                                  const ufc::function& f,
 
4593
                                  const ufc::cell& c) const
 
4594
{
 
4595
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
4596
}
 
4597
 
 
4598
/// Interpolate vertex values from dof values
 
4599
void cahnhilliard2d_0_finite_element_3::interpolate_vertex_values(double* vertex_values,
 
4600
                                              const double* dof_values,
 
4601
                                              const ufc::cell& c) const
 
4602
{
 
4603
    // Evaluate at vertices and use affine mapping
 
4604
    vertex_values[0] = dof_values[0];
 
4605
    vertex_values[1] = dof_values[0];
 
4606
    vertex_values[2] = dof_values[0];
 
4607
}
 
4608
 
 
4609
/// Return the number of sub elements (for a mixed element)
 
4610
unsigned int cahnhilliard2d_0_finite_element_3::num_sub_elements() const
 
4611
{
 
4612
    return 1;
 
4613
}
 
4614
 
 
4615
/// Create a new finite element for sub element i (for a mixed element)
 
4616
ufc::finite_element* cahnhilliard2d_0_finite_element_3::create_sub_element(unsigned int i) const
 
4617
{
 
4618
    return new cahnhilliard2d_0_finite_element_3();
 
4619
}
 
4620
 
 
4621
 
 
4622
/// Constructor
 
4623
cahnhilliard2d_0_finite_element_4::cahnhilliard2d_0_finite_element_4() : ufc::finite_element()
 
4624
{
 
4625
    // Do nothing
 
4626
}
 
4627
 
 
4628
/// Destructor
 
4629
cahnhilliard2d_0_finite_element_4::~cahnhilliard2d_0_finite_element_4()
 
4630
{
 
4631
    // Do nothing
 
4632
}
 
4633
 
 
4634
/// Return a string identifying the finite element
 
4635
const char* cahnhilliard2d_0_finite_element_4::signature() const
 
4636
{
 
4637
    return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
 
4638
}
 
4639
 
 
4640
/// Return the cell shape
 
4641
ufc::shape cahnhilliard2d_0_finite_element_4::cell_shape() const
 
4642
{
 
4643
    return ufc::triangle;
 
4644
}
 
4645
 
 
4646
/// Return the dimension of the finite element function space
 
4647
unsigned int cahnhilliard2d_0_finite_element_4::space_dimension() const
 
4648
{
 
4649
    return 1;
 
4650
}
 
4651
 
 
4652
/// Return the rank of the value space
 
4653
unsigned int cahnhilliard2d_0_finite_element_4::value_rank() const
 
4654
{
 
4655
    return 0;
 
4656
}
 
4657
 
 
4658
/// Return the dimension of the value space for axis i
 
4659
unsigned int cahnhilliard2d_0_finite_element_4::value_dimension(unsigned int i) const
 
4660
{
 
4661
    return 1;
 
4662
}
 
4663
 
 
4664
/// Evaluate basis function i at given point in cell
 
4665
void cahnhilliard2d_0_finite_element_4::evaluate_basis(unsigned int i,
 
4666
                                   double* values,
 
4667
                                   const double* coordinates,
 
4668
                                   const ufc::cell& c) const
 
4669
{
 
4670
    // Extract vertex coordinates
 
4671
    const double * const * element_coordinates = c.coordinates;
 
4672
    
 
4673
    // Compute Jacobian of affine map from reference cell
 
4674
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
4675
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
4676
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
4677
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
4678
    
 
4679
    // Compute determinant of Jacobian
 
4680
    const double detJ = J_00*J_11 - J_01*J_10;
 
4681
    
 
4682
    // Compute inverse of Jacobian
 
4683
    
 
4684
    // Get coordinates and map to the reference (UFC) element
 
4685
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
4686
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
4687
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
4688
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
4689
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
4690
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
4691
    
 
4692
    // Map coordinates to the reference square
 
4693
    if (std::abs(y - 1.0) < 1e-14)
 
4694
      x = -1.0;
 
4695
    else
 
4696
      x = 2.0 *x/(1.0 - y) - 1.0;
 
4697
    y = 2.0*y - 1.0;
 
4698
    
 
4699
    // Reset values
 
4700
    *values = 0;
 
4701
    
 
4702
    // Map degree of freedom to element degree of freedom
 
4703
    const unsigned int dof = i;
 
4704
    
 
4705
    // Generate scalings
 
4706
    const double scalings_y_0 = 1;
 
4707
    
 
4708
    // Compute psitilde_a
 
4709
    const double psitilde_a_0 = 1;
 
4710
    
 
4711
    // Compute psitilde_bs
 
4712
    const double psitilde_bs_0_0 = 1;
 
4713
    
 
4714
    // Compute basisvalues
 
4715
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
4716
    
 
4717
    // Table(s) of coefficients
 
4718
    static const double coefficients0[1][1] = \
 
4719
    {{1.41421356237309}};
 
4720
    
 
4721
    // Extract relevant coefficients
 
4722
    const double coeff0_0 = coefficients0[dof][0];
 
4723
    
 
4724
    // Compute value(s)
 
4725
    *values = coeff0_0*basisvalue0;
 
4726
}
 
4727
 
 
4728
/// Evaluate all basis functions at given point in cell
 
4729
void cahnhilliard2d_0_finite_element_4::evaluate_basis_all(double* values,
 
4730
                                       const double* coordinates,
 
4731
                                       const ufc::cell& c) const
 
4732
{
 
4733
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
4734
}
 
4735
 
 
4736
/// Evaluate order n derivatives of basis function i at given point in cell
 
4737
void cahnhilliard2d_0_finite_element_4::evaluate_basis_derivatives(unsigned int i,
 
4738
                                               unsigned int n,
 
4739
                                               double* values,
 
4740
                                               const double* coordinates,
 
4741
                                               const ufc::cell& c) const
 
4742
{
 
4743
    // Extract vertex coordinates
 
4744
    const double * const * element_coordinates = c.coordinates;
 
4745
    
 
4746
    // Compute Jacobian of affine map from reference cell
 
4747
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
4748
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
4749
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
4750
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
4751
    
 
4752
    // Compute determinant of Jacobian
 
4753
    const double detJ = J_00*J_11 - J_01*J_10;
 
4754
    
 
4755
    // Compute inverse of Jacobian
 
4756
    
 
4757
    // Get coordinates and map to the reference (UFC) element
 
4758
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
4759
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
4760
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
4761
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
4762
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
4763
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
4764
    
 
4765
    // Map coordinates to the reference square
 
4766
    if (std::abs(y - 1.0) < 1e-14)
 
4767
      x = -1.0;
 
4768
    else
 
4769
      x = 2.0 *x/(1.0 - y) - 1.0;
 
4770
    y = 2.0*y - 1.0;
 
4771
    
 
4772
    // Compute number of derivatives
 
4773
    unsigned int num_derivatives = 1;
 
4774
    
 
4775
    for (unsigned int j = 0; j < n; j++)
 
4776
      num_derivatives *= 2;
 
4777
    
 
4778
    
 
4779
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
4780
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
4781
    
 
4782
    for (unsigned int j = 0; j < num_derivatives; j++)
 
4783
    {
 
4784
      combinations[j] = new unsigned int [n];
 
4785
      for (unsigned int k = 0; k < n; k++)
 
4786
        combinations[j][k] = 0;
 
4787
    }
 
4788
    
 
4789
    // Generate combinations of derivatives
 
4790
    for (unsigned int row = 1; row < num_derivatives; row++)
 
4791
    {
 
4792
      for (unsigned int num = 0; num < row; num++)
 
4793
      {
 
4794
        for (unsigned int col = n-1; col+1 > 0; col--)
 
4795
        {
 
4796
          if (combinations[row][col] + 1 > 1)
 
4797
            combinations[row][col] = 0;
 
4798
          else
 
4799
          {
 
4800
            combinations[row][col] += 1;
 
4801
            break;
 
4802
          }
 
4803
        }
 
4804
      }
 
4805
    }
 
4806
    
 
4807
    // Compute inverse of Jacobian
 
4808
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
4809
    
 
4810
    // Declare transformation matrix
 
4811
    // Declare pointer to two dimensional array and initialise
 
4812
    double **transform = new double *[num_derivatives];
 
4813
    
 
4814
    for (unsigned int j = 0; j < num_derivatives; j++)
 
4815
    {
 
4816
      transform[j] = new double [num_derivatives];
 
4817
      for (unsigned int k = 0; k < num_derivatives; k++)
 
4818
        transform[j][k] = 1;
 
4819
    }
 
4820
    
 
4821
    // Construct transformation matrix
 
4822
    for (unsigned int row = 0; row < num_derivatives; row++)
 
4823
    {
 
4824
      for (unsigned int col = 0; col < num_derivatives; col++)
 
4825
      {
 
4826
        for (unsigned int k = 0; k < n; k++)
 
4827
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
4828
      }
 
4829
    }
 
4830
    
 
4831
    // Reset values
 
4832
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
 
4833
      values[j] = 0;
 
4834
    
 
4835
    // Map degree of freedom to element degree of freedom
 
4836
    const unsigned int dof = i;
 
4837
    
 
4838
    // Generate scalings
 
4839
    const double scalings_y_0 = 1;
 
4840
    
 
4841
    // Compute psitilde_a
 
4842
    const double psitilde_a_0 = 1;
 
4843
    
 
4844
    // Compute psitilde_bs
 
4845
    const double psitilde_bs_0_0 = 1;
 
4846
    
 
4847
    // Compute basisvalues
 
4848
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
4849
    
 
4850
    // Table(s) of coefficients
 
4851
    static const double coefficients0[1][1] = \
 
4852
    {{1.41421356237309}};
 
4853
    
 
4854
    // Interesting (new) part
 
4855
    // Tables of derivatives of the polynomial base (transpose)
 
4856
    static const double dmats0[1][1] = \
 
4857
    {{0}};
 
4858
    
 
4859
    static const double dmats1[1][1] = \
 
4860
    {{0}};
 
4861
    
 
4862
    // Compute reference derivatives
 
4863
    // Declare pointer to array of derivatives on FIAT element
 
4864
    double *derivatives = new double [num_derivatives];
 
4865
    
 
4866
    // Declare coefficients
 
4867
    double coeff0_0 = 0;
 
4868
    
 
4869
    // Declare new coefficients
 
4870
    double new_coeff0_0 = 0;
 
4871
    
 
4872
    // Loop possible derivatives
 
4873
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
4874
    {
 
4875
      // Get values from coefficients array
 
4876
      new_coeff0_0 = coefficients0[dof][0];
 
4877
    
 
4878
      // Loop derivative order
 
4879
      for (unsigned int j = 0; j < n; j++)
 
4880
      {
 
4881
        // Update old coefficients
 
4882
        coeff0_0 = new_coeff0_0;
 
4883
    
 
4884
        if(combinations[deriv_num][j] == 0)
 
4885
        {
 
4886
          new_coeff0_0 = coeff0_0*dmats0[0][0];
 
4887
        }
 
4888
        if(combinations[deriv_num][j] == 1)
 
4889
        {
 
4890
          new_coeff0_0 = coeff0_0*dmats1[0][0];
 
4891
        }
 
4892
    
 
4893
      }
 
4894
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
4895
      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
 
4896
    }
 
4897
    
 
4898
    // Transform derivatives back to physical element
 
4899
    for (unsigned int row = 0; row < num_derivatives; row++)
 
4900
    {
 
4901
      for (unsigned int col = 0; col < num_derivatives; col++)
 
4902
      {
 
4903
        values[row] += transform[row][col]*derivatives[col];
 
4904
      }
 
4905
    }
 
4906
    // Delete pointer to array of derivatives on FIAT element
 
4907
    delete [] derivatives;
 
4908
    
 
4909
    // Delete pointer to array of combinations of derivatives and transform
 
4910
    for (unsigned int row = 0; row < num_derivatives; row++)
 
4911
    {
 
4912
      delete [] combinations[row];
 
4913
      delete [] transform[row];
 
4914
    }
 
4915
    
 
4916
    delete [] combinations;
 
4917
    delete [] transform;
 
4918
}
 
4919
 
 
4920
/// Evaluate order n derivatives of all basis functions at given point in cell
 
4921
void cahnhilliard2d_0_finite_element_4::evaluate_basis_derivatives_all(unsigned int n,
 
4922
                                                   double* values,
 
4923
                                                   const double* coordinates,
 
4924
                                                   const ufc::cell& c) const
 
4925
{
 
4926
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
4927
}
 
4928
 
 
4929
/// Evaluate linear functional for dof i on the function f
 
4930
double cahnhilliard2d_0_finite_element_4::evaluate_dof(unsigned int i,
 
4931
                                   const ufc::function& f,
 
4932
                                   const ufc::cell& c) const
 
4933
{
 
4934
    // The reference points, direction and weights:
 
4935
    static const double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
 
4936
    static const double W[1][1] = {{1}};
 
4937
    static const double D[1][1][1] = {{{1}}};
 
4938
    
 
4939
    const double * const * x = c.coordinates;
 
4940
    double result = 0.0;
 
4941
    // Iterate over the points:
 
4942
    // Evaluate basis functions for affine mapping
 
4943
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
4944
    const double w1 = X[i][0][0];
 
4945
    const double w2 = X[i][0][1];
 
4946
    
 
4947
    // Compute affine mapping y = F(X)
 
4948
    double y[2];
 
4949
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
4950
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
4951
    
 
4952
    // Evaluate function at physical points
 
4953
    double values[1];
 
4954
    f.evaluate(values, y, c);
 
4955
    
 
4956
    // Map function values using appropriate mapping
 
4957
    // Affine map: Do nothing
 
4958
    
 
4959
    // Note that we do not map the weights (yet).
 
4960
    
 
4961
    // Take directional components
 
4962
    for(int k = 0; k < 1; k++)
 
4963
      result += values[k]*D[i][0][k];
 
4964
    // Multiply by weights
 
4965
    result *= W[i][0];
 
4966
    
 
4967
    return result;
 
4968
}
 
4969
 
 
4970
/// Evaluate linear functionals for all dofs on the function f
 
4971
void cahnhilliard2d_0_finite_element_4::evaluate_dofs(double* values,
 
4972
                                  const ufc::function& f,
 
4973
                                  const ufc::cell& c) const
 
4974
{
 
4975
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
4976
}
 
4977
 
 
4978
/// Interpolate vertex values from dof values
 
4979
void cahnhilliard2d_0_finite_element_4::interpolate_vertex_values(double* vertex_values,
 
4980
                                              const double* dof_values,
 
4981
                                              const ufc::cell& c) const
 
4982
{
 
4983
    // Evaluate at vertices and use affine mapping
 
4984
    vertex_values[0] = dof_values[0];
 
4985
    vertex_values[1] = dof_values[0];
 
4986
    vertex_values[2] = dof_values[0];
 
4987
}
 
4988
 
 
4989
/// Return the number of sub elements (for a mixed element)
 
4990
unsigned int cahnhilliard2d_0_finite_element_4::num_sub_elements() const
 
4991
{
 
4992
    return 1;
 
4993
}
 
4994
 
 
4995
/// Create a new finite element for sub element i (for a mixed element)
 
4996
ufc::finite_element* cahnhilliard2d_0_finite_element_4::create_sub_element(unsigned int i) const
 
4997
{
 
4998
    return new cahnhilliard2d_0_finite_element_4();
 
4999
}
 
5000
 
 
5001
 
 
5002
/// Constructor
 
5003
cahnhilliard2d_0_finite_element_5::cahnhilliard2d_0_finite_element_5() : ufc::finite_element()
 
5004
{
 
5005
    // Do nothing
 
5006
}
 
5007
 
 
5008
/// Destructor
 
5009
cahnhilliard2d_0_finite_element_5::~cahnhilliard2d_0_finite_element_5()
 
5010
{
 
5011
    // Do nothing
 
5012
}
 
5013
 
 
5014
/// Return a string identifying the finite element
 
5015
const char* cahnhilliard2d_0_finite_element_5::signature() const
 
5016
{
 
5017
    return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
 
5018
}
 
5019
 
 
5020
/// Return the cell shape
 
5021
ufc::shape cahnhilliard2d_0_finite_element_5::cell_shape() const
 
5022
{
 
5023
    return ufc::triangle;
 
5024
}
 
5025
 
 
5026
/// Return the dimension of the finite element function space
 
5027
unsigned int cahnhilliard2d_0_finite_element_5::space_dimension() const
 
5028
{
 
5029
    return 1;
 
5030
}
 
5031
 
 
5032
/// Return the rank of the value space
 
5033
unsigned int cahnhilliard2d_0_finite_element_5::value_rank() const
 
5034
{
 
5035
    return 0;
 
5036
}
 
5037
 
 
5038
/// Return the dimension of the value space for axis i
 
5039
unsigned int cahnhilliard2d_0_finite_element_5::value_dimension(unsigned int i) const
 
5040
{
 
5041
    return 1;
 
5042
}
 
5043
 
 
5044
/// Evaluate basis function i at given point in cell
 
5045
void cahnhilliard2d_0_finite_element_5::evaluate_basis(unsigned int i,
 
5046
                                   double* values,
 
5047
                                   const double* coordinates,
 
5048
                                   const ufc::cell& c) const
 
5049
{
 
5050
    // Extract vertex coordinates
 
5051
    const double * const * element_coordinates = c.coordinates;
 
5052
    
 
5053
    // Compute Jacobian of affine map from reference cell
 
5054
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
5055
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
5056
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
5057
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
5058
    
 
5059
    // Compute determinant of Jacobian
 
5060
    const double detJ = J_00*J_11 - J_01*J_10;
 
5061
    
 
5062
    // Compute inverse of Jacobian
 
5063
    
 
5064
    // Get coordinates and map to the reference (UFC) element
 
5065
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
5066
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
5067
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
5068
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
5069
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
5070
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
5071
    
 
5072
    // Map coordinates to the reference square
 
5073
    if (std::abs(y - 1.0) < 1e-14)
 
5074
      x = -1.0;
 
5075
    else
 
5076
      x = 2.0 *x/(1.0 - y) - 1.0;
 
5077
    y = 2.0*y - 1.0;
 
5078
    
 
5079
    // Reset values
 
5080
    *values = 0;
 
5081
    
 
5082
    // Map degree of freedom to element degree of freedom
 
5083
    const unsigned int dof = i;
 
5084
    
 
5085
    // Generate scalings
 
5086
    const double scalings_y_0 = 1;
 
5087
    
 
5088
    // Compute psitilde_a
 
5089
    const double psitilde_a_0 = 1;
 
5090
    
 
5091
    // Compute psitilde_bs
 
5092
    const double psitilde_bs_0_0 = 1;
 
5093
    
 
5094
    // Compute basisvalues
 
5095
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
5096
    
 
5097
    // Table(s) of coefficients
 
5098
    static const double coefficients0[1][1] = \
 
5099
    {{1.41421356237309}};
 
5100
    
 
5101
    // Extract relevant coefficients
 
5102
    const double coeff0_0 = coefficients0[dof][0];
 
5103
    
 
5104
    // Compute value(s)
 
5105
    *values = coeff0_0*basisvalue0;
 
5106
}
 
5107
 
 
5108
/// Evaluate all basis functions at given point in cell
 
5109
void cahnhilliard2d_0_finite_element_5::evaluate_basis_all(double* values,
 
5110
                                       const double* coordinates,
 
5111
                                       const ufc::cell& c) const
 
5112
{
 
5113
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
5114
}
 
5115
 
 
5116
/// Evaluate order n derivatives of basis function i at given point in cell
 
5117
void cahnhilliard2d_0_finite_element_5::evaluate_basis_derivatives(unsigned int i,
 
5118
                                               unsigned int n,
 
5119
                                               double* values,
 
5120
                                               const double* coordinates,
 
5121
                                               const ufc::cell& c) const
 
5122
{
 
5123
    // Extract vertex coordinates
 
5124
    const double * const * element_coordinates = c.coordinates;
 
5125
    
 
5126
    // Compute Jacobian of affine map from reference cell
 
5127
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
5128
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
5129
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
5130
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
5131
    
 
5132
    // Compute determinant of Jacobian
 
5133
    const double detJ = J_00*J_11 - J_01*J_10;
 
5134
    
 
5135
    // Compute inverse of Jacobian
 
5136
    
 
5137
    // Get coordinates and map to the reference (UFC) element
 
5138
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
5139
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
5140
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
5141
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
5142
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
5143
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
5144
    
 
5145
    // Map coordinates to the reference square
 
5146
    if (std::abs(y - 1.0) < 1e-14)
 
5147
      x = -1.0;
 
5148
    else
 
5149
      x = 2.0 *x/(1.0 - y) - 1.0;
 
5150
    y = 2.0*y - 1.0;
 
5151
    
 
5152
    // Compute number of derivatives
 
5153
    unsigned int num_derivatives = 1;
 
5154
    
 
5155
    for (unsigned int j = 0; j < n; j++)
 
5156
      num_derivatives *= 2;
 
5157
    
 
5158
    
 
5159
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
5160
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
5161
    
 
5162
    for (unsigned int j = 0; j < num_derivatives; j++)
 
5163
    {
 
5164
      combinations[j] = new unsigned int [n];
 
5165
      for (unsigned int k = 0; k < n; k++)
 
5166
        combinations[j][k] = 0;
 
5167
    }
 
5168
    
 
5169
    // Generate combinations of derivatives
 
5170
    for (unsigned int row = 1; row < num_derivatives; row++)
 
5171
    {
 
5172
      for (unsigned int num = 0; num < row; num++)
 
5173
      {
 
5174
        for (unsigned int col = n-1; col+1 > 0; col--)
 
5175
        {
 
5176
          if (combinations[row][col] + 1 > 1)
 
5177
            combinations[row][col] = 0;
 
5178
          else
 
5179
          {
 
5180
            combinations[row][col] += 1;
 
5181
            break;
 
5182
          }
 
5183
        }
 
5184
      }
 
5185
    }
 
5186
    
 
5187
    // Compute inverse of Jacobian
 
5188
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
5189
    
 
5190
    // Declare transformation matrix
 
5191
    // Declare pointer to two dimensional array and initialise
 
5192
    double **transform = new double *[num_derivatives];
 
5193
    
 
5194
    for (unsigned int j = 0; j < num_derivatives; j++)
 
5195
    {
 
5196
      transform[j] = new double [num_derivatives];
 
5197
      for (unsigned int k = 0; k < num_derivatives; k++)
 
5198
        transform[j][k] = 1;
 
5199
    }
 
5200
    
 
5201
    // Construct transformation matrix
 
5202
    for (unsigned int row = 0; row < num_derivatives; row++)
 
5203
    {
 
5204
      for (unsigned int col = 0; col < num_derivatives; col++)
 
5205
      {
 
5206
        for (unsigned int k = 0; k < n; k++)
 
5207
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
5208
      }
 
5209
    }
 
5210
    
 
5211
    // Reset values
 
5212
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
 
5213
      values[j] = 0;
 
5214
    
 
5215
    // Map degree of freedom to element degree of freedom
 
5216
    const unsigned int dof = i;
 
5217
    
 
5218
    // Generate scalings
 
5219
    const double scalings_y_0 = 1;
 
5220
    
 
5221
    // Compute psitilde_a
 
5222
    const double psitilde_a_0 = 1;
 
5223
    
 
5224
    // Compute psitilde_bs
 
5225
    const double psitilde_bs_0_0 = 1;
 
5226
    
 
5227
    // Compute basisvalues
 
5228
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
5229
    
 
5230
    // Table(s) of coefficients
 
5231
    static const double coefficients0[1][1] = \
 
5232
    {{1.41421356237309}};
 
5233
    
 
5234
    // Interesting (new) part
 
5235
    // Tables of derivatives of the polynomial base (transpose)
 
5236
    static const double dmats0[1][1] = \
 
5237
    {{0}};
 
5238
    
 
5239
    static const double dmats1[1][1] = \
 
5240
    {{0}};
 
5241
    
 
5242
    // Compute reference derivatives
 
5243
    // Declare pointer to array of derivatives on FIAT element
 
5244
    double *derivatives = new double [num_derivatives];
 
5245
    
 
5246
    // Declare coefficients
 
5247
    double coeff0_0 = 0;
 
5248
    
 
5249
    // Declare new coefficients
 
5250
    double new_coeff0_0 = 0;
 
5251
    
 
5252
    // Loop possible derivatives
 
5253
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
5254
    {
 
5255
      // Get values from coefficients array
 
5256
      new_coeff0_0 = coefficients0[dof][0];
 
5257
    
 
5258
      // Loop derivative order
 
5259
      for (unsigned int j = 0; j < n; j++)
 
5260
      {
 
5261
        // Update old coefficients
 
5262
        coeff0_0 = new_coeff0_0;
 
5263
    
 
5264
        if(combinations[deriv_num][j] == 0)
 
5265
        {
 
5266
          new_coeff0_0 = coeff0_0*dmats0[0][0];
 
5267
        }
 
5268
        if(combinations[deriv_num][j] == 1)
 
5269
        {
 
5270
          new_coeff0_0 = coeff0_0*dmats1[0][0];
 
5271
        }
 
5272
    
 
5273
      }
 
5274
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
5275
      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
 
5276
    }
 
5277
    
 
5278
    // Transform derivatives back to physical element
 
5279
    for (unsigned int row = 0; row < num_derivatives; row++)
 
5280
    {
 
5281
      for (unsigned int col = 0; col < num_derivatives; col++)
 
5282
      {
 
5283
        values[row] += transform[row][col]*derivatives[col];
 
5284
      }
 
5285
    }
 
5286
    // Delete pointer to array of derivatives on FIAT element
 
5287
    delete [] derivatives;
 
5288
    
 
5289
    // Delete pointer to array of combinations of derivatives and transform
 
5290
    for (unsigned int row = 0; row < num_derivatives; row++)
 
5291
    {
 
5292
      delete [] combinations[row];
 
5293
      delete [] transform[row];
 
5294
    }
 
5295
    
 
5296
    delete [] combinations;
 
5297
    delete [] transform;
 
5298
}
 
5299
 
 
5300
/// Evaluate order n derivatives of all basis functions at given point in cell
 
5301
void cahnhilliard2d_0_finite_element_5::evaluate_basis_derivatives_all(unsigned int n,
 
5302
                                                   double* values,
 
5303
                                                   const double* coordinates,
 
5304
                                                   const ufc::cell& c) const
 
5305
{
 
5306
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
5307
}
 
5308
 
 
5309
/// Evaluate linear functional for dof i on the function f
 
5310
double cahnhilliard2d_0_finite_element_5::evaluate_dof(unsigned int i,
 
5311
                                   const ufc::function& f,
 
5312
                                   const ufc::cell& c) const
 
5313
{
 
5314
    // The reference points, direction and weights:
 
5315
    static const double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
 
5316
    static const double W[1][1] = {{1}};
 
5317
    static const double D[1][1][1] = {{{1}}};
 
5318
    
 
5319
    const double * const * x = c.coordinates;
 
5320
    double result = 0.0;
 
5321
    // Iterate over the points:
 
5322
    // Evaluate basis functions for affine mapping
 
5323
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
5324
    const double w1 = X[i][0][0];
 
5325
    const double w2 = X[i][0][1];
 
5326
    
 
5327
    // Compute affine mapping y = F(X)
 
5328
    double y[2];
 
5329
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
5330
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
5331
    
 
5332
    // Evaluate function at physical points
 
5333
    double values[1];
 
5334
    f.evaluate(values, y, c);
 
5335
    
 
5336
    // Map function values using appropriate mapping
 
5337
    // Affine map: Do nothing
 
5338
    
 
5339
    // Note that we do not map the weights (yet).
 
5340
    
 
5341
    // Take directional components
 
5342
    for(int k = 0; k < 1; k++)
 
5343
      result += values[k]*D[i][0][k];
 
5344
    // Multiply by weights
 
5345
    result *= W[i][0];
 
5346
    
 
5347
    return result;
 
5348
}
 
5349
 
 
5350
/// Evaluate linear functionals for all dofs on the function f
 
5351
void cahnhilliard2d_0_finite_element_5::evaluate_dofs(double* values,
 
5352
                                  const ufc::function& f,
 
5353
                                  const ufc::cell& c) const
 
5354
{
 
5355
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
5356
}
 
5357
 
 
5358
/// Interpolate vertex values from dof values
 
5359
void cahnhilliard2d_0_finite_element_5::interpolate_vertex_values(double* vertex_values,
 
5360
                                              const double* dof_values,
 
5361
                                              const ufc::cell& c) const
 
5362
{
 
5363
    // Evaluate at vertices and use affine mapping
 
5364
    vertex_values[0] = dof_values[0];
 
5365
    vertex_values[1] = dof_values[0];
 
5366
    vertex_values[2] = dof_values[0];
 
5367
}
 
5368
 
 
5369
/// Return the number of sub elements (for a mixed element)
 
5370
unsigned int cahnhilliard2d_0_finite_element_5::num_sub_elements() const
 
5371
{
 
5372
    return 1;
 
5373
}
 
5374
 
 
5375
/// Create a new finite element for sub element i (for a mixed element)
 
5376
ufc::finite_element* cahnhilliard2d_0_finite_element_5::create_sub_element(unsigned int i) const
 
5377
{
 
5378
    return new cahnhilliard2d_0_finite_element_5();
 
5379
}
 
5380
 
 
5381
 
 
5382
/// Constructor
 
5383
cahnhilliard2d_0_finite_element_6::cahnhilliard2d_0_finite_element_6() : ufc::finite_element()
 
5384
{
 
5385
    // Do nothing
 
5386
}
 
5387
 
 
5388
/// Destructor
 
5389
cahnhilliard2d_0_finite_element_6::~cahnhilliard2d_0_finite_element_6()
 
5390
{
 
5391
    // Do nothing
 
5392
}
 
5393
 
 
5394
/// Return a string identifying the finite element
 
5395
const char* cahnhilliard2d_0_finite_element_6::signature() const
 
5396
{
 
5397
    return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
 
5398
}
 
5399
 
 
5400
/// Return the cell shape
 
5401
ufc::shape cahnhilliard2d_0_finite_element_6::cell_shape() const
 
5402
{
 
5403
    return ufc::triangle;
 
5404
}
 
5405
 
 
5406
/// Return the dimension of the finite element function space
 
5407
unsigned int cahnhilliard2d_0_finite_element_6::space_dimension() const
 
5408
{
 
5409
    return 1;
 
5410
}
 
5411
 
 
5412
/// Return the rank of the value space
 
5413
unsigned int cahnhilliard2d_0_finite_element_6::value_rank() const
 
5414
{
 
5415
    return 0;
 
5416
}
 
5417
 
 
5418
/// Return the dimension of the value space for axis i
 
5419
unsigned int cahnhilliard2d_0_finite_element_6::value_dimension(unsigned int i) const
 
5420
{
 
5421
    return 1;
 
5422
}
 
5423
 
 
5424
/// Evaluate basis function i at given point in cell
 
5425
void cahnhilliard2d_0_finite_element_6::evaluate_basis(unsigned int i,
 
5426
                                   double* values,
 
5427
                                   const double* coordinates,
 
5428
                                   const ufc::cell& c) const
 
5429
{
 
5430
    // Extract vertex coordinates
 
5431
    const double * const * element_coordinates = c.coordinates;
 
5432
    
 
5433
    // Compute Jacobian of affine map from reference cell
 
5434
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
5435
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
5436
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
5437
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
5438
    
 
5439
    // Compute determinant of Jacobian
 
5440
    const double detJ = J_00*J_11 - J_01*J_10;
 
5441
    
 
5442
    // Compute inverse of Jacobian
 
5443
    
 
5444
    // Get coordinates and map to the reference (UFC) element
 
5445
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
5446
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
5447
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
5448
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
5449
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
5450
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
5451
    
 
5452
    // Map coordinates to the reference square
 
5453
    if (std::abs(y - 1.0) < 1e-14)
 
5454
      x = -1.0;
 
5455
    else
 
5456
      x = 2.0 *x/(1.0 - y) - 1.0;
 
5457
    y = 2.0*y - 1.0;
 
5458
    
 
5459
    // Reset values
 
5460
    *values = 0;
 
5461
    
 
5462
    // Map degree of freedom to element degree of freedom
 
5463
    const unsigned int dof = i;
 
5464
    
 
5465
    // Generate scalings
 
5466
    const double scalings_y_0 = 1;
 
5467
    
 
5468
    // Compute psitilde_a
 
5469
    const double psitilde_a_0 = 1;
 
5470
    
 
5471
    // Compute psitilde_bs
 
5472
    const double psitilde_bs_0_0 = 1;
 
5473
    
 
5474
    // Compute basisvalues
 
5475
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
5476
    
 
5477
    // Table(s) of coefficients
 
5478
    static const double coefficients0[1][1] = \
 
5479
    {{1.41421356237309}};
 
5480
    
 
5481
    // Extract relevant coefficients
 
5482
    const double coeff0_0 = coefficients0[dof][0];
 
5483
    
 
5484
    // Compute value(s)
 
5485
    *values = coeff0_0*basisvalue0;
 
5486
}
 
5487
 
 
5488
/// Evaluate all basis functions at given point in cell
 
5489
void cahnhilliard2d_0_finite_element_6::evaluate_basis_all(double* values,
 
5490
                                       const double* coordinates,
 
5491
                                       const ufc::cell& c) const
 
5492
{
 
5493
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
5494
}
 
5495
 
 
5496
/// Evaluate order n derivatives of basis function i at given point in cell
 
5497
void cahnhilliard2d_0_finite_element_6::evaluate_basis_derivatives(unsigned int i,
 
5498
                                               unsigned int n,
 
5499
                                               double* values,
 
5500
                                               const double* coordinates,
 
5501
                                               const ufc::cell& c) const
 
5502
{
 
5503
    // Extract vertex coordinates
 
5504
    const double * const * element_coordinates = c.coordinates;
 
5505
    
 
5506
    // Compute Jacobian of affine map from reference cell
 
5507
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
5508
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
5509
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
5510
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
5511
    
 
5512
    // Compute determinant of Jacobian
 
5513
    const double detJ = J_00*J_11 - J_01*J_10;
 
5514
    
 
5515
    // Compute inverse of Jacobian
 
5516
    
 
5517
    // Get coordinates and map to the reference (UFC) element
 
5518
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
5519
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
5520
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
5521
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
5522
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
5523
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
5524
    
 
5525
    // Map coordinates to the reference square
 
5526
    if (std::abs(y - 1.0) < 1e-14)
 
5527
      x = -1.0;
 
5528
    else
 
5529
      x = 2.0 *x/(1.0 - y) - 1.0;
 
5530
    y = 2.0*y - 1.0;
 
5531
    
 
5532
    // Compute number of derivatives
 
5533
    unsigned int num_derivatives = 1;
 
5534
    
 
5535
    for (unsigned int j = 0; j < n; j++)
 
5536
      num_derivatives *= 2;
 
5537
    
 
5538
    
 
5539
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
5540
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
5541
    
 
5542
    for (unsigned int j = 0; j < num_derivatives; j++)
 
5543
    {
 
5544
      combinations[j] = new unsigned int [n];
 
5545
      for (unsigned int k = 0; k < n; k++)
 
5546
        combinations[j][k] = 0;
 
5547
    }
 
5548
    
 
5549
    // Generate combinations of derivatives
 
5550
    for (unsigned int row = 1; row < num_derivatives; row++)
 
5551
    {
 
5552
      for (unsigned int num = 0; num < row; num++)
 
5553
      {
 
5554
        for (unsigned int col = n-1; col+1 > 0; col--)
 
5555
        {
 
5556
          if (combinations[row][col] + 1 > 1)
 
5557
            combinations[row][col] = 0;
 
5558
          else
 
5559
          {
 
5560
            combinations[row][col] += 1;
 
5561
            break;
 
5562
          }
 
5563
        }
 
5564
      }
 
5565
    }
 
5566
    
 
5567
    // Compute inverse of Jacobian
 
5568
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
5569
    
 
5570
    // Declare transformation matrix
 
5571
    // Declare pointer to two dimensional array and initialise
 
5572
    double **transform = new double *[num_derivatives];
 
5573
    
 
5574
    for (unsigned int j = 0; j < num_derivatives; j++)
 
5575
    {
 
5576
      transform[j] = new double [num_derivatives];
 
5577
      for (unsigned int k = 0; k < num_derivatives; k++)
 
5578
        transform[j][k] = 1;
 
5579
    }
 
5580
    
 
5581
    // Construct transformation matrix
 
5582
    for (unsigned int row = 0; row < num_derivatives; row++)
 
5583
    {
 
5584
      for (unsigned int col = 0; col < num_derivatives; col++)
 
5585
      {
 
5586
        for (unsigned int k = 0; k < n; k++)
 
5587
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
5588
      }
 
5589
    }
 
5590
    
 
5591
    // Reset values
 
5592
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
 
5593
      values[j] = 0;
 
5594
    
 
5595
    // Map degree of freedom to element degree of freedom
 
5596
    const unsigned int dof = i;
 
5597
    
 
5598
    // Generate scalings
 
5599
    const double scalings_y_0 = 1;
 
5600
    
 
5601
    // Compute psitilde_a
 
5602
    const double psitilde_a_0 = 1;
 
5603
    
 
5604
    // Compute psitilde_bs
 
5605
    const double psitilde_bs_0_0 = 1;
 
5606
    
 
5607
    // Compute basisvalues
 
5608
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
5609
    
 
5610
    // Table(s) of coefficients
 
5611
    static const double coefficients0[1][1] = \
 
5612
    {{1.41421356237309}};
 
5613
    
 
5614
    // Interesting (new) part
 
5615
    // Tables of derivatives of the polynomial base (transpose)
 
5616
    static const double dmats0[1][1] = \
 
5617
    {{0}};
 
5618
    
 
5619
    static const double dmats1[1][1] = \
 
5620
    {{0}};
 
5621
    
 
5622
    // Compute reference derivatives
 
5623
    // Declare pointer to array of derivatives on FIAT element
 
5624
    double *derivatives = new double [num_derivatives];
 
5625
    
 
5626
    // Declare coefficients
 
5627
    double coeff0_0 = 0;
 
5628
    
 
5629
    // Declare new coefficients
 
5630
    double new_coeff0_0 = 0;
 
5631
    
 
5632
    // Loop possible derivatives
 
5633
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
5634
    {
 
5635
      // Get values from coefficients array
 
5636
      new_coeff0_0 = coefficients0[dof][0];
 
5637
    
 
5638
      // Loop derivative order
 
5639
      for (unsigned int j = 0; j < n; j++)
 
5640
      {
 
5641
        // Update old coefficients
 
5642
        coeff0_0 = new_coeff0_0;
 
5643
    
 
5644
        if(combinations[deriv_num][j] == 0)
 
5645
        {
 
5646
          new_coeff0_0 = coeff0_0*dmats0[0][0];
 
5647
        }
 
5648
        if(combinations[deriv_num][j] == 1)
 
5649
        {
 
5650
          new_coeff0_0 = coeff0_0*dmats1[0][0];
 
5651
        }
 
5652
    
 
5653
      }
 
5654
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
5655
      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
 
5656
    }
 
5657
    
 
5658
    // Transform derivatives back to physical element
 
5659
    for (unsigned int row = 0; row < num_derivatives; row++)
 
5660
    {
 
5661
      for (unsigned int col = 0; col < num_derivatives; col++)
 
5662
      {
 
5663
        values[row] += transform[row][col]*derivatives[col];
 
5664
      }
 
5665
    }
 
5666
    // Delete pointer to array of derivatives on FIAT element
 
5667
    delete [] derivatives;
 
5668
    
 
5669
    // Delete pointer to array of combinations of derivatives and transform
 
5670
    for (unsigned int row = 0; row < num_derivatives; row++)
 
5671
    {
 
5672
      delete [] combinations[row];
 
5673
      delete [] transform[row];
 
5674
    }
 
5675
    
 
5676
    delete [] combinations;
 
5677
    delete [] transform;
 
5678
}
 
5679
 
 
5680
/// Evaluate order n derivatives of all basis functions at given point in cell
 
5681
void cahnhilliard2d_0_finite_element_6::evaluate_basis_derivatives_all(unsigned int n,
 
5682
                                                   double* values,
 
5683
                                                   const double* coordinates,
 
5684
                                                   const ufc::cell& c) const
 
5685
{
 
5686
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
5687
}
 
5688
 
 
5689
/// Evaluate linear functional for dof i on the function f
 
5690
double cahnhilliard2d_0_finite_element_6::evaluate_dof(unsigned int i,
 
5691
                                   const ufc::function& f,
 
5692
                                   const ufc::cell& c) const
 
5693
{
 
5694
    // The reference points, direction and weights:
 
5695
    static const double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
 
5696
    static const double W[1][1] = {{1}};
 
5697
    static const double D[1][1][1] = {{{1}}};
 
5698
    
 
5699
    const double * const * x = c.coordinates;
 
5700
    double result = 0.0;
 
5701
    // Iterate over the points:
 
5702
    // Evaluate basis functions for affine mapping
 
5703
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
5704
    const double w1 = X[i][0][0];
 
5705
    const double w2 = X[i][0][1];
 
5706
    
 
5707
    // Compute affine mapping y = F(X)
 
5708
    double y[2];
 
5709
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
5710
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
5711
    
 
5712
    // Evaluate function at physical points
 
5713
    double values[1];
 
5714
    f.evaluate(values, y, c);
 
5715
    
 
5716
    // Map function values using appropriate mapping
 
5717
    // Affine map: Do nothing
 
5718
    
 
5719
    // Note that we do not map the weights (yet).
 
5720
    
 
5721
    // Take directional components
 
5722
    for(int k = 0; k < 1; k++)
 
5723
      result += values[k]*D[i][0][k];
 
5724
    // Multiply by weights
 
5725
    result *= W[i][0];
 
5726
    
 
5727
    return result;
 
5728
}
 
5729
 
 
5730
/// Evaluate linear functionals for all dofs on the function f
 
5731
void cahnhilliard2d_0_finite_element_6::evaluate_dofs(double* values,
 
5732
                                  const ufc::function& f,
 
5733
                                  const ufc::cell& c) const
 
5734
{
 
5735
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
5736
}
 
5737
 
 
5738
/// Interpolate vertex values from dof values
 
5739
void cahnhilliard2d_0_finite_element_6::interpolate_vertex_values(double* vertex_values,
 
5740
                                              const double* dof_values,
 
5741
                                              const ufc::cell& c) const
 
5742
{
 
5743
    // Evaluate at vertices and use affine mapping
 
5744
    vertex_values[0] = dof_values[0];
 
5745
    vertex_values[1] = dof_values[0];
 
5746
    vertex_values[2] = dof_values[0];
 
5747
}
 
5748
 
 
5749
/// Return the number of sub elements (for a mixed element)
 
5750
unsigned int cahnhilliard2d_0_finite_element_6::num_sub_elements() const
 
5751
{
 
5752
    return 1;
 
5753
}
 
5754
 
 
5755
/// Create a new finite element for sub element i (for a mixed element)
 
5756
ufc::finite_element* cahnhilliard2d_0_finite_element_6::create_sub_element(unsigned int i) const
 
5757
{
 
5758
    return new cahnhilliard2d_0_finite_element_6();
 
5759
}
 
5760
 
 
5761
/// Constructor
 
5762
cahnhilliard2d_0_dof_map_0_0::cahnhilliard2d_0_dof_map_0_0() : ufc::dof_map()
 
5763
{
 
5764
    __global_dimension = 0;
 
5765
}
 
5766
 
 
5767
/// Destructor
 
5768
cahnhilliard2d_0_dof_map_0_0::~cahnhilliard2d_0_dof_map_0_0()
 
5769
{
 
5770
    // Do nothing
 
5771
}
 
5772
 
 
5773
/// Return a string identifying the dof map
 
5774
const char* cahnhilliard2d_0_dof_map_0_0::signature() const
 
5775
{
 
5776
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
 
5777
}
 
5778
 
 
5779
/// Return true iff mesh entities of topological dimension d are needed
 
5780
bool cahnhilliard2d_0_dof_map_0_0::needs_mesh_entities(unsigned int d) const
 
5781
{
 
5782
    switch ( d )
 
5783
    {
 
5784
    case 0:
 
5785
      return true;
 
5786
      break;
 
5787
    case 1:
 
5788
      return false;
 
5789
      break;
 
5790
    case 2:
 
5791
      return false;
 
5792
      break;
 
5793
    }
 
5794
    return false;
 
5795
}
 
5796
 
 
5797
/// Initialize dof map for mesh (return true iff init_cell() is needed)
 
5798
bool cahnhilliard2d_0_dof_map_0_0::init_mesh(const ufc::mesh& m)
 
5799
{
 
5800
    __global_dimension = m.num_entities[0];
 
5801
    return false;
 
5802
}
 
5803
 
 
5804
/// Initialize dof map for given cell
 
5805
void cahnhilliard2d_0_dof_map_0_0::init_cell(const ufc::mesh& m,
 
5806
                              const ufc::cell& c)
 
5807
{
 
5808
    // Do nothing
 
5809
}
 
5810
 
 
5811
/// Finish initialization of dof map for cells
 
5812
void cahnhilliard2d_0_dof_map_0_0::init_cell_finalize()
 
5813
{
 
5814
    // Do nothing
 
5815
}
 
5816
 
 
5817
/// Return the dimension of the global finite element function space
 
5818
unsigned int cahnhilliard2d_0_dof_map_0_0::global_dimension() const
 
5819
{
 
5820
    return __global_dimension;
 
5821
}
 
5822
 
 
5823
/// Return the dimension of the local finite element function space for a cell
 
5824
unsigned int cahnhilliard2d_0_dof_map_0_0::local_dimension(const ufc::cell& c) const
 
5825
{
 
5826
    return 3;
 
5827
}
 
5828
 
 
5829
/// Return the maximum dimension of the local finite element function space
 
5830
unsigned int cahnhilliard2d_0_dof_map_0_0::max_local_dimension() const
 
5831
{
 
5832
    return 3;
 
5833
}
 
5834
 
 
5835
// Return the geometric dimension of the coordinates this dof map provides
 
5836
unsigned int cahnhilliard2d_0_dof_map_0_0::geometric_dimension() const
 
5837
{
 
5838
    return 2;
 
5839
}
 
5840
 
 
5841
/// Return the number of dofs on each cell facet
 
5842
unsigned int cahnhilliard2d_0_dof_map_0_0::num_facet_dofs() const
 
5843
{
 
5844
    return 2;
 
5845
}
 
5846
 
 
5847
/// Return the number of dofs associated with each cell entity of dimension d
 
5848
unsigned int cahnhilliard2d_0_dof_map_0_0::num_entity_dofs(unsigned int d) const
 
5849
{
 
5850
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
5851
}
 
5852
 
 
5853
/// Tabulate the local-to-global mapping of dofs on a cell
 
5854
void cahnhilliard2d_0_dof_map_0_0::tabulate_dofs(unsigned int* dofs,
 
5855
                                  const ufc::mesh& m,
 
5856
                                  const ufc::cell& c) const
 
5857
{
 
5858
    dofs[0] = c.entity_indices[0][0];
 
5859
    dofs[1] = c.entity_indices[0][1];
 
5860
    dofs[2] = c.entity_indices[0][2];
 
5861
}
 
5862
 
 
5863
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
5864
void cahnhilliard2d_0_dof_map_0_0::tabulate_facet_dofs(unsigned int* dofs,
 
5865
                                        unsigned int facet) const
 
5866
{
 
5867
    switch ( facet )
 
5868
    {
 
5869
    case 0:
 
5870
      dofs[0] = 1;
 
5871
      dofs[1] = 2;
 
5872
      break;
 
5873
    case 1:
 
5874
      dofs[0] = 0;
 
5875
      dofs[1] = 2;
 
5876
      break;
 
5877
    case 2:
 
5878
      dofs[0] = 0;
 
5879
      dofs[1] = 1;
 
5880
      break;
 
5881
    }
 
5882
}
 
5883
 
 
5884
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
5885
void cahnhilliard2d_0_dof_map_0_0::tabulate_entity_dofs(unsigned int* dofs,
 
5886
                                  unsigned int d, unsigned int i) const
 
5887
{
 
5888
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
5889
}
 
5890
 
 
5891
/// Tabulate the coordinates of all dofs on a cell
 
5892
void cahnhilliard2d_0_dof_map_0_0::tabulate_coordinates(double** coordinates,
 
5893
                                         const ufc::cell& c) const
 
5894
{
 
5895
    const double * const * x = c.coordinates;
 
5896
    coordinates[0][0] = x[0][0];
 
5897
    coordinates[0][1] = x[0][1];
 
5898
    coordinates[1][0] = x[1][0];
 
5899
    coordinates[1][1] = x[1][1];
 
5900
    coordinates[2][0] = x[2][0];
 
5901
    coordinates[2][1] = x[2][1];
 
5902
}
 
5903
 
 
5904
/// Return the number of sub dof maps (for a mixed element)
 
5905
unsigned int cahnhilliard2d_0_dof_map_0_0::num_sub_dof_maps() const
 
5906
{
 
5907
    return 1;
 
5908
}
 
5909
 
 
5910
/// Create a new dof_map for sub dof map i (for a mixed element)
 
5911
ufc::dof_map* cahnhilliard2d_0_dof_map_0_0::create_sub_dof_map(unsigned int i) const
 
5912
{
 
5913
    return new cahnhilliard2d_0_dof_map_0_0();
 
5914
}
 
5915
 
 
5916
 
 
5917
/// Constructor
 
5918
cahnhilliard2d_0_dof_map_0_1::cahnhilliard2d_0_dof_map_0_1() : ufc::dof_map()
 
5919
{
 
5920
    __global_dimension = 0;
 
5921
}
 
5922
 
 
5923
/// Destructor
 
5924
cahnhilliard2d_0_dof_map_0_1::~cahnhilliard2d_0_dof_map_0_1()
 
5925
{
 
5926
    // Do nothing
 
5927
}
 
5928
 
 
5929
/// Return a string identifying the dof map
 
5930
const char* cahnhilliard2d_0_dof_map_0_1::signature() const
 
5931
{
 
5932
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
 
5933
}
 
5934
 
 
5935
/// Return true iff mesh entities of topological dimension d are needed
 
5936
bool cahnhilliard2d_0_dof_map_0_1::needs_mesh_entities(unsigned int d) const
 
5937
{
 
5938
    switch ( d )
 
5939
    {
 
5940
    case 0:
 
5941
      return true;
 
5942
      break;
 
5943
    case 1:
 
5944
      return false;
 
5945
      break;
 
5946
    case 2:
 
5947
      return false;
 
5948
      break;
 
5949
    }
 
5950
    return false;
 
5951
}
 
5952
 
 
5953
/// Initialize dof map for mesh (return true iff init_cell() is needed)
 
5954
bool cahnhilliard2d_0_dof_map_0_1::init_mesh(const ufc::mesh& m)
 
5955
{
 
5956
    __global_dimension = m.num_entities[0];
 
5957
    return false;
 
5958
}
 
5959
 
 
5960
/// Initialize dof map for given cell
 
5961
void cahnhilliard2d_0_dof_map_0_1::init_cell(const ufc::mesh& m,
 
5962
                              const ufc::cell& c)
 
5963
{
 
5964
    // Do nothing
 
5965
}
 
5966
 
 
5967
/// Finish initialization of dof map for cells
 
5968
void cahnhilliard2d_0_dof_map_0_1::init_cell_finalize()
 
5969
{
 
5970
    // Do nothing
 
5971
}
 
5972
 
 
5973
/// Return the dimension of the global finite element function space
 
5974
unsigned int cahnhilliard2d_0_dof_map_0_1::global_dimension() const
 
5975
{
 
5976
    return __global_dimension;
 
5977
}
 
5978
 
 
5979
/// Return the dimension of the local finite element function space for a cell
 
5980
unsigned int cahnhilliard2d_0_dof_map_0_1::local_dimension(const ufc::cell& c) const
 
5981
{
 
5982
    return 3;
 
5983
}
 
5984
 
 
5985
/// Return the maximum dimension of the local finite element function space
 
5986
unsigned int cahnhilliard2d_0_dof_map_0_1::max_local_dimension() const
 
5987
{
 
5988
    return 3;
 
5989
}
 
5990
 
 
5991
// Return the geometric dimension of the coordinates this dof map provides
 
5992
unsigned int cahnhilliard2d_0_dof_map_0_1::geometric_dimension() const
 
5993
{
 
5994
    return 2;
 
5995
}
 
5996
 
 
5997
/// Return the number of dofs on each cell facet
 
5998
unsigned int cahnhilliard2d_0_dof_map_0_1::num_facet_dofs() const
 
5999
{
 
6000
    return 2;
 
6001
}
 
6002
 
 
6003
/// Return the number of dofs associated with each cell entity of dimension d
 
6004
unsigned int cahnhilliard2d_0_dof_map_0_1::num_entity_dofs(unsigned int d) const
 
6005
{
 
6006
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
6007
}
 
6008
 
 
6009
/// Tabulate the local-to-global mapping of dofs on a cell
 
6010
void cahnhilliard2d_0_dof_map_0_1::tabulate_dofs(unsigned int* dofs,
 
6011
                                  const ufc::mesh& m,
 
6012
                                  const ufc::cell& c) const
 
6013
{
 
6014
    dofs[0] = c.entity_indices[0][0];
 
6015
    dofs[1] = c.entity_indices[0][1];
 
6016
    dofs[2] = c.entity_indices[0][2];
 
6017
}
 
6018
 
 
6019
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
6020
void cahnhilliard2d_0_dof_map_0_1::tabulate_facet_dofs(unsigned int* dofs,
 
6021
                                        unsigned int facet) const
 
6022
{
 
6023
    switch ( facet )
 
6024
    {
 
6025
    case 0:
 
6026
      dofs[0] = 1;
 
6027
      dofs[1] = 2;
 
6028
      break;
 
6029
    case 1:
 
6030
      dofs[0] = 0;
 
6031
      dofs[1] = 2;
 
6032
      break;
 
6033
    case 2:
 
6034
      dofs[0] = 0;
 
6035
      dofs[1] = 1;
 
6036
      break;
 
6037
    }
 
6038
}
 
6039
 
 
6040
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
6041
void cahnhilliard2d_0_dof_map_0_1::tabulate_entity_dofs(unsigned int* dofs,
 
6042
                                  unsigned int d, unsigned int i) const
 
6043
{
 
6044
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
6045
}
 
6046
 
 
6047
/// Tabulate the coordinates of all dofs on a cell
 
6048
void cahnhilliard2d_0_dof_map_0_1::tabulate_coordinates(double** coordinates,
 
6049
                                         const ufc::cell& c) const
 
6050
{
 
6051
    const double * const * x = c.coordinates;
 
6052
    coordinates[0][0] = x[0][0];
 
6053
    coordinates[0][1] = x[0][1];
 
6054
    coordinates[1][0] = x[1][0];
 
6055
    coordinates[1][1] = x[1][1];
 
6056
    coordinates[2][0] = x[2][0];
 
6057
    coordinates[2][1] = x[2][1];
 
6058
}
 
6059
 
 
6060
/// Return the number of sub dof maps (for a mixed element)
 
6061
unsigned int cahnhilliard2d_0_dof_map_0_1::num_sub_dof_maps() const
 
6062
{
 
6063
    return 1;
 
6064
}
 
6065
 
 
6066
/// Create a new dof_map for sub dof map i (for a mixed element)
 
6067
ufc::dof_map* cahnhilliard2d_0_dof_map_0_1::create_sub_dof_map(unsigned int i) const
 
6068
{
 
6069
    return new cahnhilliard2d_0_dof_map_0_1();
 
6070
}
 
6071
 
 
6072
 
 
6073
/// Constructor
 
6074
cahnhilliard2d_0_dof_map_0::cahnhilliard2d_0_dof_map_0() : ufc::dof_map()
 
6075
{
 
6076
    __global_dimension = 0;
 
6077
}
 
6078
 
 
6079
/// Destructor
 
6080
cahnhilliard2d_0_dof_map_0::~cahnhilliard2d_0_dof_map_0()
 
6081
{
 
6082
    // Do nothing
 
6083
}
 
6084
 
 
6085
/// Return a string identifying the dof map
 
6086
const char* cahnhilliard2d_0_dof_map_0::signature() const
 
6087
{
 
6088
    return "FFC dof map for MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
 
6089
}
 
6090
 
 
6091
/// Return true iff mesh entities of topological dimension d are needed
 
6092
bool cahnhilliard2d_0_dof_map_0::needs_mesh_entities(unsigned int d) const
 
6093
{
 
6094
    switch ( d )
 
6095
    {
 
6096
    case 0:
 
6097
      return true;
 
6098
      break;
 
6099
    case 1:
 
6100
      return false;
 
6101
      break;
 
6102
    case 2:
 
6103
      return false;
 
6104
      break;
 
6105
    }
 
6106
    return false;
 
6107
}
 
6108
 
 
6109
/// Initialize dof map for mesh (return true iff init_cell() is needed)
 
6110
bool cahnhilliard2d_0_dof_map_0::init_mesh(const ufc::mesh& m)
 
6111
{
 
6112
    __global_dimension = 2*m.num_entities[0];
 
6113
    return false;
 
6114
}
 
6115
 
 
6116
/// Initialize dof map for given cell
 
6117
void cahnhilliard2d_0_dof_map_0::init_cell(const ufc::mesh& m,
 
6118
                              const ufc::cell& c)
 
6119
{
 
6120
    // Do nothing
 
6121
}
 
6122
 
 
6123
/// Finish initialization of dof map for cells
 
6124
void cahnhilliard2d_0_dof_map_0::init_cell_finalize()
 
6125
{
 
6126
    // Do nothing
 
6127
}
 
6128
 
 
6129
/// Return the dimension of the global finite element function space
 
6130
unsigned int cahnhilliard2d_0_dof_map_0::global_dimension() const
 
6131
{
 
6132
    return __global_dimension;
 
6133
}
 
6134
 
 
6135
/// Return the dimension of the local finite element function space for a cell
 
6136
unsigned int cahnhilliard2d_0_dof_map_0::local_dimension(const ufc::cell& c) const
 
6137
{
 
6138
    return 6;
 
6139
}
 
6140
 
 
6141
/// Return the maximum dimension of the local finite element function space
 
6142
unsigned int cahnhilliard2d_0_dof_map_0::max_local_dimension() const
 
6143
{
 
6144
    return 6;
 
6145
}
 
6146
 
 
6147
// Return the geometric dimension of the coordinates this dof map provides
 
6148
unsigned int cahnhilliard2d_0_dof_map_0::geometric_dimension() const
 
6149
{
 
6150
    return 2;
 
6151
}
 
6152
 
 
6153
/// Return the number of dofs on each cell facet
 
6154
unsigned int cahnhilliard2d_0_dof_map_0::num_facet_dofs() const
 
6155
{
 
6156
    return 4;
 
6157
}
 
6158
 
 
6159
/// Return the number of dofs associated with each cell entity of dimension d
 
6160
unsigned int cahnhilliard2d_0_dof_map_0::num_entity_dofs(unsigned int d) const
 
6161
{
 
6162
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
6163
}
 
6164
 
 
6165
/// Tabulate the local-to-global mapping of dofs on a cell
 
6166
void cahnhilliard2d_0_dof_map_0::tabulate_dofs(unsigned int* dofs,
 
6167
                                  const ufc::mesh& m,
 
6168
                                  const ufc::cell& c) const
 
6169
{
 
6170
    dofs[0] = c.entity_indices[0][0];
 
6171
    dofs[1] = c.entity_indices[0][1];
 
6172
    dofs[2] = c.entity_indices[0][2];
 
6173
    unsigned int offset = m.num_entities[0];
 
6174
    dofs[3] = offset + c.entity_indices[0][0];
 
6175
    dofs[4] = offset + c.entity_indices[0][1];
 
6176
    dofs[5] = offset + c.entity_indices[0][2];
 
6177
}
 
6178
 
 
6179
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
6180
void cahnhilliard2d_0_dof_map_0::tabulate_facet_dofs(unsigned int* dofs,
 
6181
                                        unsigned int facet) const
 
6182
{
 
6183
    switch ( facet )
 
6184
    {
 
6185
    case 0:
 
6186
      dofs[0] = 1;
 
6187
      dofs[1] = 2;
 
6188
      dofs[2] = 4;
 
6189
      dofs[3] = 5;
 
6190
      break;
 
6191
    case 1:
 
6192
      dofs[0] = 0;
 
6193
      dofs[1] = 2;
 
6194
      dofs[2] = 3;
 
6195
      dofs[3] = 5;
 
6196
      break;
 
6197
    case 2:
 
6198
      dofs[0] = 0;
 
6199
      dofs[1] = 1;
 
6200
      dofs[2] = 3;
 
6201
      dofs[3] = 4;
 
6202
      break;
 
6203
    }
 
6204
}
 
6205
 
 
6206
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
6207
void cahnhilliard2d_0_dof_map_0::tabulate_entity_dofs(unsigned int* dofs,
 
6208
                                  unsigned int d, unsigned int i) const
 
6209
{
 
6210
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
6211
}
 
6212
 
 
6213
/// Tabulate the coordinates of all dofs on a cell
 
6214
void cahnhilliard2d_0_dof_map_0::tabulate_coordinates(double** coordinates,
 
6215
                                         const ufc::cell& c) const
 
6216
{
 
6217
    const double * const * x = c.coordinates;
 
6218
    coordinates[0][0] = x[0][0];
 
6219
    coordinates[0][1] = x[0][1];
 
6220
    coordinates[1][0] = x[1][0];
 
6221
    coordinates[1][1] = x[1][1];
 
6222
    coordinates[2][0] = x[2][0];
 
6223
    coordinates[2][1] = x[2][1];
 
6224
    coordinates[3][0] = x[0][0];
 
6225
    coordinates[3][1] = x[0][1];
 
6226
    coordinates[4][0] = x[1][0];
 
6227
    coordinates[4][1] = x[1][1];
 
6228
    coordinates[5][0] = x[2][0];
 
6229
    coordinates[5][1] = x[2][1];
 
6230
}
 
6231
 
 
6232
/// Return the number of sub dof maps (for a mixed element)
 
6233
unsigned int cahnhilliard2d_0_dof_map_0::num_sub_dof_maps() const
 
6234
{
 
6235
    return 2;
 
6236
}
 
6237
 
 
6238
/// Create a new dof_map for sub dof map i (for a mixed element)
 
6239
ufc::dof_map* cahnhilliard2d_0_dof_map_0::create_sub_dof_map(unsigned int i) const
 
6240
{
 
6241
    switch ( i )
 
6242
    {
 
6243
    case 0:
 
6244
      return new cahnhilliard2d_0_dof_map_0_0();
 
6245
      break;
 
6246
    case 1:
 
6247
      return new cahnhilliard2d_0_dof_map_0_1();
 
6248
      break;
 
6249
    }
 
6250
    return 0;
 
6251
}
 
6252
 
 
6253
 
 
6254
/// Constructor
 
6255
cahnhilliard2d_0_dof_map_1_0::cahnhilliard2d_0_dof_map_1_0() : ufc::dof_map()
 
6256
{
 
6257
    __global_dimension = 0;
 
6258
}
 
6259
 
 
6260
/// Destructor
 
6261
cahnhilliard2d_0_dof_map_1_0::~cahnhilliard2d_0_dof_map_1_0()
 
6262
{
 
6263
    // Do nothing
 
6264
}
 
6265
 
 
6266
/// Return a string identifying the dof map
 
6267
const char* cahnhilliard2d_0_dof_map_1_0::signature() const
 
6268
{
 
6269
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
 
6270
}
 
6271
 
 
6272
/// Return true iff mesh entities of topological dimension d are needed
 
6273
bool cahnhilliard2d_0_dof_map_1_0::needs_mesh_entities(unsigned int d) const
 
6274
{
 
6275
    switch ( d )
 
6276
    {
 
6277
    case 0:
 
6278
      return true;
 
6279
      break;
 
6280
    case 1:
 
6281
      return false;
 
6282
      break;
 
6283
    case 2:
 
6284
      return false;
 
6285
      break;
 
6286
    }
 
6287
    return false;
 
6288
}
 
6289
 
 
6290
/// Initialize dof map for mesh (return true iff init_cell() is needed)
 
6291
bool cahnhilliard2d_0_dof_map_1_0::init_mesh(const ufc::mesh& m)
 
6292
{
 
6293
    __global_dimension = m.num_entities[0];
 
6294
    return false;
 
6295
}
 
6296
 
 
6297
/// Initialize dof map for given cell
 
6298
void cahnhilliard2d_0_dof_map_1_0::init_cell(const ufc::mesh& m,
 
6299
                              const ufc::cell& c)
 
6300
{
 
6301
    // Do nothing
 
6302
}
 
6303
 
 
6304
/// Finish initialization of dof map for cells
 
6305
void cahnhilliard2d_0_dof_map_1_0::init_cell_finalize()
 
6306
{
 
6307
    // Do nothing
 
6308
}
 
6309
 
 
6310
/// Return the dimension of the global finite element function space
 
6311
unsigned int cahnhilliard2d_0_dof_map_1_0::global_dimension() const
 
6312
{
 
6313
    return __global_dimension;
 
6314
}
 
6315
 
 
6316
/// Return the dimension of the local finite element function space for a cell
 
6317
unsigned int cahnhilliard2d_0_dof_map_1_0::local_dimension(const ufc::cell& c) const
 
6318
{
 
6319
    return 3;
 
6320
}
 
6321
 
 
6322
/// Return the maximum dimension of the local finite element function space
 
6323
unsigned int cahnhilliard2d_0_dof_map_1_0::max_local_dimension() const
 
6324
{
 
6325
    return 3;
 
6326
}
 
6327
 
 
6328
// Return the geometric dimension of the coordinates this dof map provides
 
6329
unsigned int cahnhilliard2d_0_dof_map_1_0::geometric_dimension() const
 
6330
{
 
6331
    return 2;
 
6332
}
 
6333
 
 
6334
/// Return the number of dofs on each cell facet
 
6335
unsigned int cahnhilliard2d_0_dof_map_1_0::num_facet_dofs() const
 
6336
{
 
6337
    return 2;
 
6338
}
 
6339
 
 
6340
/// Return the number of dofs associated with each cell entity of dimension d
 
6341
unsigned int cahnhilliard2d_0_dof_map_1_0::num_entity_dofs(unsigned int d) const
 
6342
{
 
6343
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
6344
}
 
6345
 
 
6346
/// Tabulate the local-to-global mapping of dofs on a cell
 
6347
void cahnhilliard2d_0_dof_map_1_0::tabulate_dofs(unsigned int* dofs,
 
6348
                                  const ufc::mesh& m,
 
6349
                                  const ufc::cell& c) const
 
6350
{
 
6351
    dofs[0] = c.entity_indices[0][0];
 
6352
    dofs[1] = c.entity_indices[0][1];
 
6353
    dofs[2] = c.entity_indices[0][2];
 
6354
}
 
6355
 
 
6356
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
6357
void cahnhilliard2d_0_dof_map_1_0::tabulate_facet_dofs(unsigned int* dofs,
 
6358
                                        unsigned int facet) const
 
6359
{
 
6360
    switch ( facet )
 
6361
    {
 
6362
    case 0:
 
6363
      dofs[0] = 1;
 
6364
      dofs[1] = 2;
 
6365
      break;
 
6366
    case 1:
 
6367
      dofs[0] = 0;
 
6368
      dofs[1] = 2;
 
6369
      break;
 
6370
    case 2:
 
6371
      dofs[0] = 0;
 
6372
      dofs[1] = 1;
 
6373
      break;
 
6374
    }
 
6375
}
 
6376
 
 
6377
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
6378
void cahnhilliard2d_0_dof_map_1_0::tabulate_entity_dofs(unsigned int* dofs,
 
6379
                                  unsigned int d, unsigned int i) const
 
6380
{
 
6381
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
6382
}
 
6383
 
 
6384
/// Tabulate the coordinates of all dofs on a cell
 
6385
void cahnhilliard2d_0_dof_map_1_0::tabulate_coordinates(double** coordinates,
 
6386
                                         const ufc::cell& c) const
 
6387
{
 
6388
    const double * const * x = c.coordinates;
 
6389
    coordinates[0][0] = x[0][0];
 
6390
    coordinates[0][1] = x[0][1];
 
6391
    coordinates[1][0] = x[1][0];
 
6392
    coordinates[1][1] = x[1][1];
 
6393
    coordinates[2][0] = x[2][0];
 
6394
    coordinates[2][1] = x[2][1];
 
6395
}
 
6396
 
 
6397
/// Return the number of sub dof maps (for a mixed element)
 
6398
unsigned int cahnhilliard2d_0_dof_map_1_0::num_sub_dof_maps() const
 
6399
{
 
6400
    return 1;
 
6401
}
 
6402
 
 
6403
/// Create a new dof_map for sub dof map i (for a mixed element)
 
6404
ufc::dof_map* cahnhilliard2d_0_dof_map_1_0::create_sub_dof_map(unsigned int i) const
 
6405
{
 
6406
    return new cahnhilliard2d_0_dof_map_1_0();
 
6407
}
 
6408
 
 
6409
 
 
6410
/// Constructor
 
6411
cahnhilliard2d_0_dof_map_1_1::cahnhilliard2d_0_dof_map_1_1() : ufc::dof_map()
 
6412
{
 
6413
    __global_dimension = 0;
 
6414
}
 
6415
 
 
6416
/// Destructor
 
6417
cahnhilliard2d_0_dof_map_1_1::~cahnhilliard2d_0_dof_map_1_1()
 
6418
{
 
6419
    // Do nothing
 
6420
}
 
6421
 
 
6422
/// Return a string identifying the dof map
 
6423
const char* cahnhilliard2d_0_dof_map_1_1::signature() const
 
6424
{
 
6425
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
 
6426
}
 
6427
 
 
6428
/// Return true iff mesh entities of topological dimension d are needed
 
6429
bool cahnhilliard2d_0_dof_map_1_1::needs_mesh_entities(unsigned int d) const
 
6430
{
 
6431
    switch ( d )
 
6432
    {
 
6433
    case 0:
 
6434
      return true;
 
6435
      break;
 
6436
    case 1:
 
6437
      return false;
 
6438
      break;
 
6439
    case 2:
 
6440
      return false;
 
6441
      break;
 
6442
    }
 
6443
    return false;
 
6444
}
 
6445
 
 
6446
/// Initialize dof map for mesh (return true iff init_cell() is needed)
 
6447
bool cahnhilliard2d_0_dof_map_1_1::init_mesh(const ufc::mesh& m)
 
6448
{
 
6449
    __global_dimension = m.num_entities[0];
 
6450
    return false;
 
6451
}
 
6452
 
 
6453
/// Initialize dof map for given cell
 
6454
void cahnhilliard2d_0_dof_map_1_1::init_cell(const ufc::mesh& m,
 
6455
                              const ufc::cell& c)
 
6456
{
 
6457
    // Do nothing
 
6458
}
 
6459
 
 
6460
/// Finish initialization of dof map for cells
 
6461
void cahnhilliard2d_0_dof_map_1_1::init_cell_finalize()
 
6462
{
 
6463
    // Do nothing
 
6464
}
 
6465
 
 
6466
/// Return the dimension of the global finite element function space
 
6467
unsigned int cahnhilliard2d_0_dof_map_1_1::global_dimension() const
 
6468
{
 
6469
    return __global_dimension;
 
6470
}
 
6471
 
 
6472
/// Return the dimension of the local finite element function space for a cell
 
6473
unsigned int cahnhilliard2d_0_dof_map_1_1::local_dimension(const ufc::cell& c) const
 
6474
{
 
6475
    return 3;
 
6476
}
 
6477
 
 
6478
/// Return the maximum dimension of the local finite element function space
 
6479
unsigned int cahnhilliard2d_0_dof_map_1_1::max_local_dimension() const
 
6480
{
 
6481
    return 3;
 
6482
}
 
6483
 
 
6484
// Return the geometric dimension of the coordinates this dof map provides
 
6485
unsigned int cahnhilliard2d_0_dof_map_1_1::geometric_dimension() const
 
6486
{
 
6487
    return 2;
 
6488
}
 
6489
 
 
6490
/// Return the number of dofs on each cell facet
 
6491
unsigned int cahnhilliard2d_0_dof_map_1_1::num_facet_dofs() const
 
6492
{
 
6493
    return 2;
 
6494
}
 
6495
 
 
6496
/// Return the number of dofs associated with each cell entity of dimension d
 
6497
unsigned int cahnhilliard2d_0_dof_map_1_1::num_entity_dofs(unsigned int d) const
 
6498
{
 
6499
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
6500
}
 
6501
 
 
6502
/// Tabulate the local-to-global mapping of dofs on a cell
 
6503
void cahnhilliard2d_0_dof_map_1_1::tabulate_dofs(unsigned int* dofs,
 
6504
                                  const ufc::mesh& m,
 
6505
                                  const ufc::cell& c) const
 
6506
{
 
6507
    dofs[0] = c.entity_indices[0][0];
 
6508
    dofs[1] = c.entity_indices[0][1];
 
6509
    dofs[2] = c.entity_indices[0][2];
 
6510
}
 
6511
 
 
6512
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
6513
void cahnhilliard2d_0_dof_map_1_1::tabulate_facet_dofs(unsigned int* dofs,
 
6514
                                        unsigned int facet) const
 
6515
{
 
6516
    switch ( facet )
 
6517
    {
 
6518
    case 0:
 
6519
      dofs[0] = 1;
 
6520
      dofs[1] = 2;
 
6521
      break;
 
6522
    case 1:
 
6523
      dofs[0] = 0;
 
6524
      dofs[1] = 2;
 
6525
      break;
 
6526
    case 2:
 
6527
      dofs[0] = 0;
 
6528
      dofs[1] = 1;
 
6529
      break;
 
6530
    }
 
6531
}
 
6532
 
 
6533
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
6534
void cahnhilliard2d_0_dof_map_1_1::tabulate_entity_dofs(unsigned int* dofs,
 
6535
                                  unsigned int d, unsigned int i) const
 
6536
{
 
6537
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
6538
}
 
6539
 
 
6540
/// Tabulate the coordinates of all dofs on a cell
 
6541
void cahnhilliard2d_0_dof_map_1_1::tabulate_coordinates(double** coordinates,
 
6542
                                         const ufc::cell& c) const
 
6543
{
 
6544
    const double * const * x = c.coordinates;
 
6545
    coordinates[0][0] = x[0][0];
 
6546
    coordinates[0][1] = x[0][1];
 
6547
    coordinates[1][0] = x[1][0];
 
6548
    coordinates[1][1] = x[1][1];
 
6549
    coordinates[2][0] = x[2][0];
 
6550
    coordinates[2][1] = x[2][1];
 
6551
}
 
6552
 
 
6553
/// Return the number of sub dof maps (for a mixed element)
 
6554
unsigned int cahnhilliard2d_0_dof_map_1_1::num_sub_dof_maps() const
 
6555
{
 
6556
    return 1;
 
6557
}
 
6558
 
 
6559
/// Create a new dof_map for sub dof map i (for a mixed element)
 
6560
ufc::dof_map* cahnhilliard2d_0_dof_map_1_1::create_sub_dof_map(unsigned int i) const
 
6561
{
 
6562
    return new cahnhilliard2d_0_dof_map_1_1();
 
6563
}
 
6564
 
 
6565
 
 
6566
/// Constructor
 
6567
cahnhilliard2d_0_dof_map_1::cahnhilliard2d_0_dof_map_1() : ufc::dof_map()
 
6568
{
 
6569
    __global_dimension = 0;
 
6570
}
 
6571
 
 
6572
/// Destructor
 
6573
cahnhilliard2d_0_dof_map_1::~cahnhilliard2d_0_dof_map_1()
 
6574
{
 
6575
    // Do nothing
 
6576
}
 
6577
 
 
6578
/// Return a string identifying the dof map
 
6579
const char* cahnhilliard2d_0_dof_map_1::signature() const
 
6580
{
 
6581
    return "FFC dof map for MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
 
6582
}
 
6583
 
 
6584
/// Return true iff mesh entities of topological dimension d are needed
 
6585
bool cahnhilliard2d_0_dof_map_1::needs_mesh_entities(unsigned int d) const
 
6586
{
 
6587
    switch ( d )
 
6588
    {
 
6589
    case 0:
 
6590
      return true;
 
6591
      break;
 
6592
    case 1:
 
6593
      return false;
 
6594
      break;
 
6595
    case 2:
 
6596
      return false;
 
6597
      break;
 
6598
    }
 
6599
    return false;
 
6600
}
 
6601
 
 
6602
/// Initialize dof map for mesh (return true iff init_cell() is needed)
 
6603
bool cahnhilliard2d_0_dof_map_1::init_mesh(const ufc::mesh& m)
 
6604
{
 
6605
    __global_dimension = 2*m.num_entities[0];
 
6606
    return false;
 
6607
}
 
6608
 
 
6609
/// Initialize dof map for given cell
 
6610
void cahnhilliard2d_0_dof_map_1::init_cell(const ufc::mesh& m,
 
6611
                              const ufc::cell& c)
 
6612
{
 
6613
    // Do nothing
 
6614
}
 
6615
 
 
6616
/// Finish initialization of dof map for cells
 
6617
void cahnhilliard2d_0_dof_map_1::init_cell_finalize()
 
6618
{
 
6619
    // Do nothing
 
6620
}
 
6621
 
 
6622
/// Return the dimension of the global finite element function space
 
6623
unsigned int cahnhilliard2d_0_dof_map_1::global_dimension() const
 
6624
{
 
6625
    return __global_dimension;
 
6626
}
 
6627
 
 
6628
/// Return the dimension of the local finite element function space for a cell
 
6629
unsigned int cahnhilliard2d_0_dof_map_1::local_dimension(const ufc::cell& c) const
 
6630
{
 
6631
    return 6;
 
6632
}
 
6633
 
 
6634
/// Return the maximum dimension of the local finite element function space
 
6635
unsigned int cahnhilliard2d_0_dof_map_1::max_local_dimension() const
 
6636
{
 
6637
    return 6;
 
6638
}
 
6639
 
 
6640
// Return the geometric dimension of the coordinates this dof map provides
 
6641
unsigned int cahnhilliard2d_0_dof_map_1::geometric_dimension() const
 
6642
{
 
6643
    return 2;
 
6644
}
 
6645
 
 
6646
/// Return the number of dofs on each cell facet
 
6647
unsigned int cahnhilliard2d_0_dof_map_1::num_facet_dofs() const
 
6648
{
 
6649
    return 4;
 
6650
}
 
6651
 
 
6652
/// Return the number of dofs associated with each cell entity of dimension d
 
6653
unsigned int cahnhilliard2d_0_dof_map_1::num_entity_dofs(unsigned int d) const
 
6654
{
 
6655
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
6656
}
 
6657
 
 
6658
/// Tabulate the local-to-global mapping of dofs on a cell
 
6659
void cahnhilliard2d_0_dof_map_1::tabulate_dofs(unsigned int* dofs,
 
6660
                                  const ufc::mesh& m,
 
6661
                                  const ufc::cell& c) const
 
6662
{
 
6663
    dofs[0] = c.entity_indices[0][0];
 
6664
    dofs[1] = c.entity_indices[0][1];
 
6665
    dofs[2] = c.entity_indices[0][2];
 
6666
    unsigned int offset = m.num_entities[0];
 
6667
    dofs[3] = offset + c.entity_indices[0][0];
 
6668
    dofs[4] = offset + c.entity_indices[0][1];
 
6669
    dofs[5] = offset + c.entity_indices[0][2];
 
6670
}
 
6671
 
 
6672
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
6673
void cahnhilliard2d_0_dof_map_1::tabulate_facet_dofs(unsigned int* dofs,
 
6674
                                        unsigned int facet) const
 
6675
{
 
6676
    switch ( facet )
 
6677
    {
 
6678
    case 0:
 
6679
      dofs[0] = 1;
 
6680
      dofs[1] = 2;
 
6681
      dofs[2] = 4;
 
6682
      dofs[3] = 5;
 
6683
      break;
 
6684
    case 1:
 
6685
      dofs[0] = 0;
 
6686
      dofs[1] = 2;
 
6687
      dofs[2] = 3;
 
6688
      dofs[3] = 5;
 
6689
      break;
 
6690
    case 2:
 
6691
      dofs[0] = 0;
 
6692
      dofs[1] = 1;
 
6693
      dofs[2] = 3;
 
6694
      dofs[3] = 4;
 
6695
      break;
 
6696
    }
 
6697
}
 
6698
 
 
6699
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
6700
void cahnhilliard2d_0_dof_map_1::tabulate_entity_dofs(unsigned int* dofs,
 
6701
                                  unsigned int d, unsigned int i) const
 
6702
{
 
6703
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
6704
}
 
6705
 
 
6706
/// Tabulate the coordinates of all dofs on a cell
 
6707
void cahnhilliard2d_0_dof_map_1::tabulate_coordinates(double** coordinates,
 
6708
                                         const ufc::cell& c) const
 
6709
{
 
6710
    const double * const * x = c.coordinates;
 
6711
    coordinates[0][0] = x[0][0];
 
6712
    coordinates[0][1] = x[0][1];
 
6713
    coordinates[1][0] = x[1][0];
 
6714
    coordinates[1][1] = x[1][1];
 
6715
    coordinates[2][0] = x[2][0];
 
6716
    coordinates[2][1] = x[2][1];
 
6717
    coordinates[3][0] = x[0][0];
 
6718
    coordinates[3][1] = x[0][1];
 
6719
    coordinates[4][0] = x[1][0];
 
6720
    coordinates[4][1] = x[1][1];
 
6721
    coordinates[5][0] = x[2][0];
 
6722
    coordinates[5][1] = x[2][1];
 
6723
}
 
6724
 
 
6725
/// Return the number of sub dof maps (for a mixed element)
 
6726
unsigned int cahnhilliard2d_0_dof_map_1::num_sub_dof_maps() const
 
6727
{
 
6728
    return 2;
 
6729
}
 
6730
 
 
6731
/// Create a new dof_map for sub dof map i (for a mixed element)
 
6732
ufc::dof_map* cahnhilliard2d_0_dof_map_1::create_sub_dof_map(unsigned int i) const
 
6733
{
 
6734
    switch ( i )
 
6735
    {
 
6736
    case 0:
 
6737
      return new cahnhilliard2d_0_dof_map_1_0();
 
6738
      break;
 
6739
    case 1:
 
6740
      return new cahnhilliard2d_0_dof_map_1_1();
 
6741
      break;
 
6742
    }
 
6743
    return 0;
 
6744
}
 
6745
 
 
6746
 
 
6747
/// Constructor
 
6748
cahnhilliard2d_0_dof_map_2_0::cahnhilliard2d_0_dof_map_2_0() : ufc::dof_map()
 
6749
{
 
6750
    __global_dimension = 0;
 
6751
}
 
6752
 
 
6753
/// Destructor
 
6754
cahnhilliard2d_0_dof_map_2_0::~cahnhilliard2d_0_dof_map_2_0()
 
6755
{
 
6756
    // Do nothing
 
6757
}
 
6758
 
 
6759
/// Return a string identifying the dof map
 
6760
const char* cahnhilliard2d_0_dof_map_2_0::signature() const
 
6761
{
 
6762
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
 
6763
}
 
6764
 
 
6765
/// Return true iff mesh entities of topological dimension d are needed
 
6766
bool cahnhilliard2d_0_dof_map_2_0::needs_mesh_entities(unsigned int d) const
 
6767
{
 
6768
    switch ( d )
 
6769
    {
 
6770
    case 0:
 
6771
      return true;
 
6772
      break;
 
6773
    case 1:
 
6774
      return false;
 
6775
      break;
 
6776
    case 2:
 
6777
      return false;
 
6778
      break;
 
6779
    }
 
6780
    return false;
 
6781
}
 
6782
 
 
6783
/// Initialize dof map for mesh (return true iff init_cell() is needed)
 
6784
bool cahnhilliard2d_0_dof_map_2_0::init_mesh(const ufc::mesh& m)
 
6785
{
 
6786
    __global_dimension = m.num_entities[0];
 
6787
    return false;
 
6788
}
 
6789
 
 
6790
/// Initialize dof map for given cell
 
6791
void cahnhilliard2d_0_dof_map_2_0::init_cell(const ufc::mesh& m,
 
6792
                              const ufc::cell& c)
 
6793
{
 
6794
    // Do nothing
 
6795
}
 
6796
 
 
6797
/// Finish initialization of dof map for cells
 
6798
void cahnhilliard2d_0_dof_map_2_0::init_cell_finalize()
 
6799
{
 
6800
    // Do nothing
 
6801
}
 
6802
 
 
6803
/// Return the dimension of the global finite element function space
 
6804
unsigned int cahnhilliard2d_0_dof_map_2_0::global_dimension() const
 
6805
{
 
6806
    return __global_dimension;
 
6807
}
 
6808
 
 
6809
/// Return the dimension of the local finite element function space for a cell
 
6810
unsigned int cahnhilliard2d_0_dof_map_2_0::local_dimension(const ufc::cell& c) const
 
6811
{
 
6812
    return 3;
 
6813
}
 
6814
 
 
6815
/// Return the maximum dimension of the local finite element function space
 
6816
unsigned int cahnhilliard2d_0_dof_map_2_0::max_local_dimension() const
 
6817
{
 
6818
    return 3;
 
6819
}
 
6820
 
 
6821
// Return the geometric dimension of the coordinates this dof map provides
 
6822
unsigned int cahnhilliard2d_0_dof_map_2_0::geometric_dimension() const
 
6823
{
 
6824
    return 2;
 
6825
}
 
6826
 
 
6827
/// Return the number of dofs on each cell facet
 
6828
unsigned int cahnhilliard2d_0_dof_map_2_0::num_facet_dofs() const
 
6829
{
 
6830
    return 2;
 
6831
}
 
6832
 
 
6833
/// Return the number of dofs associated with each cell entity of dimension d
 
6834
unsigned int cahnhilliard2d_0_dof_map_2_0::num_entity_dofs(unsigned int d) const
 
6835
{
 
6836
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
6837
}
 
6838
 
 
6839
/// Tabulate the local-to-global mapping of dofs on a cell
 
6840
void cahnhilliard2d_0_dof_map_2_0::tabulate_dofs(unsigned int* dofs,
 
6841
                                  const ufc::mesh& m,
 
6842
                                  const ufc::cell& c) const
 
6843
{
 
6844
    dofs[0] = c.entity_indices[0][0];
 
6845
    dofs[1] = c.entity_indices[0][1];
 
6846
    dofs[2] = c.entity_indices[0][2];
 
6847
}
 
6848
 
 
6849
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
6850
void cahnhilliard2d_0_dof_map_2_0::tabulate_facet_dofs(unsigned int* dofs,
 
6851
                                        unsigned int facet) const
 
6852
{
 
6853
    switch ( facet )
 
6854
    {
 
6855
    case 0:
 
6856
      dofs[0] = 1;
 
6857
      dofs[1] = 2;
 
6858
      break;
 
6859
    case 1:
 
6860
      dofs[0] = 0;
 
6861
      dofs[1] = 2;
 
6862
      break;
 
6863
    case 2:
 
6864
      dofs[0] = 0;
 
6865
      dofs[1] = 1;
 
6866
      break;
 
6867
    }
 
6868
}
 
6869
 
 
6870
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
6871
void cahnhilliard2d_0_dof_map_2_0::tabulate_entity_dofs(unsigned int* dofs,
 
6872
                                  unsigned int d, unsigned int i) const
 
6873
{
 
6874
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
6875
}
 
6876
 
 
6877
/// Tabulate the coordinates of all dofs on a cell
 
6878
void cahnhilliard2d_0_dof_map_2_0::tabulate_coordinates(double** coordinates,
 
6879
                                         const ufc::cell& c) const
 
6880
{
 
6881
    const double * const * x = c.coordinates;
 
6882
    coordinates[0][0] = x[0][0];
 
6883
    coordinates[0][1] = x[0][1];
 
6884
    coordinates[1][0] = x[1][0];
 
6885
    coordinates[1][1] = x[1][1];
 
6886
    coordinates[2][0] = x[2][0];
 
6887
    coordinates[2][1] = x[2][1];
 
6888
}
 
6889
 
 
6890
/// Return the number of sub dof maps (for a mixed element)
 
6891
unsigned int cahnhilliard2d_0_dof_map_2_0::num_sub_dof_maps() const
 
6892
{
 
6893
    return 1;
 
6894
}
 
6895
 
 
6896
/// Create a new dof_map for sub dof map i (for a mixed element)
 
6897
ufc::dof_map* cahnhilliard2d_0_dof_map_2_0::create_sub_dof_map(unsigned int i) const
 
6898
{
 
6899
    return new cahnhilliard2d_0_dof_map_2_0();
 
6900
}
 
6901
 
 
6902
 
 
6903
/// Constructor
 
6904
cahnhilliard2d_0_dof_map_2_1::cahnhilliard2d_0_dof_map_2_1() : ufc::dof_map()
 
6905
{
 
6906
    __global_dimension = 0;
 
6907
}
 
6908
 
 
6909
/// Destructor
 
6910
cahnhilliard2d_0_dof_map_2_1::~cahnhilliard2d_0_dof_map_2_1()
 
6911
{
 
6912
    // Do nothing
 
6913
}
 
6914
 
 
6915
/// Return a string identifying the dof map
 
6916
const char* cahnhilliard2d_0_dof_map_2_1::signature() const
 
6917
{
 
6918
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
 
6919
}
 
6920
 
 
6921
/// Return true iff mesh entities of topological dimension d are needed
 
6922
bool cahnhilliard2d_0_dof_map_2_1::needs_mesh_entities(unsigned int d) const
 
6923
{
 
6924
    switch ( d )
 
6925
    {
 
6926
    case 0:
 
6927
      return true;
 
6928
      break;
 
6929
    case 1:
 
6930
      return false;
 
6931
      break;
 
6932
    case 2:
 
6933
      return false;
 
6934
      break;
 
6935
    }
 
6936
    return false;
 
6937
}
 
6938
 
 
6939
/// Initialize dof map for mesh (return true iff init_cell() is needed)
 
6940
bool cahnhilliard2d_0_dof_map_2_1::init_mesh(const ufc::mesh& m)
 
6941
{
 
6942
    __global_dimension = m.num_entities[0];
 
6943
    return false;
 
6944
}
 
6945
 
 
6946
/// Initialize dof map for given cell
 
6947
void cahnhilliard2d_0_dof_map_2_1::init_cell(const ufc::mesh& m,
 
6948
                              const ufc::cell& c)
 
6949
{
 
6950
    // Do nothing
 
6951
}
 
6952
 
 
6953
/// Finish initialization of dof map for cells
 
6954
void cahnhilliard2d_0_dof_map_2_1::init_cell_finalize()
 
6955
{
 
6956
    // Do nothing
 
6957
}
 
6958
 
 
6959
/// Return the dimension of the global finite element function space
 
6960
unsigned int cahnhilliard2d_0_dof_map_2_1::global_dimension() const
 
6961
{
 
6962
    return __global_dimension;
 
6963
}
 
6964
 
 
6965
/// Return the dimension of the local finite element function space for a cell
 
6966
unsigned int cahnhilliard2d_0_dof_map_2_1::local_dimension(const ufc::cell& c) const
 
6967
{
 
6968
    return 3;
 
6969
}
 
6970
 
 
6971
/// Return the maximum dimension of the local finite element function space
 
6972
unsigned int cahnhilliard2d_0_dof_map_2_1::max_local_dimension() const
 
6973
{
 
6974
    return 3;
 
6975
}
 
6976
 
 
6977
// Return the geometric dimension of the coordinates this dof map provides
 
6978
unsigned int cahnhilliard2d_0_dof_map_2_1::geometric_dimension() const
 
6979
{
 
6980
    return 2;
 
6981
}
 
6982
 
 
6983
/// Return the number of dofs on each cell facet
 
6984
unsigned int cahnhilliard2d_0_dof_map_2_1::num_facet_dofs() const
 
6985
{
 
6986
    return 2;
 
6987
}
 
6988
 
 
6989
/// Return the number of dofs associated with each cell entity of dimension d
 
6990
unsigned int cahnhilliard2d_0_dof_map_2_1::num_entity_dofs(unsigned int d) const
 
6991
{
 
6992
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
6993
}
 
6994
 
 
6995
/// Tabulate the local-to-global mapping of dofs on a cell
 
6996
void cahnhilliard2d_0_dof_map_2_1::tabulate_dofs(unsigned int* dofs,
 
6997
                                  const ufc::mesh& m,
 
6998
                                  const ufc::cell& c) const
 
6999
{
 
7000
    dofs[0] = c.entity_indices[0][0];
 
7001
    dofs[1] = c.entity_indices[0][1];
 
7002
    dofs[2] = c.entity_indices[0][2];
 
7003
}
 
7004
 
 
7005
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
7006
void cahnhilliard2d_0_dof_map_2_1::tabulate_facet_dofs(unsigned int* dofs,
 
7007
                                        unsigned int facet) const
 
7008
{
 
7009
    switch ( facet )
 
7010
    {
 
7011
    case 0:
 
7012
      dofs[0] = 1;
 
7013
      dofs[1] = 2;
 
7014
      break;
 
7015
    case 1:
 
7016
      dofs[0] = 0;
 
7017
      dofs[1] = 2;
 
7018
      break;
 
7019
    case 2:
 
7020
      dofs[0] = 0;
 
7021
      dofs[1] = 1;
 
7022
      break;
 
7023
    }
 
7024
}
 
7025
 
 
7026
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
7027
void cahnhilliard2d_0_dof_map_2_1::tabulate_entity_dofs(unsigned int* dofs,
 
7028
                                  unsigned int d, unsigned int i) const
 
7029
{
 
7030
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
7031
}
 
7032
 
 
7033
/// Tabulate the coordinates of all dofs on a cell
 
7034
void cahnhilliard2d_0_dof_map_2_1::tabulate_coordinates(double** coordinates,
 
7035
                                         const ufc::cell& c) const
 
7036
{
 
7037
    const double * const * x = c.coordinates;
 
7038
    coordinates[0][0] = x[0][0];
 
7039
    coordinates[0][1] = x[0][1];
 
7040
    coordinates[1][0] = x[1][0];
 
7041
    coordinates[1][1] = x[1][1];
 
7042
    coordinates[2][0] = x[2][0];
 
7043
    coordinates[2][1] = x[2][1];
 
7044
}
 
7045
 
 
7046
/// Return the number of sub dof maps (for a mixed element)
 
7047
unsigned int cahnhilliard2d_0_dof_map_2_1::num_sub_dof_maps() const
 
7048
{
 
7049
    return 1;
 
7050
}
 
7051
 
 
7052
/// Create a new dof_map for sub dof map i (for a mixed element)
 
7053
ufc::dof_map* cahnhilliard2d_0_dof_map_2_1::create_sub_dof_map(unsigned int i) const
 
7054
{
 
7055
    return new cahnhilliard2d_0_dof_map_2_1();
 
7056
}
 
7057
 
 
7058
 
 
7059
/// Constructor
 
7060
cahnhilliard2d_0_dof_map_2::cahnhilliard2d_0_dof_map_2() : ufc::dof_map()
 
7061
{
 
7062
    __global_dimension = 0;
 
7063
}
 
7064
 
 
7065
/// Destructor
 
7066
cahnhilliard2d_0_dof_map_2::~cahnhilliard2d_0_dof_map_2()
 
7067
{
 
7068
    // Do nothing
 
7069
}
 
7070
 
 
7071
/// Return a string identifying the dof map
 
7072
const char* cahnhilliard2d_0_dof_map_2::signature() const
 
7073
{
 
7074
    return "FFC dof map for MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
 
7075
}
 
7076
 
 
7077
/// Return true iff mesh entities of topological dimension d are needed
 
7078
bool cahnhilliard2d_0_dof_map_2::needs_mesh_entities(unsigned int d) const
 
7079
{
 
7080
    switch ( d )
 
7081
    {
 
7082
    case 0:
 
7083
      return true;
 
7084
      break;
 
7085
    case 1:
 
7086
      return false;
 
7087
      break;
 
7088
    case 2:
 
7089
      return false;
 
7090
      break;
 
7091
    }
 
7092
    return false;
 
7093
}
 
7094
 
 
7095
/// Initialize dof map for mesh (return true iff init_cell() is needed)
 
7096
bool cahnhilliard2d_0_dof_map_2::init_mesh(const ufc::mesh& m)
 
7097
{
 
7098
    __global_dimension = 2*m.num_entities[0];
 
7099
    return false;
 
7100
}
 
7101
 
 
7102
/// Initialize dof map for given cell
 
7103
void cahnhilliard2d_0_dof_map_2::init_cell(const ufc::mesh& m,
 
7104
                              const ufc::cell& c)
 
7105
{
 
7106
    // Do nothing
 
7107
}
 
7108
 
 
7109
/// Finish initialization of dof map for cells
 
7110
void cahnhilliard2d_0_dof_map_2::init_cell_finalize()
 
7111
{
 
7112
    // Do nothing
 
7113
}
 
7114
 
 
7115
/// Return the dimension of the global finite element function space
 
7116
unsigned int cahnhilliard2d_0_dof_map_2::global_dimension() const
 
7117
{
 
7118
    return __global_dimension;
 
7119
}
 
7120
 
 
7121
/// Return the dimension of the local finite element function space for a cell
 
7122
unsigned int cahnhilliard2d_0_dof_map_2::local_dimension(const ufc::cell& c) const
 
7123
{
 
7124
    return 6;
 
7125
}
 
7126
 
 
7127
/// Return the maximum dimension of the local finite element function space
 
7128
unsigned int cahnhilliard2d_0_dof_map_2::max_local_dimension() const
 
7129
{
 
7130
    return 6;
 
7131
}
 
7132
 
 
7133
// Return the geometric dimension of the coordinates this dof map provides
 
7134
unsigned int cahnhilliard2d_0_dof_map_2::geometric_dimension() const
 
7135
{
 
7136
    return 2;
 
7137
}
 
7138
 
 
7139
/// Return the number of dofs on each cell facet
 
7140
unsigned int cahnhilliard2d_0_dof_map_2::num_facet_dofs() const
 
7141
{
 
7142
    return 4;
 
7143
}
 
7144
 
 
7145
/// Return the number of dofs associated with each cell entity of dimension d
 
7146
unsigned int cahnhilliard2d_0_dof_map_2::num_entity_dofs(unsigned int d) const
 
7147
{
 
7148
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
7149
}
 
7150
 
 
7151
/// Tabulate the local-to-global mapping of dofs on a cell
 
7152
void cahnhilliard2d_0_dof_map_2::tabulate_dofs(unsigned int* dofs,
 
7153
                                  const ufc::mesh& m,
 
7154
                                  const ufc::cell& c) const
 
7155
{
 
7156
    dofs[0] = c.entity_indices[0][0];
 
7157
    dofs[1] = c.entity_indices[0][1];
 
7158
    dofs[2] = c.entity_indices[0][2];
 
7159
    unsigned int offset = m.num_entities[0];
 
7160
    dofs[3] = offset + c.entity_indices[0][0];
 
7161
    dofs[4] = offset + c.entity_indices[0][1];
 
7162
    dofs[5] = offset + c.entity_indices[0][2];
 
7163
}
 
7164
 
 
7165
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
7166
void cahnhilliard2d_0_dof_map_2::tabulate_facet_dofs(unsigned int* dofs,
 
7167
                                        unsigned int facet) const
 
7168
{
 
7169
    switch ( facet )
 
7170
    {
 
7171
    case 0:
 
7172
      dofs[0] = 1;
 
7173
      dofs[1] = 2;
 
7174
      dofs[2] = 4;
 
7175
      dofs[3] = 5;
 
7176
      break;
 
7177
    case 1:
 
7178
      dofs[0] = 0;
 
7179
      dofs[1] = 2;
 
7180
      dofs[2] = 3;
 
7181
      dofs[3] = 5;
 
7182
      break;
 
7183
    case 2:
 
7184
      dofs[0] = 0;
 
7185
      dofs[1] = 1;
 
7186
      dofs[2] = 3;
 
7187
      dofs[3] = 4;
 
7188
      break;
 
7189
    }
 
7190
}
 
7191
 
 
7192
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
7193
void cahnhilliard2d_0_dof_map_2::tabulate_entity_dofs(unsigned int* dofs,
 
7194
                                  unsigned int d, unsigned int i) const
 
7195
{
 
7196
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
7197
}
 
7198
 
 
7199
/// Tabulate the coordinates of all dofs on a cell
 
7200
void cahnhilliard2d_0_dof_map_2::tabulate_coordinates(double** coordinates,
 
7201
                                         const ufc::cell& c) const
 
7202
{
 
7203
    const double * const * x = c.coordinates;
 
7204
    coordinates[0][0] = x[0][0];
 
7205
    coordinates[0][1] = x[0][1];
 
7206
    coordinates[1][0] = x[1][0];
 
7207
    coordinates[1][1] = x[1][1];
 
7208
    coordinates[2][0] = x[2][0];
 
7209
    coordinates[2][1] = x[2][1];
 
7210
    coordinates[3][0] = x[0][0];
 
7211
    coordinates[3][1] = x[0][1];
 
7212
    coordinates[4][0] = x[1][0];
 
7213
    coordinates[4][1] = x[1][1];
 
7214
    coordinates[5][0] = x[2][0];
 
7215
    coordinates[5][1] = x[2][1];
 
7216
}
 
7217
 
 
7218
/// Return the number of sub dof maps (for a mixed element)
 
7219
unsigned int cahnhilliard2d_0_dof_map_2::num_sub_dof_maps() const
 
7220
{
 
7221
    return 2;
 
7222
}
 
7223
 
 
7224
/// Create a new dof_map for sub dof map i (for a mixed element)
 
7225
ufc::dof_map* cahnhilliard2d_0_dof_map_2::create_sub_dof_map(unsigned int i) const
 
7226
{
 
7227
    switch ( i )
 
7228
    {
 
7229
    case 0:
 
7230
      return new cahnhilliard2d_0_dof_map_2_0();
 
7231
      break;
 
7232
    case 1:
 
7233
      return new cahnhilliard2d_0_dof_map_2_1();
 
7234
      break;
 
7235
    }
 
7236
    return 0;
 
7237
}
 
7238
 
 
7239
 
 
7240
/// Constructor
 
7241
cahnhilliard2d_0_dof_map_3::cahnhilliard2d_0_dof_map_3() : ufc::dof_map()
 
7242
{
 
7243
    __global_dimension = 0;
 
7244
}
 
7245
 
 
7246
/// Destructor
 
7247
cahnhilliard2d_0_dof_map_3::~cahnhilliard2d_0_dof_map_3()
 
7248
{
 
7249
    // Do nothing
 
7250
}
 
7251
 
 
7252
/// Return a string identifying the dof map
 
7253
const char* cahnhilliard2d_0_dof_map_3::signature() const
 
7254
{
 
7255
    return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
 
7256
}
 
7257
 
 
7258
/// Return true iff mesh entities of topological dimension d are needed
 
7259
bool cahnhilliard2d_0_dof_map_3::needs_mesh_entities(unsigned int d) const
 
7260
{
 
7261
    switch ( d )
 
7262
    {
 
7263
    case 0:
 
7264
      return false;
 
7265
      break;
 
7266
    case 1:
 
7267
      return false;
 
7268
      break;
 
7269
    case 2:
 
7270
      return true;
 
7271
      break;
 
7272
    }
 
7273
    return false;
 
7274
}
 
7275
 
 
7276
/// Initialize dof map for mesh (return true iff init_cell() is needed)
 
7277
bool cahnhilliard2d_0_dof_map_3::init_mesh(const ufc::mesh& m)
 
7278
{
 
7279
    __global_dimension = m.num_entities[2];
 
7280
    return false;
 
7281
}
 
7282
 
 
7283
/// Initialize dof map for given cell
 
7284
void cahnhilliard2d_0_dof_map_3::init_cell(const ufc::mesh& m,
 
7285
                              const ufc::cell& c)
 
7286
{
 
7287
    // Do nothing
 
7288
}
 
7289
 
 
7290
/// Finish initialization of dof map for cells
 
7291
void cahnhilliard2d_0_dof_map_3::init_cell_finalize()
 
7292
{
 
7293
    // Do nothing
 
7294
}
 
7295
 
 
7296
/// Return the dimension of the global finite element function space
 
7297
unsigned int cahnhilliard2d_0_dof_map_3::global_dimension() const
 
7298
{
 
7299
    return __global_dimension;
 
7300
}
 
7301
 
 
7302
/// Return the dimension of the local finite element function space for a cell
 
7303
unsigned int cahnhilliard2d_0_dof_map_3::local_dimension(const ufc::cell& c) const
 
7304
{
 
7305
    return 1;
 
7306
}
 
7307
 
 
7308
/// Return the maximum dimension of the local finite element function space
 
7309
unsigned int cahnhilliard2d_0_dof_map_3::max_local_dimension() const
 
7310
{
 
7311
    return 1;
 
7312
}
 
7313
 
 
7314
// Return the geometric dimension of the coordinates this dof map provides
 
7315
unsigned int cahnhilliard2d_0_dof_map_3::geometric_dimension() const
 
7316
{
 
7317
    return 2;
 
7318
}
 
7319
 
 
7320
/// Return the number of dofs on each cell facet
 
7321
unsigned int cahnhilliard2d_0_dof_map_3::num_facet_dofs() const
 
7322
{
 
7323
    return 0;
 
7324
}
 
7325
 
 
7326
/// Return the number of dofs associated with each cell entity of dimension d
 
7327
unsigned int cahnhilliard2d_0_dof_map_3::num_entity_dofs(unsigned int d) const
 
7328
{
 
7329
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
7330
}
 
7331
 
 
7332
/// Tabulate the local-to-global mapping of dofs on a cell
 
7333
void cahnhilliard2d_0_dof_map_3::tabulate_dofs(unsigned int* dofs,
 
7334
                                  const ufc::mesh& m,
 
7335
                                  const ufc::cell& c) const
 
7336
{
 
7337
    dofs[0] = c.entity_indices[2][0];
 
7338
}
 
7339
 
 
7340
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
7341
void cahnhilliard2d_0_dof_map_3::tabulate_facet_dofs(unsigned int* dofs,
 
7342
                                        unsigned int facet) const
 
7343
{
 
7344
    switch ( facet )
 
7345
    {
 
7346
    case 0:
 
7347
      
 
7348
      break;
 
7349
    case 1:
 
7350
      
 
7351
      break;
 
7352
    case 2:
 
7353
      
 
7354
      break;
 
7355
    }
 
7356
}
 
7357
 
 
7358
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
7359
void cahnhilliard2d_0_dof_map_3::tabulate_entity_dofs(unsigned int* dofs,
 
7360
                                  unsigned int d, unsigned int i) const
 
7361
{
 
7362
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
7363
}
 
7364
 
 
7365
/// Tabulate the coordinates of all dofs on a cell
 
7366
void cahnhilliard2d_0_dof_map_3::tabulate_coordinates(double** coordinates,
 
7367
                                         const ufc::cell& c) const
 
7368
{
 
7369
    const double * const * x = c.coordinates;
 
7370
    coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
 
7371
    coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
 
7372
}
 
7373
 
 
7374
/// Return the number of sub dof maps (for a mixed element)
 
7375
unsigned int cahnhilliard2d_0_dof_map_3::num_sub_dof_maps() const
 
7376
{
 
7377
    return 1;
 
7378
}
 
7379
 
 
7380
/// Create a new dof_map for sub dof map i (for a mixed element)
 
7381
ufc::dof_map* cahnhilliard2d_0_dof_map_3::create_sub_dof_map(unsigned int i) const
 
7382
{
 
7383
    return new cahnhilliard2d_0_dof_map_3();
 
7384
}
 
7385
 
 
7386
 
 
7387
/// Constructor
 
7388
cahnhilliard2d_0_dof_map_4::cahnhilliard2d_0_dof_map_4() : ufc::dof_map()
 
7389
{
 
7390
    __global_dimension = 0;
 
7391
}
 
7392
 
 
7393
/// Destructor
 
7394
cahnhilliard2d_0_dof_map_4::~cahnhilliard2d_0_dof_map_4()
 
7395
{
 
7396
    // Do nothing
 
7397
}
 
7398
 
 
7399
/// Return a string identifying the dof map
 
7400
const char* cahnhilliard2d_0_dof_map_4::signature() const
 
7401
{
 
7402
    return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
 
7403
}
 
7404
 
 
7405
/// Return true iff mesh entities of topological dimension d are needed
 
7406
bool cahnhilliard2d_0_dof_map_4::needs_mesh_entities(unsigned int d) const
 
7407
{
 
7408
    switch ( d )
 
7409
    {
 
7410
    case 0:
 
7411
      return false;
 
7412
      break;
 
7413
    case 1:
 
7414
      return false;
 
7415
      break;
 
7416
    case 2:
 
7417
      return true;
 
7418
      break;
 
7419
    }
 
7420
    return false;
 
7421
}
 
7422
 
 
7423
/// Initialize dof map for mesh (return true iff init_cell() is needed)
 
7424
bool cahnhilliard2d_0_dof_map_4::init_mesh(const ufc::mesh& m)
 
7425
{
 
7426
    __global_dimension = m.num_entities[2];
 
7427
    return false;
 
7428
}
 
7429
 
 
7430
/// Initialize dof map for given cell
 
7431
void cahnhilliard2d_0_dof_map_4::init_cell(const ufc::mesh& m,
 
7432
                              const ufc::cell& c)
 
7433
{
 
7434
    // Do nothing
 
7435
}
 
7436
 
 
7437
/// Finish initialization of dof map for cells
 
7438
void cahnhilliard2d_0_dof_map_4::init_cell_finalize()
 
7439
{
 
7440
    // Do nothing
 
7441
}
 
7442
 
 
7443
/// Return the dimension of the global finite element function space
 
7444
unsigned int cahnhilliard2d_0_dof_map_4::global_dimension() const
 
7445
{
 
7446
    return __global_dimension;
 
7447
}
 
7448
 
 
7449
/// Return the dimension of the local finite element function space for a cell
 
7450
unsigned int cahnhilliard2d_0_dof_map_4::local_dimension(const ufc::cell& c) const
 
7451
{
 
7452
    return 1;
 
7453
}
 
7454
 
 
7455
/// Return the maximum dimension of the local finite element function space
 
7456
unsigned int cahnhilliard2d_0_dof_map_4::max_local_dimension() const
 
7457
{
 
7458
    return 1;
 
7459
}
 
7460
 
 
7461
// Return the geometric dimension of the coordinates this dof map provides
 
7462
unsigned int cahnhilliard2d_0_dof_map_4::geometric_dimension() const
 
7463
{
 
7464
    return 2;
 
7465
}
 
7466
 
 
7467
/// Return the number of dofs on each cell facet
 
7468
unsigned int cahnhilliard2d_0_dof_map_4::num_facet_dofs() const
 
7469
{
 
7470
    return 0;
 
7471
}
 
7472
 
 
7473
/// Return the number of dofs associated with each cell entity of dimension d
 
7474
unsigned int cahnhilliard2d_0_dof_map_4::num_entity_dofs(unsigned int d) const
 
7475
{
 
7476
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
7477
}
 
7478
 
 
7479
/// Tabulate the local-to-global mapping of dofs on a cell
 
7480
void cahnhilliard2d_0_dof_map_4::tabulate_dofs(unsigned int* dofs,
 
7481
                                  const ufc::mesh& m,
 
7482
                                  const ufc::cell& c) const
 
7483
{
 
7484
    dofs[0] = c.entity_indices[2][0];
 
7485
}
 
7486
 
 
7487
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
7488
void cahnhilliard2d_0_dof_map_4::tabulate_facet_dofs(unsigned int* dofs,
 
7489
                                        unsigned int facet) const
 
7490
{
 
7491
    switch ( facet )
 
7492
    {
 
7493
    case 0:
 
7494
      
 
7495
      break;
 
7496
    case 1:
 
7497
      
 
7498
      break;
 
7499
    case 2:
 
7500
      
 
7501
      break;
 
7502
    }
 
7503
}
 
7504
 
 
7505
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
7506
void cahnhilliard2d_0_dof_map_4::tabulate_entity_dofs(unsigned int* dofs,
 
7507
                                  unsigned int d, unsigned int i) const
 
7508
{
 
7509
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
7510
}
 
7511
 
 
7512
/// Tabulate the coordinates of all dofs on a cell
 
7513
void cahnhilliard2d_0_dof_map_4::tabulate_coordinates(double** coordinates,
 
7514
                                         const ufc::cell& c) const
 
7515
{
 
7516
    const double * const * x = c.coordinates;
 
7517
    coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
 
7518
    coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
 
7519
}
 
7520
 
 
7521
/// Return the number of sub dof maps (for a mixed element)
 
7522
unsigned int cahnhilliard2d_0_dof_map_4::num_sub_dof_maps() const
 
7523
{
 
7524
    return 1;
 
7525
}
 
7526
 
 
7527
/// Create a new dof_map for sub dof map i (for a mixed element)
 
7528
ufc::dof_map* cahnhilliard2d_0_dof_map_4::create_sub_dof_map(unsigned int i) const
 
7529
{
 
7530
    return new cahnhilliard2d_0_dof_map_4();
 
7531
}
 
7532
 
 
7533
 
 
7534
/// Constructor
 
7535
cahnhilliard2d_0_dof_map_5::cahnhilliard2d_0_dof_map_5() : ufc::dof_map()
 
7536
{
 
7537
    __global_dimension = 0;
 
7538
}
 
7539
 
 
7540
/// Destructor
 
7541
cahnhilliard2d_0_dof_map_5::~cahnhilliard2d_0_dof_map_5()
 
7542
{
 
7543
    // Do nothing
 
7544
}
 
7545
 
 
7546
/// Return a string identifying the dof map
 
7547
const char* cahnhilliard2d_0_dof_map_5::signature() const
 
7548
{
 
7549
    return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
 
7550
}
 
7551
 
 
7552
/// Return true iff mesh entities of topological dimension d are needed
 
7553
bool cahnhilliard2d_0_dof_map_5::needs_mesh_entities(unsigned int d) const
 
7554
{
 
7555
    switch ( d )
 
7556
    {
 
7557
    case 0:
 
7558
      return false;
 
7559
      break;
 
7560
    case 1:
 
7561
      return false;
 
7562
      break;
 
7563
    case 2:
 
7564
      return true;
 
7565
      break;
 
7566
    }
 
7567
    return false;
 
7568
}
 
7569
 
 
7570
/// Initialize dof map for mesh (return true iff init_cell() is needed)
 
7571
bool cahnhilliard2d_0_dof_map_5::init_mesh(const ufc::mesh& m)
 
7572
{
 
7573
    __global_dimension = m.num_entities[2];
 
7574
    return false;
 
7575
}
 
7576
 
 
7577
/// Initialize dof map for given cell
 
7578
void cahnhilliard2d_0_dof_map_5::init_cell(const ufc::mesh& m,
 
7579
                              const ufc::cell& c)
 
7580
{
 
7581
    // Do nothing
 
7582
}
 
7583
 
 
7584
/// Finish initialization of dof map for cells
 
7585
void cahnhilliard2d_0_dof_map_5::init_cell_finalize()
 
7586
{
 
7587
    // Do nothing
 
7588
}
 
7589
 
 
7590
/// Return the dimension of the global finite element function space
 
7591
unsigned int cahnhilliard2d_0_dof_map_5::global_dimension() const
 
7592
{
 
7593
    return __global_dimension;
 
7594
}
 
7595
 
 
7596
/// Return the dimension of the local finite element function space for a cell
 
7597
unsigned int cahnhilliard2d_0_dof_map_5::local_dimension(const ufc::cell& c) const
 
7598
{
 
7599
    return 1;
 
7600
}
 
7601
 
 
7602
/// Return the maximum dimension of the local finite element function space
 
7603
unsigned int cahnhilliard2d_0_dof_map_5::max_local_dimension() const
 
7604
{
 
7605
    return 1;
 
7606
}
 
7607
 
 
7608
// Return the geometric dimension of the coordinates this dof map provides
 
7609
unsigned int cahnhilliard2d_0_dof_map_5::geometric_dimension() const
 
7610
{
 
7611
    return 2;
 
7612
}
 
7613
 
 
7614
/// Return the number of dofs on each cell facet
 
7615
unsigned int cahnhilliard2d_0_dof_map_5::num_facet_dofs() const
 
7616
{
 
7617
    return 0;
 
7618
}
 
7619
 
 
7620
/// Return the number of dofs associated with each cell entity of dimension d
 
7621
unsigned int cahnhilliard2d_0_dof_map_5::num_entity_dofs(unsigned int d) const
 
7622
{
 
7623
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
7624
}
 
7625
 
 
7626
/// Tabulate the local-to-global mapping of dofs on a cell
 
7627
void cahnhilliard2d_0_dof_map_5::tabulate_dofs(unsigned int* dofs,
 
7628
                                  const ufc::mesh& m,
 
7629
                                  const ufc::cell& c) const
 
7630
{
 
7631
    dofs[0] = c.entity_indices[2][0];
 
7632
}
 
7633
 
 
7634
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
7635
void cahnhilliard2d_0_dof_map_5::tabulate_facet_dofs(unsigned int* dofs,
 
7636
                                        unsigned int facet) const
 
7637
{
 
7638
    switch ( facet )
 
7639
    {
 
7640
    case 0:
 
7641
      
 
7642
      break;
 
7643
    case 1:
 
7644
      
 
7645
      break;
 
7646
    case 2:
 
7647
      
 
7648
      break;
 
7649
    }
 
7650
}
 
7651
 
 
7652
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
7653
void cahnhilliard2d_0_dof_map_5::tabulate_entity_dofs(unsigned int* dofs,
 
7654
                                  unsigned int d, unsigned int i) const
 
7655
{
 
7656
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
7657
}
 
7658
 
 
7659
/// Tabulate the coordinates of all dofs on a cell
 
7660
void cahnhilliard2d_0_dof_map_5::tabulate_coordinates(double** coordinates,
 
7661
                                         const ufc::cell& c) const
 
7662
{
 
7663
    const double * const * x = c.coordinates;
 
7664
    coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
 
7665
    coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
 
7666
}
 
7667
 
 
7668
/// Return the number of sub dof maps (for a mixed element)
 
7669
unsigned int cahnhilliard2d_0_dof_map_5::num_sub_dof_maps() const
 
7670
{
 
7671
    return 1;
 
7672
}
 
7673
 
 
7674
/// Create a new dof_map for sub dof map i (for a mixed element)
 
7675
ufc::dof_map* cahnhilliard2d_0_dof_map_5::create_sub_dof_map(unsigned int i) const
 
7676
{
 
7677
    return new cahnhilliard2d_0_dof_map_5();
 
7678
}
 
7679
 
 
7680
 
 
7681
/// Constructor
 
7682
cahnhilliard2d_0_dof_map_6::cahnhilliard2d_0_dof_map_6() : ufc::dof_map()
 
7683
{
 
7684
    __global_dimension = 0;
 
7685
}
 
7686
 
 
7687
/// Destructor
 
7688
cahnhilliard2d_0_dof_map_6::~cahnhilliard2d_0_dof_map_6()
 
7689
{
 
7690
    // Do nothing
 
7691
}
 
7692
 
 
7693
/// Return a string identifying the dof map
 
7694
const char* cahnhilliard2d_0_dof_map_6::signature() const
 
7695
{
 
7696
    return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
 
7697
}
 
7698
 
 
7699
/// Return true iff mesh entities of topological dimension d are needed
 
7700
bool cahnhilliard2d_0_dof_map_6::needs_mesh_entities(unsigned int d) const
 
7701
{
 
7702
    switch ( d )
 
7703
    {
 
7704
    case 0:
 
7705
      return false;
 
7706
      break;
 
7707
    case 1:
 
7708
      return false;
 
7709
      break;
 
7710
    case 2:
 
7711
      return true;
 
7712
      break;
 
7713
    }
 
7714
    return false;
 
7715
}
 
7716
 
 
7717
/// Initialize dof map for mesh (return true iff init_cell() is needed)
 
7718
bool cahnhilliard2d_0_dof_map_6::init_mesh(const ufc::mesh& m)
 
7719
{
 
7720
    __global_dimension = m.num_entities[2];
 
7721
    return false;
 
7722
}
 
7723
 
 
7724
/// Initialize dof map for given cell
 
7725
void cahnhilliard2d_0_dof_map_6::init_cell(const ufc::mesh& m,
 
7726
                              const ufc::cell& c)
 
7727
{
 
7728
    // Do nothing
 
7729
}
 
7730
 
 
7731
/// Finish initialization of dof map for cells
 
7732
void cahnhilliard2d_0_dof_map_6::init_cell_finalize()
 
7733
{
 
7734
    // Do nothing
 
7735
}
 
7736
 
 
7737
/// Return the dimension of the global finite element function space
 
7738
unsigned int cahnhilliard2d_0_dof_map_6::global_dimension() const
 
7739
{
 
7740
    return __global_dimension;
 
7741
}
 
7742
 
 
7743
/// Return the dimension of the local finite element function space for a cell
 
7744
unsigned int cahnhilliard2d_0_dof_map_6::local_dimension(const ufc::cell& c) const
 
7745
{
 
7746
    return 1;
 
7747
}
 
7748
 
 
7749
/// Return the maximum dimension of the local finite element function space
 
7750
unsigned int cahnhilliard2d_0_dof_map_6::max_local_dimension() const
 
7751
{
 
7752
    return 1;
 
7753
}
 
7754
 
 
7755
// Return the geometric dimension of the coordinates this dof map provides
 
7756
unsigned int cahnhilliard2d_0_dof_map_6::geometric_dimension() const
 
7757
{
 
7758
    return 2;
 
7759
}
 
7760
 
 
7761
/// Return the number of dofs on each cell facet
 
7762
unsigned int cahnhilliard2d_0_dof_map_6::num_facet_dofs() const
 
7763
{
 
7764
    return 0;
 
7765
}
 
7766
 
 
7767
/// Return the number of dofs associated with each cell entity of dimension d
 
7768
unsigned int cahnhilliard2d_0_dof_map_6::num_entity_dofs(unsigned int d) const
 
7769
{
 
7770
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
7771
}
 
7772
 
 
7773
/// Tabulate the local-to-global mapping of dofs on a cell
 
7774
void cahnhilliard2d_0_dof_map_6::tabulate_dofs(unsigned int* dofs,
 
7775
                                  const ufc::mesh& m,
 
7776
                                  const ufc::cell& c) const
 
7777
{
 
7778
    dofs[0] = c.entity_indices[2][0];
 
7779
}
 
7780
 
 
7781
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
7782
void cahnhilliard2d_0_dof_map_6::tabulate_facet_dofs(unsigned int* dofs,
 
7783
                                        unsigned int facet) const
 
7784
{
 
7785
    switch ( facet )
 
7786
    {
 
7787
    case 0:
 
7788
      
 
7789
      break;
 
7790
    case 1:
 
7791
      
 
7792
      break;
 
7793
    case 2:
 
7794
      
 
7795
      break;
 
7796
    }
 
7797
}
 
7798
 
 
7799
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
7800
void cahnhilliard2d_0_dof_map_6::tabulate_entity_dofs(unsigned int* dofs,
 
7801
                                  unsigned int d, unsigned int i) const
 
7802
{
 
7803
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
7804
}
 
7805
 
 
7806
/// Tabulate the coordinates of all dofs on a cell
 
7807
void cahnhilliard2d_0_dof_map_6::tabulate_coordinates(double** coordinates,
 
7808
                                         const ufc::cell& c) const
 
7809
{
 
7810
    const double * const * x = c.coordinates;
 
7811
    coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
 
7812
    coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
 
7813
}
 
7814
 
 
7815
/// Return the number of sub dof maps (for a mixed element)
 
7816
unsigned int cahnhilliard2d_0_dof_map_6::num_sub_dof_maps() const
 
7817
{
 
7818
    return 1;
 
7819
}
 
7820
 
 
7821
/// Create a new dof_map for sub dof map i (for a mixed element)
 
7822
ufc::dof_map* cahnhilliard2d_0_dof_map_6::create_sub_dof_map(unsigned int i) const
 
7823
{
 
7824
    return new cahnhilliard2d_0_dof_map_6();
 
7825
}
 
7826
 
 
7827
 
 
7828
/// Constructor
 
7829
cahnhilliard2d_0_cell_integral_0_quadrature::cahnhilliard2d_0_cell_integral_0_quadrature() : ufc::cell_integral()
 
7830
{
 
7831
    // Do nothing
 
7832
}
 
7833
 
 
7834
/// Destructor
 
7835
cahnhilliard2d_0_cell_integral_0_quadrature::~cahnhilliard2d_0_cell_integral_0_quadrature()
7757
7836
{
7758
7837
    // Do nothing
7759
7838
}
7760
7839
 
7761
7840
/// Tabulate the tensor for the contribution from a local cell
7762
 
void UFC_CahnHilliard2DBilinearForm_cell_integral_0::tabulate_tensor(double* A,
 
7841
void cahnhilliard2d_0_cell_integral_0_quadrature::tabulate_tensor(double* A,
7763
7842
                                    const double * const * w,
7764
7843
                                    const ufc::cell& c) const
7765
7844
{
7771
7850
    const double J_01 = x[2][0] - x[0][0];
7772
7851
    const double J_10 = x[1][1] - x[0][1];
7773
7852
    const double J_11 = x[2][1] - x[0][1];
7774
 
      
 
7853
    
7775
7854
    // Compute determinant of Jacobian
7776
7855
    double detJ = J_00*J_11 - J_01*J_10;
7777
 
      
 
7856
    
7778
7857
    // Compute inverse of Jacobian
7779
7858
    const double Jinv_00 =  J_11 / detJ;
7780
7859
    const double Jinv_01 = -J_01 / detJ;
7784
7863
    // Set scale factor
7785
7864
    const double det = std::abs(detJ);
7786
7865
    
7787
 
    // Number of operations to compute element tensor = 377
7788
 
    // Compute coefficients
7789
 
    const double c3_2_0_0 = w[3][0];
7790
 
    const double c4_2_1_0 = w[4][0];
7791
 
    const double c2_3_0_0 = w[2][0];
7792
 
    const double c0_3_1_3 = w[0][3];
7793
 
    const double c0_3_1_4 = w[0][4];
7794
 
    const double c0_3_1_5 = w[0][5];
7795
 
    const double c0_3_2_3 = w[0][3];
7796
 
    const double c0_3_2_4 = w[0][4];
7797
 
    const double c0_3_2_5 = w[0][5];
7798
 
    const double c2_4_0_0 = w[2][0];
7799
 
    const double c0_4_1_3 = w[0][3];
7800
 
    const double c0_4_1_4 = w[0][4];
7801
 
    const double c0_4_1_5 = w[0][5];
7802
 
    const double c2_5_0_0 = w[2][0];
7803
 
    const double c1_6_0_0 = w[1][0];
7804
 
    
7805
 
    // Compute geometry tensors
7806
 
    // Number of operations to compute decalrations = 79
7807
 
    const double G0_ = det;
7808
 
    const double G2_0_0_0_0 = det*c3_2_0_0*c4_2_1_0*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
7809
 
    const double G2_0_0_0_1 = det*c3_2_0_0*c4_2_1_0*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
7810
 
    const double G2_0_0_1_0 = det*c3_2_0_0*c4_2_1_0*(Jinv_10*Jinv_00 + Jinv_11*Jinv_01);
7811
 
    const double G2_0_0_1_1 = det*c3_2_0_0*c4_2_1_0*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
7812
 
    const double G3_0_3_3 = det*c2_3_0_0*c0_3_1_3*c0_3_2_3;
7813
 
    const double G3_0_3_4 = det*c2_3_0_0*c0_3_1_3*c0_3_2_4;
7814
 
    const double G3_0_3_5 = det*c2_3_0_0*c0_3_1_3*c0_3_2_5;
7815
 
    const double G3_0_4_3 = det*c2_3_0_0*c0_3_1_4*c0_3_2_3;
7816
 
    const double G3_0_4_4 = det*c2_3_0_0*c0_3_1_4*c0_3_2_4;
7817
 
    const double G3_0_4_5 = det*c2_3_0_0*c0_3_1_4*c0_3_2_5;
7818
 
    const double G3_0_5_3 = det*c2_3_0_0*c0_3_1_5*c0_3_2_3;
7819
 
    const double G3_0_5_4 = det*c2_3_0_0*c0_3_1_5*c0_3_2_4;
7820
 
    const double G3_0_5_5 = det*c2_3_0_0*c0_3_1_5*c0_3_2_5;
7821
 
    const double G4_0_3 = det*c2_4_0_0*c0_4_1_3;
7822
 
    const double G4_0_4 = det*c2_4_0_0*c0_4_1_4;
7823
 
    const double G4_0_5 = det*c2_4_0_0*c0_4_1_5;
7824
 
    const double G5_0 = det*c2_5_0_0;
7825
 
    const double G6_0_0_0 = det*c1_6_0_0*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
7826
 
    const double G6_0_0_1 = det*c1_6_0_0*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
7827
 
    const double G6_0_1_0 = det*c1_6_0_0*(Jinv_10*Jinv_00 + Jinv_11*Jinv_01);
7828
 
    const double G6_0_1_1 = det*c1_6_0_0*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
7829
 
    
7830
 
    // Compute element tensor
7831
 
    // Number of operations to compute tensor = 298
7832
 
    A[0] = 0.0833333333333332*G0_;
7833
 
    A[1] = 0.0416666666666666*G0_;
7834
 
    A[2] = 0.0416666666666666*G0_;
7835
 
    A[3] = -0.4*G3_0_3_3 - 0.0999999999999999*G3_0_3_4 - 0.0999999999999999*G3_0_3_5 - 0.0999999999999999*G3_0_4_3 - 0.0666666666666666*G3_0_4_4 - 0.0333333333333333*G3_0_4_5 - 0.0999999999999999*G3_0_5_3 - 0.0333333333333333*G3_0_5_4 - 0.0666666666666666*G3_0_5_5 + 0.599999999999999*G4_0_3 + 0.2*G4_0_4 + 0.2*G4_0_5 - 0.166666666666666*G5_0 - 0.5*G6_0_0_0 - 0.5*G6_0_0_1 - 0.5*G6_0_1_0 - 0.5*G6_0_1_1;
7836
 
    A[4] = -0.0999999999999999*G3_0_3_3 - 0.0666666666666666*G3_0_3_4 - 0.0333333333333333*G3_0_3_5 - 0.0666666666666666*G3_0_4_3 - 0.0999999999999999*G3_0_4_4 - 0.0333333333333333*G3_0_4_5 - 0.0333333333333333*G3_0_5_3 - 0.0333333333333333*G3_0_5_4 - 0.0333333333333333*G3_0_5_5 + 0.2*G4_0_3 + 0.2*G4_0_4 + 0.0999999999999998*G4_0_5 - 0.0833333333333332*G5_0 + 0.5*G6_0_0_0 + 0.5*G6_0_1_0;
7837
 
    A[5] = -0.1*G3_0_3_3 - 0.0333333333333333*G3_0_3_4 - 0.0666666666666666*G3_0_3_5 - 0.0333333333333333*G3_0_4_3 - 0.0333333333333333*G3_0_4_4 - 0.0333333333333333*G3_0_4_5 - 0.0666666666666666*G3_0_5_3 - 0.0333333333333333*G3_0_5_4 - 0.0999999999999999*G3_0_5_5 + 0.2*G4_0_3 + 0.0999999999999998*G4_0_4 + 0.2*G4_0_5 - 0.0833333333333332*G5_0 + 0.5*G6_0_0_1 + 0.5*G6_0_1_1;
7838
 
    A[6] = 0.0416666666666666*G0_;
7839
 
    A[7] = 0.0833333333333332*G0_;
7840
 
    A[8] = 0.0416666666666666*G0_;
7841
 
    A[9] = -0.0999999999999999*G3_0_3_3 - 0.0666666666666666*G3_0_3_4 - 0.0333333333333333*G3_0_3_5 - 0.0666666666666666*G3_0_4_3 - 0.0999999999999999*G3_0_4_4 - 0.0333333333333333*G3_0_4_5 - 0.0333333333333333*G3_0_5_3 - 0.0333333333333333*G3_0_5_4 - 0.0333333333333333*G3_0_5_5 + 0.2*G4_0_3 + 0.2*G4_0_4 + 0.0999999999999998*G4_0_5 - 0.0833333333333332*G5_0 + 0.5*G6_0_0_0 + 0.5*G6_0_0_1;
7842
 
    A[10] = -0.0666666666666666*G3_0_3_3 - 0.0999999999999999*G3_0_3_4 - 0.0333333333333333*G3_0_3_5 - 0.0999999999999999*G3_0_4_3 - 0.4*G3_0_4_4 - 0.0999999999999999*G3_0_4_5 - 0.0333333333333333*G3_0_5_3 - 0.0999999999999999*G3_0_5_4 - 0.0666666666666666*G3_0_5_5 + 0.2*G4_0_3 + 0.599999999999999*G4_0_4 + 0.2*G4_0_5 - 0.166666666666666*G5_0 - 0.5*G6_0_0_0;
7843
 
    A[11] = -0.0333333333333333*G3_0_3_3 - 0.0333333333333333*G3_0_3_4 - 0.0333333333333333*G3_0_3_5 - 0.0333333333333333*G3_0_4_3 - 0.1*G3_0_4_4 - 0.0666666666666666*G3_0_4_5 - 0.0333333333333333*G3_0_5_3 - 0.0666666666666666*G3_0_5_4 - 0.1*G3_0_5_5 + 0.0999999999999998*G4_0_3 + 0.2*G4_0_4 + 0.2*G4_0_5 - 0.0833333333333332*G5_0 - 0.5*G6_0_0_1;
7844
 
    A[12] = 0.0416666666666666*G0_;
7845
 
    A[13] = 0.0416666666666666*G0_;
7846
 
    A[14] = 0.0833333333333332*G0_;
7847
 
    A[15] = -0.0999999999999999*G3_0_3_3 - 0.0333333333333333*G3_0_3_4 - 0.0666666666666666*G3_0_3_5 - 0.0333333333333333*G3_0_4_3 - 0.0333333333333333*G3_0_4_4 - 0.0333333333333333*G3_0_4_5 - 0.0666666666666666*G3_0_5_3 - 0.0333333333333333*G3_0_5_4 - 0.0999999999999999*G3_0_5_5 + 0.2*G4_0_3 + 0.0999999999999998*G4_0_4 + 0.2*G4_0_5 - 0.0833333333333332*G5_0 + 0.5*G6_0_1_0 + 0.5*G6_0_1_1;
7848
 
    A[16] = -0.0333333333333333*G3_0_3_3 - 0.0333333333333333*G3_0_3_4 - 0.0333333333333333*G3_0_3_5 - 0.0333333333333333*G3_0_4_3 - 0.0999999999999999*G3_0_4_4 - 0.0666666666666666*G3_0_4_5 - 0.0333333333333333*G3_0_5_3 - 0.0666666666666666*G3_0_5_4 - 0.1*G3_0_5_5 + 0.0999999999999998*G4_0_3 + 0.2*G4_0_4 + 0.2*G4_0_5 - 0.0833333333333332*G5_0 - 0.5*G6_0_1_0;
7849
 
    A[17] = -0.0666666666666666*G3_0_3_3 - 0.0333333333333333*G3_0_3_4 - 0.0999999999999999*G3_0_3_5 - 0.0333333333333333*G3_0_4_3 - 0.0666666666666666*G3_0_4_4 - 0.1*G3_0_4_5 - 0.0999999999999999*G3_0_5_3 - 0.0999999999999999*G3_0_5_4 - 0.4*G3_0_5_5 + 0.2*G4_0_3 + 0.2*G4_0_4 + 0.599999999999999*G4_0_5 - 0.166666666666666*G5_0 - 0.5*G6_0_1_1;
7850
 
    A[18] = 0.5*G2_0_0_0_0 + 0.5*G2_0_0_0_1 + 0.5*G2_0_0_1_0 + 0.5*G2_0_0_1_1;
7851
 
    A[19] = -0.5*G2_0_0_0_0 - 0.5*G2_0_0_1_0;
7852
 
    A[20] = -0.5*G2_0_0_0_1 - 0.5*G2_0_0_1_1;
7853
 
    A[21] = 0.0833333333333332*G0_;
7854
 
    A[22] = 0.0416666666666666*G0_;
7855
 
    A[23] = 0.0416666666666666*G0_;
7856
 
    A[24] = -0.5*G2_0_0_0_0 - 0.5*G2_0_0_0_1;
7857
 
    A[25] = 0.5*G2_0_0_0_0;
7858
 
    A[26] = 0.5*G2_0_0_0_1;
7859
 
    A[27] = 0.0416666666666666*G0_;
7860
 
    A[28] = 0.0833333333333332*G0_;
7861
 
    A[29] = 0.0416666666666666*G0_;
7862
 
    A[30] = -0.5*G2_0_0_1_0 - 0.5*G2_0_0_1_1;
7863
 
    A[31] = 0.5*G2_0_0_1_0;
7864
 
    A[32] = 0.5*G2_0_0_1_1;
7865
 
    A[33] = 0.0416666666666666*G0_;
7866
 
    A[34] = 0.0416666666666666*G0_;
7867
 
    A[35] = 0.0833333333333332*G0_;
7868
 
}
7869
 
 
7870
 
/// Constructor
7871
 
UFC_CahnHilliard2DBilinearForm::UFC_CahnHilliard2DBilinearForm() : ufc::form()
7872
 
{
7873
 
    // Do nothing
7874
 
}
7875
 
 
7876
 
/// Destructor
7877
 
UFC_CahnHilliard2DBilinearForm::~UFC_CahnHilliard2DBilinearForm()
 
7866
    
 
7867
    // Array of quadrature weights
 
7868
    static const double W9[9] = {0.0558144204830443, 0.063678085099885, 0.0193963833059595, 0.0893030727728709, 0.101884936159816, 0.0310342132895351, 0.0558144204830443, 0.063678085099885, 0.0193963833059595};
 
7869
    // Quadrature points on the UFC reference element: (0.102717654809626, 0.088587959512704), (0.0665540678391645, 0.409466864440735), (0.0239311322870806, 0.787659461760847), (0.455706020243648, 0.088587959512704), (0.295266567779633, 0.409466864440735), (0.106170269119576, 0.787659461760847), (0.80869438567767, 0.088587959512704), (0.523979067720101, 0.409466864440735), (0.188409405952072, 0.787659461760847)
 
7870
    
 
7871
    // Value of basis functions at quadrature points.
 
7872
    static const double FE0_C1_D01[9][2] = \
 
7873
    {{-1, 1},
 
7874
    {-1, 1},
 
7875
    {-1, 1},
 
7876
    {-1, 1},
 
7877
    {-1, 1},
 
7878
    {-1, 1},
 
7879
    {-1, 1},
 
7880
    {-1, 1},
 
7881
    {-1, 1}};
 
7882
    
 
7883
    // Array of non-zero columns
 
7884
    static const unsigned int nzc0[2] = {3, 5};
 
7885
    // Array of non-zero columns
 
7886
    static const unsigned int nzc1[2] = {3, 4};
 
7887
    // Array of non-zero columns
 
7888
    static const unsigned int nzc2[2] = {0, 1};
 
7889
    // Array of non-zero columns
 
7890
    static const unsigned int nzc3[2] = {0, 2};
 
7891
    static const double FE0_C1[9][3] = \
 
7892
    {{0.80869438567767, 0.102717654809626, 0.088587959512704},
 
7893
    {0.523979067720101, 0.0665540678391645, 0.409466864440735},
 
7894
    {0.188409405952072, 0.0239311322870807, 0.787659461760847},
 
7895
    {0.455706020243648, 0.455706020243648, 0.088587959512704},
 
7896
    {0.295266567779633, 0.295266567779633, 0.409466864440735},
 
7897
    {0.106170269119576, 0.106170269119577, 0.787659461760847},
 
7898
    {0.102717654809626, 0.80869438567767, 0.088587959512704},
 
7899
    {0.0665540678391645, 0.523979067720101, 0.409466864440735},
 
7900
    {0.0239311322870807, 0.188409405952072, 0.787659461760847}};
 
7901
    
 
7902
    // Array of non-zero columns
 
7903
    static const unsigned int nzc4[3] = {3, 4, 5};
 
7904
    // Array of non-zero columns
 
7905
    static const unsigned int nzc5[3] = {0, 1, 2};
 
7906
    
 
7907
    // Number of operations to compute geometry constants: 39
 
7908
    const double G0 = -det*w[1][0]*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
 
7909
    const double G1 = det*w[3][0]*w[4][0]*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
 
7910
    const double G2 = -det*w[1][0]*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
 
7911
    const double G3 = -12*det*w[2][0];
 
7912
    const double G4 = 12*det*w[2][0];
 
7913
    const double G5 = -2*det*w[2][0];
 
7914
    const double G6 = det*w[3][0]*w[4][0]*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
 
7915
    const double G7 = -det*w[1][0]*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
 
7916
    const double G8 = det*w[3][0]*w[4][0]*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
 
7917
    
 
7918
    // Compute element tensor using UFL quadrature representation
 
7919
    // Optimisations: ('simplify expressions', True), ('ignore zero tables', True), ('non zero columns', True), ('remove zero terms', True), ('ignore ones', True)
 
7920
    // Total number of operations to compute element tensor: 1794
 
7921
    
 
7922
    // Loop quadrature points for integral
 
7923
    // Number of operations to compute element tensor for following IP loop = 1755
 
7924
    for (unsigned int ip = 0; ip < 9; ip++)
 
7925
    {
 
7926
      
 
7927
      // Function declarations
 
7928
      double F0 = 0;
 
7929
      
 
7930
      // Total number of operations to compute function values = 6
 
7931
      for (unsigned int r = 0; r < 3; r++)
 
7932
      {
 
7933
        F0 += FE0_C1[ip][r]*w[0][nzc4[r]];
 
7934
      }// end loop over 'r'
 
7935
      
 
7936
      // Number of operations to compute ip constants: 12
 
7937
      // Number of operations: 1
 
7938
      const double Gip0 = W9[ip]*det;
 
7939
      
 
7940
      // Number of operations: 1
 
7941
      const double Gip1 = G0*W9[ip];
 
7942
      
 
7943
      // Number of operations: 1
 
7944
      const double Gip2 = G1*W9[ip];
 
7945
      
 
7946
      // Number of operations: 1
 
7947
      const double Gip3 = G2*W9[ip];
 
7948
      
 
7949
      // Number of operations: 5
 
7950
      const double Gip4 = W9[ip]*(G5 + F0*(G4 + F0*G3));
 
7951
      
 
7952
      // Number of operations: 1
 
7953
      const double Gip5 = G6*W9[ip];
 
7954
      
 
7955
      // Number of operations: 1
 
7956
      const double Gip6 = G7*W9[ip];
 
7957
      
 
7958
      // Number of operations: 1
 
7959
      const double Gip7 = G8*W9[ip];
 
7960
      
 
7961
      
 
7962
      // Number of operations for primary indices = 81
 
7963
      for (unsigned int j = 0; j < 3; j++)
 
7964
      {
 
7965
        for (unsigned int k = 0; k < 3; k++)
 
7966
        {
 
7967
          // Number of operations to compute entry = 3
 
7968
          A[nzc4[j]*6 + nzc5[k]] += FE0_C1[ip][j]*FE0_C1[ip][k]*Gip0;
 
7969
          // Number of operations to compute entry = 3
 
7970
          A[nzc4[j]*6 + nzc4[k]] += FE0_C1[ip][j]*FE0_C1[ip][k]*Gip4;
 
7971
          // Number of operations to compute entry = 3
 
7972
          A[nzc5[j]*6 + nzc4[k]] += FE0_C1[ip][j]*FE0_C1[ip][k]*Gip0;
 
7973
        }// end loop over 'k'
 
7974
      }// end loop over 'j'
 
7975
      
 
7976
      // Number of operations for primary indices = 96
 
7977
      for (unsigned int j = 0; j < 2; j++)
 
7978
      {
 
7979
        for (unsigned int k = 0; k < 2; k++)
 
7980
        {
 
7981
          // Number of operations to compute entry = 3
 
7982
          A[nzc0[j]*6 + nzc1[k]] += FE0_C1_D01[ip][j]*FE0_C1_D01[ip][k]*Gip1;
 
7983
          // Number of operations to compute entry = 3
 
7984
          A[nzc2[j]*6 + nzc3[k]] += FE0_C1_D01[ip][j]*FE0_C1_D01[ip][k]*Gip2;
 
7985
          // Number of operations to compute entry = 3
 
7986
          A[nzc1[j]*6 + nzc1[k]] += FE0_C1_D01[ip][j]*FE0_C1_D01[ip][k]*Gip3;
 
7987
          // Number of operations to compute entry = 3
 
7988
          A[nzc3[j]*6 + nzc2[k]] += FE0_C1_D01[ip][j]*FE0_C1_D01[ip][k]*Gip2;
 
7989
          // Number of operations to compute entry = 3
 
7990
          A[nzc1[j]*6 + nzc0[k]] += FE0_C1_D01[ip][j]*FE0_C1_D01[ip][k]*Gip1;
 
7991
          // Number of operations to compute entry = 3
 
7992
          A[nzc3[j]*6 + nzc3[k]] += FE0_C1_D01[ip][j]*FE0_C1_D01[ip][k]*Gip5;
 
7993
          // Number of operations to compute entry = 3
 
7994
          A[nzc0[j]*6 + nzc0[k]] += FE0_C1_D01[ip][j]*FE0_C1_D01[ip][k]*Gip6;
 
7995
          // Number of operations to compute entry = 3
 
7996
          A[nzc2[j]*6 + nzc2[k]] += FE0_C1_D01[ip][j]*FE0_C1_D01[ip][k]*Gip7;
 
7997
        }// end loop over 'k'
 
7998
      }// end loop over 'j'
 
7999
    }// end loop over 'ip'
 
8000
}
 
8001
 
 
8002
/// Constructor
 
8003
cahnhilliard2d_0_cell_integral_0::cahnhilliard2d_0_cell_integral_0() : ufc::cell_integral()
 
8004
{
 
8005
    // Do nothing
 
8006
}
 
8007
 
 
8008
/// Destructor
 
8009
cahnhilliard2d_0_cell_integral_0::~cahnhilliard2d_0_cell_integral_0()
 
8010
{
 
8011
    // Do nothing
 
8012
}
 
8013
 
 
8014
/// Tabulate the tensor for the contribution from a local cell
 
8015
void cahnhilliard2d_0_cell_integral_0::tabulate_tensor(double* A,
 
8016
                                    const double * const * w,
 
8017
                                    const ufc::cell& c) const
 
8018
{
 
8019
    // Reset values of the element tensor block
 
8020
    for (unsigned int j = 0; j < 36; j++)
 
8021
      A[j] = 0;
 
8022
    
 
8023
    // Add all contributions to element tensor
 
8024
    integral_0_quadrature.tabulate_tensor(A, w, c);
 
8025
}
 
8026
 
 
8027
/// Constructor
 
8028
cahnhilliard2d_form_0::cahnhilliard2d_form_0() : ufc::form()
 
8029
{
 
8030
    // Do nothing
 
8031
}
 
8032
 
 
8033
/// Destructor
 
8034
cahnhilliard2d_form_0::~cahnhilliard2d_form_0()
7878
8035
{
7879
8036
    // Do nothing
7880
8037
}
7881
8038
 
7882
8039
/// Return a string identifying the form
7883
 
const char* UFC_CahnHilliard2DBilinearForm::signature() const
 
8040
const char* cahnhilliard2d_form_0::signature() const
7884
8041
{
7885
 
    return " | vi0[0, 1, 2, 3, 4, 5][b0[0, 1]]*vi1[0, 1, 2, 3, 4, 5][b0[0, 1]]*dX(0) + w3_a0[0]w4_a1[0](dXa2[0, 1]/dxb0[0, 1])(dXa3[0, 1]/dxb0[0, 1]) | va0[0]*((d/dXa2[0, 1])vi0[0, 1, 2, 3, 4, 5][1])*((d/dXa3[0, 1])va1[0])*vi1[0, 1, 2, 3, 4, 5][0]*dX(0) + w3_a0[0]w4_a1[0](dXa2[0, 1]/dxb0[0, 1])(dXa3[0, 1]/dxb0[0, 1]) | va0[0]*((d/dXa2[0, 1])vi0[0, 1, 2, 3, 4, 5][1])*va1[0]*((d/dXa3[0, 1])vi1[0, 1, 2, 3, 4, 5][0])*dX(0) + -12.0w2_a0[0]w0_a1[0, 1, 2, 3, 4, 5]w0_a2[0, 1, 2, 3, 4, 5] | vi0[0, 1, 2, 3, 4, 5][0]*va0[0]*va1[0, 1, 2, 3, 4, 5][1]*va2[0, 1, 2, 3, 4, 5][1]*vi1[0, 1, 2, 3, 4, 5][1]*dX(0) + 12.0w2_a0[0]w0_a1[0, 1, 2, 3, 4, 5] | vi0[0, 1, 2, 3, 4, 5][0]*va0[0]*va1[0, 1, 2, 3, 4, 5][1]*vi1[0, 1, 2, 3, 4, 5][1]*dX(0) + -2.0w2_a0[0] | vi0[0, 1, 2, 3, 4, 5][0]*va0[0]*vi1[0, 1, 2, 3, 4, 5][1]*dX(0) + -w1_a0[0](dXa1[0, 1]/dxb0[0, 1])(dXa2[0, 1]/dxb0[0, 1]) | va0[0]*((d/dXa1[0, 1])vi0[0, 1, 2, 3, 4, 5][0])*((d/dXa2[0, 1])vi1[0, 1, 2, 3, 4, 5][1])*dX(0)";
 
8042
    return "Form([Integral(Sum(Sum(Product(Constant(Cell('triangle', 1, Space(2)), 3), IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((FixedIndex(0),), {})), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), Indexed(ComponentTensor(Product(Constant(Cell('triangle', 1, Space(2)), 4), Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 1), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((FixedIndex(0),), {}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(1),), {Index(1): 2}))), MultiIndex((Index(1),), {Index(1): 2}))), Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})), Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))), Sum(Product(IntValue(-1, (), (), {}), Product(Constant(Cell('triangle', 1, Space(2)), 1), IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((Index(3),), {Index(3): 2})), MultiIndex((FixedIndex(1),), {})), MultiIndex((Index(3),), {Index(3): 2})), MultiIndex((Index(4),), {Index(4): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 1), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((FixedIndex(1),), {})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(4),), {Index(4): 2}))), MultiIndex((Index(4),), {Index(4): 2})))), Sum(Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2}))), Product(IntValue(-1, (), (), {}), Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(Constant(Cell('triangle', 1, Space(2)), 2), Sum(Product(IntValue(-1, (), (), {}), Sum(Product(Product(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(IntValue(2, (), (), {}), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))), Product(IntValue(-1, (), (), {}), Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))), Product(Sum(IntValue(1, (), (), {}), Product(IntValue(-1, (), (), {}), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))), Sum(Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(IntValue(2, (), (), {}), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))), Product(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(IntValue(2, (), (), {}), Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))))))), Sum(Product(Product(IntValue(-1, (), (), {}), Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2}))), Product(Product(IntValue(2, (), (), {}), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2}))), Sum(IntValue(1, (), (), {}), Product(IntValue(-1, (), (), {}), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))))), Product(Sum(IntValue(1, (), (), {}), Product(IntValue(-1, (), (), {}), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))), Sum(Product(Product(IntValue(-1, (), (), {}), Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2}))), Product(IntValue(2, (), (), {}), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))), Product(Product(IntValue(2, (), (), {}), Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2}))), Sum(IntValue(1, (), (), {}), Product(IntValue(-1, (), (), {}), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2}))))))))))))))), Measure('cell', 0, None))])";
7886
8043
}
7887
8044
 
7888
8045
/// Return the rank of the global tensor (r)
7889
 
unsigned int UFC_CahnHilliard2DBilinearForm::rank() const
 
8046
unsigned int cahnhilliard2d_form_0::rank() const
7890
8047
{
7891
8048
    return 2;
7892
8049
}
7893
8050
 
7894
8051
/// Return the number of coefficients (n)
7895
 
unsigned int UFC_CahnHilliard2DBilinearForm::num_coefficients() const
 
8052
unsigned int cahnhilliard2d_form_0::num_coefficients() const
7896
8053
{
7897
8054
    return 5;
7898
8055
}
7899
8056
 
7900
8057
/// Return the number of cell integrals
7901
 
unsigned int UFC_CahnHilliard2DBilinearForm::num_cell_integrals() const
 
8058
unsigned int cahnhilliard2d_form_0::num_cell_integrals() const
7902
8059
{
7903
8060
    return 1;
7904
8061
}
7905
 
  
 
8062
 
7906
8063
/// Return the number of exterior facet integrals
7907
 
unsigned int UFC_CahnHilliard2DBilinearForm::num_exterior_facet_integrals() const
 
8064
unsigned int cahnhilliard2d_form_0::num_exterior_facet_integrals() const
7908
8065
{
7909
8066
    return 0;
7910
8067
}
7911
 
  
 
8068
 
7912
8069
/// Return the number of interior facet integrals
7913
 
unsigned int UFC_CahnHilliard2DBilinearForm::num_interior_facet_integrals() const
 
8070
unsigned int cahnhilliard2d_form_0::num_interior_facet_integrals() const
7914
8071
{
7915
8072
    return 0;
7916
8073
}
7917
8074
 
7918
8075
/// Create a new finite element for argument function i
7919
 
ufc::finite_element* UFC_CahnHilliard2DBilinearForm::create_finite_element(unsigned int i) const
 
8076
ufc::finite_element* cahnhilliard2d_form_0::create_finite_element(unsigned int i) const
7920
8077
{
7921
8078
    switch ( i )
7922
8079
    {
7923
8080
    case 0:
7924
 
      return new UFC_CahnHilliard2DBilinearForm_finite_element_0();
 
8081
      return new cahnhilliard2d_0_finite_element_0();
7925
8082
      break;
7926
8083
    case 1:
7927
 
      return new UFC_CahnHilliard2DBilinearForm_finite_element_1();
 
8084
      return new cahnhilliard2d_0_finite_element_1();
7928
8085
      break;
7929
8086
    case 2:
7930
 
      return new UFC_CahnHilliard2DBilinearForm_finite_element_2();
 
8087
      return new cahnhilliard2d_0_finite_element_2();
7931
8088
      break;
7932
8089
    case 3:
7933
 
      return new UFC_CahnHilliard2DBilinearForm_finite_element_3();
 
8090
      return new cahnhilliard2d_0_finite_element_3();
7934
8091
      break;
7935
8092
    case 4:
7936
 
      return new UFC_CahnHilliard2DBilinearForm_finite_element_4();
 
8093
      return new cahnhilliard2d_0_finite_element_4();
7937
8094
      break;
7938
8095
    case 5:
7939
 
      return new UFC_CahnHilliard2DBilinearForm_finite_element_5();
 
8096
      return new cahnhilliard2d_0_finite_element_5();
7940
8097
      break;
7941
8098
    case 6:
7942
 
      return new UFC_CahnHilliard2DBilinearForm_finite_element_6();
 
8099
      return new cahnhilliard2d_0_finite_element_6();
7943
8100
      break;
7944
8101
    }
7945
8102
    return 0;
7946
8103
}
7947
8104
 
7948
8105
/// Create a new dof map for argument function i
7949
 
ufc::dof_map* UFC_CahnHilliard2DBilinearForm::create_dof_map(unsigned int i) const
 
8106
ufc::dof_map* cahnhilliard2d_form_0::create_dof_map(unsigned int i) const
7950
8107
{
7951
8108
    switch ( i )
7952
8109
    {
7953
8110
    case 0:
7954
 
      return new UFC_CahnHilliard2DBilinearForm_dof_map_0();
 
8111
      return new cahnhilliard2d_0_dof_map_0();
7955
8112
      break;
7956
8113
    case 1:
7957
 
      return new UFC_CahnHilliard2DBilinearForm_dof_map_1();
 
8114
      return new cahnhilliard2d_0_dof_map_1();
7958
8115
      break;
7959
8116
    case 2:
7960
 
      return new UFC_CahnHilliard2DBilinearForm_dof_map_2();
 
8117
      return new cahnhilliard2d_0_dof_map_2();
7961
8118
      break;
7962
8119
    case 3:
7963
 
      return new UFC_CahnHilliard2DBilinearForm_dof_map_3();
 
8120
      return new cahnhilliard2d_0_dof_map_3();
7964
8121
      break;
7965
8122
    case 4:
7966
 
      return new UFC_CahnHilliard2DBilinearForm_dof_map_4();
 
8123
      return new cahnhilliard2d_0_dof_map_4();
7967
8124
      break;
7968
8125
    case 5:
7969
 
      return new UFC_CahnHilliard2DBilinearForm_dof_map_5();
 
8126
      return new cahnhilliard2d_0_dof_map_5();
7970
8127
      break;
7971
8128
    case 6:
7972
 
      return new UFC_CahnHilliard2DBilinearForm_dof_map_6();
 
8129
      return new cahnhilliard2d_0_dof_map_6();
7973
8130
      break;
7974
8131
    }
7975
8132
    return 0;
7976
8133
}
7977
8134
 
7978
8135
/// Create a new cell integral on sub domain i
7979
 
ufc::cell_integral* UFC_CahnHilliard2DBilinearForm::create_cell_integral(unsigned int i) const
 
8136
ufc::cell_integral* cahnhilliard2d_form_0::create_cell_integral(unsigned int i) const
7980
8137
{
7981
 
    return new UFC_CahnHilliard2DBilinearForm_cell_integral_0();
 
8138
    return new cahnhilliard2d_0_cell_integral_0();
7982
8139
}
7983
8140
 
7984
8141
/// Create a new exterior facet integral on sub domain i
7985
 
ufc::exterior_facet_integral* UFC_CahnHilliard2DBilinearForm::create_exterior_facet_integral(unsigned int i) const
 
8142
ufc::exterior_facet_integral* cahnhilliard2d_form_0::create_exterior_facet_integral(unsigned int i) const
7986
8143
{
7987
8144
    return 0;
7988
8145
}
7989
8146
 
7990
8147
/// Create a new interior facet integral on sub domain i
7991
 
ufc::interior_facet_integral* UFC_CahnHilliard2DBilinearForm::create_interior_facet_integral(unsigned int i) const
7992
 
{
7993
 
    return 0;
7994
 
}
7995
 
 
7996
 
 
7997
 
/// Constructor
7998
 
UFC_CahnHilliard2DLinearForm_finite_element_0_0::UFC_CahnHilliard2DLinearForm_finite_element_0_0() : ufc::finite_element()
7999
 
{
8000
 
    // Do nothing
8001
 
}
8002
 
 
8003
 
/// Destructor
8004
 
UFC_CahnHilliard2DLinearForm_finite_element_0_0::~UFC_CahnHilliard2DLinearForm_finite_element_0_0()
8005
 
{
8006
 
    // Do nothing
8007
 
}
8008
 
 
8009
 
/// Return a string identifying the finite element
8010
 
const char* UFC_CahnHilliard2DLinearForm_finite_element_0_0::signature() const
8011
 
{
8012
 
    return "FiniteElement('Lagrange', 'triangle', 1)";
8013
 
}
8014
 
 
8015
 
/// Return the cell shape
8016
 
ufc::shape UFC_CahnHilliard2DLinearForm_finite_element_0_0::cell_shape() const
8017
 
{
8018
 
    return ufc::triangle;
8019
 
}
8020
 
 
8021
 
/// Return the dimension of the finite element function space
8022
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_0_0::space_dimension() const
8023
 
{
8024
 
    return 3;
8025
 
}
8026
 
 
8027
 
/// Return the rank of the value space
8028
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_0_0::value_rank() const
8029
 
{
8030
 
    return 0;
8031
 
}
8032
 
 
8033
 
/// Return the dimension of the value space for axis i
8034
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_0_0::value_dimension(unsigned int i) const
8035
 
{
8036
 
    return 1;
8037
 
}
8038
 
 
8039
 
/// Evaluate basis function i at given point in cell
8040
 
void UFC_CahnHilliard2DLinearForm_finite_element_0_0::evaluate_basis(unsigned int i,
8041
 
                                   double* values,
8042
 
                                   const double* coordinates,
8043
 
                                   const ufc::cell& c) const
8044
 
{
8045
 
    // Extract vertex coordinates
8046
 
    const double * const * element_coordinates = c.coordinates;
8047
 
    
8048
 
    // Compute Jacobian of affine map from reference cell
8049
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
8050
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
8051
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
8052
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
8053
 
      
8054
 
    // Compute determinant of Jacobian
8055
 
    const double detJ = J_00*J_11 - J_01*J_10;
8056
 
    
8057
 
    // Compute inverse of Jacobian
8058
 
    
8059
 
    // Get coordinates and map to the reference (UFC) element
8060
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
8061
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
8062
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
8063
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
8064
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
8065
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
8066
 
    
8067
 
    // Map coordinates to the reference square
8068
 
    if (std::abs(y - 1.0) < 1e-14)
8069
 
      x = -1.0;
8070
 
    else
8071
 
      x = 2.0 *x/(1.0 - y) - 1.0;
8072
 
    y = 2.0*y - 1.0;
8073
 
    
8074
 
    // Reset values
8075
 
    *values = 0;
8076
 
    
8077
 
    // Map degree of freedom to element degree of freedom
8078
 
    const unsigned int dof = i;
8079
 
    
8080
 
    // Generate scalings
8081
 
    const double scalings_y_0 = 1;
8082
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
8083
 
    
8084
 
    // Compute psitilde_a
8085
 
    const double psitilde_a_0 = 1;
8086
 
    const double psitilde_a_1 = x;
8087
 
    
8088
 
    // Compute psitilde_bs
8089
 
    const double psitilde_bs_0_0 = 1;
8090
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
8091
 
    const double psitilde_bs_1_0 = 1;
8092
 
    
8093
 
    // Compute basisvalues
8094
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
8095
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
8096
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
8097
 
    
8098
 
    // Table(s) of coefficients
8099
 
    const static double coefficients0[3][3] = \
8100
 
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
8101
 
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
8102
 
    {0.471404520791032, 0, 0.333333333333333}};
8103
 
    
8104
 
    // Extract relevant coefficients
8105
 
    const double coeff0_0 = coefficients0[dof][0];
8106
 
    const double coeff0_1 = coefficients0[dof][1];
8107
 
    const double coeff0_2 = coefficients0[dof][2];
8108
 
    
8109
 
    // Compute value(s)
8110
 
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
8111
 
}
8112
 
 
8113
 
/// Evaluate all basis functions at given point in cell
8114
 
void UFC_CahnHilliard2DLinearForm_finite_element_0_0::evaluate_basis_all(double* values,
8115
 
                                       const double* coordinates,
8116
 
                                       const ufc::cell& c) const
8117
 
{
8118
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
8119
 
}
8120
 
 
8121
 
/// Evaluate order n derivatives of basis function i at given point in cell
8122
 
void UFC_CahnHilliard2DLinearForm_finite_element_0_0::evaluate_basis_derivatives(unsigned int i,
8123
 
                                               unsigned int n,
8124
 
                                               double* values,
8125
 
                                               const double* coordinates,
8126
 
                                               const ufc::cell& c) const
8127
 
{
8128
 
    // Extract vertex coordinates
8129
 
    const double * const * element_coordinates = c.coordinates;
8130
 
    
8131
 
    // Compute Jacobian of affine map from reference cell
8132
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
8133
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
8134
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
8135
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
8136
 
      
8137
 
    // Compute determinant of Jacobian
8138
 
    const double detJ = J_00*J_11 - J_01*J_10;
8139
 
    
8140
 
    // Compute inverse of Jacobian
8141
 
    
8142
 
    // Get coordinates and map to the reference (UFC) element
8143
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
8144
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
8145
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
8146
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
8147
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
8148
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
8149
 
    
8150
 
    // Map coordinates to the reference square
8151
 
    if (std::abs(y - 1.0) < 1e-14)
8152
 
      x = -1.0;
8153
 
    else
8154
 
      x = 2.0 *x/(1.0 - y) - 1.0;
8155
 
    y = 2.0*y - 1.0;
8156
 
    
8157
 
    // Compute number of derivatives
8158
 
    unsigned int num_derivatives = 1;
8159
 
    
8160
 
    for (unsigned int j = 0; j < n; j++)
8161
 
      num_derivatives *= 2;
8162
 
    
8163
 
    
8164
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
8165
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
8166
 
        
8167
 
    for (unsigned int j = 0; j < num_derivatives; j++)
8168
 
    {
8169
 
      combinations[j] = new unsigned int [n];
8170
 
      for (unsigned int k = 0; k < n; k++)
8171
 
        combinations[j][k] = 0;
8172
 
    }
8173
 
        
8174
 
    // Generate combinations of derivatives
8175
 
    for (unsigned int row = 1; row < num_derivatives; row++)
8176
 
    {
8177
 
      for (unsigned int num = 0; num < row; num++)
8178
 
      {
8179
 
        for (unsigned int col = n-1; col+1 > 0; col--)
8180
 
        {
8181
 
          if (combinations[row][col] + 1 > 1)
8182
 
            combinations[row][col] = 0;
8183
 
          else
8184
 
          {
8185
 
            combinations[row][col] += 1;
8186
 
            break;
8187
 
          }
8188
 
        }
8189
 
      }
8190
 
    }
8191
 
    
8192
 
    // Compute inverse of Jacobian
8193
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
8194
 
    
8195
 
    // Declare transformation matrix
8196
 
    // Declare pointer to two dimensional array and initialise
8197
 
    double **transform = new double *[num_derivatives];
8198
 
        
8199
 
    for (unsigned int j = 0; j < num_derivatives; j++)
8200
 
    {
8201
 
      transform[j] = new double [num_derivatives];
8202
 
      for (unsigned int k = 0; k < num_derivatives; k++)
8203
 
        transform[j][k] = 1;
8204
 
    }
8205
 
    
8206
 
    // Construct transformation matrix
8207
 
    for (unsigned int row = 0; row < num_derivatives; row++)
8208
 
    {
8209
 
      for (unsigned int col = 0; col < num_derivatives; col++)
8210
 
      {
8211
 
        for (unsigned int k = 0; k < n; k++)
8212
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
8213
 
      }
8214
 
    }
8215
 
    
8216
 
    // Reset values
8217
 
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
8218
 
      values[j] = 0;
8219
 
    
8220
 
    // Map degree of freedom to element degree of freedom
8221
 
    const unsigned int dof = i;
8222
 
    
8223
 
    // Generate scalings
8224
 
    const double scalings_y_0 = 1;
8225
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
8226
 
    
8227
 
    // Compute psitilde_a
8228
 
    const double psitilde_a_0 = 1;
8229
 
    const double psitilde_a_1 = x;
8230
 
    
8231
 
    // Compute psitilde_bs
8232
 
    const double psitilde_bs_0_0 = 1;
8233
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
8234
 
    const double psitilde_bs_1_0 = 1;
8235
 
    
8236
 
    // Compute basisvalues
8237
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
8238
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
8239
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
8240
 
    
8241
 
    // Table(s) of coefficients
8242
 
    const static double coefficients0[3][3] = \
8243
 
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
8244
 
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
8245
 
    {0.471404520791032, 0, 0.333333333333333}};
8246
 
    
8247
 
    // Interesting (new) part
8248
 
    // Tables of derivatives of the polynomial base (transpose)
8249
 
    const static double dmats0[3][3] = \
8250
 
    {{0, 0, 0},
8251
 
    {4.89897948556636, 0, 0},
8252
 
    {0, 0, 0}};
8253
 
    
8254
 
    const static double dmats1[3][3] = \
8255
 
    {{0, 0, 0},
8256
 
    {2.44948974278318, 0, 0},
8257
 
    {4.24264068711928, 0, 0}};
8258
 
    
8259
 
    // Compute reference derivatives
8260
 
    // Declare pointer to array of derivatives on FIAT element
8261
 
    double *derivatives = new double [num_derivatives];
8262
 
    
8263
 
    // Declare coefficients
8264
 
    double coeff0_0 = 0;
8265
 
    double coeff0_1 = 0;
8266
 
    double coeff0_2 = 0;
8267
 
    
8268
 
    // Declare new coefficients
8269
 
    double new_coeff0_0 = 0;
8270
 
    double new_coeff0_1 = 0;
8271
 
    double new_coeff0_2 = 0;
8272
 
    
8273
 
    // Loop possible derivatives
8274
 
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
8275
 
    {
8276
 
      // Get values from coefficients array
8277
 
      new_coeff0_0 = coefficients0[dof][0];
8278
 
      new_coeff0_1 = coefficients0[dof][1];
8279
 
      new_coeff0_2 = coefficients0[dof][2];
8280
 
    
8281
 
      // Loop derivative order
8282
 
      for (unsigned int j = 0; j < n; j++)
8283
 
      {
8284
 
        // Update old coefficients
8285
 
        coeff0_0 = new_coeff0_0;
8286
 
        coeff0_1 = new_coeff0_1;
8287
 
        coeff0_2 = new_coeff0_2;
8288
 
    
8289
 
        if(combinations[deriv_num][j] == 0)
8290
 
        {
8291
 
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
8292
 
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
8293
 
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
8294
 
        }
8295
 
        if(combinations[deriv_num][j] == 1)
8296
 
        {
8297
 
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
8298
 
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
8299
 
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
8300
 
        }
8301
 
    
8302
 
      }
8303
 
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
8304
 
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
8305
 
    }
8306
 
    
8307
 
    // Transform derivatives back to physical element
8308
 
    for (unsigned int row = 0; row < num_derivatives; row++)
8309
 
    {
8310
 
      for (unsigned int col = 0; col < num_derivatives; col++)
8311
 
      {
8312
 
        values[row] += transform[row][col]*derivatives[col];
8313
 
      }
8314
 
    }
8315
 
    // Delete pointer to array of derivatives on FIAT element
8316
 
    delete [] derivatives;
8317
 
    
8318
 
    // Delete pointer to array of combinations of derivatives and transform
8319
 
    for (unsigned int row = 0; row < num_derivatives; row++)
8320
 
    {
8321
 
      delete [] combinations[row];
8322
 
      delete [] transform[row];
8323
 
    }
8324
 
    
8325
 
    delete [] combinations;
8326
 
    delete [] transform;
8327
 
}
8328
 
 
8329
 
/// Evaluate order n derivatives of all basis functions at given point in cell
8330
 
void UFC_CahnHilliard2DLinearForm_finite_element_0_0::evaluate_basis_derivatives_all(unsigned int n,
8331
 
                                                   double* values,
8332
 
                                                   const double* coordinates,
8333
 
                                                   const ufc::cell& c) const
8334
 
{
8335
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
8336
 
}
8337
 
 
8338
 
/// Evaluate linear functional for dof i on the function f
8339
 
double UFC_CahnHilliard2DLinearForm_finite_element_0_0::evaluate_dof(unsigned int i,
8340
 
                                   const ufc::function& f,
8341
 
                                   const ufc::cell& c) const
8342
 
{
8343
 
    // The reference points, direction and weights:
8344
 
    const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
8345
 
    const static double W[3][1] = {{1}, {1}, {1}};
8346
 
    const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
8347
 
    
8348
 
    const double * const * x = c.coordinates;
8349
 
    double result = 0.0;
8350
 
    // Iterate over the points:
8351
 
    // Evaluate basis functions for affine mapping
8352
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
8353
 
    const double w1 = X[i][0][0];
8354
 
    const double w2 = X[i][0][1];
8355
 
    
8356
 
    // Compute affine mapping y = F(X)
8357
 
    double y[2];
8358
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
8359
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
8360
 
    
8361
 
    // Evaluate function at physical points
8362
 
    double values[1];
8363
 
    f.evaluate(values, y, c);
8364
 
    
8365
 
    // Map function values using appropriate mapping
8366
 
    // Affine map: Do nothing
8367
 
    
8368
 
    // Note that we do not map the weights (yet).
8369
 
    
8370
 
    // Take directional components
8371
 
    for(int k = 0; k < 1; k++)
8372
 
      result += values[k]*D[i][0][k];
8373
 
    // Multiply by weights 
8374
 
    result *= W[i][0];
8375
 
    
8376
 
    return result;
8377
 
}
8378
 
 
8379
 
/// Evaluate linear functionals for all dofs on the function f
8380
 
void UFC_CahnHilliard2DLinearForm_finite_element_0_0::evaluate_dofs(double* values,
8381
 
                                  const ufc::function& f,
8382
 
                                  const ufc::cell& c) const
8383
 
{
8384
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
8385
 
}
8386
 
 
8387
 
/// Interpolate vertex values from dof values
8388
 
void UFC_CahnHilliard2DLinearForm_finite_element_0_0::interpolate_vertex_values(double* vertex_values,
8389
 
                                              const double* dof_values,
8390
 
                                              const ufc::cell& c) const
8391
 
{
8392
 
    // Evaluate at vertices and use affine mapping
8393
 
    vertex_values[0] = dof_values[0];
8394
 
    vertex_values[1] = dof_values[1];
8395
 
    vertex_values[2] = dof_values[2];
8396
 
}
8397
 
 
8398
 
/// Return the number of sub elements (for a mixed element)
8399
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_0_0::num_sub_elements() const
8400
 
{
8401
 
    return 1;
8402
 
}
8403
 
 
8404
 
/// Create a new finite element for sub element i (for a mixed element)
8405
 
ufc::finite_element* UFC_CahnHilliard2DLinearForm_finite_element_0_0::create_sub_element(unsigned int i) const
8406
 
{
8407
 
    return new UFC_CahnHilliard2DLinearForm_finite_element_0_0();
8408
 
}
8409
 
 
8410
 
 
8411
 
/// Constructor
8412
 
UFC_CahnHilliard2DLinearForm_finite_element_0_1::UFC_CahnHilliard2DLinearForm_finite_element_0_1() : ufc::finite_element()
8413
 
{
8414
 
    // Do nothing
8415
 
}
8416
 
 
8417
 
/// Destructor
8418
 
UFC_CahnHilliard2DLinearForm_finite_element_0_1::~UFC_CahnHilliard2DLinearForm_finite_element_0_1()
8419
 
{
8420
 
    // Do nothing
8421
 
}
8422
 
 
8423
 
/// Return a string identifying the finite element
8424
 
const char* UFC_CahnHilliard2DLinearForm_finite_element_0_1::signature() const
8425
 
{
8426
 
    return "FiniteElement('Lagrange', 'triangle', 1)";
8427
 
}
8428
 
 
8429
 
/// Return the cell shape
8430
 
ufc::shape UFC_CahnHilliard2DLinearForm_finite_element_0_1::cell_shape() const
8431
 
{
8432
 
    return ufc::triangle;
8433
 
}
8434
 
 
8435
 
/// Return the dimension of the finite element function space
8436
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_0_1::space_dimension() const
8437
 
{
8438
 
    return 3;
8439
 
}
8440
 
 
8441
 
/// Return the rank of the value space
8442
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_0_1::value_rank() const
8443
 
{
8444
 
    return 0;
8445
 
}
8446
 
 
8447
 
/// Return the dimension of the value space for axis i
8448
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_0_1::value_dimension(unsigned int i) const
8449
 
{
8450
 
    return 1;
8451
 
}
8452
 
 
8453
 
/// Evaluate basis function i at given point in cell
8454
 
void UFC_CahnHilliard2DLinearForm_finite_element_0_1::evaluate_basis(unsigned int i,
8455
 
                                   double* values,
8456
 
                                   const double* coordinates,
8457
 
                                   const ufc::cell& c) const
8458
 
{
8459
 
    // Extract vertex coordinates
8460
 
    const double * const * element_coordinates = c.coordinates;
8461
 
    
8462
 
    // Compute Jacobian of affine map from reference cell
8463
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
8464
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
8465
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
8466
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
8467
 
      
8468
 
    // Compute determinant of Jacobian
8469
 
    const double detJ = J_00*J_11 - J_01*J_10;
8470
 
    
8471
 
    // Compute inverse of Jacobian
8472
 
    
8473
 
    // Get coordinates and map to the reference (UFC) element
8474
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
8475
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
8476
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
8477
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
8478
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
8479
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
8480
 
    
8481
 
    // Map coordinates to the reference square
8482
 
    if (std::abs(y - 1.0) < 1e-14)
8483
 
      x = -1.0;
8484
 
    else
8485
 
      x = 2.0 *x/(1.0 - y) - 1.0;
8486
 
    y = 2.0*y - 1.0;
8487
 
    
8488
 
    // Reset values
8489
 
    *values = 0;
8490
 
    
8491
 
    // Map degree of freedom to element degree of freedom
8492
 
    const unsigned int dof = i;
8493
 
    
8494
 
    // Generate scalings
8495
 
    const double scalings_y_0 = 1;
8496
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
8497
 
    
8498
 
    // Compute psitilde_a
8499
 
    const double psitilde_a_0 = 1;
8500
 
    const double psitilde_a_1 = x;
8501
 
    
8502
 
    // Compute psitilde_bs
8503
 
    const double psitilde_bs_0_0 = 1;
8504
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
8505
 
    const double psitilde_bs_1_0 = 1;
8506
 
    
8507
 
    // Compute basisvalues
8508
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
8509
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
8510
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
8511
 
    
8512
 
    // Table(s) of coefficients
8513
 
    const static double coefficients0[3][3] = \
8514
 
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
8515
 
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
8516
 
    {0.471404520791032, 0, 0.333333333333333}};
8517
 
    
8518
 
    // Extract relevant coefficients
8519
 
    const double coeff0_0 = coefficients0[dof][0];
8520
 
    const double coeff0_1 = coefficients0[dof][1];
8521
 
    const double coeff0_2 = coefficients0[dof][2];
8522
 
    
8523
 
    // Compute value(s)
8524
 
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
8525
 
}
8526
 
 
8527
 
/// Evaluate all basis functions at given point in cell
8528
 
void UFC_CahnHilliard2DLinearForm_finite_element_0_1::evaluate_basis_all(double* values,
8529
 
                                       const double* coordinates,
8530
 
                                       const ufc::cell& c) const
8531
 
{
8532
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
8533
 
}
8534
 
 
8535
 
/// Evaluate order n derivatives of basis function i at given point in cell
8536
 
void UFC_CahnHilliard2DLinearForm_finite_element_0_1::evaluate_basis_derivatives(unsigned int i,
8537
 
                                               unsigned int n,
8538
 
                                               double* values,
8539
 
                                               const double* coordinates,
8540
 
                                               const ufc::cell& c) const
8541
 
{
8542
 
    // Extract vertex coordinates
8543
 
    const double * const * element_coordinates = c.coordinates;
8544
 
    
8545
 
    // Compute Jacobian of affine map from reference cell
8546
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
8547
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
8548
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
8549
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
8550
 
      
8551
 
    // Compute determinant of Jacobian
8552
 
    const double detJ = J_00*J_11 - J_01*J_10;
8553
 
    
8554
 
    // Compute inverse of Jacobian
8555
 
    
8556
 
    // Get coordinates and map to the reference (UFC) element
8557
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
8558
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
8559
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
8560
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
8561
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
8562
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
8563
 
    
8564
 
    // Map coordinates to the reference square
8565
 
    if (std::abs(y - 1.0) < 1e-14)
8566
 
      x = -1.0;
8567
 
    else
8568
 
      x = 2.0 *x/(1.0 - y) - 1.0;
8569
 
    y = 2.0*y - 1.0;
8570
 
    
8571
 
    // Compute number of derivatives
8572
 
    unsigned int num_derivatives = 1;
8573
 
    
8574
 
    for (unsigned int j = 0; j < n; j++)
8575
 
      num_derivatives *= 2;
8576
 
    
8577
 
    
8578
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
8579
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
8580
 
        
8581
 
    for (unsigned int j = 0; j < num_derivatives; j++)
8582
 
    {
8583
 
      combinations[j] = new unsigned int [n];
8584
 
      for (unsigned int k = 0; k < n; k++)
8585
 
        combinations[j][k] = 0;
8586
 
    }
8587
 
        
8588
 
    // Generate combinations of derivatives
8589
 
    for (unsigned int row = 1; row < num_derivatives; row++)
8590
 
    {
8591
 
      for (unsigned int num = 0; num < row; num++)
8592
 
      {
8593
 
        for (unsigned int col = n-1; col+1 > 0; col--)
8594
 
        {
8595
 
          if (combinations[row][col] + 1 > 1)
8596
 
            combinations[row][col] = 0;
8597
 
          else
8598
 
          {
8599
 
            combinations[row][col] += 1;
8600
 
            break;
8601
 
          }
8602
 
        }
8603
 
      }
8604
 
    }
8605
 
    
8606
 
    // Compute inverse of Jacobian
8607
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
8608
 
    
8609
 
    // Declare transformation matrix
8610
 
    // Declare pointer to two dimensional array and initialise
8611
 
    double **transform = new double *[num_derivatives];
8612
 
        
8613
 
    for (unsigned int j = 0; j < num_derivatives; j++)
8614
 
    {
8615
 
      transform[j] = new double [num_derivatives];
8616
 
      for (unsigned int k = 0; k < num_derivatives; k++)
8617
 
        transform[j][k] = 1;
8618
 
    }
8619
 
    
8620
 
    // Construct transformation matrix
8621
 
    for (unsigned int row = 0; row < num_derivatives; row++)
8622
 
    {
8623
 
      for (unsigned int col = 0; col < num_derivatives; col++)
8624
 
      {
8625
 
        for (unsigned int k = 0; k < n; k++)
8626
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
8627
 
      }
8628
 
    }
8629
 
    
8630
 
    // Reset values
8631
 
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
8632
 
      values[j] = 0;
8633
 
    
8634
 
    // Map degree of freedom to element degree of freedom
8635
 
    const unsigned int dof = i;
8636
 
    
8637
 
    // Generate scalings
8638
 
    const double scalings_y_0 = 1;
8639
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
8640
 
    
8641
 
    // Compute psitilde_a
8642
 
    const double psitilde_a_0 = 1;
8643
 
    const double psitilde_a_1 = x;
8644
 
    
8645
 
    // Compute psitilde_bs
8646
 
    const double psitilde_bs_0_0 = 1;
8647
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
8648
 
    const double psitilde_bs_1_0 = 1;
8649
 
    
8650
 
    // Compute basisvalues
8651
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
8652
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
8653
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
8654
 
    
8655
 
    // Table(s) of coefficients
8656
 
    const static double coefficients0[3][3] = \
8657
 
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
8658
 
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
8659
 
    {0.471404520791032, 0, 0.333333333333333}};
8660
 
    
8661
 
    // Interesting (new) part
8662
 
    // Tables of derivatives of the polynomial base (transpose)
8663
 
    const static double dmats0[3][3] = \
8664
 
    {{0, 0, 0},
8665
 
    {4.89897948556636, 0, 0},
8666
 
    {0, 0, 0}};
8667
 
    
8668
 
    const static double dmats1[3][3] = \
8669
 
    {{0, 0, 0},
8670
 
    {2.44948974278318, 0, 0},
8671
 
    {4.24264068711928, 0, 0}};
8672
 
    
8673
 
    // Compute reference derivatives
8674
 
    // Declare pointer to array of derivatives on FIAT element
8675
 
    double *derivatives = new double [num_derivatives];
8676
 
    
8677
 
    // Declare coefficients
8678
 
    double coeff0_0 = 0;
8679
 
    double coeff0_1 = 0;
8680
 
    double coeff0_2 = 0;
8681
 
    
8682
 
    // Declare new coefficients
8683
 
    double new_coeff0_0 = 0;
8684
 
    double new_coeff0_1 = 0;
8685
 
    double new_coeff0_2 = 0;
8686
 
    
8687
 
    // Loop possible derivatives
8688
 
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
8689
 
    {
8690
 
      // Get values from coefficients array
8691
 
      new_coeff0_0 = coefficients0[dof][0];
8692
 
      new_coeff0_1 = coefficients0[dof][1];
8693
 
      new_coeff0_2 = coefficients0[dof][2];
8694
 
    
8695
 
      // Loop derivative order
8696
 
      for (unsigned int j = 0; j < n; j++)
8697
 
      {
8698
 
        // Update old coefficients
8699
 
        coeff0_0 = new_coeff0_0;
8700
 
        coeff0_1 = new_coeff0_1;
8701
 
        coeff0_2 = new_coeff0_2;
8702
 
    
8703
 
        if(combinations[deriv_num][j] == 0)
8704
 
        {
8705
 
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
8706
 
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
8707
 
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
8708
 
        }
8709
 
        if(combinations[deriv_num][j] == 1)
8710
 
        {
8711
 
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
8712
 
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
8713
 
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
8714
 
        }
8715
 
    
8716
 
      }
8717
 
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
8718
 
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
8719
 
    }
8720
 
    
8721
 
    // Transform derivatives back to physical element
8722
 
    for (unsigned int row = 0; row < num_derivatives; row++)
8723
 
    {
8724
 
      for (unsigned int col = 0; col < num_derivatives; col++)
8725
 
      {
8726
 
        values[row] += transform[row][col]*derivatives[col];
8727
 
      }
8728
 
    }
8729
 
    // Delete pointer to array of derivatives on FIAT element
8730
 
    delete [] derivatives;
8731
 
    
8732
 
    // Delete pointer to array of combinations of derivatives and transform
8733
 
    for (unsigned int row = 0; row < num_derivatives; row++)
8734
 
    {
8735
 
      delete [] combinations[row];
8736
 
      delete [] transform[row];
8737
 
    }
8738
 
    
8739
 
    delete [] combinations;
8740
 
    delete [] transform;
8741
 
}
8742
 
 
8743
 
/// Evaluate order n derivatives of all basis functions at given point in cell
8744
 
void UFC_CahnHilliard2DLinearForm_finite_element_0_1::evaluate_basis_derivatives_all(unsigned int n,
8745
 
                                                   double* values,
8746
 
                                                   const double* coordinates,
8747
 
                                                   const ufc::cell& c) const
8748
 
{
8749
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
8750
 
}
8751
 
 
8752
 
/// Evaluate linear functional for dof i on the function f
8753
 
double UFC_CahnHilliard2DLinearForm_finite_element_0_1::evaluate_dof(unsigned int i,
8754
 
                                   const ufc::function& f,
8755
 
                                   const ufc::cell& c) const
8756
 
{
8757
 
    // The reference points, direction and weights:
8758
 
    const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
8759
 
    const static double W[3][1] = {{1}, {1}, {1}};
8760
 
    const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
8761
 
    
8762
 
    const double * const * x = c.coordinates;
8763
 
    double result = 0.0;
8764
 
    // Iterate over the points:
8765
 
    // Evaluate basis functions for affine mapping
8766
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
8767
 
    const double w1 = X[i][0][0];
8768
 
    const double w2 = X[i][0][1];
8769
 
    
8770
 
    // Compute affine mapping y = F(X)
8771
 
    double y[2];
8772
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
8773
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
8774
 
    
8775
 
    // Evaluate function at physical points
8776
 
    double values[1];
8777
 
    f.evaluate(values, y, c);
8778
 
    
8779
 
    // Map function values using appropriate mapping
8780
 
    // Affine map: Do nothing
8781
 
    
8782
 
    // Note that we do not map the weights (yet).
8783
 
    
8784
 
    // Take directional components
8785
 
    for(int k = 0; k < 1; k++)
8786
 
      result += values[k]*D[i][0][k];
8787
 
    // Multiply by weights 
8788
 
    result *= W[i][0];
8789
 
    
8790
 
    return result;
8791
 
}
8792
 
 
8793
 
/// Evaluate linear functionals for all dofs on the function f
8794
 
void UFC_CahnHilliard2DLinearForm_finite_element_0_1::evaluate_dofs(double* values,
8795
 
                                  const ufc::function& f,
8796
 
                                  const ufc::cell& c) const
8797
 
{
8798
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
8799
 
}
8800
 
 
8801
 
/// Interpolate vertex values from dof values
8802
 
void UFC_CahnHilliard2DLinearForm_finite_element_0_1::interpolate_vertex_values(double* vertex_values,
8803
 
                                              const double* dof_values,
8804
 
                                              const ufc::cell& c) const
8805
 
{
8806
 
    // Evaluate at vertices and use affine mapping
8807
 
    vertex_values[0] = dof_values[0];
8808
 
    vertex_values[1] = dof_values[1];
8809
 
    vertex_values[2] = dof_values[2];
8810
 
}
8811
 
 
8812
 
/// Return the number of sub elements (for a mixed element)
8813
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_0_1::num_sub_elements() const
8814
 
{
8815
 
    return 1;
8816
 
}
8817
 
 
8818
 
/// Create a new finite element for sub element i (for a mixed element)
8819
 
ufc::finite_element* UFC_CahnHilliard2DLinearForm_finite_element_0_1::create_sub_element(unsigned int i) const
8820
 
{
8821
 
    return new UFC_CahnHilliard2DLinearForm_finite_element_0_1();
8822
 
}
8823
 
 
8824
 
 
8825
 
/// Constructor
8826
 
UFC_CahnHilliard2DLinearForm_finite_element_0::UFC_CahnHilliard2DLinearForm_finite_element_0() : ufc::finite_element()
8827
 
{
8828
 
    // Do nothing
8829
 
}
8830
 
 
8831
 
/// Destructor
8832
 
UFC_CahnHilliard2DLinearForm_finite_element_0::~UFC_CahnHilliard2DLinearForm_finite_element_0()
8833
 
{
8834
 
    // Do nothing
8835
 
}
8836
 
 
8837
 
/// Return a string identifying the finite element
8838
 
const char* UFC_CahnHilliard2DLinearForm_finite_element_0::signature() const
8839
 
{
8840
 
    return "MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
8841
 
}
8842
 
 
8843
 
/// Return the cell shape
8844
 
ufc::shape UFC_CahnHilliard2DLinearForm_finite_element_0::cell_shape() const
8845
 
{
8846
 
    return ufc::triangle;
8847
 
}
8848
 
 
8849
 
/// Return the dimension of the finite element function space
8850
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_0::space_dimension() const
8851
 
{
8852
 
    return 6;
8853
 
}
8854
 
 
8855
 
/// Return the rank of the value space
8856
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_0::value_rank() const
8857
 
{
8858
 
    return 1;
8859
 
}
8860
 
 
8861
 
/// Return the dimension of the value space for axis i
8862
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_0::value_dimension(unsigned int i) const
8863
 
{
8864
 
    return 2;
8865
 
}
8866
 
 
8867
 
/// Evaluate basis function i at given point in cell
8868
 
void UFC_CahnHilliard2DLinearForm_finite_element_0::evaluate_basis(unsigned int i,
8869
 
                                   double* values,
8870
 
                                   const double* coordinates,
8871
 
                                   const ufc::cell& c) const
8872
 
{
8873
 
    // Extract vertex coordinates
8874
 
    const double * const * element_coordinates = c.coordinates;
8875
 
    
8876
 
    // Compute Jacobian of affine map from reference cell
8877
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
8878
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
8879
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
8880
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
8881
 
      
8882
 
    // Compute determinant of Jacobian
8883
 
    const double detJ = J_00*J_11 - J_01*J_10;
8884
 
    
8885
 
    // Compute inverse of Jacobian
8886
 
    
8887
 
    // Get coordinates and map to the reference (UFC) element
8888
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
8889
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
8890
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
8891
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
8892
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
8893
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
8894
 
    
8895
 
    // Map coordinates to the reference square
8896
 
    if (std::abs(y - 1.0) < 1e-14)
8897
 
      x = -1.0;
8898
 
    else
8899
 
      x = 2.0 *x/(1.0 - y) - 1.0;
8900
 
    y = 2.0*y - 1.0;
8901
 
    
8902
 
    // Reset values
8903
 
    values[0] = 0;
8904
 
    values[1] = 0;
8905
 
    
8906
 
    if (0 <= i && i <= 2)
8907
 
    {
8908
 
      // Map degree of freedom to element degree of freedom
8909
 
      const unsigned int dof = i;
8910
 
    
8911
 
      // Generate scalings
8912
 
      const double scalings_y_0 = 1;
8913
 
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
8914
 
    
8915
 
      // Compute psitilde_a
8916
 
      const double psitilde_a_0 = 1;
8917
 
      const double psitilde_a_1 = x;
8918
 
    
8919
 
      // Compute psitilde_bs
8920
 
      const double psitilde_bs_0_0 = 1;
8921
 
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
8922
 
      const double psitilde_bs_1_0 = 1;
8923
 
    
8924
 
      // Compute basisvalues
8925
 
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
8926
 
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
8927
 
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
8928
 
    
8929
 
      // Table(s) of coefficients
8930
 
      const static double coefficients0[3][3] =   \
8931
 
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
8932
 
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
8933
 
      {0.471404520791032, 0, 0.333333333333333}};
8934
 
    
8935
 
      // Extract relevant coefficients
8936
 
      const double coeff0_0 =   coefficients0[dof][0];
8937
 
      const double coeff0_1 =   coefficients0[dof][1];
8938
 
      const double coeff0_2 =   coefficients0[dof][2];
8939
 
    
8940
 
      // Compute value(s)
8941
 
      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
8942
 
    }
8943
 
    
8944
 
    if (3 <= i && i <= 5)
8945
 
    {
8946
 
      // Map degree of freedom to element degree of freedom
8947
 
      const unsigned int dof = i - 3;
8948
 
    
8949
 
      // Generate scalings
8950
 
      const double scalings_y_0 = 1;
8951
 
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
8952
 
    
8953
 
      // Compute psitilde_a
8954
 
      const double psitilde_a_0 = 1;
8955
 
      const double psitilde_a_1 = x;
8956
 
    
8957
 
      // Compute psitilde_bs
8958
 
      const double psitilde_bs_0_0 = 1;
8959
 
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
8960
 
      const double psitilde_bs_1_0 = 1;
8961
 
    
8962
 
      // Compute basisvalues
8963
 
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
8964
 
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
8965
 
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
8966
 
    
8967
 
      // Table(s) of coefficients
8968
 
      const static double coefficients0[3][3] =   \
8969
 
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
8970
 
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
8971
 
      {0.471404520791032, 0, 0.333333333333333}};
8972
 
    
8973
 
      // Extract relevant coefficients
8974
 
      const double coeff0_0 =   coefficients0[dof][0];
8975
 
      const double coeff0_1 =   coefficients0[dof][1];
8976
 
      const double coeff0_2 =   coefficients0[dof][2];
8977
 
    
8978
 
      // Compute value(s)
8979
 
      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
8980
 
    }
8981
 
    
8982
 
}
8983
 
 
8984
 
/// Evaluate all basis functions at given point in cell
8985
 
void UFC_CahnHilliard2DLinearForm_finite_element_0::evaluate_basis_all(double* values,
8986
 
                                       const double* coordinates,
8987
 
                                       const ufc::cell& c) const
8988
 
{
8989
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
8990
 
}
8991
 
 
8992
 
/// Evaluate order n derivatives of basis function i at given point in cell
8993
 
void UFC_CahnHilliard2DLinearForm_finite_element_0::evaluate_basis_derivatives(unsigned int i,
8994
 
                                               unsigned int n,
8995
 
                                               double* values,
8996
 
                                               const double* coordinates,
8997
 
                                               const ufc::cell& c) const
8998
 
{
8999
 
    // Extract vertex coordinates
9000
 
    const double * const * element_coordinates = c.coordinates;
9001
 
    
9002
 
    // Compute Jacobian of affine map from reference cell
9003
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
9004
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
9005
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
9006
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
9007
 
      
9008
 
    // Compute determinant of Jacobian
9009
 
    const double detJ = J_00*J_11 - J_01*J_10;
9010
 
    
9011
 
    // Compute inverse of Jacobian
9012
 
    
9013
 
    // Get coordinates and map to the reference (UFC) element
9014
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
9015
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
9016
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
9017
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
9018
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
9019
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
9020
 
    
9021
 
    // Map coordinates to the reference square
9022
 
    if (std::abs(y - 1.0) < 1e-14)
9023
 
      x = -1.0;
9024
 
    else
9025
 
      x = 2.0 *x/(1.0 - y) - 1.0;
9026
 
    y = 2.0*y - 1.0;
9027
 
    
9028
 
    // Compute number of derivatives
9029
 
    unsigned int num_derivatives = 1;
9030
 
    
9031
 
    for (unsigned int j = 0; j < n; j++)
9032
 
      num_derivatives *= 2;
9033
 
    
9034
 
    
9035
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
9036
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
9037
 
        
9038
 
    for (unsigned int j = 0; j < num_derivatives; j++)
9039
 
    {
9040
 
      combinations[j] = new unsigned int [n];
9041
 
      for (unsigned int k = 0; k < n; k++)
9042
 
        combinations[j][k] = 0;
9043
 
    }
9044
 
        
9045
 
    // Generate combinations of derivatives
9046
 
    for (unsigned int row = 1; row < num_derivatives; row++)
9047
 
    {
9048
 
      for (unsigned int num = 0; num < row; num++)
9049
 
      {
9050
 
        for (unsigned int col = n-1; col+1 > 0; col--)
9051
 
        {
9052
 
          if (combinations[row][col] + 1 > 1)
9053
 
            combinations[row][col] = 0;
9054
 
          else
9055
 
          {
9056
 
            combinations[row][col] += 1;
9057
 
            break;
9058
 
          }
9059
 
        }
9060
 
      }
9061
 
    }
9062
 
    
9063
 
    // Compute inverse of Jacobian
9064
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
9065
 
    
9066
 
    // Declare transformation matrix
9067
 
    // Declare pointer to two dimensional array and initialise
9068
 
    double **transform = new double *[num_derivatives];
9069
 
        
9070
 
    for (unsigned int j = 0; j < num_derivatives; j++)
9071
 
    {
9072
 
      transform[j] = new double [num_derivatives];
9073
 
      for (unsigned int k = 0; k < num_derivatives; k++)
9074
 
        transform[j][k] = 1;
9075
 
    }
9076
 
    
9077
 
    // Construct transformation matrix
9078
 
    for (unsigned int row = 0; row < num_derivatives; row++)
9079
 
    {
9080
 
      for (unsigned int col = 0; col < num_derivatives; col++)
9081
 
      {
9082
 
        for (unsigned int k = 0; k < n; k++)
9083
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
9084
 
      }
9085
 
    }
9086
 
    
9087
 
    // Reset values
9088
 
    for (unsigned int j = 0; j < 2*num_derivatives; j++)
9089
 
      values[j] = 0;
9090
 
    
9091
 
    if (0 <= i && i <= 2)
9092
 
    {
9093
 
      // Map degree of freedom to element degree of freedom
9094
 
      const unsigned int dof = i;
9095
 
    
9096
 
      // Generate scalings
9097
 
      const double scalings_y_0 = 1;
9098
 
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
9099
 
    
9100
 
      // Compute psitilde_a
9101
 
      const double psitilde_a_0 = 1;
9102
 
      const double psitilde_a_1 = x;
9103
 
    
9104
 
      // Compute psitilde_bs
9105
 
      const double psitilde_bs_0_0 = 1;
9106
 
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
9107
 
      const double psitilde_bs_1_0 = 1;
9108
 
    
9109
 
      // Compute basisvalues
9110
 
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
9111
 
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
9112
 
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
9113
 
    
9114
 
      // Table(s) of coefficients
9115
 
      const static double coefficients0[3][3] =   \
9116
 
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
9117
 
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
9118
 
      {0.471404520791032, 0, 0.333333333333333}};
9119
 
    
9120
 
      // Interesting (new) part
9121
 
      // Tables of derivatives of the polynomial base (transpose)
9122
 
      const static double dmats0[3][3] =   \
9123
 
      {{0, 0, 0},
9124
 
      {4.89897948556636, 0, 0},
9125
 
      {0, 0, 0}};
9126
 
    
9127
 
      const static double dmats1[3][3] =   \
9128
 
      {{0, 0, 0},
9129
 
      {2.44948974278318, 0, 0},
9130
 
      {4.24264068711928, 0, 0}};
9131
 
    
9132
 
      // Compute reference derivatives
9133
 
      // Declare pointer to array of derivatives on FIAT element
9134
 
      double *derivatives = new double [num_derivatives];
9135
 
    
9136
 
      // Declare coefficients
9137
 
      double coeff0_0 = 0;
9138
 
      double coeff0_1 = 0;
9139
 
      double coeff0_2 = 0;
9140
 
    
9141
 
      // Declare new coefficients
9142
 
      double new_coeff0_0 = 0;
9143
 
      double new_coeff0_1 = 0;
9144
 
      double new_coeff0_2 = 0;
9145
 
    
9146
 
      // Loop possible derivatives
9147
 
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
9148
 
      {
9149
 
        // Get values from coefficients array
9150
 
        new_coeff0_0 = coefficients0[dof][0];
9151
 
        new_coeff0_1 = coefficients0[dof][1];
9152
 
        new_coeff0_2 = coefficients0[dof][2];
9153
 
    
9154
 
        // Loop derivative order
9155
 
        for (unsigned int j = 0; j < n; j++)
9156
 
        {
9157
 
          // Update old coefficients
9158
 
          coeff0_0 = new_coeff0_0;
9159
 
          coeff0_1 = new_coeff0_1;
9160
 
          coeff0_2 = new_coeff0_2;
9161
 
    
9162
 
          if(combinations[deriv_num][j] == 0)
9163
 
          {
9164
 
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
9165
 
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
9166
 
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
9167
 
          }
9168
 
          if(combinations[deriv_num][j] == 1)
9169
 
          {
9170
 
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
9171
 
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
9172
 
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
9173
 
          }
9174
 
    
9175
 
        }
9176
 
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
9177
 
        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
9178
 
      }
9179
 
    
9180
 
      // Transform derivatives back to physical element
9181
 
      for (unsigned int row = 0; row < num_derivatives; row++)
9182
 
      {
9183
 
        for (unsigned int col = 0; col < num_derivatives; col++)
9184
 
        {
9185
 
          values[row] += transform[row][col]*derivatives[col];
9186
 
        }
9187
 
      }
9188
 
      // Delete pointer to array of derivatives on FIAT element
9189
 
      delete [] derivatives;
9190
 
    
9191
 
      // Delete pointer to array of combinations of derivatives and transform
9192
 
      for (unsigned int row = 0; row < num_derivatives; row++)
9193
 
      {
9194
 
        delete [] combinations[row];
9195
 
        delete [] transform[row];
9196
 
      }
9197
 
    
9198
 
      delete [] combinations;
9199
 
      delete [] transform;
9200
 
    }
9201
 
    
9202
 
    if (3 <= i && i <= 5)
9203
 
    {
9204
 
      // Map degree of freedom to element degree of freedom
9205
 
      const unsigned int dof = i - 3;
9206
 
    
9207
 
      // Generate scalings
9208
 
      const double scalings_y_0 = 1;
9209
 
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
9210
 
    
9211
 
      // Compute psitilde_a
9212
 
      const double psitilde_a_0 = 1;
9213
 
      const double psitilde_a_1 = x;
9214
 
    
9215
 
      // Compute psitilde_bs
9216
 
      const double psitilde_bs_0_0 = 1;
9217
 
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
9218
 
      const double psitilde_bs_1_0 = 1;
9219
 
    
9220
 
      // Compute basisvalues
9221
 
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
9222
 
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
9223
 
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
9224
 
    
9225
 
      // Table(s) of coefficients
9226
 
      const static double coefficients0[3][3] =   \
9227
 
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
9228
 
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
9229
 
      {0.471404520791032, 0, 0.333333333333333}};
9230
 
    
9231
 
      // Interesting (new) part
9232
 
      // Tables of derivatives of the polynomial base (transpose)
9233
 
      const static double dmats0[3][3] =   \
9234
 
      {{0, 0, 0},
9235
 
      {4.89897948556636, 0, 0},
9236
 
      {0, 0, 0}};
9237
 
    
9238
 
      const static double dmats1[3][3] =   \
9239
 
      {{0, 0, 0},
9240
 
      {2.44948974278318, 0, 0},
9241
 
      {4.24264068711928, 0, 0}};
9242
 
    
9243
 
      // Compute reference derivatives
9244
 
      // Declare pointer to array of derivatives on FIAT element
9245
 
      double *derivatives = new double [num_derivatives];
9246
 
    
9247
 
      // Declare coefficients
9248
 
      double coeff0_0 = 0;
9249
 
      double coeff0_1 = 0;
9250
 
      double coeff0_2 = 0;
9251
 
    
9252
 
      // Declare new coefficients
9253
 
      double new_coeff0_0 = 0;
9254
 
      double new_coeff0_1 = 0;
9255
 
      double new_coeff0_2 = 0;
9256
 
    
9257
 
      // Loop possible derivatives
9258
 
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
9259
 
      {
9260
 
        // Get values from coefficients array
9261
 
        new_coeff0_0 = coefficients0[dof][0];
9262
 
        new_coeff0_1 = coefficients0[dof][1];
9263
 
        new_coeff0_2 = coefficients0[dof][2];
9264
 
    
9265
 
        // Loop derivative order
9266
 
        for (unsigned int j = 0; j < n; j++)
9267
 
        {
9268
 
          // Update old coefficients
9269
 
          coeff0_0 = new_coeff0_0;
9270
 
          coeff0_1 = new_coeff0_1;
9271
 
          coeff0_2 = new_coeff0_2;
9272
 
    
9273
 
          if(combinations[deriv_num][j] == 0)
9274
 
          {
9275
 
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
9276
 
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
9277
 
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
9278
 
          }
9279
 
          if(combinations[deriv_num][j] == 1)
9280
 
          {
9281
 
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
9282
 
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
9283
 
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
9284
 
          }
9285
 
    
9286
 
        }
9287
 
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
9288
 
        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
9289
 
      }
9290
 
    
9291
 
      // Transform derivatives back to physical element
9292
 
      for (unsigned int row = 0; row < num_derivatives; row++)
9293
 
      {
9294
 
        for (unsigned int col = 0; col < num_derivatives; col++)
9295
 
        {
9296
 
          values[num_derivatives + row] += transform[row][col]*derivatives[col];
9297
 
        }
9298
 
      }
9299
 
      // Delete pointer to array of derivatives on FIAT element
9300
 
      delete [] derivatives;
9301
 
    
9302
 
      // Delete pointer to array of combinations of derivatives and transform
9303
 
      for (unsigned int row = 0; row < num_derivatives; row++)
9304
 
      {
9305
 
        delete [] combinations[row];
9306
 
        delete [] transform[row];
9307
 
      }
9308
 
    
9309
 
      delete [] combinations;
9310
 
      delete [] transform;
9311
 
    }
9312
 
    
9313
 
}
9314
 
 
9315
 
/// Evaluate order n derivatives of all basis functions at given point in cell
9316
 
void UFC_CahnHilliard2DLinearForm_finite_element_0::evaluate_basis_derivatives_all(unsigned int n,
9317
 
                                                   double* values,
9318
 
                                                   const double* coordinates,
9319
 
                                                   const ufc::cell& c) const
9320
 
{
9321
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
9322
 
}
9323
 
 
9324
 
/// Evaluate linear functional for dof i on the function f
9325
 
double UFC_CahnHilliard2DLinearForm_finite_element_0::evaluate_dof(unsigned int i,
9326
 
                                   const ufc::function& f,
9327
 
                                   const ufc::cell& c) const
9328
 
{
9329
 
    // The reference points, direction and weights:
9330
 
    const static double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
9331
 
    const static double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
9332
 
    const static double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
9333
 
    
9334
 
    const double * const * x = c.coordinates;
9335
 
    double result = 0.0;
9336
 
    // Iterate over the points:
9337
 
    // Evaluate basis functions for affine mapping
9338
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
9339
 
    const double w1 = X[i][0][0];
9340
 
    const double w2 = X[i][0][1];
9341
 
    
9342
 
    // Compute affine mapping y = F(X)
9343
 
    double y[2];
9344
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
9345
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
9346
 
    
9347
 
    // Evaluate function at physical points
9348
 
    double values[2];
9349
 
    f.evaluate(values, y, c);
9350
 
    
9351
 
    // Map function values using appropriate mapping
9352
 
    // Affine map: Do nothing
9353
 
    
9354
 
    // Note that we do not map the weights (yet).
9355
 
    
9356
 
    // Take directional components
9357
 
    for(int k = 0; k < 2; k++)
9358
 
      result += values[k]*D[i][0][k];
9359
 
    // Multiply by weights 
9360
 
    result *= W[i][0];
9361
 
    
9362
 
    return result;
9363
 
}
9364
 
 
9365
 
/// Evaluate linear functionals for all dofs on the function f
9366
 
void UFC_CahnHilliard2DLinearForm_finite_element_0::evaluate_dofs(double* values,
9367
 
                                  const ufc::function& f,
9368
 
                                  const ufc::cell& c) const
9369
 
{
9370
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
9371
 
}
9372
 
 
9373
 
/// Interpolate vertex values from dof values
9374
 
void UFC_CahnHilliard2DLinearForm_finite_element_0::interpolate_vertex_values(double* vertex_values,
9375
 
                                              const double* dof_values,
9376
 
                                              const ufc::cell& c) const
9377
 
{
9378
 
    // Evaluate at vertices and use affine mapping
9379
 
    vertex_values[0] = dof_values[0];
9380
 
    vertex_values[2] = dof_values[1];
9381
 
    vertex_values[4] = dof_values[2];
9382
 
    // Evaluate at vertices and use affine mapping
9383
 
    vertex_values[1] = dof_values[3];
9384
 
    vertex_values[3] = dof_values[4];
9385
 
    vertex_values[5] = dof_values[5];
9386
 
}
9387
 
 
9388
 
/// Return the number of sub elements (for a mixed element)
9389
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_0::num_sub_elements() const
9390
 
{
9391
 
    return 2;
9392
 
}
9393
 
 
9394
 
/// Create a new finite element for sub element i (for a mixed element)
9395
 
ufc::finite_element* UFC_CahnHilliard2DLinearForm_finite_element_0::create_sub_element(unsigned int i) const
9396
 
{
9397
 
    switch ( i )
9398
 
    {
9399
 
    case 0:
9400
 
      return new UFC_CahnHilliard2DLinearForm_finite_element_0_0();
9401
 
      break;
9402
 
    case 1:
9403
 
      return new UFC_CahnHilliard2DLinearForm_finite_element_0_1();
9404
 
      break;
9405
 
    }
9406
 
    return 0;
9407
 
}
9408
 
 
9409
 
 
9410
 
/// Constructor
9411
 
UFC_CahnHilliard2DLinearForm_finite_element_1_0::UFC_CahnHilliard2DLinearForm_finite_element_1_0() : ufc::finite_element()
9412
 
{
9413
 
    // Do nothing
9414
 
}
9415
 
 
9416
 
/// Destructor
9417
 
UFC_CahnHilliard2DLinearForm_finite_element_1_0::~UFC_CahnHilliard2DLinearForm_finite_element_1_0()
9418
 
{
9419
 
    // Do nothing
9420
 
}
9421
 
 
9422
 
/// Return a string identifying the finite element
9423
 
const char* UFC_CahnHilliard2DLinearForm_finite_element_1_0::signature() const
9424
 
{
9425
 
    return "FiniteElement('Lagrange', 'triangle', 1)";
9426
 
}
9427
 
 
9428
 
/// Return the cell shape
9429
 
ufc::shape UFC_CahnHilliard2DLinearForm_finite_element_1_0::cell_shape() const
9430
 
{
9431
 
    return ufc::triangle;
9432
 
}
9433
 
 
9434
 
/// Return the dimension of the finite element function space
9435
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_1_0::space_dimension() const
9436
 
{
9437
 
    return 3;
9438
 
}
9439
 
 
9440
 
/// Return the rank of the value space
9441
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_1_0::value_rank() const
9442
 
{
9443
 
    return 0;
9444
 
}
9445
 
 
9446
 
/// Return the dimension of the value space for axis i
9447
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_1_0::value_dimension(unsigned int i) const
9448
 
{
9449
 
    return 1;
9450
 
}
9451
 
 
9452
 
/// Evaluate basis function i at given point in cell
9453
 
void UFC_CahnHilliard2DLinearForm_finite_element_1_0::evaluate_basis(unsigned int i,
9454
 
                                   double* values,
9455
 
                                   const double* coordinates,
9456
 
                                   const ufc::cell& c) const
9457
 
{
9458
 
    // Extract vertex coordinates
9459
 
    const double * const * element_coordinates = c.coordinates;
9460
 
    
9461
 
    // Compute Jacobian of affine map from reference cell
9462
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
9463
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
9464
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
9465
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
9466
 
      
9467
 
    // Compute determinant of Jacobian
9468
 
    const double detJ = J_00*J_11 - J_01*J_10;
9469
 
    
9470
 
    // Compute inverse of Jacobian
9471
 
    
9472
 
    // Get coordinates and map to the reference (UFC) element
9473
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
9474
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
9475
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
9476
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
9477
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
9478
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
9479
 
    
9480
 
    // Map coordinates to the reference square
9481
 
    if (std::abs(y - 1.0) < 1e-14)
9482
 
      x = -1.0;
9483
 
    else
9484
 
      x = 2.0 *x/(1.0 - y) - 1.0;
9485
 
    y = 2.0*y - 1.0;
9486
 
    
9487
 
    // Reset values
9488
 
    *values = 0;
9489
 
    
9490
 
    // Map degree of freedom to element degree of freedom
9491
 
    const unsigned int dof = i;
9492
 
    
9493
 
    // Generate scalings
9494
 
    const double scalings_y_0 = 1;
9495
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
9496
 
    
9497
 
    // Compute psitilde_a
9498
 
    const double psitilde_a_0 = 1;
9499
 
    const double psitilde_a_1 = x;
9500
 
    
9501
 
    // Compute psitilde_bs
9502
 
    const double psitilde_bs_0_0 = 1;
9503
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
9504
 
    const double psitilde_bs_1_0 = 1;
9505
 
    
9506
 
    // Compute basisvalues
9507
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
9508
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
9509
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
9510
 
    
9511
 
    // Table(s) of coefficients
9512
 
    const static double coefficients0[3][3] = \
9513
 
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
9514
 
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
9515
 
    {0.471404520791032, 0, 0.333333333333333}};
9516
 
    
9517
 
    // Extract relevant coefficients
9518
 
    const double coeff0_0 = coefficients0[dof][0];
9519
 
    const double coeff0_1 = coefficients0[dof][1];
9520
 
    const double coeff0_2 = coefficients0[dof][2];
9521
 
    
9522
 
    // Compute value(s)
9523
 
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
9524
 
}
9525
 
 
9526
 
/// Evaluate all basis functions at given point in cell
9527
 
void UFC_CahnHilliard2DLinearForm_finite_element_1_0::evaluate_basis_all(double* values,
9528
 
                                       const double* coordinates,
9529
 
                                       const ufc::cell& c) const
9530
 
{
9531
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
9532
 
}
9533
 
 
9534
 
/// Evaluate order n derivatives of basis function i at given point in cell
9535
 
void UFC_CahnHilliard2DLinearForm_finite_element_1_0::evaluate_basis_derivatives(unsigned int i,
9536
 
                                               unsigned int n,
9537
 
                                               double* values,
9538
 
                                               const double* coordinates,
9539
 
                                               const ufc::cell& c) const
9540
 
{
9541
 
    // Extract vertex coordinates
9542
 
    const double * const * element_coordinates = c.coordinates;
9543
 
    
9544
 
    // Compute Jacobian of affine map from reference cell
9545
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
9546
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
9547
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
9548
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
9549
 
      
9550
 
    // Compute determinant of Jacobian
9551
 
    const double detJ = J_00*J_11 - J_01*J_10;
9552
 
    
9553
 
    // Compute inverse of Jacobian
9554
 
    
9555
 
    // Get coordinates and map to the reference (UFC) element
9556
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
9557
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
9558
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
9559
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
9560
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
9561
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
9562
 
    
9563
 
    // Map coordinates to the reference square
9564
 
    if (std::abs(y - 1.0) < 1e-14)
9565
 
      x = -1.0;
9566
 
    else
9567
 
      x = 2.0 *x/(1.0 - y) - 1.0;
9568
 
    y = 2.0*y - 1.0;
9569
 
    
9570
 
    // Compute number of derivatives
9571
 
    unsigned int num_derivatives = 1;
9572
 
    
9573
 
    for (unsigned int j = 0; j < n; j++)
9574
 
      num_derivatives *= 2;
9575
 
    
9576
 
    
9577
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
9578
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
9579
 
        
9580
 
    for (unsigned int j = 0; j < num_derivatives; j++)
9581
 
    {
9582
 
      combinations[j] = new unsigned int [n];
9583
 
      for (unsigned int k = 0; k < n; k++)
9584
 
        combinations[j][k] = 0;
9585
 
    }
9586
 
        
9587
 
    // Generate combinations of derivatives
9588
 
    for (unsigned int row = 1; row < num_derivatives; row++)
9589
 
    {
9590
 
      for (unsigned int num = 0; num < row; num++)
9591
 
      {
9592
 
        for (unsigned int col = n-1; col+1 > 0; col--)
9593
 
        {
9594
 
          if (combinations[row][col] + 1 > 1)
9595
 
            combinations[row][col] = 0;
9596
 
          else
9597
 
          {
9598
 
            combinations[row][col] += 1;
9599
 
            break;
9600
 
          }
9601
 
        }
9602
 
      }
9603
 
    }
9604
 
    
9605
 
    // Compute inverse of Jacobian
9606
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
9607
 
    
9608
 
    // Declare transformation matrix
9609
 
    // Declare pointer to two dimensional array and initialise
9610
 
    double **transform = new double *[num_derivatives];
9611
 
        
9612
 
    for (unsigned int j = 0; j < num_derivatives; j++)
9613
 
    {
9614
 
      transform[j] = new double [num_derivatives];
9615
 
      for (unsigned int k = 0; k < num_derivatives; k++)
9616
 
        transform[j][k] = 1;
9617
 
    }
9618
 
    
9619
 
    // Construct transformation matrix
9620
 
    for (unsigned int row = 0; row < num_derivatives; row++)
9621
 
    {
9622
 
      for (unsigned int col = 0; col < num_derivatives; col++)
9623
 
      {
9624
 
        for (unsigned int k = 0; k < n; k++)
9625
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
9626
 
      }
9627
 
    }
9628
 
    
9629
 
    // Reset values
9630
 
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
9631
 
      values[j] = 0;
9632
 
    
9633
 
    // Map degree of freedom to element degree of freedom
9634
 
    const unsigned int dof = i;
9635
 
    
9636
 
    // Generate scalings
9637
 
    const double scalings_y_0 = 1;
9638
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
9639
 
    
9640
 
    // Compute psitilde_a
9641
 
    const double psitilde_a_0 = 1;
9642
 
    const double psitilde_a_1 = x;
9643
 
    
9644
 
    // Compute psitilde_bs
9645
 
    const double psitilde_bs_0_0 = 1;
9646
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
9647
 
    const double psitilde_bs_1_0 = 1;
9648
 
    
9649
 
    // Compute basisvalues
9650
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
9651
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
9652
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
9653
 
    
9654
 
    // Table(s) of coefficients
9655
 
    const static double coefficients0[3][3] = \
9656
 
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
9657
 
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
9658
 
    {0.471404520791032, 0, 0.333333333333333}};
9659
 
    
9660
 
    // Interesting (new) part
9661
 
    // Tables of derivatives of the polynomial base (transpose)
9662
 
    const static double dmats0[3][3] = \
9663
 
    {{0, 0, 0},
9664
 
    {4.89897948556636, 0, 0},
9665
 
    {0, 0, 0}};
9666
 
    
9667
 
    const static double dmats1[3][3] = \
9668
 
    {{0, 0, 0},
9669
 
    {2.44948974278318, 0, 0},
9670
 
    {4.24264068711928, 0, 0}};
9671
 
    
9672
 
    // Compute reference derivatives
9673
 
    // Declare pointer to array of derivatives on FIAT element
9674
 
    double *derivatives = new double [num_derivatives];
9675
 
    
9676
 
    // Declare coefficients
9677
 
    double coeff0_0 = 0;
9678
 
    double coeff0_1 = 0;
9679
 
    double coeff0_2 = 0;
9680
 
    
9681
 
    // Declare new coefficients
9682
 
    double new_coeff0_0 = 0;
9683
 
    double new_coeff0_1 = 0;
9684
 
    double new_coeff0_2 = 0;
9685
 
    
9686
 
    // Loop possible derivatives
9687
 
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
9688
 
    {
9689
 
      // Get values from coefficients array
9690
 
      new_coeff0_0 = coefficients0[dof][0];
9691
 
      new_coeff0_1 = coefficients0[dof][1];
9692
 
      new_coeff0_2 = coefficients0[dof][2];
9693
 
    
9694
 
      // Loop derivative order
9695
 
      for (unsigned int j = 0; j < n; j++)
9696
 
      {
9697
 
        // Update old coefficients
9698
 
        coeff0_0 = new_coeff0_0;
9699
 
        coeff0_1 = new_coeff0_1;
9700
 
        coeff0_2 = new_coeff0_2;
9701
 
    
9702
 
        if(combinations[deriv_num][j] == 0)
9703
 
        {
9704
 
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
9705
 
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
9706
 
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
9707
 
        }
9708
 
        if(combinations[deriv_num][j] == 1)
9709
 
        {
9710
 
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
9711
 
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
9712
 
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
9713
 
        }
9714
 
    
9715
 
      }
9716
 
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
9717
 
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
9718
 
    }
9719
 
    
9720
 
    // Transform derivatives back to physical element
9721
 
    for (unsigned int row = 0; row < num_derivatives; row++)
9722
 
    {
9723
 
      for (unsigned int col = 0; col < num_derivatives; col++)
9724
 
      {
9725
 
        values[row] += transform[row][col]*derivatives[col];
9726
 
      }
9727
 
    }
9728
 
    // Delete pointer to array of derivatives on FIAT element
9729
 
    delete [] derivatives;
9730
 
    
9731
 
    // Delete pointer to array of combinations of derivatives and transform
9732
 
    for (unsigned int row = 0; row < num_derivatives; row++)
9733
 
    {
9734
 
      delete [] combinations[row];
9735
 
      delete [] transform[row];
9736
 
    }
9737
 
    
9738
 
    delete [] combinations;
9739
 
    delete [] transform;
9740
 
}
9741
 
 
9742
 
/// Evaluate order n derivatives of all basis functions at given point in cell
9743
 
void UFC_CahnHilliard2DLinearForm_finite_element_1_0::evaluate_basis_derivatives_all(unsigned int n,
9744
 
                                                   double* values,
9745
 
                                                   const double* coordinates,
9746
 
                                                   const ufc::cell& c) const
9747
 
{
9748
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
9749
 
}
9750
 
 
9751
 
/// Evaluate linear functional for dof i on the function f
9752
 
double UFC_CahnHilliard2DLinearForm_finite_element_1_0::evaluate_dof(unsigned int i,
9753
 
                                   const ufc::function& f,
9754
 
                                   const ufc::cell& c) const
9755
 
{
9756
 
    // The reference points, direction and weights:
9757
 
    const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
9758
 
    const static double W[3][1] = {{1}, {1}, {1}};
9759
 
    const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
9760
 
    
9761
 
    const double * const * x = c.coordinates;
9762
 
    double result = 0.0;
9763
 
    // Iterate over the points:
9764
 
    // Evaluate basis functions for affine mapping
9765
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
9766
 
    const double w1 = X[i][0][0];
9767
 
    const double w2 = X[i][0][1];
9768
 
    
9769
 
    // Compute affine mapping y = F(X)
9770
 
    double y[2];
9771
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
9772
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
9773
 
    
9774
 
    // Evaluate function at physical points
9775
 
    double values[1];
9776
 
    f.evaluate(values, y, c);
9777
 
    
9778
 
    // Map function values using appropriate mapping
9779
 
    // Affine map: Do nothing
9780
 
    
9781
 
    // Note that we do not map the weights (yet).
9782
 
    
9783
 
    // Take directional components
9784
 
    for(int k = 0; k < 1; k++)
9785
 
      result += values[k]*D[i][0][k];
9786
 
    // Multiply by weights 
9787
 
    result *= W[i][0];
9788
 
    
9789
 
    return result;
9790
 
}
9791
 
 
9792
 
/// Evaluate linear functionals for all dofs on the function f
9793
 
void UFC_CahnHilliard2DLinearForm_finite_element_1_0::evaluate_dofs(double* values,
9794
 
                                  const ufc::function& f,
9795
 
                                  const ufc::cell& c) const
9796
 
{
9797
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
9798
 
}
9799
 
 
9800
 
/// Interpolate vertex values from dof values
9801
 
void UFC_CahnHilliard2DLinearForm_finite_element_1_0::interpolate_vertex_values(double* vertex_values,
9802
 
                                              const double* dof_values,
9803
 
                                              const ufc::cell& c) const
9804
 
{
9805
 
    // Evaluate at vertices and use affine mapping
9806
 
    vertex_values[0] = dof_values[0];
9807
 
    vertex_values[1] = dof_values[1];
9808
 
    vertex_values[2] = dof_values[2];
9809
 
}
9810
 
 
9811
 
/// Return the number of sub elements (for a mixed element)
9812
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_1_0::num_sub_elements() const
9813
 
{
9814
 
    return 1;
9815
 
}
9816
 
 
9817
 
/// Create a new finite element for sub element i (for a mixed element)
9818
 
ufc::finite_element* UFC_CahnHilliard2DLinearForm_finite_element_1_0::create_sub_element(unsigned int i) const
9819
 
{
9820
 
    return new UFC_CahnHilliard2DLinearForm_finite_element_1_0();
9821
 
}
9822
 
 
9823
 
 
9824
 
/// Constructor
9825
 
UFC_CahnHilliard2DLinearForm_finite_element_1_1::UFC_CahnHilliard2DLinearForm_finite_element_1_1() : ufc::finite_element()
9826
 
{
9827
 
    // Do nothing
9828
 
}
9829
 
 
9830
 
/// Destructor
9831
 
UFC_CahnHilliard2DLinearForm_finite_element_1_1::~UFC_CahnHilliard2DLinearForm_finite_element_1_1()
9832
 
{
9833
 
    // Do nothing
9834
 
}
9835
 
 
9836
 
/// Return a string identifying the finite element
9837
 
const char* UFC_CahnHilliard2DLinearForm_finite_element_1_1::signature() const
9838
 
{
9839
 
    return "FiniteElement('Lagrange', 'triangle', 1)";
9840
 
}
9841
 
 
9842
 
/// Return the cell shape
9843
 
ufc::shape UFC_CahnHilliard2DLinearForm_finite_element_1_1::cell_shape() const
9844
 
{
9845
 
    return ufc::triangle;
9846
 
}
9847
 
 
9848
 
/// Return the dimension of the finite element function space
9849
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_1_1::space_dimension() const
9850
 
{
9851
 
    return 3;
9852
 
}
9853
 
 
9854
 
/// Return the rank of the value space
9855
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_1_1::value_rank() const
9856
 
{
9857
 
    return 0;
9858
 
}
9859
 
 
9860
 
/// Return the dimension of the value space for axis i
9861
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_1_1::value_dimension(unsigned int i) const
9862
 
{
9863
 
    return 1;
9864
 
}
9865
 
 
9866
 
/// Evaluate basis function i at given point in cell
9867
 
void UFC_CahnHilliard2DLinearForm_finite_element_1_1::evaluate_basis(unsigned int i,
9868
 
                                   double* values,
9869
 
                                   const double* coordinates,
9870
 
                                   const ufc::cell& c) const
9871
 
{
9872
 
    // Extract vertex coordinates
9873
 
    const double * const * element_coordinates = c.coordinates;
9874
 
    
9875
 
    // Compute Jacobian of affine map from reference cell
9876
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
9877
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
9878
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
9879
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
9880
 
      
9881
 
    // Compute determinant of Jacobian
9882
 
    const double detJ = J_00*J_11 - J_01*J_10;
9883
 
    
9884
 
    // Compute inverse of Jacobian
9885
 
    
9886
 
    // Get coordinates and map to the reference (UFC) element
9887
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
9888
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
9889
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
9890
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
9891
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
9892
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
9893
 
    
9894
 
    // Map coordinates to the reference square
9895
 
    if (std::abs(y - 1.0) < 1e-14)
9896
 
      x = -1.0;
9897
 
    else
9898
 
      x = 2.0 *x/(1.0 - y) - 1.0;
9899
 
    y = 2.0*y - 1.0;
9900
 
    
9901
 
    // Reset values
9902
 
    *values = 0;
9903
 
    
9904
 
    // Map degree of freedom to element degree of freedom
9905
 
    const unsigned int dof = i;
9906
 
    
9907
 
    // Generate scalings
9908
 
    const double scalings_y_0 = 1;
9909
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
9910
 
    
9911
 
    // Compute psitilde_a
9912
 
    const double psitilde_a_0 = 1;
9913
 
    const double psitilde_a_1 = x;
9914
 
    
9915
 
    // Compute psitilde_bs
9916
 
    const double psitilde_bs_0_0 = 1;
9917
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
9918
 
    const double psitilde_bs_1_0 = 1;
9919
 
    
9920
 
    // Compute basisvalues
9921
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
9922
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
9923
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
9924
 
    
9925
 
    // Table(s) of coefficients
9926
 
    const static double coefficients0[3][3] = \
9927
 
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
9928
 
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
9929
 
    {0.471404520791032, 0, 0.333333333333333}};
9930
 
    
9931
 
    // Extract relevant coefficients
9932
 
    const double coeff0_0 = coefficients0[dof][0];
9933
 
    const double coeff0_1 = coefficients0[dof][1];
9934
 
    const double coeff0_2 = coefficients0[dof][2];
9935
 
    
9936
 
    // Compute value(s)
9937
 
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
9938
 
}
9939
 
 
9940
 
/// Evaluate all basis functions at given point in cell
9941
 
void UFC_CahnHilliard2DLinearForm_finite_element_1_1::evaluate_basis_all(double* values,
9942
 
                                       const double* coordinates,
9943
 
                                       const ufc::cell& c) const
9944
 
{
9945
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
9946
 
}
9947
 
 
9948
 
/// Evaluate order n derivatives of basis function i at given point in cell
9949
 
void UFC_CahnHilliard2DLinearForm_finite_element_1_1::evaluate_basis_derivatives(unsigned int i,
9950
 
                                               unsigned int n,
9951
 
                                               double* values,
9952
 
                                               const double* coordinates,
9953
 
                                               const ufc::cell& c) const
9954
 
{
9955
 
    // Extract vertex coordinates
9956
 
    const double * const * element_coordinates = c.coordinates;
9957
 
    
9958
 
    // Compute Jacobian of affine map from reference cell
9959
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
9960
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
9961
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
9962
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
9963
 
      
9964
 
    // Compute determinant of Jacobian
9965
 
    const double detJ = J_00*J_11 - J_01*J_10;
9966
 
    
9967
 
    // Compute inverse of Jacobian
9968
 
    
9969
 
    // Get coordinates and map to the reference (UFC) element
9970
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
9971
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
9972
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
9973
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
9974
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
9975
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
9976
 
    
9977
 
    // Map coordinates to the reference square
9978
 
    if (std::abs(y - 1.0) < 1e-14)
9979
 
      x = -1.0;
9980
 
    else
9981
 
      x = 2.0 *x/(1.0 - y) - 1.0;
9982
 
    y = 2.0*y - 1.0;
9983
 
    
9984
 
    // Compute number of derivatives
9985
 
    unsigned int num_derivatives = 1;
9986
 
    
9987
 
    for (unsigned int j = 0; j < n; j++)
9988
 
      num_derivatives *= 2;
9989
 
    
9990
 
    
9991
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
9992
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
9993
 
        
9994
 
    for (unsigned int j = 0; j < num_derivatives; j++)
9995
 
    {
9996
 
      combinations[j] = new unsigned int [n];
9997
 
      for (unsigned int k = 0; k < n; k++)
9998
 
        combinations[j][k] = 0;
9999
 
    }
10000
 
        
10001
 
    // Generate combinations of derivatives
10002
 
    for (unsigned int row = 1; row < num_derivatives; row++)
10003
 
    {
10004
 
      for (unsigned int num = 0; num < row; num++)
10005
 
      {
10006
 
        for (unsigned int col = n-1; col+1 > 0; col--)
10007
 
        {
10008
 
          if (combinations[row][col] + 1 > 1)
10009
 
            combinations[row][col] = 0;
10010
 
          else
10011
 
          {
10012
 
            combinations[row][col] += 1;
10013
 
            break;
10014
 
          }
10015
 
        }
10016
 
      }
10017
 
    }
10018
 
    
10019
 
    // Compute inverse of Jacobian
10020
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
10021
 
    
10022
 
    // Declare transformation matrix
10023
 
    // Declare pointer to two dimensional array and initialise
10024
 
    double **transform = new double *[num_derivatives];
10025
 
        
10026
 
    for (unsigned int j = 0; j < num_derivatives; j++)
10027
 
    {
10028
 
      transform[j] = new double [num_derivatives];
10029
 
      for (unsigned int k = 0; k < num_derivatives; k++)
10030
 
        transform[j][k] = 1;
10031
 
    }
10032
 
    
10033
 
    // Construct transformation matrix
10034
 
    for (unsigned int row = 0; row < num_derivatives; row++)
10035
 
    {
10036
 
      for (unsigned int col = 0; col < num_derivatives; col++)
10037
 
      {
10038
 
        for (unsigned int k = 0; k < n; k++)
10039
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
10040
 
      }
10041
 
    }
10042
 
    
10043
 
    // Reset values
10044
 
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
10045
 
      values[j] = 0;
10046
 
    
10047
 
    // Map degree of freedom to element degree of freedom
10048
 
    const unsigned int dof = i;
10049
 
    
10050
 
    // Generate scalings
10051
 
    const double scalings_y_0 = 1;
10052
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
10053
 
    
10054
 
    // Compute psitilde_a
10055
 
    const double psitilde_a_0 = 1;
10056
 
    const double psitilde_a_1 = x;
10057
 
    
10058
 
    // Compute psitilde_bs
10059
 
    const double psitilde_bs_0_0 = 1;
10060
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
10061
 
    const double psitilde_bs_1_0 = 1;
10062
 
    
10063
 
    // Compute basisvalues
10064
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
10065
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
10066
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
10067
 
    
10068
 
    // Table(s) of coefficients
10069
 
    const static double coefficients0[3][3] = \
10070
 
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
10071
 
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
10072
 
    {0.471404520791032, 0, 0.333333333333333}};
10073
 
    
10074
 
    // Interesting (new) part
10075
 
    // Tables of derivatives of the polynomial base (transpose)
10076
 
    const static double dmats0[3][3] = \
10077
 
    {{0, 0, 0},
10078
 
    {4.89897948556636, 0, 0},
10079
 
    {0, 0, 0}};
10080
 
    
10081
 
    const static double dmats1[3][3] = \
10082
 
    {{0, 0, 0},
10083
 
    {2.44948974278318, 0, 0},
10084
 
    {4.24264068711928, 0, 0}};
10085
 
    
10086
 
    // Compute reference derivatives
10087
 
    // Declare pointer to array of derivatives on FIAT element
10088
 
    double *derivatives = new double [num_derivatives];
10089
 
    
10090
 
    // Declare coefficients
10091
 
    double coeff0_0 = 0;
10092
 
    double coeff0_1 = 0;
10093
 
    double coeff0_2 = 0;
10094
 
    
10095
 
    // Declare new coefficients
10096
 
    double new_coeff0_0 = 0;
10097
 
    double new_coeff0_1 = 0;
10098
 
    double new_coeff0_2 = 0;
10099
 
    
10100
 
    // Loop possible derivatives
10101
 
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
10102
 
    {
10103
 
      // Get values from coefficients array
10104
 
      new_coeff0_0 = coefficients0[dof][0];
10105
 
      new_coeff0_1 = coefficients0[dof][1];
10106
 
      new_coeff0_2 = coefficients0[dof][2];
10107
 
    
10108
 
      // Loop derivative order
10109
 
      for (unsigned int j = 0; j < n; j++)
10110
 
      {
10111
 
        // Update old coefficients
10112
 
        coeff0_0 = new_coeff0_0;
10113
 
        coeff0_1 = new_coeff0_1;
10114
 
        coeff0_2 = new_coeff0_2;
10115
 
    
10116
 
        if(combinations[deriv_num][j] == 0)
10117
 
        {
10118
 
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
10119
 
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
10120
 
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
10121
 
        }
10122
 
        if(combinations[deriv_num][j] == 1)
10123
 
        {
10124
 
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
10125
 
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
10126
 
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
10127
 
        }
10128
 
    
10129
 
      }
10130
 
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
10131
 
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
10132
 
    }
10133
 
    
10134
 
    // Transform derivatives back to physical element
10135
 
    for (unsigned int row = 0; row < num_derivatives; row++)
10136
 
    {
10137
 
      for (unsigned int col = 0; col < num_derivatives; col++)
10138
 
      {
10139
 
        values[row] += transform[row][col]*derivatives[col];
10140
 
      }
10141
 
    }
10142
 
    // Delete pointer to array of derivatives on FIAT element
10143
 
    delete [] derivatives;
10144
 
    
10145
 
    // Delete pointer to array of combinations of derivatives and transform
10146
 
    for (unsigned int row = 0; row < num_derivatives; row++)
10147
 
    {
10148
 
      delete [] combinations[row];
10149
 
      delete [] transform[row];
10150
 
    }
10151
 
    
10152
 
    delete [] combinations;
10153
 
    delete [] transform;
10154
 
}
10155
 
 
10156
 
/// Evaluate order n derivatives of all basis functions at given point in cell
10157
 
void UFC_CahnHilliard2DLinearForm_finite_element_1_1::evaluate_basis_derivatives_all(unsigned int n,
10158
 
                                                   double* values,
10159
 
                                                   const double* coordinates,
10160
 
                                                   const ufc::cell& c) const
10161
 
{
10162
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
10163
 
}
10164
 
 
10165
 
/// Evaluate linear functional for dof i on the function f
10166
 
double UFC_CahnHilliard2DLinearForm_finite_element_1_1::evaluate_dof(unsigned int i,
10167
 
                                   const ufc::function& f,
10168
 
                                   const ufc::cell& c) const
10169
 
{
10170
 
    // The reference points, direction and weights:
10171
 
    const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
10172
 
    const static double W[3][1] = {{1}, {1}, {1}};
10173
 
    const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
10174
 
    
10175
 
    const double * const * x = c.coordinates;
10176
 
    double result = 0.0;
10177
 
    // Iterate over the points:
10178
 
    // Evaluate basis functions for affine mapping
10179
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
10180
 
    const double w1 = X[i][0][0];
10181
 
    const double w2 = X[i][0][1];
10182
 
    
10183
 
    // Compute affine mapping y = F(X)
10184
 
    double y[2];
10185
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
10186
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
10187
 
    
10188
 
    // Evaluate function at physical points
10189
 
    double values[1];
10190
 
    f.evaluate(values, y, c);
10191
 
    
10192
 
    // Map function values using appropriate mapping
10193
 
    // Affine map: Do nothing
10194
 
    
10195
 
    // Note that we do not map the weights (yet).
10196
 
    
10197
 
    // Take directional components
10198
 
    for(int k = 0; k < 1; k++)
10199
 
      result += values[k]*D[i][0][k];
10200
 
    // Multiply by weights 
10201
 
    result *= W[i][0];
10202
 
    
10203
 
    return result;
10204
 
}
10205
 
 
10206
 
/// Evaluate linear functionals for all dofs on the function f
10207
 
void UFC_CahnHilliard2DLinearForm_finite_element_1_1::evaluate_dofs(double* values,
10208
 
                                  const ufc::function& f,
10209
 
                                  const ufc::cell& c) const
10210
 
{
10211
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
10212
 
}
10213
 
 
10214
 
/// Interpolate vertex values from dof values
10215
 
void UFC_CahnHilliard2DLinearForm_finite_element_1_1::interpolate_vertex_values(double* vertex_values,
10216
 
                                              const double* dof_values,
10217
 
                                              const ufc::cell& c) const
10218
 
{
10219
 
    // Evaluate at vertices and use affine mapping
10220
 
    vertex_values[0] = dof_values[0];
10221
 
    vertex_values[1] = dof_values[1];
10222
 
    vertex_values[2] = dof_values[2];
10223
 
}
10224
 
 
10225
 
/// Return the number of sub elements (for a mixed element)
10226
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_1_1::num_sub_elements() const
10227
 
{
10228
 
    return 1;
10229
 
}
10230
 
 
10231
 
/// Create a new finite element for sub element i (for a mixed element)
10232
 
ufc::finite_element* UFC_CahnHilliard2DLinearForm_finite_element_1_1::create_sub_element(unsigned int i) const
10233
 
{
10234
 
    return new UFC_CahnHilliard2DLinearForm_finite_element_1_1();
10235
 
}
10236
 
 
10237
 
 
10238
 
/// Constructor
10239
 
UFC_CahnHilliard2DLinearForm_finite_element_1::UFC_CahnHilliard2DLinearForm_finite_element_1() : ufc::finite_element()
10240
 
{
10241
 
    // Do nothing
10242
 
}
10243
 
 
10244
 
/// Destructor
10245
 
UFC_CahnHilliard2DLinearForm_finite_element_1::~UFC_CahnHilliard2DLinearForm_finite_element_1()
10246
 
{
10247
 
    // Do nothing
10248
 
}
10249
 
 
10250
 
/// Return a string identifying the finite element
10251
 
const char* UFC_CahnHilliard2DLinearForm_finite_element_1::signature() const
10252
 
{
10253
 
    return "MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
10254
 
}
10255
 
 
10256
 
/// Return the cell shape
10257
 
ufc::shape UFC_CahnHilliard2DLinearForm_finite_element_1::cell_shape() const
10258
 
{
10259
 
    return ufc::triangle;
10260
 
}
10261
 
 
10262
 
/// Return the dimension of the finite element function space
10263
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_1::space_dimension() const
10264
 
{
10265
 
    return 6;
10266
 
}
10267
 
 
10268
 
/// Return the rank of the value space
10269
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_1::value_rank() const
10270
 
{
10271
 
    return 1;
10272
 
}
10273
 
 
10274
 
/// Return the dimension of the value space for axis i
10275
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_1::value_dimension(unsigned int i) const
10276
 
{
10277
 
    return 2;
10278
 
}
10279
 
 
10280
 
/// Evaluate basis function i at given point in cell
10281
 
void UFC_CahnHilliard2DLinearForm_finite_element_1::evaluate_basis(unsigned int i,
10282
 
                                   double* values,
10283
 
                                   const double* coordinates,
10284
 
                                   const ufc::cell& c) const
10285
 
{
10286
 
    // Extract vertex coordinates
10287
 
    const double * const * element_coordinates = c.coordinates;
10288
 
    
10289
 
    // Compute Jacobian of affine map from reference cell
10290
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
10291
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
10292
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
10293
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
10294
 
      
10295
 
    // Compute determinant of Jacobian
10296
 
    const double detJ = J_00*J_11 - J_01*J_10;
10297
 
    
10298
 
    // Compute inverse of Jacobian
10299
 
    
10300
 
    // Get coordinates and map to the reference (UFC) element
10301
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
10302
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
10303
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
10304
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
10305
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
10306
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
10307
 
    
10308
 
    // Map coordinates to the reference square
10309
 
    if (std::abs(y - 1.0) < 1e-14)
10310
 
      x = -1.0;
10311
 
    else
10312
 
      x = 2.0 *x/(1.0 - y) - 1.0;
10313
 
    y = 2.0*y - 1.0;
10314
 
    
10315
 
    // Reset values
10316
 
    values[0] = 0;
10317
 
    values[1] = 0;
10318
 
    
10319
 
    if (0 <= i && i <= 2)
10320
 
    {
10321
 
      // Map degree of freedom to element degree of freedom
10322
 
      const unsigned int dof = i;
10323
 
    
10324
 
      // Generate scalings
10325
 
      const double scalings_y_0 = 1;
10326
 
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
10327
 
    
10328
 
      // Compute psitilde_a
10329
 
      const double psitilde_a_0 = 1;
10330
 
      const double psitilde_a_1 = x;
10331
 
    
10332
 
      // Compute psitilde_bs
10333
 
      const double psitilde_bs_0_0 = 1;
10334
 
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
10335
 
      const double psitilde_bs_1_0 = 1;
10336
 
    
10337
 
      // Compute basisvalues
10338
 
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
10339
 
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
10340
 
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
10341
 
    
10342
 
      // Table(s) of coefficients
10343
 
      const static double coefficients0[3][3] =   \
10344
 
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
10345
 
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
10346
 
      {0.471404520791032, 0, 0.333333333333333}};
10347
 
    
10348
 
      // Extract relevant coefficients
10349
 
      const double coeff0_0 =   coefficients0[dof][0];
10350
 
      const double coeff0_1 =   coefficients0[dof][1];
10351
 
      const double coeff0_2 =   coefficients0[dof][2];
10352
 
    
10353
 
      // Compute value(s)
10354
 
      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
10355
 
    }
10356
 
    
10357
 
    if (3 <= i && i <= 5)
10358
 
    {
10359
 
      // Map degree of freedom to element degree of freedom
10360
 
      const unsigned int dof = i - 3;
10361
 
    
10362
 
      // Generate scalings
10363
 
      const double scalings_y_0 = 1;
10364
 
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
10365
 
    
10366
 
      // Compute psitilde_a
10367
 
      const double psitilde_a_0 = 1;
10368
 
      const double psitilde_a_1 = x;
10369
 
    
10370
 
      // Compute psitilde_bs
10371
 
      const double psitilde_bs_0_0 = 1;
10372
 
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
10373
 
      const double psitilde_bs_1_0 = 1;
10374
 
    
10375
 
      // Compute basisvalues
10376
 
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
10377
 
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
10378
 
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
10379
 
    
10380
 
      // Table(s) of coefficients
10381
 
      const static double coefficients0[3][3] =   \
10382
 
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
10383
 
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
10384
 
      {0.471404520791032, 0, 0.333333333333333}};
10385
 
    
10386
 
      // Extract relevant coefficients
10387
 
      const double coeff0_0 =   coefficients0[dof][0];
10388
 
      const double coeff0_1 =   coefficients0[dof][1];
10389
 
      const double coeff0_2 =   coefficients0[dof][2];
10390
 
    
10391
 
      // Compute value(s)
10392
 
      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
10393
 
    }
10394
 
    
10395
 
}
10396
 
 
10397
 
/// Evaluate all basis functions at given point in cell
10398
 
void UFC_CahnHilliard2DLinearForm_finite_element_1::evaluate_basis_all(double* values,
10399
 
                                       const double* coordinates,
10400
 
                                       const ufc::cell& c) const
10401
 
{
10402
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
10403
 
}
10404
 
 
10405
 
/// Evaluate order n derivatives of basis function i at given point in cell
10406
 
void UFC_CahnHilliard2DLinearForm_finite_element_1::evaluate_basis_derivatives(unsigned int i,
10407
 
                                               unsigned int n,
10408
 
                                               double* values,
10409
 
                                               const double* coordinates,
10410
 
                                               const ufc::cell& c) const
10411
 
{
10412
 
    // Extract vertex coordinates
10413
 
    const double * const * element_coordinates = c.coordinates;
10414
 
    
10415
 
    // Compute Jacobian of affine map from reference cell
10416
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
10417
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
10418
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
10419
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
10420
 
      
10421
 
    // Compute determinant of Jacobian
10422
 
    const double detJ = J_00*J_11 - J_01*J_10;
10423
 
    
10424
 
    // Compute inverse of Jacobian
10425
 
    
10426
 
    // Get coordinates and map to the reference (UFC) element
10427
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
10428
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
10429
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
10430
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
10431
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
10432
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
10433
 
    
10434
 
    // Map coordinates to the reference square
10435
 
    if (std::abs(y - 1.0) < 1e-14)
10436
 
      x = -1.0;
10437
 
    else
10438
 
      x = 2.0 *x/(1.0 - y) - 1.0;
10439
 
    y = 2.0*y - 1.0;
10440
 
    
10441
 
    // Compute number of derivatives
10442
 
    unsigned int num_derivatives = 1;
10443
 
    
10444
 
    for (unsigned int j = 0; j < n; j++)
10445
 
      num_derivatives *= 2;
10446
 
    
10447
 
    
10448
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
10449
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
10450
 
        
10451
 
    for (unsigned int j = 0; j < num_derivatives; j++)
10452
 
    {
10453
 
      combinations[j] = new unsigned int [n];
10454
 
      for (unsigned int k = 0; k < n; k++)
10455
 
        combinations[j][k] = 0;
10456
 
    }
10457
 
        
10458
 
    // Generate combinations of derivatives
10459
 
    for (unsigned int row = 1; row < num_derivatives; row++)
10460
 
    {
10461
 
      for (unsigned int num = 0; num < row; num++)
10462
 
      {
10463
 
        for (unsigned int col = n-1; col+1 > 0; col--)
10464
 
        {
10465
 
          if (combinations[row][col] + 1 > 1)
10466
 
            combinations[row][col] = 0;
10467
 
          else
10468
 
          {
10469
 
            combinations[row][col] += 1;
10470
 
            break;
10471
 
          }
10472
 
        }
10473
 
      }
10474
 
    }
10475
 
    
10476
 
    // Compute inverse of Jacobian
10477
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
10478
 
    
10479
 
    // Declare transformation matrix
10480
 
    // Declare pointer to two dimensional array and initialise
10481
 
    double **transform = new double *[num_derivatives];
10482
 
        
10483
 
    for (unsigned int j = 0; j < num_derivatives; j++)
10484
 
    {
10485
 
      transform[j] = new double [num_derivatives];
10486
 
      for (unsigned int k = 0; k < num_derivatives; k++)
10487
 
        transform[j][k] = 1;
10488
 
    }
10489
 
    
10490
 
    // Construct transformation matrix
10491
 
    for (unsigned int row = 0; row < num_derivatives; row++)
10492
 
    {
10493
 
      for (unsigned int col = 0; col < num_derivatives; col++)
10494
 
      {
10495
 
        for (unsigned int k = 0; k < n; k++)
10496
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
10497
 
      }
10498
 
    }
10499
 
    
10500
 
    // Reset values
10501
 
    for (unsigned int j = 0; j < 2*num_derivatives; j++)
10502
 
      values[j] = 0;
10503
 
    
10504
 
    if (0 <= i && i <= 2)
10505
 
    {
10506
 
      // Map degree of freedom to element degree of freedom
10507
 
      const unsigned int dof = i;
10508
 
    
10509
 
      // Generate scalings
10510
 
      const double scalings_y_0 = 1;
10511
 
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
10512
 
    
10513
 
      // Compute psitilde_a
10514
 
      const double psitilde_a_0 = 1;
10515
 
      const double psitilde_a_1 = x;
10516
 
    
10517
 
      // Compute psitilde_bs
10518
 
      const double psitilde_bs_0_0 = 1;
10519
 
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
10520
 
      const double psitilde_bs_1_0 = 1;
10521
 
    
10522
 
      // Compute basisvalues
10523
 
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
10524
 
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
10525
 
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
10526
 
    
10527
 
      // Table(s) of coefficients
10528
 
      const static double coefficients0[3][3] =   \
10529
 
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
10530
 
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
10531
 
      {0.471404520791032, 0, 0.333333333333333}};
10532
 
    
10533
 
      // Interesting (new) part
10534
 
      // Tables of derivatives of the polynomial base (transpose)
10535
 
      const static double dmats0[3][3] =   \
10536
 
      {{0, 0, 0},
10537
 
      {4.89897948556636, 0, 0},
10538
 
      {0, 0, 0}};
10539
 
    
10540
 
      const static double dmats1[3][3] =   \
10541
 
      {{0, 0, 0},
10542
 
      {2.44948974278318, 0, 0},
10543
 
      {4.24264068711928, 0, 0}};
10544
 
    
10545
 
      // Compute reference derivatives
10546
 
      // Declare pointer to array of derivatives on FIAT element
10547
 
      double *derivatives = new double [num_derivatives];
10548
 
    
10549
 
      // Declare coefficients
10550
 
      double coeff0_0 = 0;
10551
 
      double coeff0_1 = 0;
10552
 
      double coeff0_2 = 0;
10553
 
    
10554
 
      // Declare new coefficients
10555
 
      double new_coeff0_0 = 0;
10556
 
      double new_coeff0_1 = 0;
10557
 
      double new_coeff0_2 = 0;
10558
 
    
10559
 
      // Loop possible derivatives
10560
 
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
10561
 
      {
10562
 
        // Get values from coefficients array
10563
 
        new_coeff0_0 = coefficients0[dof][0];
10564
 
        new_coeff0_1 = coefficients0[dof][1];
10565
 
        new_coeff0_2 = coefficients0[dof][2];
10566
 
    
10567
 
        // Loop derivative order
10568
 
        for (unsigned int j = 0; j < n; j++)
10569
 
        {
10570
 
          // Update old coefficients
10571
 
          coeff0_0 = new_coeff0_0;
10572
 
          coeff0_1 = new_coeff0_1;
10573
 
          coeff0_2 = new_coeff0_2;
10574
 
    
10575
 
          if(combinations[deriv_num][j] == 0)
10576
 
          {
10577
 
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
10578
 
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
10579
 
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
10580
 
          }
10581
 
          if(combinations[deriv_num][j] == 1)
10582
 
          {
10583
 
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
10584
 
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
10585
 
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
10586
 
          }
10587
 
    
10588
 
        }
10589
 
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
10590
 
        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
10591
 
      }
10592
 
    
10593
 
      // Transform derivatives back to physical element
10594
 
      for (unsigned int row = 0; row < num_derivatives; row++)
10595
 
      {
10596
 
        for (unsigned int col = 0; col < num_derivatives; col++)
10597
 
        {
10598
 
          values[row] += transform[row][col]*derivatives[col];
10599
 
        }
10600
 
      }
10601
 
      // Delete pointer to array of derivatives on FIAT element
10602
 
      delete [] derivatives;
10603
 
    
10604
 
      // Delete pointer to array of combinations of derivatives and transform
10605
 
      for (unsigned int row = 0; row < num_derivatives; row++)
10606
 
      {
10607
 
        delete [] combinations[row];
10608
 
        delete [] transform[row];
10609
 
      }
10610
 
    
10611
 
      delete [] combinations;
10612
 
      delete [] transform;
10613
 
    }
10614
 
    
10615
 
    if (3 <= i && i <= 5)
10616
 
    {
10617
 
      // Map degree of freedom to element degree of freedom
10618
 
      const unsigned int dof = i - 3;
10619
 
    
10620
 
      // Generate scalings
10621
 
      const double scalings_y_0 = 1;
10622
 
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
10623
 
    
10624
 
      // Compute psitilde_a
10625
 
      const double psitilde_a_0 = 1;
10626
 
      const double psitilde_a_1 = x;
10627
 
    
10628
 
      // Compute psitilde_bs
10629
 
      const double psitilde_bs_0_0 = 1;
10630
 
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
10631
 
      const double psitilde_bs_1_0 = 1;
10632
 
    
10633
 
      // Compute basisvalues
10634
 
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
10635
 
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
10636
 
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
10637
 
    
10638
 
      // Table(s) of coefficients
10639
 
      const static double coefficients0[3][3] =   \
10640
 
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
10641
 
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
10642
 
      {0.471404520791032, 0, 0.333333333333333}};
10643
 
    
10644
 
      // Interesting (new) part
10645
 
      // Tables of derivatives of the polynomial base (transpose)
10646
 
      const static double dmats0[3][3] =   \
10647
 
      {{0, 0, 0},
10648
 
      {4.89897948556636, 0, 0},
10649
 
      {0, 0, 0}};
10650
 
    
10651
 
      const static double dmats1[3][3] =   \
10652
 
      {{0, 0, 0},
10653
 
      {2.44948974278318, 0, 0},
10654
 
      {4.24264068711928, 0, 0}};
10655
 
    
10656
 
      // Compute reference derivatives
10657
 
      // Declare pointer to array of derivatives on FIAT element
10658
 
      double *derivatives = new double [num_derivatives];
10659
 
    
10660
 
      // Declare coefficients
10661
 
      double coeff0_0 = 0;
10662
 
      double coeff0_1 = 0;
10663
 
      double coeff0_2 = 0;
10664
 
    
10665
 
      // Declare new coefficients
10666
 
      double new_coeff0_0 = 0;
10667
 
      double new_coeff0_1 = 0;
10668
 
      double new_coeff0_2 = 0;
10669
 
    
10670
 
      // Loop possible derivatives
10671
 
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
10672
 
      {
10673
 
        // Get values from coefficients array
10674
 
        new_coeff0_0 = coefficients0[dof][0];
10675
 
        new_coeff0_1 = coefficients0[dof][1];
10676
 
        new_coeff0_2 = coefficients0[dof][2];
10677
 
    
10678
 
        // Loop derivative order
10679
 
        for (unsigned int j = 0; j < n; j++)
10680
 
        {
10681
 
          // Update old coefficients
10682
 
          coeff0_0 = new_coeff0_0;
10683
 
          coeff0_1 = new_coeff0_1;
10684
 
          coeff0_2 = new_coeff0_2;
10685
 
    
10686
 
          if(combinations[deriv_num][j] == 0)
10687
 
          {
10688
 
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
10689
 
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
10690
 
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
10691
 
          }
10692
 
          if(combinations[deriv_num][j] == 1)
10693
 
          {
10694
 
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
10695
 
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
10696
 
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
10697
 
          }
10698
 
    
10699
 
        }
10700
 
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
10701
 
        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
10702
 
      }
10703
 
    
10704
 
      // Transform derivatives back to physical element
10705
 
      for (unsigned int row = 0; row < num_derivatives; row++)
10706
 
      {
10707
 
        for (unsigned int col = 0; col < num_derivatives; col++)
10708
 
        {
10709
 
          values[num_derivatives + row] += transform[row][col]*derivatives[col];
10710
 
        }
10711
 
      }
10712
 
      // Delete pointer to array of derivatives on FIAT element
10713
 
      delete [] derivatives;
10714
 
    
10715
 
      // Delete pointer to array of combinations of derivatives and transform
10716
 
      for (unsigned int row = 0; row < num_derivatives; row++)
10717
 
      {
10718
 
        delete [] combinations[row];
10719
 
        delete [] transform[row];
10720
 
      }
10721
 
    
10722
 
      delete [] combinations;
10723
 
      delete [] transform;
10724
 
    }
10725
 
    
10726
 
}
10727
 
 
10728
 
/// Evaluate order n derivatives of all basis functions at given point in cell
10729
 
void UFC_CahnHilliard2DLinearForm_finite_element_1::evaluate_basis_derivatives_all(unsigned int n,
10730
 
                                                   double* values,
10731
 
                                                   const double* coordinates,
10732
 
                                                   const ufc::cell& c) const
10733
 
{
10734
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
10735
 
}
10736
 
 
10737
 
/// Evaluate linear functional for dof i on the function f
10738
 
double UFC_CahnHilliard2DLinearForm_finite_element_1::evaluate_dof(unsigned int i,
10739
 
                                   const ufc::function& f,
10740
 
                                   const ufc::cell& c) const
10741
 
{
10742
 
    // The reference points, direction and weights:
10743
 
    const static double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
10744
 
    const static double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
10745
 
    const static double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
10746
 
    
10747
 
    const double * const * x = c.coordinates;
10748
 
    double result = 0.0;
10749
 
    // Iterate over the points:
10750
 
    // Evaluate basis functions for affine mapping
10751
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
10752
 
    const double w1 = X[i][0][0];
10753
 
    const double w2 = X[i][0][1];
10754
 
    
10755
 
    // Compute affine mapping y = F(X)
10756
 
    double y[2];
10757
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
10758
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
10759
 
    
10760
 
    // Evaluate function at physical points
10761
 
    double values[2];
10762
 
    f.evaluate(values, y, c);
10763
 
    
10764
 
    // Map function values using appropriate mapping
10765
 
    // Affine map: Do nothing
10766
 
    
10767
 
    // Note that we do not map the weights (yet).
10768
 
    
10769
 
    // Take directional components
10770
 
    for(int k = 0; k < 2; k++)
10771
 
      result += values[k]*D[i][0][k];
10772
 
    // Multiply by weights 
10773
 
    result *= W[i][0];
10774
 
    
10775
 
    return result;
10776
 
}
10777
 
 
10778
 
/// Evaluate linear functionals for all dofs on the function f
10779
 
void UFC_CahnHilliard2DLinearForm_finite_element_1::evaluate_dofs(double* values,
10780
 
                                  const ufc::function& f,
10781
 
                                  const ufc::cell& c) const
10782
 
{
10783
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
10784
 
}
10785
 
 
10786
 
/// Interpolate vertex values from dof values
10787
 
void UFC_CahnHilliard2DLinearForm_finite_element_1::interpolate_vertex_values(double* vertex_values,
10788
 
                                              const double* dof_values,
10789
 
                                              const ufc::cell& c) const
10790
 
{
10791
 
    // Evaluate at vertices and use affine mapping
10792
 
    vertex_values[0] = dof_values[0];
10793
 
    vertex_values[2] = dof_values[1];
10794
 
    vertex_values[4] = dof_values[2];
10795
 
    // Evaluate at vertices and use affine mapping
10796
 
    vertex_values[1] = dof_values[3];
10797
 
    vertex_values[3] = dof_values[4];
10798
 
    vertex_values[5] = dof_values[5];
10799
 
}
10800
 
 
10801
 
/// Return the number of sub elements (for a mixed element)
10802
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_1::num_sub_elements() const
10803
 
{
10804
 
    return 2;
10805
 
}
10806
 
 
10807
 
/// Create a new finite element for sub element i (for a mixed element)
10808
 
ufc::finite_element* UFC_CahnHilliard2DLinearForm_finite_element_1::create_sub_element(unsigned int i) const
10809
 
{
10810
 
    switch ( i )
10811
 
    {
10812
 
    case 0:
10813
 
      return new UFC_CahnHilliard2DLinearForm_finite_element_1_0();
10814
 
      break;
10815
 
    case 1:
10816
 
      return new UFC_CahnHilliard2DLinearForm_finite_element_1_1();
10817
 
      break;
10818
 
    }
10819
 
    return 0;
10820
 
}
10821
 
 
10822
 
 
10823
 
/// Constructor
10824
 
UFC_CahnHilliard2DLinearForm_finite_element_2_0::UFC_CahnHilliard2DLinearForm_finite_element_2_0() : ufc::finite_element()
10825
 
{
10826
 
    // Do nothing
10827
 
}
10828
 
 
10829
 
/// Destructor
10830
 
UFC_CahnHilliard2DLinearForm_finite_element_2_0::~UFC_CahnHilliard2DLinearForm_finite_element_2_0()
10831
 
{
10832
 
    // Do nothing
10833
 
}
10834
 
 
10835
 
/// Return a string identifying the finite element
10836
 
const char* UFC_CahnHilliard2DLinearForm_finite_element_2_0::signature() const
10837
 
{
10838
 
    return "FiniteElement('Lagrange', 'triangle', 1)";
10839
 
}
10840
 
 
10841
 
/// Return the cell shape
10842
 
ufc::shape UFC_CahnHilliard2DLinearForm_finite_element_2_0::cell_shape() const
10843
 
{
10844
 
    return ufc::triangle;
10845
 
}
10846
 
 
10847
 
/// Return the dimension of the finite element function space
10848
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_2_0::space_dimension() const
10849
 
{
10850
 
    return 3;
10851
 
}
10852
 
 
10853
 
/// Return the rank of the value space
10854
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_2_0::value_rank() const
10855
 
{
10856
 
    return 0;
10857
 
}
10858
 
 
10859
 
/// Return the dimension of the value space for axis i
10860
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_2_0::value_dimension(unsigned int i) const
10861
 
{
10862
 
    return 1;
10863
 
}
10864
 
 
10865
 
/// Evaluate basis function i at given point in cell
10866
 
void UFC_CahnHilliard2DLinearForm_finite_element_2_0::evaluate_basis(unsigned int i,
10867
 
                                   double* values,
10868
 
                                   const double* coordinates,
10869
 
                                   const ufc::cell& c) const
10870
 
{
10871
 
    // Extract vertex coordinates
10872
 
    const double * const * element_coordinates = c.coordinates;
10873
 
    
10874
 
    // Compute Jacobian of affine map from reference cell
10875
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
10876
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
10877
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
10878
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
10879
 
      
10880
 
    // Compute determinant of Jacobian
10881
 
    const double detJ = J_00*J_11 - J_01*J_10;
10882
 
    
10883
 
    // Compute inverse of Jacobian
10884
 
    
10885
 
    // Get coordinates and map to the reference (UFC) element
10886
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
10887
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
10888
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
10889
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
10890
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
10891
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
10892
 
    
10893
 
    // Map coordinates to the reference square
10894
 
    if (std::abs(y - 1.0) < 1e-14)
10895
 
      x = -1.0;
10896
 
    else
10897
 
      x = 2.0 *x/(1.0 - y) - 1.0;
10898
 
    y = 2.0*y - 1.0;
10899
 
    
10900
 
    // Reset values
10901
 
    *values = 0;
10902
 
    
10903
 
    // Map degree of freedom to element degree of freedom
10904
 
    const unsigned int dof = i;
10905
 
    
10906
 
    // Generate scalings
10907
 
    const double scalings_y_0 = 1;
10908
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
10909
 
    
10910
 
    // Compute psitilde_a
10911
 
    const double psitilde_a_0 = 1;
10912
 
    const double psitilde_a_1 = x;
10913
 
    
10914
 
    // Compute psitilde_bs
10915
 
    const double psitilde_bs_0_0 = 1;
10916
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
10917
 
    const double psitilde_bs_1_0 = 1;
10918
 
    
10919
 
    // Compute basisvalues
10920
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
10921
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
10922
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
10923
 
    
10924
 
    // Table(s) of coefficients
10925
 
    const static double coefficients0[3][3] = \
10926
 
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
10927
 
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
10928
 
    {0.471404520791032, 0, 0.333333333333333}};
10929
 
    
10930
 
    // Extract relevant coefficients
10931
 
    const double coeff0_0 = coefficients0[dof][0];
10932
 
    const double coeff0_1 = coefficients0[dof][1];
10933
 
    const double coeff0_2 = coefficients0[dof][2];
10934
 
    
10935
 
    // Compute value(s)
10936
 
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
10937
 
}
10938
 
 
10939
 
/// Evaluate all basis functions at given point in cell
10940
 
void UFC_CahnHilliard2DLinearForm_finite_element_2_0::evaluate_basis_all(double* values,
10941
 
                                       const double* coordinates,
10942
 
                                       const ufc::cell& c) const
10943
 
{
10944
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
10945
 
}
10946
 
 
10947
 
/// Evaluate order n derivatives of basis function i at given point in cell
10948
 
void UFC_CahnHilliard2DLinearForm_finite_element_2_0::evaluate_basis_derivatives(unsigned int i,
10949
 
                                               unsigned int n,
10950
 
                                               double* values,
10951
 
                                               const double* coordinates,
10952
 
                                               const ufc::cell& c) const
10953
 
{
10954
 
    // Extract vertex coordinates
10955
 
    const double * const * element_coordinates = c.coordinates;
10956
 
    
10957
 
    // Compute Jacobian of affine map from reference cell
10958
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
10959
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
10960
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
10961
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
10962
 
      
10963
 
    // Compute determinant of Jacobian
10964
 
    const double detJ = J_00*J_11 - J_01*J_10;
10965
 
    
10966
 
    // Compute inverse of Jacobian
10967
 
    
10968
 
    // Get coordinates and map to the reference (UFC) element
10969
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
10970
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
10971
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
10972
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
10973
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
10974
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
10975
 
    
10976
 
    // Map coordinates to the reference square
10977
 
    if (std::abs(y - 1.0) < 1e-14)
10978
 
      x = -1.0;
10979
 
    else
10980
 
      x = 2.0 *x/(1.0 - y) - 1.0;
10981
 
    y = 2.0*y - 1.0;
10982
 
    
10983
 
    // Compute number of derivatives
10984
 
    unsigned int num_derivatives = 1;
10985
 
    
10986
 
    for (unsigned int j = 0; j < n; j++)
10987
 
      num_derivatives *= 2;
10988
 
    
10989
 
    
10990
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
10991
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
10992
 
        
10993
 
    for (unsigned int j = 0; j < num_derivatives; j++)
10994
 
    {
10995
 
      combinations[j] = new unsigned int [n];
10996
 
      for (unsigned int k = 0; k < n; k++)
10997
 
        combinations[j][k] = 0;
10998
 
    }
10999
 
        
11000
 
    // Generate combinations of derivatives
11001
 
    for (unsigned int row = 1; row < num_derivatives; row++)
11002
 
    {
11003
 
      for (unsigned int num = 0; num < row; num++)
11004
 
      {
11005
 
        for (unsigned int col = n-1; col+1 > 0; col--)
11006
 
        {
11007
 
          if (combinations[row][col] + 1 > 1)
11008
 
            combinations[row][col] = 0;
11009
 
          else
11010
 
          {
11011
 
            combinations[row][col] += 1;
11012
 
            break;
11013
 
          }
11014
 
        }
11015
 
      }
11016
 
    }
11017
 
    
11018
 
    // Compute inverse of Jacobian
11019
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
11020
 
    
11021
 
    // Declare transformation matrix
11022
 
    // Declare pointer to two dimensional array and initialise
11023
 
    double **transform = new double *[num_derivatives];
11024
 
        
11025
 
    for (unsigned int j = 0; j < num_derivatives; j++)
11026
 
    {
11027
 
      transform[j] = new double [num_derivatives];
11028
 
      for (unsigned int k = 0; k < num_derivatives; k++)
11029
 
        transform[j][k] = 1;
11030
 
    }
11031
 
    
11032
 
    // Construct transformation matrix
11033
 
    for (unsigned int row = 0; row < num_derivatives; row++)
11034
 
    {
11035
 
      for (unsigned int col = 0; col < num_derivatives; col++)
11036
 
      {
11037
 
        for (unsigned int k = 0; k < n; k++)
11038
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
11039
 
      }
11040
 
    }
11041
 
    
11042
 
    // Reset values
11043
 
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
11044
 
      values[j] = 0;
11045
 
    
11046
 
    // Map degree of freedom to element degree of freedom
11047
 
    const unsigned int dof = i;
11048
 
    
11049
 
    // Generate scalings
11050
 
    const double scalings_y_0 = 1;
11051
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
11052
 
    
11053
 
    // Compute psitilde_a
11054
 
    const double psitilde_a_0 = 1;
11055
 
    const double psitilde_a_1 = x;
11056
 
    
11057
 
    // Compute psitilde_bs
11058
 
    const double psitilde_bs_0_0 = 1;
11059
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
11060
 
    const double psitilde_bs_1_0 = 1;
11061
 
    
11062
 
    // Compute basisvalues
11063
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
11064
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
11065
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
11066
 
    
11067
 
    // Table(s) of coefficients
11068
 
    const static double coefficients0[3][3] = \
11069
 
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
11070
 
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
11071
 
    {0.471404520791032, 0, 0.333333333333333}};
11072
 
    
11073
 
    // Interesting (new) part
11074
 
    // Tables of derivatives of the polynomial base (transpose)
11075
 
    const static double dmats0[3][3] = \
11076
 
    {{0, 0, 0},
11077
 
    {4.89897948556636, 0, 0},
11078
 
    {0, 0, 0}};
11079
 
    
11080
 
    const static double dmats1[3][3] = \
11081
 
    {{0, 0, 0},
11082
 
    {2.44948974278318, 0, 0},
11083
 
    {4.24264068711928, 0, 0}};
11084
 
    
11085
 
    // Compute reference derivatives
11086
 
    // Declare pointer to array of derivatives on FIAT element
11087
 
    double *derivatives = new double [num_derivatives];
11088
 
    
11089
 
    // Declare coefficients
11090
 
    double coeff0_0 = 0;
11091
 
    double coeff0_1 = 0;
11092
 
    double coeff0_2 = 0;
11093
 
    
11094
 
    // Declare new coefficients
11095
 
    double new_coeff0_0 = 0;
11096
 
    double new_coeff0_1 = 0;
11097
 
    double new_coeff0_2 = 0;
11098
 
    
11099
 
    // Loop possible derivatives
11100
 
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
11101
 
    {
11102
 
      // Get values from coefficients array
11103
 
      new_coeff0_0 = coefficients0[dof][0];
11104
 
      new_coeff0_1 = coefficients0[dof][1];
11105
 
      new_coeff0_2 = coefficients0[dof][2];
11106
 
    
11107
 
      // Loop derivative order
11108
 
      for (unsigned int j = 0; j < n; j++)
11109
 
      {
11110
 
        // Update old coefficients
11111
 
        coeff0_0 = new_coeff0_0;
11112
 
        coeff0_1 = new_coeff0_1;
11113
 
        coeff0_2 = new_coeff0_2;
11114
 
    
11115
 
        if(combinations[deriv_num][j] == 0)
11116
 
        {
11117
 
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
11118
 
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
11119
 
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
11120
 
        }
11121
 
        if(combinations[deriv_num][j] == 1)
11122
 
        {
11123
 
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
11124
 
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
11125
 
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
11126
 
        }
11127
 
    
11128
 
      }
11129
 
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
11130
 
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
11131
 
    }
11132
 
    
11133
 
    // Transform derivatives back to physical element
11134
 
    for (unsigned int row = 0; row < num_derivatives; row++)
11135
 
    {
11136
 
      for (unsigned int col = 0; col < num_derivatives; col++)
11137
 
      {
11138
 
        values[row] += transform[row][col]*derivatives[col];
11139
 
      }
11140
 
    }
11141
 
    // Delete pointer to array of derivatives on FIAT element
11142
 
    delete [] derivatives;
11143
 
    
11144
 
    // Delete pointer to array of combinations of derivatives and transform
11145
 
    for (unsigned int row = 0; row < num_derivatives; row++)
11146
 
    {
11147
 
      delete [] combinations[row];
11148
 
      delete [] transform[row];
11149
 
    }
11150
 
    
11151
 
    delete [] combinations;
11152
 
    delete [] transform;
11153
 
}
11154
 
 
11155
 
/// Evaluate order n derivatives of all basis functions at given point in cell
11156
 
void UFC_CahnHilliard2DLinearForm_finite_element_2_0::evaluate_basis_derivatives_all(unsigned int n,
11157
 
                                                   double* values,
11158
 
                                                   const double* coordinates,
11159
 
                                                   const ufc::cell& c) const
11160
 
{
11161
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
11162
 
}
11163
 
 
11164
 
/// Evaluate linear functional for dof i on the function f
11165
 
double UFC_CahnHilliard2DLinearForm_finite_element_2_0::evaluate_dof(unsigned int i,
11166
 
                                   const ufc::function& f,
11167
 
                                   const ufc::cell& c) const
11168
 
{
11169
 
    // The reference points, direction and weights:
11170
 
    const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
11171
 
    const static double W[3][1] = {{1}, {1}, {1}};
11172
 
    const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
11173
 
    
11174
 
    const double * const * x = c.coordinates;
11175
 
    double result = 0.0;
11176
 
    // Iterate over the points:
11177
 
    // Evaluate basis functions for affine mapping
11178
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
11179
 
    const double w1 = X[i][0][0];
11180
 
    const double w2 = X[i][0][1];
11181
 
    
11182
 
    // Compute affine mapping y = F(X)
11183
 
    double y[2];
11184
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
11185
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
11186
 
    
11187
 
    // Evaluate function at physical points
11188
 
    double values[1];
11189
 
    f.evaluate(values, y, c);
11190
 
    
11191
 
    // Map function values using appropriate mapping
11192
 
    // Affine map: Do nothing
11193
 
    
11194
 
    // Note that we do not map the weights (yet).
11195
 
    
11196
 
    // Take directional components
11197
 
    for(int k = 0; k < 1; k++)
11198
 
      result += values[k]*D[i][0][k];
11199
 
    // Multiply by weights 
11200
 
    result *= W[i][0];
11201
 
    
11202
 
    return result;
11203
 
}
11204
 
 
11205
 
/// Evaluate linear functionals for all dofs on the function f
11206
 
void UFC_CahnHilliard2DLinearForm_finite_element_2_0::evaluate_dofs(double* values,
11207
 
                                  const ufc::function& f,
11208
 
                                  const ufc::cell& c) const
11209
 
{
11210
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
11211
 
}
11212
 
 
11213
 
/// Interpolate vertex values from dof values
11214
 
void UFC_CahnHilliard2DLinearForm_finite_element_2_0::interpolate_vertex_values(double* vertex_values,
11215
 
                                              const double* dof_values,
11216
 
                                              const ufc::cell& c) const
11217
 
{
11218
 
    // Evaluate at vertices and use affine mapping
11219
 
    vertex_values[0] = dof_values[0];
11220
 
    vertex_values[1] = dof_values[1];
11221
 
    vertex_values[2] = dof_values[2];
11222
 
}
11223
 
 
11224
 
/// Return the number of sub elements (for a mixed element)
11225
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_2_0::num_sub_elements() const
11226
 
{
11227
 
    return 1;
11228
 
}
11229
 
 
11230
 
/// Create a new finite element for sub element i (for a mixed element)
11231
 
ufc::finite_element* UFC_CahnHilliard2DLinearForm_finite_element_2_0::create_sub_element(unsigned int i) const
11232
 
{
11233
 
    return new UFC_CahnHilliard2DLinearForm_finite_element_2_0();
11234
 
}
11235
 
 
11236
 
 
11237
 
/// Constructor
11238
 
UFC_CahnHilliard2DLinearForm_finite_element_2_1::UFC_CahnHilliard2DLinearForm_finite_element_2_1() : ufc::finite_element()
11239
 
{
11240
 
    // Do nothing
11241
 
}
11242
 
 
11243
 
/// Destructor
11244
 
UFC_CahnHilliard2DLinearForm_finite_element_2_1::~UFC_CahnHilliard2DLinearForm_finite_element_2_1()
11245
 
{
11246
 
    // Do nothing
11247
 
}
11248
 
 
11249
 
/// Return a string identifying the finite element
11250
 
const char* UFC_CahnHilliard2DLinearForm_finite_element_2_1::signature() const
11251
 
{
11252
 
    return "FiniteElement('Lagrange', 'triangle', 1)";
11253
 
}
11254
 
 
11255
 
/// Return the cell shape
11256
 
ufc::shape UFC_CahnHilliard2DLinearForm_finite_element_2_1::cell_shape() const
11257
 
{
11258
 
    return ufc::triangle;
11259
 
}
11260
 
 
11261
 
/// Return the dimension of the finite element function space
11262
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_2_1::space_dimension() const
11263
 
{
11264
 
    return 3;
11265
 
}
11266
 
 
11267
 
/// Return the rank of the value space
11268
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_2_1::value_rank() const
11269
 
{
11270
 
    return 0;
11271
 
}
11272
 
 
11273
 
/// Return the dimension of the value space for axis i
11274
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_2_1::value_dimension(unsigned int i) const
11275
 
{
11276
 
    return 1;
11277
 
}
11278
 
 
11279
 
/// Evaluate basis function i at given point in cell
11280
 
void UFC_CahnHilliard2DLinearForm_finite_element_2_1::evaluate_basis(unsigned int i,
11281
 
                                   double* values,
11282
 
                                   const double* coordinates,
11283
 
                                   const ufc::cell& c) const
11284
 
{
11285
 
    // Extract vertex coordinates
11286
 
    const double * const * element_coordinates = c.coordinates;
11287
 
    
11288
 
    // Compute Jacobian of affine map from reference cell
11289
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
11290
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
11291
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
11292
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
11293
 
      
11294
 
    // Compute determinant of Jacobian
11295
 
    const double detJ = J_00*J_11 - J_01*J_10;
11296
 
    
11297
 
    // Compute inverse of Jacobian
11298
 
    
11299
 
    // Get coordinates and map to the reference (UFC) element
11300
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
11301
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
11302
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
11303
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
11304
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
11305
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
11306
 
    
11307
 
    // Map coordinates to the reference square
11308
 
    if (std::abs(y - 1.0) < 1e-14)
11309
 
      x = -1.0;
11310
 
    else
11311
 
      x = 2.0 *x/(1.0 - y) - 1.0;
11312
 
    y = 2.0*y - 1.0;
11313
 
    
11314
 
    // Reset values
11315
 
    *values = 0;
11316
 
    
11317
 
    // Map degree of freedom to element degree of freedom
11318
 
    const unsigned int dof = i;
11319
 
    
11320
 
    // Generate scalings
11321
 
    const double scalings_y_0 = 1;
11322
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
11323
 
    
11324
 
    // Compute psitilde_a
11325
 
    const double psitilde_a_0 = 1;
11326
 
    const double psitilde_a_1 = x;
11327
 
    
11328
 
    // Compute psitilde_bs
11329
 
    const double psitilde_bs_0_0 = 1;
11330
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
11331
 
    const double psitilde_bs_1_0 = 1;
11332
 
    
11333
 
    // Compute basisvalues
11334
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
11335
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
11336
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
11337
 
    
11338
 
    // Table(s) of coefficients
11339
 
    const static double coefficients0[3][3] = \
11340
 
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
11341
 
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
11342
 
    {0.471404520791032, 0, 0.333333333333333}};
11343
 
    
11344
 
    // Extract relevant coefficients
11345
 
    const double coeff0_0 = coefficients0[dof][0];
11346
 
    const double coeff0_1 = coefficients0[dof][1];
11347
 
    const double coeff0_2 = coefficients0[dof][2];
11348
 
    
11349
 
    // Compute value(s)
11350
 
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
11351
 
}
11352
 
 
11353
 
/// Evaluate all basis functions at given point in cell
11354
 
void UFC_CahnHilliard2DLinearForm_finite_element_2_1::evaluate_basis_all(double* values,
11355
 
                                       const double* coordinates,
11356
 
                                       const ufc::cell& c) const
11357
 
{
11358
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
11359
 
}
11360
 
 
11361
 
/// Evaluate order n derivatives of basis function i at given point in cell
11362
 
void UFC_CahnHilliard2DLinearForm_finite_element_2_1::evaluate_basis_derivatives(unsigned int i,
11363
 
                                               unsigned int n,
11364
 
                                               double* values,
11365
 
                                               const double* coordinates,
11366
 
                                               const ufc::cell& c) const
11367
 
{
11368
 
    // Extract vertex coordinates
11369
 
    const double * const * element_coordinates = c.coordinates;
11370
 
    
11371
 
    // Compute Jacobian of affine map from reference cell
11372
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
11373
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
11374
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
11375
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
11376
 
      
11377
 
    // Compute determinant of Jacobian
11378
 
    const double detJ = J_00*J_11 - J_01*J_10;
11379
 
    
11380
 
    // Compute inverse of Jacobian
11381
 
    
11382
 
    // Get coordinates and map to the reference (UFC) element
11383
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
11384
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
11385
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
11386
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
11387
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
11388
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
11389
 
    
11390
 
    // Map coordinates to the reference square
11391
 
    if (std::abs(y - 1.0) < 1e-14)
11392
 
      x = -1.0;
11393
 
    else
11394
 
      x = 2.0 *x/(1.0 - y) - 1.0;
11395
 
    y = 2.0*y - 1.0;
11396
 
    
11397
 
    // Compute number of derivatives
11398
 
    unsigned int num_derivatives = 1;
11399
 
    
11400
 
    for (unsigned int j = 0; j < n; j++)
11401
 
      num_derivatives *= 2;
11402
 
    
11403
 
    
11404
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
11405
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
11406
 
        
11407
 
    for (unsigned int j = 0; j < num_derivatives; j++)
11408
 
    {
11409
 
      combinations[j] = new unsigned int [n];
11410
 
      for (unsigned int k = 0; k < n; k++)
11411
 
        combinations[j][k] = 0;
11412
 
    }
11413
 
        
11414
 
    // Generate combinations of derivatives
11415
 
    for (unsigned int row = 1; row < num_derivatives; row++)
11416
 
    {
11417
 
      for (unsigned int num = 0; num < row; num++)
11418
 
      {
11419
 
        for (unsigned int col = n-1; col+1 > 0; col--)
11420
 
        {
11421
 
          if (combinations[row][col] + 1 > 1)
11422
 
            combinations[row][col] = 0;
11423
 
          else
11424
 
          {
11425
 
            combinations[row][col] += 1;
11426
 
            break;
11427
 
          }
11428
 
        }
11429
 
      }
11430
 
    }
11431
 
    
11432
 
    // Compute inverse of Jacobian
11433
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
11434
 
    
11435
 
    // Declare transformation matrix
11436
 
    // Declare pointer to two dimensional array and initialise
11437
 
    double **transform = new double *[num_derivatives];
11438
 
        
11439
 
    for (unsigned int j = 0; j < num_derivatives; j++)
11440
 
    {
11441
 
      transform[j] = new double [num_derivatives];
11442
 
      for (unsigned int k = 0; k < num_derivatives; k++)
11443
 
        transform[j][k] = 1;
11444
 
    }
11445
 
    
11446
 
    // Construct transformation matrix
11447
 
    for (unsigned int row = 0; row < num_derivatives; row++)
11448
 
    {
11449
 
      for (unsigned int col = 0; col < num_derivatives; col++)
11450
 
      {
11451
 
        for (unsigned int k = 0; k < n; k++)
11452
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
11453
 
      }
11454
 
    }
11455
 
    
11456
 
    // Reset values
11457
 
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
11458
 
      values[j] = 0;
11459
 
    
11460
 
    // Map degree of freedom to element degree of freedom
11461
 
    const unsigned int dof = i;
11462
 
    
11463
 
    // Generate scalings
11464
 
    const double scalings_y_0 = 1;
11465
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
11466
 
    
11467
 
    // Compute psitilde_a
11468
 
    const double psitilde_a_0 = 1;
11469
 
    const double psitilde_a_1 = x;
11470
 
    
11471
 
    // Compute psitilde_bs
11472
 
    const double psitilde_bs_0_0 = 1;
11473
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
11474
 
    const double psitilde_bs_1_0 = 1;
11475
 
    
11476
 
    // Compute basisvalues
11477
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
11478
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
11479
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
11480
 
    
11481
 
    // Table(s) of coefficients
11482
 
    const static double coefficients0[3][3] = \
11483
 
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
11484
 
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
11485
 
    {0.471404520791032, 0, 0.333333333333333}};
11486
 
    
11487
 
    // Interesting (new) part
11488
 
    // Tables of derivatives of the polynomial base (transpose)
11489
 
    const static double dmats0[3][3] = \
11490
 
    {{0, 0, 0},
11491
 
    {4.89897948556636, 0, 0},
11492
 
    {0, 0, 0}};
11493
 
    
11494
 
    const static double dmats1[3][3] = \
11495
 
    {{0, 0, 0},
11496
 
    {2.44948974278318, 0, 0},
11497
 
    {4.24264068711928, 0, 0}};
11498
 
    
11499
 
    // Compute reference derivatives
11500
 
    // Declare pointer to array of derivatives on FIAT element
11501
 
    double *derivatives = new double [num_derivatives];
11502
 
    
11503
 
    // Declare coefficients
11504
 
    double coeff0_0 = 0;
11505
 
    double coeff0_1 = 0;
11506
 
    double coeff0_2 = 0;
11507
 
    
11508
 
    // Declare new coefficients
11509
 
    double new_coeff0_0 = 0;
11510
 
    double new_coeff0_1 = 0;
11511
 
    double new_coeff0_2 = 0;
11512
 
    
11513
 
    // Loop possible derivatives
11514
 
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
11515
 
    {
11516
 
      // Get values from coefficients array
11517
 
      new_coeff0_0 = coefficients0[dof][0];
11518
 
      new_coeff0_1 = coefficients0[dof][1];
11519
 
      new_coeff0_2 = coefficients0[dof][2];
11520
 
    
11521
 
      // Loop derivative order
11522
 
      for (unsigned int j = 0; j < n; j++)
11523
 
      {
11524
 
        // Update old coefficients
11525
 
        coeff0_0 = new_coeff0_0;
11526
 
        coeff0_1 = new_coeff0_1;
11527
 
        coeff0_2 = new_coeff0_2;
11528
 
    
11529
 
        if(combinations[deriv_num][j] == 0)
11530
 
        {
11531
 
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
11532
 
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
11533
 
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
11534
 
        }
11535
 
        if(combinations[deriv_num][j] == 1)
11536
 
        {
11537
 
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
11538
 
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
11539
 
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
11540
 
        }
11541
 
    
11542
 
      }
11543
 
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
11544
 
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
11545
 
    }
11546
 
    
11547
 
    // Transform derivatives back to physical element
11548
 
    for (unsigned int row = 0; row < num_derivatives; row++)
11549
 
    {
11550
 
      for (unsigned int col = 0; col < num_derivatives; col++)
11551
 
      {
11552
 
        values[row] += transform[row][col]*derivatives[col];
11553
 
      }
11554
 
    }
11555
 
    // Delete pointer to array of derivatives on FIAT element
11556
 
    delete [] derivatives;
11557
 
    
11558
 
    // Delete pointer to array of combinations of derivatives and transform
11559
 
    for (unsigned int row = 0; row < num_derivatives; row++)
11560
 
    {
11561
 
      delete [] combinations[row];
11562
 
      delete [] transform[row];
11563
 
    }
11564
 
    
11565
 
    delete [] combinations;
11566
 
    delete [] transform;
11567
 
}
11568
 
 
11569
 
/// Evaluate order n derivatives of all basis functions at given point in cell
11570
 
void UFC_CahnHilliard2DLinearForm_finite_element_2_1::evaluate_basis_derivatives_all(unsigned int n,
11571
 
                                                   double* values,
11572
 
                                                   const double* coordinates,
11573
 
                                                   const ufc::cell& c) const
11574
 
{
11575
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
11576
 
}
11577
 
 
11578
 
/// Evaluate linear functional for dof i on the function f
11579
 
double UFC_CahnHilliard2DLinearForm_finite_element_2_1::evaluate_dof(unsigned int i,
11580
 
                                   const ufc::function& f,
11581
 
                                   const ufc::cell& c) const
11582
 
{
11583
 
    // The reference points, direction and weights:
11584
 
    const static double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
11585
 
    const static double W[3][1] = {{1}, {1}, {1}};
11586
 
    const static double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
11587
 
    
11588
 
    const double * const * x = c.coordinates;
11589
 
    double result = 0.0;
11590
 
    // Iterate over the points:
11591
 
    // Evaluate basis functions for affine mapping
11592
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
11593
 
    const double w1 = X[i][0][0];
11594
 
    const double w2 = X[i][0][1];
11595
 
    
11596
 
    // Compute affine mapping y = F(X)
11597
 
    double y[2];
11598
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
11599
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
11600
 
    
11601
 
    // Evaluate function at physical points
11602
 
    double values[1];
11603
 
    f.evaluate(values, y, c);
11604
 
    
11605
 
    // Map function values using appropriate mapping
11606
 
    // Affine map: Do nothing
11607
 
    
11608
 
    // Note that we do not map the weights (yet).
11609
 
    
11610
 
    // Take directional components
11611
 
    for(int k = 0; k < 1; k++)
11612
 
      result += values[k]*D[i][0][k];
11613
 
    // Multiply by weights 
11614
 
    result *= W[i][0];
11615
 
    
11616
 
    return result;
11617
 
}
11618
 
 
11619
 
/// Evaluate linear functionals for all dofs on the function f
11620
 
void UFC_CahnHilliard2DLinearForm_finite_element_2_1::evaluate_dofs(double* values,
11621
 
                                  const ufc::function& f,
11622
 
                                  const ufc::cell& c) const
11623
 
{
11624
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
11625
 
}
11626
 
 
11627
 
/// Interpolate vertex values from dof values
11628
 
void UFC_CahnHilliard2DLinearForm_finite_element_2_1::interpolate_vertex_values(double* vertex_values,
11629
 
                                              const double* dof_values,
11630
 
                                              const ufc::cell& c) const
11631
 
{
11632
 
    // Evaluate at vertices and use affine mapping
11633
 
    vertex_values[0] = dof_values[0];
11634
 
    vertex_values[1] = dof_values[1];
11635
 
    vertex_values[2] = dof_values[2];
11636
 
}
11637
 
 
11638
 
/// Return the number of sub elements (for a mixed element)
11639
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_2_1::num_sub_elements() const
11640
 
{
11641
 
    return 1;
11642
 
}
11643
 
 
11644
 
/// Create a new finite element for sub element i (for a mixed element)
11645
 
ufc::finite_element* UFC_CahnHilliard2DLinearForm_finite_element_2_1::create_sub_element(unsigned int i) const
11646
 
{
11647
 
    return new UFC_CahnHilliard2DLinearForm_finite_element_2_1();
11648
 
}
11649
 
 
11650
 
 
11651
 
/// Constructor
11652
 
UFC_CahnHilliard2DLinearForm_finite_element_2::UFC_CahnHilliard2DLinearForm_finite_element_2() : ufc::finite_element()
11653
 
{
11654
 
    // Do nothing
11655
 
}
11656
 
 
11657
 
/// Destructor
11658
 
UFC_CahnHilliard2DLinearForm_finite_element_2::~UFC_CahnHilliard2DLinearForm_finite_element_2()
11659
 
{
11660
 
    // Do nothing
11661
 
}
11662
 
 
11663
 
/// Return a string identifying the finite element
11664
 
const char* UFC_CahnHilliard2DLinearForm_finite_element_2::signature() const
11665
 
{
11666
 
    return "MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
11667
 
}
11668
 
 
11669
 
/// Return the cell shape
11670
 
ufc::shape UFC_CahnHilliard2DLinearForm_finite_element_2::cell_shape() const
11671
 
{
11672
 
    return ufc::triangle;
11673
 
}
11674
 
 
11675
 
/// Return the dimension of the finite element function space
11676
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_2::space_dimension() const
11677
 
{
11678
 
    return 6;
11679
 
}
11680
 
 
11681
 
/// Return the rank of the value space
11682
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_2::value_rank() const
11683
 
{
11684
 
    return 1;
11685
 
}
11686
 
 
11687
 
/// Return the dimension of the value space for axis i
11688
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_2::value_dimension(unsigned int i) const
11689
 
{
11690
 
    return 2;
11691
 
}
11692
 
 
11693
 
/// Evaluate basis function i at given point in cell
11694
 
void UFC_CahnHilliard2DLinearForm_finite_element_2::evaluate_basis(unsigned int i,
11695
 
                                   double* values,
11696
 
                                   const double* coordinates,
11697
 
                                   const ufc::cell& c) const
11698
 
{
11699
 
    // Extract vertex coordinates
11700
 
    const double * const * element_coordinates = c.coordinates;
11701
 
    
11702
 
    // Compute Jacobian of affine map from reference cell
11703
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
11704
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
11705
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
11706
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
11707
 
      
11708
 
    // Compute determinant of Jacobian
11709
 
    const double detJ = J_00*J_11 - J_01*J_10;
11710
 
    
11711
 
    // Compute inverse of Jacobian
11712
 
    
11713
 
    // Get coordinates and map to the reference (UFC) element
11714
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
11715
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
11716
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
11717
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
11718
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
11719
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
11720
 
    
11721
 
    // Map coordinates to the reference square
11722
 
    if (std::abs(y - 1.0) < 1e-14)
11723
 
      x = -1.0;
11724
 
    else
11725
 
      x = 2.0 *x/(1.0 - y) - 1.0;
11726
 
    y = 2.0*y - 1.0;
11727
 
    
11728
 
    // Reset values
11729
 
    values[0] = 0;
11730
 
    values[1] = 0;
11731
 
    
11732
 
    if (0 <= i && i <= 2)
11733
 
    {
11734
 
      // Map degree of freedom to element degree of freedom
11735
 
      const unsigned int dof = i;
11736
 
    
11737
 
      // Generate scalings
11738
 
      const double scalings_y_0 = 1;
11739
 
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
11740
 
    
11741
 
      // Compute psitilde_a
11742
 
      const double psitilde_a_0 = 1;
11743
 
      const double psitilde_a_1 = x;
11744
 
    
11745
 
      // Compute psitilde_bs
11746
 
      const double psitilde_bs_0_0 = 1;
11747
 
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
11748
 
      const double psitilde_bs_1_0 = 1;
11749
 
    
11750
 
      // Compute basisvalues
11751
 
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
11752
 
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
11753
 
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
11754
 
    
11755
 
      // Table(s) of coefficients
11756
 
      const static double coefficients0[3][3] =   \
11757
 
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
11758
 
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
11759
 
      {0.471404520791032, 0, 0.333333333333333}};
11760
 
    
11761
 
      // Extract relevant coefficients
11762
 
      const double coeff0_0 =   coefficients0[dof][0];
11763
 
      const double coeff0_1 =   coefficients0[dof][1];
11764
 
      const double coeff0_2 =   coefficients0[dof][2];
11765
 
    
11766
 
      // Compute value(s)
11767
 
      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
11768
 
    }
11769
 
    
11770
 
    if (3 <= i && i <= 5)
11771
 
    {
11772
 
      // Map degree of freedom to element degree of freedom
11773
 
      const unsigned int dof = i - 3;
11774
 
    
11775
 
      // Generate scalings
11776
 
      const double scalings_y_0 = 1;
11777
 
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
11778
 
    
11779
 
      // Compute psitilde_a
11780
 
      const double psitilde_a_0 = 1;
11781
 
      const double psitilde_a_1 = x;
11782
 
    
11783
 
      // Compute psitilde_bs
11784
 
      const double psitilde_bs_0_0 = 1;
11785
 
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
11786
 
      const double psitilde_bs_1_0 = 1;
11787
 
    
11788
 
      // Compute basisvalues
11789
 
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
11790
 
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
11791
 
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
11792
 
    
11793
 
      // Table(s) of coefficients
11794
 
      const static double coefficients0[3][3] =   \
11795
 
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
11796
 
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
11797
 
      {0.471404520791032, 0, 0.333333333333333}};
11798
 
    
11799
 
      // Extract relevant coefficients
11800
 
      const double coeff0_0 =   coefficients0[dof][0];
11801
 
      const double coeff0_1 =   coefficients0[dof][1];
11802
 
      const double coeff0_2 =   coefficients0[dof][2];
11803
 
    
11804
 
      // Compute value(s)
11805
 
      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
11806
 
    }
11807
 
    
11808
 
}
11809
 
 
11810
 
/// Evaluate all basis functions at given point in cell
11811
 
void UFC_CahnHilliard2DLinearForm_finite_element_2::evaluate_basis_all(double* values,
11812
 
                                       const double* coordinates,
11813
 
                                       const ufc::cell& c) const
11814
 
{
11815
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
11816
 
}
11817
 
 
11818
 
/// Evaluate order n derivatives of basis function i at given point in cell
11819
 
void UFC_CahnHilliard2DLinearForm_finite_element_2::evaluate_basis_derivatives(unsigned int i,
11820
 
                                               unsigned int n,
11821
 
                                               double* values,
11822
 
                                               const double* coordinates,
11823
 
                                               const ufc::cell& c) const
11824
 
{
11825
 
    // Extract vertex coordinates
11826
 
    const double * const * element_coordinates = c.coordinates;
11827
 
    
11828
 
    // Compute Jacobian of affine map from reference cell
11829
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
11830
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
11831
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
11832
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
11833
 
      
11834
 
    // Compute determinant of Jacobian
11835
 
    const double detJ = J_00*J_11 - J_01*J_10;
11836
 
    
11837
 
    // Compute inverse of Jacobian
11838
 
    
11839
 
    // Get coordinates and map to the reference (UFC) element
11840
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
11841
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
11842
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
11843
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
11844
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
11845
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
11846
 
    
11847
 
    // Map coordinates to the reference square
11848
 
    if (std::abs(y - 1.0) < 1e-14)
11849
 
      x = -1.0;
11850
 
    else
11851
 
      x = 2.0 *x/(1.0 - y) - 1.0;
11852
 
    y = 2.0*y - 1.0;
11853
 
    
11854
 
    // Compute number of derivatives
11855
 
    unsigned int num_derivatives = 1;
11856
 
    
11857
 
    for (unsigned int j = 0; j < n; j++)
11858
 
      num_derivatives *= 2;
11859
 
    
11860
 
    
11861
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
11862
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
11863
 
        
11864
 
    for (unsigned int j = 0; j < num_derivatives; j++)
11865
 
    {
11866
 
      combinations[j] = new unsigned int [n];
11867
 
      for (unsigned int k = 0; k < n; k++)
11868
 
        combinations[j][k] = 0;
11869
 
    }
11870
 
        
11871
 
    // Generate combinations of derivatives
11872
 
    for (unsigned int row = 1; row < num_derivatives; row++)
11873
 
    {
11874
 
      for (unsigned int num = 0; num < row; num++)
11875
 
      {
11876
 
        for (unsigned int col = n-1; col+1 > 0; col--)
11877
 
        {
11878
 
          if (combinations[row][col] + 1 > 1)
11879
 
            combinations[row][col] = 0;
11880
 
          else
11881
 
          {
11882
 
            combinations[row][col] += 1;
11883
 
            break;
11884
 
          }
11885
 
        }
11886
 
      }
11887
 
    }
11888
 
    
11889
 
    // Compute inverse of Jacobian
11890
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
11891
 
    
11892
 
    // Declare transformation matrix
11893
 
    // Declare pointer to two dimensional array and initialise
11894
 
    double **transform = new double *[num_derivatives];
11895
 
        
11896
 
    for (unsigned int j = 0; j < num_derivatives; j++)
11897
 
    {
11898
 
      transform[j] = new double [num_derivatives];
11899
 
      for (unsigned int k = 0; k < num_derivatives; k++)
11900
 
        transform[j][k] = 1;
11901
 
    }
11902
 
    
11903
 
    // Construct transformation matrix
11904
 
    for (unsigned int row = 0; row < num_derivatives; row++)
11905
 
    {
11906
 
      for (unsigned int col = 0; col < num_derivatives; col++)
11907
 
      {
11908
 
        for (unsigned int k = 0; k < n; k++)
11909
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
11910
 
      }
11911
 
    }
11912
 
    
11913
 
    // Reset values
11914
 
    for (unsigned int j = 0; j < 2*num_derivatives; j++)
11915
 
      values[j] = 0;
11916
 
    
11917
 
    if (0 <= i && i <= 2)
11918
 
    {
11919
 
      // Map degree of freedom to element degree of freedom
11920
 
      const unsigned int dof = i;
11921
 
    
11922
 
      // Generate scalings
11923
 
      const double scalings_y_0 = 1;
11924
 
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
11925
 
    
11926
 
      // Compute psitilde_a
11927
 
      const double psitilde_a_0 = 1;
11928
 
      const double psitilde_a_1 = x;
11929
 
    
11930
 
      // Compute psitilde_bs
11931
 
      const double psitilde_bs_0_0 = 1;
11932
 
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
11933
 
      const double psitilde_bs_1_0 = 1;
11934
 
    
11935
 
      // Compute basisvalues
11936
 
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
11937
 
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
11938
 
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
11939
 
    
11940
 
      // Table(s) of coefficients
11941
 
      const static double coefficients0[3][3] =   \
11942
 
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
11943
 
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
11944
 
      {0.471404520791032, 0, 0.333333333333333}};
11945
 
    
11946
 
      // Interesting (new) part
11947
 
      // Tables of derivatives of the polynomial base (transpose)
11948
 
      const static double dmats0[3][3] =   \
11949
 
      {{0, 0, 0},
11950
 
      {4.89897948556636, 0, 0},
11951
 
      {0, 0, 0}};
11952
 
    
11953
 
      const static double dmats1[3][3] =   \
11954
 
      {{0, 0, 0},
11955
 
      {2.44948974278318, 0, 0},
11956
 
      {4.24264068711928, 0, 0}};
11957
 
    
11958
 
      // Compute reference derivatives
11959
 
      // Declare pointer to array of derivatives on FIAT element
11960
 
      double *derivatives = new double [num_derivatives];
11961
 
    
11962
 
      // Declare coefficients
11963
 
      double coeff0_0 = 0;
11964
 
      double coeff0_1 = 0;
11965
 
      double coeff0_2 = 0;
11966
 
    
11967
 
      // Declare new coefficients
11968
 
      double new_coeff0_0 = 0;
11969
 
      double new_coeff0_1 = 0;
11970
 
      double new_coeff0_2 = 0;
11971
 
    
11972
 
      // Loop possible derivatives
11973
 
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
11974
 
      {
11975
 
        // Get values from coefficients array
11976
 
        new_coeff0_0 = coefficients0[dof][0];
11977
 
        new_coeff0_1 = coefficients0[dof][1];
11978
 
        new_coeff0_2 = coefficients0[dof][2];
11979
 
    
11980
 
        // Loop derivative order
11981
 
        for (unsigned int j = 0; j < n; j++)
11982
 
        {
11983
 
          // Update old coefficients
11984
 
          coeff0_0 = new_coeff0_0;
11985
 
          coeff0_1 = new_coeff0_1;
11986
 
          coeff0_2 = new_coeff0_2;
11987
 
    
11988
 
          if(combinations[deriv_num][j] == 0)
11989
 
          {
11990
 
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
11991
 
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
11992
 
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
11993
 
          }
11994
 
          if(combinations[deriv_num][j] == 1)
11995
 
          {
11996
 
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
11997
 
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
11998
 
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
11999
 
          }
12000
 
    
12001
 
        }
12002
 
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
12003
 
        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
12004
 
      }
12005
 
    
12006
 
      // Transform derivatives back to physical element
12007
 
      for (unsigned int row = 0; row < num_derivatives; row++)
12008
 
      {
12009
 
        for (unsigned int col = 0; col < num_derivatives; col++)
12010
 
        {
12011
 
          values[row] += transform[row][col]*derivatives[col];
12012
 
        }
12013
 
      }
12014
 
      // Delete pointer to array of derivatives on FIAT element
12015
 
      delete [] derivatives;
12016
 
    
12017
 
      // Delete pointer to array of combinations of derivatives and transform
12018
 
      for (unsigned int row = 0; row < num_derivatives; row++)
12019
 
      {
12020
 
        delete [] combinations[row];
12021
 
        delete [] transform[row];
12022
 
      }
12023
 
    
12024
 
      delete [] combinations;
12025
 
      delete [] transform;
12026
 
    }
12027
 
    
12028
 
    if (3 <= i && i <= 5)
12029
 
    {
12030
 
      // Map degree of freedom to element degree of freedom
12031
 
      const unsigned int dof = i - 3;
12032
 
    
12033
 
      // Generate scalings
12034
 
      const double scalings_y_0 = 1;
12035
 
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
12036
 
    
12037
 
      // Compute psitilde_a
12038
 
      const double psitilde_a_0 = 1;
12039
 
      const double psitilde_a_1 = x;
12040
 
    
12041
 
      // Compute psitilde_bs
12042
 
      const double psitilde_bs_0_0 = 1;
12043
 
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
12044
 
      const double psitilde_bs_1_0 = 1;
12045
 
    
12046
 
      // Compute basisvalues
12047
 
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
12048
 
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
12049
 
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
12050
 
    
12051
 
      // Table(s) of coefficients
12052
 
      const static double coefficients0[3][3] =   \
12053
 
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
12054
 
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
12055
 
      {0.471404520791032, 0, 0.333333333333333}};
12056
 
    
12057
 
      // Interesting (new) part
12058
 
      // Tables of derivatives of the polynomial base (transpose)
12059
 
      const static double dmats0[3][3] =   \
12060
 
      {{0, 0, 0},
12061
 
      {4.89897948556636, 0, 0},
12062
 
      {0, 0, 0}};
12063
 
    
12064
 
      const static double dmats1[3][3] =   \
12065
 
      {{0, 0, 0},
12066
 
      {2.44948974278318, 0, 0},
12067
 
      {4.24264068711928, 0, 0}};
12068
 
    
12069
 
      // Compute reference derivatives
12070
 
      // Declare pointer to array of derivatives on FIAT element
12071
 
      double *derivatives = new double [num_derivatives];
12072
 
    
12073
 
      // Declare coefficients
12074
 
      double coeff0_0 = 0;
12075
 
      double coeff0_1 = 0;
12076
 
      double coeff0_2 = 0;
12077
 
    
12078
 
      // Declare new coefficients
12079
 
      double new_coeff0_0 = 0;
12080
 
      double new_coeff0_1 = 0;
12081
 
      double new_coeff0_2 = 0;
12082
 
    
12083
 
      // Loop possible derivatives
12084
 
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
12085
 
      {
12086
 
        // Get values from coefficients array
12087
 
        new_coeff0_0 = coefficients0[dof][0];
12088
 
        new_coeff0_1 = coefficients0[dof][1];
12089
 
        new_coeff0_2 = coefficients0[dof][2];
12090
 
    
12091
 
        // Loop derivative order
12092
 
        for (unsigned int j = 0; j < n; j++)
12093
 
        {
12094
 
          // Update old coefficients
12095
 
          coeff0_0 = new_coeff0_0;
12096
 
          coeff0_1 = new_coeff0_1;
12097
 
          coeff0_2 = new_coeff0_2;
12098
 
    
12099
 
          if(combinations[deriv_num][j] == 0)
12100
 
          {
12101
 
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
12102
 
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
12103
 
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
12104
 
          }
12105
 
          if(combinations[deriv_num][j] == 1)
12106
 
          {
12107
 
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
12108
 
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
12109
 
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
12110
 
          }
12111
 
    
12112
 
        }
12113
 
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
12114
 
        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
12115
 
      }
12116
 
    
12117
 
      // Transform derivatives back to physical element
12118
 
      for (unsigned int row = 0; row < num_derivatives; row++)
12119
 
      {
12120
 
        for (unsigned int col = 0; col < num_derivatives; col++)
12121
 
        {
12122
 
          values[num_derivatives + row] += transform[row][col]*derivatives[col];
12123
 
        }
12124
 
      }
12125
 
      // Delete pointer to array of derivatives on FIAT element
12126
 
      delete [] derivatives;
12127
 
    
12128
 
      // Delete pointer to array of combinations of derivatives and transform
12129
 
      for (unsigned int row = 0; row < num_derivatives; row++)
12130
 
      {
12131
 
        delete [] combinations[row];
12132
 
        delete [] transform[row];
12133
 
      }
12134
 
    
12135
 
      delete [] combinations;
12136
 
      delete [] transform;
12137
 
    }
12138
 
    
12139
 
}
12140
 
 
12141
 
/// Evaluate order n derivatives of all basis functions at given point in cell
12142
 
void UFC_CahnHilliard2DLinearForm_finite_element_2::evaluate_basis_derivatives_all(unsigned int n,
12143
 
                                                   double* values,
12144
 
                                                   const double* coordinates,
12145
 
                                                   const ufc::cell& c) const
12146
 
{
12147
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
12148
 
}
12149
 
 
12150
 
/// Evaluate linear functional for dof i on the function f
12151
 
double UFC_CahnHilliard2DLinearForm_finite_element_2::evaluate_dof(unsigned int i,
12152
 
                                   const ufc::function& f,
12153
 
                                   const ufc::cell& c) const
12154
 
{
12155
 
    // The reference points, direction and weights:
12156
 
    const static double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
12157
 
    const static double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
12158
 
    const static double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
12159
 
    
12160
 
    const double * const * x = c.coordinates;
12161
 
    double result = 0.0;
12162
 
    // Iterate over the points:
12163
 
    // Evaluate basis functions for affine mapping
12164
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
12165
 
    const double w1 = X[i][0][0];
12166
 
    const double w2 = X[i][0][1];
12167
 
    
12168
 
    // Compute affine mapping y = F(X)
12169
 
    double y[2];
12170
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
12171
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
12172
 
    
12173
 
    // Evaluate function at physical points
12174
 
    double values[2];
12175
 
    f.evaluate(values, y, c);
12176
 
    
12177
 
    // Map function values using appropriate mapping
12178
 
    // Affine map: Do nothing
12179
 
    
12180
 
    // Note that we do not map the weights (yet).
12181
 
    
12182
 
    // Take directional components
12183
 
    for(int k = 0; k < 2; k++)
12184
 
      result += values[k]*D[i][0][k];
12185
 
    // Multiply by weights 
12186
 
    result *= W[i][0];
12187
 
    
12188
 
    return result;
12189
 
}
12190
 
 
12191
 
/// Evaluate linear functionals for all dofs on the function f
12192
 
void UFC_CahnHilliard2DLinearForm_finite_element_2::evaluate_dofs(double* values,
12193
 
                                  const ufc::function& f,
12194
 
                                  const ufc::cell& c) const
12195
 
{
12196
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
12197
 
}
12198
 
 
12199
 
/// Interpolate vertex values from dof values
12200
 
void UFC_CahnHilliard2DLinearForm_finite_element_2::interpolate_vertex_values(double* vertex_values,
12201
 
                                              const double* dof_values,
12202
 
                                              const ufc::cell& c) const
12203
 
{
12204
 
    // Evaluate at vertices and use affine mapping
12205
 
    vertex_values[0] = dof_values[0];
12206
 
    vertex_values[2] = dof_values[1];
12207
 
    vertex_values[4] = dof_values[2];
12208
 
    // Evaluate at vertices and use affine mapping
12209
 
    vertex_values[1] = dof_values[3];
12210
 
    vertex_values[3] = dof_values[4];
12211
 
    vertex_values[5] = dof_values[5];
12212
 
}
12213
 
 
12214
 
/// Return the number of sub elements (for a mixed element)
12215
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_2::num_sub_elements() const
12216
 
{
12217
 
    return 2;
12218
 
}
12219
 
 
12220
 
/// Create a new finite element for sub element i (for a mixed element)
12221
 
ufc::finite_element* UFC_CahnHilliard2DLinearForm_finite_element_2::create_sub_element(unsigned int i) const
12222
 
{
12223
 
    switch ( i )
12224
 
    {
12225
 
    case 0:
12226
 
      return new UFC_CahnHilliard2DLinearForm_finite_element_2_0();
12227
 
      break;
12228
 
    case 1:
12229
 
      return new UFC_CahnHilliard2DLinearForm_finite_element_2_1();
12230
 
      break;
12231
 
    }
12232
 
    return 0;
12233
 
}
12234
 
 
12235
 
 
12236
 
/// Constructor
12237
 
UFC_CahnHilliard2DLinearForm_finite_element_3::UFC_CahnHilliard2DLinearForm_finite_element_3() : ufc::finite_element()
12238
 
{
12239
 
    // Do nothing
12240
 
}
12241
 
 
12242
 
/// Destructor
12243
 
UFC_CahnHilliard2DLinearForm_finite_element_3::~UFC_CahnHilliard2DLinearForm_finite_element_3()
12244
 
{
12245
 
    // Do nothing
12246
 
}
12247
 
 
12248
 
/// Return a string identifying the finite element
12249
 
const char* UFC_CahnHilliard2DLinearForm_finite_element_3::signature() const
12250
 
{
12251
 
    return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
12252
 
}
12253
 
 
12254
 
/// Return the cell shape
12255
 
ufc::shape UFC_CahnHilliard2DLinearForm_finite_element_3::cell_shape() const
12256
 
{
12257
 
    return ufc::triangle;
12258
 
}
12259
 
 
12260
 
/// Return the dimension of the finite element function space
12261
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_3::space_dimension() const
12262
 
{
12263
 
    return 1;
12264
 
}
12265
 
 
12266
 
/// Return the rank of the value space
12267
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_3::value_rank() const
12268
 
{
12269
 
    return 0;
12270
 
}
12271
 
 
12272
 
/// Return the dimension of the value space for axis i
12273
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_3::value_dimension(unsigned int i) const
12274
 
{
12275
 
    return 1;
12276
 
}
12277
 
 
12278
 
/// Evaluate basis function i at given point in cell
12279
 
void UFC_CahnHilliard2DLinearForm_finite_element_3::evaluate_basis(unsigned int i,
12280
 
                                   double* values,
12281
 
                                   const double* coordinates,
12282
 
                                   const ufc::cell& c) const
12283
 
{
12284
 
    // Extract vertex coordinates
12285
 
    const double * const * element_coordinates = c.coordinates;
12286
 
    
12287
 
    // Compute Jacobian of affine map from reference cell
12288
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
12289
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
12290
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
12291
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
12292
 
      
12293
 
    // Compute determinant of Jacobian
12294
 
    const double detJ = J_00*J_11 - J_01*J_10;
12295
 
    
12296
 
    // Compute inverse of Jacobian
12297
 
    
12298
 
    // Get coordinates and map to the reference (UFC) element
12299
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
12300
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
12301
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
12302
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
12303
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
12304
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
12305
 
    
12306
 
    // Map coordinates to the reference square
12307
 
    if (std::abs(y - 1.0) < 1e-14)
12308
 
      x = -1.0;
12309
 
    else
12310
 
      x = 2.0 *x/(1.0 - y) - 1.0;
12311
 
    y = 2.0*y - 1.0;
12312
 
    
12313
 
    // Reset values
12314
 
    *values = 0;
12315
 
    
12316
 
    // Map degree of freedom to element degree of freedom
12317
 
    const unsigned int dof = i;
12318
 
    
12319
 
    // Generate scalings
12320
 
    const double scalings_y_0 = 1;
12321
 
    
12322
 
    // Compute psitilde_a
12323
 
    const double psitilde_a_0 = 1;
12324
 
    
12325
 
    // Compute psitilde_bs
12326
 
    const double psitilde_bs_0_0 = 1;
12327
 
    
12328
 
    // Compute basisvalues
12329
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
12330
 
    
12331
 
    // Table(s) of coefficients
12332
 
    const static double coefficients0[1][1] = \
12333
 
    {{1.41421356237309}};
12334
 
    
12335
 
    // Extract relevant coefficients
12336
 
    const double coeff0_0 = coefficients0[dof][0];
12337
 
    
12338
 
    // Compute value(s)
12339
 
    *values = coeff0_0*basisvalue0;
12340
 
}
12341
 
 
12342
 
/// Evaluate all basis functions at given point in cell
12343
 
void UFC_CahnHilliard2DLinearForm_finite_element_3::evaluate_basis_all(double* values,
12344
 
                                       const double* coordinates,
12345
 
                                       const ufc::cell& c) const
12346
 
{
12347
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
12348
 
}
12349
 
 
12350
 
/// Evaluate order n derivatives of basis function i at given point in cell
12351
 
void UFC_CahnHilliard2DLinearForm_finite_element_3::evaluate_basis_derivatives(unsigned int i,
12352
 
                                               unsigned int n,
12353
 
                                               double* values,
12354
 
                                               const double* coordinates,
12355
 
                                               const ufc::cell& c) const
12356
 
{
12357
 
    // Extract vertex coordinates
12358
 
    const double * const * element_coordinates = c.coordinates;
12359
 
    
12360
 
    // Compute Jacobian of affine map from reference cell
12361
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
12362
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
12363
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
12364
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
12365
 
      
12366
 
    // Compute determinant of Jacobian
12367
 
    const double detJ = J_00*J_11 - J_01*J_10;
12368
 
    
12369
 
    // Compute inverse of Jacobian
12370
 
    
12371
 
    // Get coordinates and map to the reference (UFC) element
12372
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
12373
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
12374
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
12375
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
12376
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
12377
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
12378
 
    
12379
 
    // Map coordinates to the reference square
12380
 
    if (std::abs(y - 1.0) < 1e-14)
12381
 
      x = -1.0;
12382
 
    else
12383
 
      x = 2.0 *x/(1.0 - y) - 1.0;
12384
 
    y = 2.0*y - 1.0;
12385
 
    
12386
 
    // Compute number of derivatives
12387
 
    unsigned int num_derivatives = 1;
12388
 
    
12389
 
    for (unsigned int j = 0; j < n; j++)
12390
 
      num_derivatives *= 2;
12391
 
    
12392
 
    
12393
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
12394
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
12395
 
        
12396
 
    for (unsigned int j = 0; j < num_derivatives; j++)
12397
 
    {
12398
 
      combinations[j] = new unsigned int [n];
12399
 
      for (unsigned int k = 0; k < n; k++)
12400
 
        combinations[j][k] = 0;
12401
 
    }
12402
 
        
12403
 
    // Generate combinations of derivatives
12404
 
    for (unsigned int row = 1; row < num_derivatives; row++)
12405
 
    {
12406
 
      for (unsigned int num = 0; num < row; num++)
12407
 
      {
12408
 
        for (unsigned int col = n-1; col+1 > 0; col--)
12409
 
        {
12410
 
          if (combinations[row][col] + 1 > 1)
12411
 
            combinations[row][col] = 0;
12412
 
          else
12413
 
          {
12414
 
            combinations[row][col] += 1;
12415
 
            break;
12416
 
          }
12417
 
        }
12418
 
      }
12419
 
    }
12420
 
    
12421
 
    // Compute inverse of Jacobian
12422
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
12423
 
    
12424
 
    // Declare transformation matrix
12425
 
    // Declare pointer to two dimensional array and initialise
12426
 
    double **transform = new double *[num_derivatives];
12427
 
        
12428
 
    for (unsigned int j = 0; j < num_derivatives; j++)
12429
 
    {
12430
 
      transform[j] = new double [num_derivatives];
12431
 
      for (unsigned int k = 0; k < num_derivatives; k++)
12432
 
        transform[j][k] = 1;
12433
 
    }
12434
 
    
12435
 
    // Construct transformation matrix
12436
 
    for (unsigned int row = 0; row < num_derivatives; row++)
12437
 
    {
12438
 
      for (unsigned int col = 0; col < num_derivatives; col++)
12439
 
      {
12440
 
        for (unsigned int k = 0; k < n; k++)
12441
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
12442
 
      }
12443
 
    }
12444
 
    
12445
 
    // Reset values
12446
 
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
12447
 
      values[j] = 0;
12448
 
    
12449
 
    // Map degree of freedom to element degree of freedom
12450
 
    const unsigned int dof = i;
12451
 
    
12452
 
    // Generate scalings
12453
 
    const double scalings_y_0 = 1;
12454
 
    
12455
 
    // Compute psitilde_a
12456
 
    const double psitilde_a_0 = 1;
12457
 
    
12458
 
    // Compute psitilde_bs
12459
 
    const double psitilde_bs_0_0 = 1;
12460
 
    
12461
 
    // Compute basisvalues
12462
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
12463
 
    
12464
 
    // Table(s) of coefficients
12465
 
    const static double coefficients0[1][1] = \
12466
 
    {{1.41421356237309}};
12467
 
    
12468
 
    // Interesting (new) part
12469
 
    // Tables of derivatives of the polynomial base (transpose)
12470
 
    const static double dmats0[1][1] = \
12471
 
    {{0}};
12472
 
    
12473
 
    const static double dmats1[1][1] = \
12474
 
    {{0}};
12475
 
    
12476
 
    // Compute reference derivatives
12477
 
    // Declare pointer to array of derivatives on FIAT element
12478
 
    double *derivatives = new double [num_derivatives];
12479
 
    
12480
 
    // Declare coefficients
12481
 
    double coeff0_0 = 0;
12482
 
    
12483
 
    // Declare new coefficients
12484
 
    double new_coeff0_0 = 0;
12485
 
    
12486
 
    // Loop possible derivatives
12487
 
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
12488
 
    {
12489
 
      // Get values from coefficients array
12490
 
      new_coeff0_0 = coefficients0[dof][0];
12491
 
    
12492
 
      // Loop derivative order
12493
 
      for (unsigned int j = 0; j < n; j++)
12494
 
      {
12495
 
        // Update old coefficients
12496
 
        coeff0_0 = new_coeff0_0;
12497
 
    
12498
 
        if(combinations[deriv_num][j] == 0)
12499
 
        {
12500
 
          new_coeff0_0 = coeff0_0*dmats0[0][0];
12501
 
        }
12502
 
        if(combinations[deriv_num][j] == 1)
12503
 
        {
12504
 
          new_coeff0_0 = coeff0_0*dmats1[0][0];
12505
 
        }
12506
 
    
12507
 
      }
12508
 
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
12509
 
      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
12510
 
    }
12511
 
    
12512
 
    // Transform derivatives back to physical element
12513
 
    for (unsigned int row = 0; row < num_derivatives; row++)
12514
 
    {
12515
 
      for (unsigned int col = 0; col < num_derivatives; col++)
12516
 
      {
12517
 
        values[row] += transform[row][col]*derivatives[col];
12518
 
      }
12519
 
    }
12520
 
    // Delete pointer to array of derivatives on FIAT element
12521
 
    delete [] derivatives;
12522
 
    
12523
 
    // Delete pointer to array of combinations of derivatives and transform
12524
 
    for (unsigned int row = 0; row < num_derivatives; row++)
12525
 
    {
12526
 
      delete [] combinations[row];
12527
 
      delete [] transform[row];
12528
 
    }
12529
 
    
12530
 
    delete [] combinations;
12531
 
    delete [] transform;
12532
 
}
12533
 
 
12534
 
/// Evaluate order n derivatives of all basis functions at given point in cell
12535
 
void UFC_CahnHilliard2DLinearForm_finite_element_3::evaluate_basis_derivatives_all(unsigned int n,
12536
 
                                                   double* values,
12537
 
                                                   const double* coordinates,
12538
 
                                                   const ufc::cell& c) const
12539
 
{
12540
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
12541
 
}
12542
 
 
12543
 
/// Evaluate linear functional for dof i on the function f
12544
 
double UFC_CahnHilliard2DLinearForm_finite_element_3::evaluate_dof(unsigned int i,
12545
 
                                   const ufc::function& f,
12546
 
                                   const ufc::cell& c) const
12547
 
{
12548
 
    // The reference points, direction and weights:
12549
 
    const static double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
12550
 
    const static double W[1][1] = {{1}};
12551
 
    const static double D[1][1][1] = {{{1}}};
12552
 
    
12553
 
    const double * const * x = c.coordinates;
12554
 
    double result = 0.0;
12555
 
    // Iterate over the points:
12556
 
    // Evaluate basis functions for affine mapping
12557
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
12558
 
    const double w1 = X[i][0][0];
12559
 
    const double w2 = X[i][0][1];
12560
 
    
12561
 
    // Compute affine mapping y = F(X)
12562
 
    double y[2];
12563
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
12564
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
12565
 
    
12566
 
    // Evaluate function at physical points
12567
 
    double values[1];
12568
 
    f.evaluate(values, y, c);
12569
 
    
12570
 
    // Map function values using appropriate mapping
12571
 
    // Affine map: Do nothing
12572
 
    
12573
 
    // Note that we do not map the weights (yet).
12574
 
    
12575
 
    // Take directional components
12576
 
    for(int k = 0; k < 1; k++)
12577
 
      result += values[k]*D[i][0][k];
12578
 
    // Multiply by weights 
12579
 
    result *= W[i][0];
12580
 
    
12581
 
    return result;
12582
 
}
12583
 
 
12584
 
/// Evaluate linear functionals for all dofs on the function f
12585
 
void UFC_CahnHilliard2DLinearForm_finite_element_3::evaluate_dofs(double* values,
12586
 
                                  const ufc::function& f,
12587
 
                                  const ufc::cell& c) const
12588
 
{
12589
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
12590
 
}
12591
 
 
12592
 
/// Interpolate vertex values from dof values
12593
 
void UFC_CahnHilliard2DLinearForm_finite_element_3::interpolate_vertex_values(double* vertex_values,
12594
 
                                              const double* dof_values,
12595
 
                                              const ufc::cell& c) const
12596
 
{
12597
 
    // Evaluate at vertices and use affine mapping
12598
 
    vertex_values[0] = dof_values[0];
12599
 
    vertex_values[1] = dof_values[0];
12600
 
    vertex_values[2] = dof_values[0];
12601
 
}
12602
 
 
12603
 
/// Return the number of sub elements (for a mixed element)
12604
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_3::num_sub_elements() const
12605
 
{
12606
 
    return 1;
12607
 
}
12608
 
 
12609
 
/// Create a new finite element for sub element i (for a mixed element)
12610
 
ufc::finite_element* UFC_CahnHilliard2DLinearForm_finite_element_3::create_sub_element(unsigned int i) const
12611
 
{
12612
 
    return new UFC_CahnHilliard2DLinearForm_finite_element_3();
12613
 
}
12614
 
 
12615
 
 
12616
 
/// Constructor
12617
 
UFC_CahnHilliard2DLinearForm_finite_element_4::UFC_CahnHilliard2DLinearForm_finite_element_4() : ufc::finite_element()
12618
 
{
12619
 
    // Do nothing
12620
 
}
12621
 
 
12622
 
/// Destructor
12623
 
UFC_CahnHilliard2DLinearForm_finite_element_4::~UFC_CahnHilliard2DLinearForm_finite_element_4()
12624
 
{
12625
 
    // Do nothing
12626
 
}
12627
 
 
12628
 
/// Return a string identifying the finite element
12629
 
const char* UFC_CahnHilliard2DLinearForm_finite_element_4::signature() const
12630
 
{
12631
 
    return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
12632
 
}
12633
 
 
12634
 
/// Return the cell shape
12635
 
ufc::shape UFC_CahnHilliard2DLinearForm_finite_element_4::cell_shape() const
12636
 
{
12637
 
    return ufc::triangle;
12638
 
}
12639
 
 
12640
 
/// Return the dimension of the finite element function space
12641
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_4::space_dimension() const
12642
 
{
12643
 
    return 1;
12644
 
}
12645
 
 
12646
 
/// Return the rank of the value space
12647
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_4::value_rank() const
12648
 
{
12649
 
    return 0;
12650
 
}
12651
 
 
12652
 
/// Return the dimension of the value space for axis i
12653
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_4::value_dimension(unsigned int i) const
12654
 
{
12655
 
    return 1;
12656
 
}
12657
 
 
12658
 
/// Evaluate basis function i at given point in cell
12659
 
void UFC_CahnHilliard2DLinearForm_finite_element_4::evaluate_basis(unsigned int i,
12660
 
                                   double* values,
12661
 
                                   const double* coordinates,
12662
 
                                   const ufc::cell& c) const
12663
 
{
12664
 
    // Extract vertex coordinates
12665
 
    const double * const * element_coordinates = c.coordinates;
12666
 
    
12667
 
    // Compute Jacobian of affine map from reference cell
12668
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
12669
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
12670
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
12671
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
12672
 
      
12673
 
    // Compute determinant of Jacobian
12674
 
    const double detJ = J_00*J_11 - J_01*J_10;
12675
 
    
12676
 
    // Compute inverse of Jacobian
12677
 
    
12678
 
    // Get coordinates and map to the reference (UFC) element
12679
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
12680
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
12681
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
12682
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
12683
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
12684
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
12685
 
    
12686
 
    // Map coordinates to the reference square
12687
 
    if (std::abs(y - 1.0) < 1e-14)
12688
 
      x = -1.0;
12689
 
    else
12690
 
      x = 2.0 *x/(1.0 - y) - 1.0;
12691
 
    y = 2.0*y - 1.0;
12692
 
    
12693
 
    // Reset values
12694
 
    *values = 0;
12695
 
    
12696
 
    // Map degree of freedom to element degree of freedom
12697
 
    const unsigned int dof = i;
12698
 
    
12699
 
    // Generate scalings
12700
 
    const double scalings_y_0 = 1;
12701
 
    
12702
 
    // Compute psitilde_a
12703
 
    const double psitilde_a_0 = 1;
12704
 
    
12705
 
    // Compute psitilde_bs
12706
 
    const double psitilde_bs_0_0 = 1;
12707
 
    
12708
 
    // Compute basisvalues
12709
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
12710
 
    
12711
 
    // Table(s) of coefficients
12712
 
    const static double coefficients0[1][1] = \
12713
 
    {{1.41421356237309}};
12714
 
    
12715
 
    // Extract relevant coefficients
12716
 
    const double coeff0_0 = coefficients0[dof][0];
12717
 
    
12718
 
    // Compute value(s)
12719
 
    *values = coeff0_0*basisvalue0;
12720
 
}
12721
 
 
12722
 
/// Evaluate all basis functions at given point in cell
12723
 
void UFC_CahnHilliard2DLinearForm_finite_element_4::evaluate_basis_all(double* values,
12724
 
                                       const double* coordinates,
12725
 
                                       const ufc::cell& c) const
12726
 
{
12727
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
12728
 
}
12729
 
 
12730
 
/// Evaluate order n derivatives of basis function i at given point in cell
12731
 
void UFC_CahnHilliard2DLinearForm_finite_element_4::evaluate_basis_derivatives(unsigned int i,
12732
 
                                               unsigned int n,
12733
 
                                               double* values,
12734
 
                                               const double* coordinates,
12735
 
                                               const ufc::cell& c) const
12736
 
{
12737
 
    // Extract vertex coordinates
12738
 
    const double * const * element_coordinates = c.coordinates;
12739
 
    
12740
 
    // Compute Jacobian of affine map from reference cell
12741
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
12742
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
12743
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
12744
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
12745
 
      
12746
 
    // Compute determinant of Jacobian
12747
 
    const double detJ = J_00*J_11 - J_01*J_10;
12748
 
    
12749
 
    // Compute inverse of Jacobian
12750
 
    
12751
 
    // Get coordinates and map to the reference (UFC) element
12752
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
12753
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
12754
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
12755
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
12756
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
12757
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
12758
 
    
12759
 
    // Map coordinates to the reference square
12760
 
    if (std::abs(y - 1.0) < 1e-14)
12761
 
      x = -1.0;
12762
 
    else
12763
 
      x = 2.0 *x/(1.0 - y) - 1.0;
12764
 
    y = 2.0*y - 1.0;
12765
 
    
12766
 
    // Compute number of derivatives
12767
 
    unsigned int num_derivatives = 1;
12768
 
    
12769
 
    for (unsigned int j = 0; j < n; j++)
12770
 
      num_derivatives *= 2;
12771
 
    
12772
 
    
12773
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
12774
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
12775
 
        
12776
 
    for (unsigned int j = 0; j < num_derivatives; j++)
12777
 
    {
12778
 
      combinations[j] = new unsigned int [n];
12779
 
      for (unsigned int k = 0; k < n; k++)
12780
 
        combinations[j][k] = 0;
12781
 
    }
12782
 
        
12783
 
    // Generate combinations of derivatives
12784
 
    for (unsigned int row = 1; row < num_derivatives; row++)
12785
 
    {
12786
 
      for (unsigned int num = 0; num < row; num++)
12787
 
      {
12788
 
        for (unsigned int col = n-1; col+1 > 0; col--)
12789
 
        {
12790
 
          if (combinations[row][col] + 1 > 1)
12791
 
            combinations[row][col] = 0;
12792
 
          else
12793
 
          {
12794
 
            combinations[row][col] += 1;
12795
 
            break;
12796
 
          }
12797
 
        }
12798
 
      }
12799
 
    }
12800
 
    
12801
 
    // Compute inverse of Jacobian
12802
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
12803
 
    
12804
 
    // Declare transformation matrix
12805
 
    // Declare pointer to two dimensional array and initialise
12806
 
    double **transform = new double *[num_derivatives];
12807
 
        
12808
 
    for (unsigned int j = 0; j < num_derivatives; j++)
12809
 
    {
12810
 
      transform[j] = new double [num_derivatives];
12811
 
      for (unsigned int k = 0; k < num_derivatives; k++)
12812
 
        transform[j][k] = 1;
12813
 
    }
12814
 
    
12815
 
    // Construct transformation matrix
12816
 
    for (unsigned int row = 0; row < num_derivatives; row++)
12817
 
    {
12818
 
      for (unsigned int col = 0; col < num_derivatives; col++)
12819
 
      {
12820
 
        for (unsigned int k = 0; k < n; k++)
12821
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
12822
 
      }
12823
 
    }
12824
 
    
12825
 
    // Reset values
12826
 
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
12827
 
      values[j] = 0;
12828
 
    
12829
 
    // Map degree of freedom to element degree of freedom
12830
 
    const unsigned int dof = i;
12831
 
    
12832
 
    // Generate scalings
12833
 
    const double scalings_y_0 = 1;
12834
 
    
12835
 
    // Compute psitilde_a
12836
 
    const double psitilde_a_0 = 1;
12837
 
    
12838
 
    // Compute psitilde_bs
12839
 
    const double psitilde_bs_0_0 = 1;
12840
 
    
12841
 
    // Compute basisvalues
12842
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
12843
 
    
12844
 
    // Table(s) of coefficients
12845
 
    const static double coefficients0[1][1] = \
12846
 
    {{1.41421356237309}};
12847
 
    
12848
 
    // Interesting (new) part
12849
 
    // Tables of derivatives of the polynomial base (transpose)
12850
 
    const static double dmats0[1][1] = \
12851
 
    {{0}};
12852
 
    
12853
 
    const static double dmats1[1][1] = \
12854
 
    {{0}};
12855
 
    
12856
 
    // Compute reference derivatives
12857
 
    // Declare pointer to array of derivatives on FIAT element
12858
 
    double *derivatives = new double [num_derivatives];
12859
 
    
12860
 
    // Declare coefficients
12861
 
    double coeff0_0 = 0;
12862
 
    
12863
 
    // Declare new coefficients
12864
 
    double new_coeff0_0 = 0;
12865
 
    
12866
 
    // Loop possible derivatives
12867
 
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
12868
 
    {
12869
 
      // Get values from coefficients array
12870
 
      new_coeff0_0 = coefficients0[dof][0];
12871
 
    
12872
 
      // Loop derivative order
12873
 
      for (unsigned int j = 0; j < n; j++)
12874
 
      {
12875
 
        // Update old coefficients
12876
 
        coeff0_0 = new_coeff0_0;
12877
 
    
12878
 
        if(combinations[deriv_num][j] == 0)
12879
 
        {
12880
 
          new_coeff0_0 = coeff0_0*dmats0[0][0];
12881
 
        }
12882
 
        if(combinations[deriv_num][j] == 1)
12883
 
        {
12884
 
          new_coeff0_0 = coeff0_0*dmats1[0][0];
12885
 
        }
12886
 
    
12887
 
      }
12888
 
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
12889
 
      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
12890
 
    }
12891
 
    
12892
 
    // Transform derivatives back to physical element
12893
 
    for (unsigned int row = 0; row < num_derivatives; row++)
12894
 
    {
12895
 
      for (unsigned int col = 0; col < num_derivatives; col++)
12896
 
      {
12897
 
        values[row] += transform[row][col]*derivatives[col];
12898
 
      }
12899
 
    }
12900
 
    // Delete pointer to array of derivatives on FIAT element
12901
 
    delete [] derivatives;
12902
 
    
12903
 
    // Delete pointer to array of combinations of derivatives and transform
12904
 
    for (unsigned int row = 0; row < num_derivatives; row++)
12905
 
    {
12906
 
      delete [] combinations[row];
12907
 
      delete [] transform[row];
12908
 
    }
12909
 
    
12910
 
    delete [] combinations;
12911
 
    delete [] transform;
12912
 
}
12913
 
 
12914
 
/// Evaluate order n derivatives of all basis functions at given point in cell
12915
 
void UFC_CahnHilliard2DLinearForm_finite_element_4::evaluate_basis_derivatives_all(unsigned int n,
12916
 
                                                   double* values,
12917
 
                                                   const double* coordinates,
12918
 
                                                   const ufc::cell& c) const
12919
 
{
12920
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
12921
 
}
12922
 
 
12923
 
/// Evaluate linear functional for dof i on the function f
12924
 
double UFC_CahnHilliard2DLinearForm_finite_element_4::evaluate_dof(unsigned int i,
12925
 
                                   const ufc::function& f,
12926
 
                                   const ufc::cell& c) const
12927
 
{
12928
 
    // The reference points, direction and weights:
12929
 
    const static double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
12930
 
    const static double W[1][1] = {{1}};
12931
 
    const static double D[1][1][1] = {{{1}}};
12932
 
    
12933
 
    const double * const * x = c.coordinates;
12934
 
    double result = 0.0;
12935
 
    // Iterate over the points:
12936
 
    // Evaluate basis functions for affine mapping
12937
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
12938
 
    const double w1 = X[i][0][0];
12939
 
    const double w2 = X[i][0][1];
12940
 
    
12941
 
    // Compute affine mapping y = F(X)
12942
 
    double y[2];
12943
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
12944
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
12945
 
    
12946
 
    // Evaluate function at physical points
12947
 
    double values[1];
12948
 
    f.evaluate(values, y, c);
12949
 
    
12950
 
    // Map function values using appropriate mapping
12951
 
    // Affine map: Do nothing
12952
 
    
12953
 
    // Note that we do not map the weights (yet).
12954
 
    
12955
 
    // Take directional components
12956
 
    for(int k = 0; k < 1; k++)
12957
 
      result += values[k]*D[i][0][k];
12958
 
    // Multiply by weights 
12959
 
    result *= W[i][0];
12960
 
    
12961
 
    return result;
12962
 
}
12963
 
 
12964
 
/// Evaluate linear functionals for all dofs on the function f
12965
 
void UFC_CahnHilliard2DLinearForm_finite_element_4::evaluate_dofs(double* values,
12966
 
                                  const ufc::function& f,
12967
 
                                  const ufc::cell& c) const
12968
 
{
12969
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
12970
 
}
12971
 
 
12972
 
/// Interpolate vertex values from dof values
12973
 
void UFC_CahnHilliard2DLinearForm_finite_element_4::interpolate_vertex_values(double* vertex_values,
12974
 
                                              const double* dof_values,
12975
 
                                              const ufc::cell& c) const
12976
 
{
12977
 
    // Evaluate at vertices and use affine mapping
12978
 
    vertex_values[0] = dof_values[0];
12979
 
    vertex_values[1] = dof_values[0];
12980
 
    vertex_values[2] = dof_values[0];
12981
 
}
12982
 
 
12983
 
/// Return the number of sub elements (for a mixed element)
12984
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_4::num_sub_elements() const
12985
 
{
12986
 
    return 1;
12987
 
}
12988
 
 
12989
 
/// Create a new finite element for sub element i (for a mixed element)
12990
 
ufc::finite_element* UFC_CahnHilliard2DLinearForm_finite_element_4::create_sub_element(unsigned int i) const
12991
 
{
12992
 
    return new UFC_CahnHilliard2DLinearForm_finite_element_4();
12993
 
}
12994
 
 
12995
 
 
12996
 
/// Constructor
12997
 
UFC_CahnHilliard2DLinearForm_finite_element_5::UFC_CahnHilliard2DLinearForm_finite_element_5() : ufc::finite_element()
12998
 
{
12999
 
    // Do nothing
13000
 
}
13001
 
 
13002
 
/// Destructor
13003
 
UFC_CahnHilliard2DLinearForm_finite_element_5::~UFC_CahnHilliard2DLinearForm_finite_element_5()
13004
 
{
13005
 
    // Do nothing
13006
 
}
13007
 
 
13008
 
/// Return a string identifying the finite element
13009
 
const char* UFC_CahnHilliard2DLinearForm_finite_element_5::signature() const
13010
 
{
13011
 
    return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
13012
 
}
13013
 
 
13014
 
/// Return the cell shape
13015
 
ufc::shape UFC_CahnHilliard2DLinearForm_finite_element_5::cell_shape() const
13016
 
{
13017
 
    return ufc::triangle;
13018
 
}
13019
 
 
13020
 
/// Return the dimension of the finite element function space
13021
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_5::space_dimension() const
13022
 
{
13023
 
    return 1;
13024
 
}
13025
 
 
13026
 
/// Return the rank of the value space
13027
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_5::value_rank() const
13028
 
{
13029
 
    return 0;
13030
 
}
13031
 
 
13032
 
/// Return the dimension of the value space for axis i
13033
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_5::value_dimension(unsigned int i) const
13034
 
{
13035
 
    return 1;
13036
 
}
13037
 
 
13038
 
/// Evaluate basis function i at given point in cell
13039
 
void UFC_CahnHilliard2DLinearForm_finite_element_5::evaluate_basis(unsigned int i,
13040
 
                                   double* values,
13041
 
                                   const double* coordinates,
13042
 
                                   const ufc::cell& c) const
13043
 
{
13044
 
    // Extract vertex coordinates
13045
 
    const double * const * element_coordinates = c.coordinates;
13046
 
    
13047
 
    // Compute Jacobian of affine map from reference cell
13048
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
13049
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
13050
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
13051
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
13052
 
      
13053
 
    // Compute determinant of Jacobian
13054
 
    const double detJ = J_00*J_11 - J_01*J_10;
13055
 
    
13056
 
    // Compute inverse of Jacobian
13057
 
    
13058
 
    // Get coordinates and map to the reference (UFC) element
13059
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
13060
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
13061
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
13062
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
13063
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
13064
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
13065
 
    
13066
 
    // Map coordinates to the reference square
13067
 
    if (std::abs(y - 1.0) < 1e-14)
13068
 
      x = -1.0;
13069
 
    else
13070
 
      x = 2.0 *x/(1.0 - y) - 1.0;
13071
 
    y = 2.0*y - 1.0;
13072
 
    
13073
 
    // Reset values
13074
 
    *values = 0;
13075
 
    
13076
 
    // Map degree of freedom to element degree of freedom
13077
 
    const unsigned int dof = i;
13078
 
    
13079
 
    // Generate scalings
13080
 
    const double scalings_y_0 = 1;
13081
 
    
13082
 
    // Compute psitilde_a
13083
 
    const double psitilde_a_0 = 1;
13084
 
    
13085
 
    // Compute psitilde_bs
13086
 
    const double psitilde_bs_0_0 = 1;
13087
 
    
13088
 
    // Compute basisvalues
13089
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
13090
 
    
13091
 
    // Table(s) of coefficients
13092
 
    const static double coefficients0[1][1] = \
13093
 
    {{1.41421356237309}};
13094
 
    
13095
 
    // Extract relevant coefficients
13096
 
    const double coeff0_0 = coefficients0[dof][0];
13097
 
    
13098
 
    // Compute value(s)
13099
 
    *values = coeff0_0*basisvalue0;
13100
 
}
13101
 
 
13102
 
/// Evaluate all basis functions at given point in cell
13103
 
void UFC_CahnHilliard2DLinearForm_finite_element_5::evaluate_basis_all(double* values,
13104
 
                                       const double* coordinates,
13105
 
                                       const ufc::cell& c) const
13106
 
{
13107
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
13108
 
}
13109
 
 
13110
 
/// Evaluate order n derivatives of basis function i at given point in cell
13111
 
void UFC_CahnHilliard2DLinearForm_finite_element_5::evaluate_basis_derivatives(unsigned int i,
13112
 
                                               unsigned int n,
13113
 
                                               double* values,
13114
 
                                               const double* coordinates,
13115
 
                                               const ufc::cell& c) const
13116
 
{
13117
 
    // Extract vertex coordinates
13118
 
    const double * const * element_coordinates = c.coordinates;
13119
 
    
13120
 
    // Compute Jacobian of affine map from reference cell
13121
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
13122
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
13123
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
13124
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
13125
 
      
13126
 
    // Compute determinant of Jacobian
13127
 
    const double detJ = J_00*J_11 - J_01*J_10;
13128
 
    
13129
 
    // Compute inverse of Jacobian
13130
 
    
13131
 
    // Get coordinates and map to the reference (UFC) element
13132
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
13133
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
13134
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
13135
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
13136
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
13137
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
13138
 
    
13139
 
    // Map coordinates to the reference square
13140
 
    if (std::abs(y - 1.0) < 1e-14)
13141
 
      x = -1.0;
13142
 
    else
13143
 
      x = 2.0 *x/(1.0 - y) - 1.0;
13144
 
    y = 2.0*y - 1.0;
13145
 
    
13146
 
    // Compute number of derivatives
13147
 
    unsigned int num_derivatives = 1;
13148
 
    
13149
 
    for (unsigned int j = 0; j < n; j++)
13150
 
      num_derivatives *= 2;
13151
 
    
13152
 
    
13153
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
13154
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
13155
 
        
13156
 
    for (unsigned int j = 0; j < num_derivatives; j++)
13157
 
    {
13158
 
      combinations[j] = new unsigned int [n];
13159
 
      for (unsigned int k = 0; k < n; k++)
13160
 
        combinations[j][k] = 0;
13161
 
    }
13162
 
        
13163
 
    // Generate combinations of derivatives
13164
 
    for (unsigned int row = 1; row < num_derivatives; row++)
13165
 
    {
13166
 
      for (unsigned int num = 0; num < row; num++)
13167
 
      {
13168
 
        for (unsigned int col = n-1; col+1 > 0; col--)
13169
 
        {
13170
 
          if (combinations[row][col] + 1 > 1)
13171
 
            combinations[row][col] = 0;
13172
 
          else
13173
 
          {
13174
 
            combinations[row][col] += 1;
13175
 
            break;
13176
 
          }
13177
 
        }
13178
 
      }
13179
 
    }
13180
 
    
13181
 
    // Compute inverse of Jacobian
13182
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
13183
 
    
13184
 
    // Declare transformation matrix
13185
 
    // Declare pointer to two dimensional array and initialise
13186
 
    double **transform = new double *[num_derivatives];
13187
 
        
13188
 
    for (unsigned int j = 0; j < num_derivatives; j++)
13189
 
    {
13190
 
      transform[j] = new double [num_derivatives];
13191
 
      for (unsigned int k = 0; k < num_derivatives; k++)
13192
 
        transform[j][k] = 1;
13193
 
    }
13194
 
    
13195
 
    // Construct transformation matrix
13196
 
    for (unsigned int row = 0; row < num_derivatives; row++)
13197
 
    {
13198
 
      for (unsigned int col = 0; col < num_derivatives; col++)
13199
 
      {
13200
 
        for (unsigned int k = 0; k < n; k++)
13201
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
13202
 
      }
13203
 
    }
13204
 
    
13205
 
    // Reset values
13206
 
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
13207
 
      values[j] = 0;
13208
 
    
13209
 
    // Map degree of freedom to element degree of freedom
13210
 
    const unsigned int dof = i;
13211
 
    
13212
 
    // Generate scalings
13213
 
    const double scalings_y_0 = 1;
13214
 
    
13215
 
    // Compute psitilde_a
13216
 
    const double psitilde_a_0 = 1;
13217
 
    
13218
 
    // Compute psitilde_bs
13219
 
    const double psitilde_bs_0_0 = 1;
13220
 
    
13221
 
    // Compute basisvalues
13222
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
13223
 
    
13224
 
    // Table(s) of coefficients
13225
 
    const static double coefficients0[1][1] = \
13226
 
    {{1.41421356237309}};
13227
 
    
13228
 
    // Interesting (new) part
13229
 
    // Tables of derivatives of the polynomial base (transpose)
13230
 
    const static double dmats0[1][1] = \
13231
 
    {{0}};
13232
 
    
13233
 
    const static double dmats1[1][1] = \
13234
 
    {{0}};
13235
 
    
13236
 
    // Compute reference derivatives
13237
 
    // Declare pointer to array of derivatives on FIAT element
13238
 
    double *derivatives = new double [num_derivatives];
13239
 
    
13240
 
    // Declare coefficients
13241
 
    double coeff0_0 = 0;
13242
 
    
13243
 
    // Declare new coefficients
13244
 
    double new_coeff0_0 = 0;
13245
 
    
13246
 
    // Loop possible derivatives
13247
 
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
13248
 
    {
13249
 
      // Get values from coefficients array
13250
 
      new_coeff0_0 = coefficients0[dof][0];
13251
 
    
13252
 
      // Loop derivative order
13253
 
      for (unsigned int j = 0; j < n; j++)
13254
 
      {
13255
 
        // Update old coefficients
13256
 
        coeff0_0 = new_coeff0_0;
13257
 
    
13258
 
        if(combinations[deriv_num][j] == 0)
13259
 
        {
13260
 
          new_coeff0_0 = coeff0_0*dmats0[0][0];
13261
 
        }
13262
 
        if(combinations[deriv_num][j] == 1)
13263
 
        {
13264
 
          new_coeff0_0 = coeff0_0*dmats1[0][0];
13265
 
        }
13266
 
    
13267
 
      }
13268
 
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
13269
 
      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
13270
 
    }
13271
 
    
13272
 
    // Transform derivatives back to physical element
13273
 
    for (unsigned int row = 0; row < num_derivatives; row++)
13274
 
    {
13275
 
      for (unsigned int col = 0; col < num_derivatives; col++)
13276
 
      {
13277
 
        values[row] += transform[row][col]*derivatives[col];
13278
 
      }
13279
 
    }
13280
 
    // Delete pointer to array of derivatives on FIAT element
13281
 
    delete [] derivatives;
13282
 
    
13283
 
    // Delete pointer to array of combinations of derivatives and transform
13284
 
    for (unsigned int row = 0; row < num_derivatives; row++)
13285
 
    {
13286
 
      delete [] combinations[row];
13287
 
      delete [] transform[row];
13288
 
    }
13289
 
    
13290
 
    delete [] combinations;
13291
 
    delete [] transform;
13292
 
}
13293
 
 
13294
 
/// Evaluate order n derivatives of all basis functions at given point in cell
13295
 
void UFC_CahnHilliard2DLinearForm_finite_element_5::evaluate_basis_derivatives_all(unsigned int n,
13296
 
                                                   double* values,
13297
 
                                                   const double* coordinates,
13298
 
                                                   const ufc::cell& c) const
13299
 
{
13300
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
13301
 
}
13302
 
 
13303
 
/// Evaluate linear functional for dof i on the function f
13304
 
double UFC_CahnHilliard2DLinearForm_finite_element_5::evaluate_dof(unsigned int i,
13305
 
                                   const ufc::function& f,
13306
 
                                   const ufc::cell& c) const
13307
 
{
13308
 
    // The reference points, direction and weights:
13309
 
    const static double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
13310
 
    const static double W[1][1] = {{1}};
13311
 
    const static double D[1][1][1] = {{{1}}};
13312
 
    
13313
 
    const double * const * x = c.coordinates;
13314
 
    double result = 0.0;
13315
 
    // Iterate over the points:
13316
 
    // Evaluate basis functions for affine mapping
13317
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
13318
 
    const double w1 = X[i][0][0];
13319
 
    const double w2 = X[i][0][1];
13320
 
    
13321
 
    // Compute affine mapping y = F(X)
13322
 
    double y[2];
13323
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
13324
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
13325
 
    
13326
 
    // Evaluate function at physical points
13327
 
    double values[1];
13328
 
    f.evaluate(values, y, c);
13329
 
    
13330
 
    // Map function values using appropriate mapping
13331
 
    // Affine map: Do nothing
13332
 
    
13333
 
    // Note that we do not map the weights (yet).
13334
 
    
13335
 
    // Take directional components
13336
 
    for(int k = 0; k < 1; k++)
13337
 
      result += values[k]*D[i][0][k];
13338
 
    // Multiply by weights 
13339
 
    result *= W[i][0];
13340
 
    
13341
 
    return result;
13342
 
}
13343
 
 
13344
 
/// Evaluate linear functionals for all dofs on the function f
13345
 
void UFC_CahnHilliard2DLinearForm_finite_element_5::evaluate_dofs(double* values,
13346
 
                                  const ufc::function& f,
13347
 
                                  const ufc::cell& c) const
13348
 
{
13349
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
13350
 
}
13351
 
 
13352
 
/// Interpolate vertex values from dof values
13353
 
void UFC_CahnHilliard2DLinearForm_finite_element_5::interpolate_vertex_values(double* vertex_values,
13354
 
                                              const double* dof_values,
13355
 
                                              const ufc::cell& c) const
13356
 
{
13357
 
    // Evaluate at vertices and use affine mapping
13358
 
    vertex_values[0] = dof_values[0];
13359
 
    vertex_values[1] = dof_values[0];
13360
 
    vertex_values[2] = dof_values[0];
13361
 
}
13362
 
 
13363
 
/// Return the number of sub elements (for a mixed element)
13364
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_5::num_sub_elements() const
13365
 
{
13366
 
    return 1;
13367
 
}
13368
 
 
13369
 
/// Create a new finite element for sub element i (for a mixed element)
13370
 
ufc::finite_element* UFC_CahnHilliard2DLinearForm_finite_element_5::create_sub_element(unsigned int i) const
13371
 
{
13372
 
    return new UFC_CahnHilliard2DLinearForm_finite_element_5();
13373
 
}
13374
 
 
13375
 
 
13376
 
/// Constructor
13377
 
UFC_CahnHilliard2DLinearForm_finite_element_6::UFC_CahnHilliard2DLinearForm_finite_element_6() : ufc::finite_element()
13378
 
{
13379
 
    // Do nothing
13380
 
}
13381
 
 
13382
 
/// Destructor
13383
 
UFC_CahnHilliard2DLinearForm_finite_element_6::~UFC_CahnHilliard2DLinearForm_finite_element_6()
13384
 
{
13385
 
    // Do nothing
13386
 
}
13387
 
 
13388
 
/// Return a string identifying the finite element
13389
 
const char* UFC_CahnHilliard2DLinearForm_finite_element_6::signature() const
13390
 
{
13391
 
    return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
13392
 
}
13393
 
 
13394
 
/// Return the cell shape
13395
 
ufc::shape UFC_CahnHilliard2DLinearForm_finite_element_6::cell_shape() const
13396
 
{
13397
 
    return ufc::triangle;
13398
 
}
13399
 
 
13400
 
/// Return the dimension of the finite element function space
13401
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_6::space_dimension() const
13402
 
{
13403
 
    return 1;
13404
 
}
13405
 
 
13406
 
/// Return the rank of the value space
13407
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_6::value_rank() const
13408
 
{
13409
 
    return 0;
13410
 
}
13411
 
 
13412
 
/// Return the dimension of the value space for axis i
13413
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_6::value_dimension(unsigned int i) const
13414
 
{
13415
 
    return 1;
13416
 
}
13417
 
 
13418
 
/// Evaluate basis function i at given point in cell
13419
 
void UFC_CahnHilliard2DLinearForm_finite_element_6::evaluate_basis(unsigned int i,
13420
 
                                   double* values,
13421
 
                                   const double* coordinates,
13422
 
                                   const ufc::cell& c) const
13423
 
{
13424
 
    // Extract vertex coordinates
13425
 
    const double * const * element_coordinates = c.coordinates;
13426
 
    
13427
 
    // Compute Jacobian of affine map from reference cell
13428
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
13429
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
13430
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
13431
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
13432
 
      
13433
 
    // Compute determinant of Jacobian
13434
 
    const double detJ = J_00*J_11 - J_01*J_10;
13435
 
    
13436
 
    // Compute inverse of Jacobian
13437
 
    
13438
 
    // Get coordinates and map to the reference (UFC) element
13439
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
13440
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
13441
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
13442
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
13443
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
13444
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
13445
 
    
13446
 
    // Map coordinates to the reference square
13447
 
    if (std::abs(y - 1.0) < 1e-14)
13448
 
      x = -1.0;
13449
 
    else
13450
 
      x = 2.0 *x/(1.0 - y) - 1.0;
13451
 
    y = 2.0*y - 1.0;
13452
 
    
13453
 
    // Reset values
13454
 
    *values = 0;
13455
 
    
13456
 
    // Map degree of freedom to element degree of freedom
13457
 
    const unsigned int dof = i;
13458
 
    
13459
 
    // Generate scalings
13460
 
    const double scalings_y_0 = 1;
13461
 
    
13462
 
    // Compute psitilde_a
13463
 
    const double psitilde_a_0 = 1;
13464
 
    
13465
 
    // Compute psitilde_bs
13466
 
    const double psitilde_bs_0_0 = 1;
13467
 
    
13468
 
    // Compute basisvalues
13469
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
13470
 
    
13471
 
    // Table(s) of coefficients
13472
 
    const static double coefficients0[1][1] = \
13473
 
    {{1.41421356237309}};
13474
 
    
13475
 
    // Extract relevant coefficients
13476
 
    const double coeff0_0 = coefficients0[dof][0];
13477
 
    
13478
 
    // Compute value(s)
13479
 
    *values = coeff0_0*basisvalue0;
13480
 
}
13481
 
 
13482
 
/// Evaluate all basis functions at given point in cell
13483
 
void UFC_CahnHilliard2DLinearForm_finite_element_6::evaluate_basis_all(double* values,
13484
 
                                       const double* coordinates,
13485
 
                                       const ufc::cell& c) const
13486
 
{
13487
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
13488
 
}
13489
 
 
13490
 
/// Evaluate order n derivatives of basis function i at given point in cell
13491
 
void UFC_CahnHilliard2DLinearForm_finite_element_6::evaluate_basis_derivatives(unsigned int i,
13492
 
                                               unsigned int n,
13493
 
                                               double* values,
13494
 
                                               const double* coordinates,
13495
 
                                               const ufc::cell& c) const
13496
 
{
13497
 
    // Extract vertex coordinates
13498
 
    const double * const * element_coordinates = c.coordinates;
13499
 
    
13500
 
    // Compute Jacobian of affine map from reference cell
13501
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
13502
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
13503
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
13504
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
13505
 
      
13506
 
    // Compute determinant of Jacobian
13507
 
    const double detJ = J_00*J_11 - J_01*J_10;
13508
 
    
13509
 
    // Compute inverse of Jacobian
13510
 
    
13511
 
    // Get coordinates and map to the reference (UFC) element
13512
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
13513
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
13514
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
13515
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
13516
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
13517
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
13518
 
    
13519
 
    // Map coordinates to the reference square
13520
 
    if (std::abs(y - 1.0) < 1e-14)
13521
 
      x = -1.0;
13522
 
    else
13523
 
      x = 2.0 *x/(1.0 - y) - 1.0;
13524
 
    y = 2.0*y - 1.0;
13525
 
    
13526
 
    // Compute number of derivatives
13527
 
    unsigned int num_derivatives = 1;
13528
 
    
13529
 
    for (unsigned int j = 0; j < n; j++)
13530
 
      num_derivatives *= 2;
13531
 
    
13532
 
    
13533
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
13534
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
13535
 
        
13536
 
    for (unsigned int j = 0; j < num_derivatives; j++)
13537
 
    {
13538
 
      combinations[j] = new unsigned int [n];
13539
 
      for (unsigned int k = 0; k < n; k++)
13540
 
        combinations[j][k] = 0;
13541
 
    }
13542
 
        
13543
 
    // Generate combinations of derivatives
13544
 
    for (unsigned int row = 1; row < num_derivatives; row++)
13545
 
    {
13546
 
      for (unsigned int num = 0; num < row; num++)
13547
 
      {
13548
 
        for (unsigned int col = n-1; col+1 > 0; col--)
13549
 
        {
13550
 
          if (combinations[row][col] + 1 > 1)
13551
 
            combinations[row][col] = 0;
13552
 
          else
13553
 
          {
13554
 
            combinations[row][col] += 1;
13555
 
            break;
13556
 
          }
13557
 
        }
13558
 
      }
13559
 
    }
13560
 
    
13561
 
    // Compute inverse of Jacobian
13562
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
13563
 
    
13564
 
    // Declare transformation matrix
13565
 
    // Declare pointer to two dimensional array and initialise
13566
 
    double **transform = new double *[num_derivatives];
13567
 
        
13568
 
    for (unsigned int j = 0; j < num_derivatives; j++)
13569
 
    {
13570
 
      transform[j] = new double [num_derivatives];
13571
 
      for (unsigned int k = 0; k < num_derivatives; k++)
13572
 
        transform[j][k] = 1;
13573
 
    }
13574
 
    
13575
 
    // Construct transformation matrix
13576
 
    for (unsigned int row = 0; row < num_derivatives; row++)
13577
 
    {
13578
 
      for (unsigned int col = 0; col < num_derivatives; col++)
13579
 
      {
13580
 
        for (unsigned int k = 0; k < n; k++)
13581
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
13582
 
      }
13583
 
    }
13584
 
    
13585
 
    // Reset values
13586
 
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
13587
 
      values[j] = 0;
13588
 
    
13589
 
    // Map degree of freedom to element degree of freedom
13590
 
    const unsigned int dof = i;
13591
 
    
13592
 
    // Generate scalings
13593
 
    const double scalings_y_0 = 1;
13594
 
    
13595
 
    // Compute psitilde_a
13596
 
    const double psitilde_a_0 = 1;
13597
 
    
13598
 
    // Compute psitilde_bs
13599
 
    const double psitilde_bs_0_0 = 1;
13600
 
    
13601
 
    // Compute basisvalues
13602
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
13603
 
    
13604
 
    // Table(s) of coefficients
13605
 
    const static double coefficients0[1][1] = \
13606
 
    {{1.41421356237309}};
13607
 
    
13608
 
    // Interesting (new) part
13609
 
    // Tables of derivatives of the polynomial base (transpose)
13610
 
    const static double dmats0[1][1] = \
13611
 
    {{0}};
13612
 
    
13613
 
    const static double dmats1[1][1] = \
13614
 
    {{0}};
13615
 
    
13616
 
    // Compute reference derivatives
13617
 
    // Declare pointer to array of derivatives on FIAT element
13618
 
    double *derivatives = new double [num_derivatives];
13619
 
    
13620
 
    // Declare coefficients
13621
 
    double coeff0_0 = 0;
13622
 
    
13623
 
    // Declare new coefficients
13624
 
    double new_coeff0_0 = 0;
13625
 
    
13626
 
    // Loop possible derivatives
13627
 
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
13628
 
    {
13629
 
      // Get values from coefficients array
13630
 
      new_coeff0_0 = coefficients0[dof][0];
13631
 
    
13632
 
      // Loop derivative order
13633
 
      for (unsigned int j = 0; j < n; j++)
13634
 
      {
13635
 
        // Update old coefficients
13636
 
        coeff0_0 = new_coeff0_0;
13637
 
    
13638
 
        if(combinations[deriv_num][j] == 0)
13639
 
        {
13640
 
          new_coeff0_0 = coeff0_0*dmats0[0][0];
13641
 
        }
13642
 
        if(combinations[deriv_num][j] == 1)
13643
 
        {
13644
 
          new_coeff0_0 = coeff0_0*dmats1[0][0];
13645
 
        }
13646
 
    
13647
 
      }
13648
 
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
13649
 
      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
13650
 
    }
13651
 
    
13652
 
    // Transform derivatives back to physical element
13653
 
    for (unsigned int row = 0; row < num_derivatives; row++)
13654
 
    {
13655
 
      for (unsigned int col = 0; col < num_derivatives; col++)
13656
 
      {
13657
 
        values[row] += transform[row][col]*derivatives[col];
13658
 
      }
13659
 
    }
13660
 
    // Delete pointer to array of derivatives on FIAT element
13661
 
    delete [] derivatives;
13662
 
    
13663
 
    // Delete pointer to array of combinations of derivatives and transform
13664
 
    for (unsigned int row = 0; row < num_derivatives; row++)
13665
 
    {
13666
 
      delete [] combinations[row];
13667
 
      delete [] transform[row];
13668
 
    }
13669
 
    
13670
 
    delete [] combinations;
13671
 
    delete [] transform;
13672
 
}
13673
 
 
13674
 
/// Evaluate order n derivatives of all basis functions at given point in cell
13675
 
void UFC_CahnHilliard2DLinearForm_finite_element_6::evaluate_basis_derivatives_all(unsigned int n,
13676
 
                                                   double* values,
13677
 
                                                   const double* coordinates,
13678
 
                                                   const ufc::cell& c) const
13679
 
{
13680
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
13681
 
}
13682
 
 
13683
 
/// Evaluate linear functional for dof i on the function f
13684
 
double UFC_CahnHilliard2DLinearForm_finite_element_6::evaluate_dof(unsigned int i,
13685
 
                                   const ufc::function& f,
13686
 
                                   const ufc::cell& c) const
13687
 
{
13688
 
    // The reference points, direction and weights:
13689
 
    const static double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
13690
 
    const static double W[1][1] = {{1}};
13691
 
    const static double D[1][1][1] = {{{1}}};
13692
 
    
13693
 
    const double * const * x = c.coordinates;
13694
 
    double result = 0.0;
13695
 
    // Iterate over the points:
13696
 
    // Evaluate basis functions for affine mapping
13697
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
13698
 
    const double w1 = X[i][0][0];
13699
 
    const double w2 = X[i][0][1];
13700
 
    
13701
 
    // Compute affine mapping y = F(X)
13702
 
    double y[2];
13703
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
13704
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
13705
 
    
13706
 
    // Evaluate function at physical points
13707
 
    double values[1];
13708
 
    f.evaluate(values, y, c);
13709
 
    
13710
 
    // Map function values using appropriate mapping
13711
 
    // Affine map: Do nothing
13712
 
    
13713
 
    // Note that we do not map the weights (yet).
13714
 
    
13715
 
    // Take directional components
13716
 
    for(int k = 0; k < 1; k++)
13717
 
      result += values[k]*D[i][0][k];
13718
 
    // Multiply by weights 
13719
 
    result *= W[i][0];
13720
 
    
13721
 
    return result;
13722
 
}
13723
 
 
13724
 
/// Evaluate linear functionals for all dofs on the function f
13725
 
void UFC_CahnHilliard2DLinearForm_finite_element_6::evaluate_dofs(double* values,
13726
 
                                  const ufc::function& f,
13727
 
                                  const ufc::cell& c) const
13728
 
{
13729
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
13730
 
}
13731
 
 
13732
 
/// Interpolate vertex values from dof values
13733
 
void UFC_CahnHilliard2DLinearForm_finite_element_6::interpolate_vertex_values(double* vertex_values,
13734
 
                                              const double* dof_values,
13735
 
                                              const ufc::cell& c) const
13736
 
{
13737
 
    // Evaluate at vertices and use affine mapping
13738
 
    vertex_values[0] = dof_values[0];
13739
 
    vertex_values[1] = dof_values[0];
13740
 
    vertex_values[2] = dof_values[0];
13741
 
}
13742
 
 
13743
 
/// Return the number of sub elements (for a mixed element)
13744
 
unsigned int UFC_CahnHilliard2DLinearForm_finite_element_6::num_sub_elements() const
13745
 
{
13746
 
    return 1;
13747
 
}
13748
 
 
13749
 
/// Create a new finite element for sub element i (for a mixed element)
13750
 
ufc::finite_element* UFC_CahnHilliard2DLinearForm_finite_element_6::create_sub_element(unsigned int i) const
13751
 
{
13752
 
    return new UFC_CahnHilliard2DLinearForm_finite_element_6();
13753
 
}
13754
 
 
13755
 
/// Constructor
13756
 
UFC_CahnHilliard2DLinearForm_dof_map_0_0::UFC_CahnHilliard2DLinearForm_dof_map_0_0() : ufc::dof_map()
13757
 
{
13758
 
    __global_dimension = 0;
13759
 
}
13760
 
 
13761
 
/// Destructor
13762
 
UFC_CahnHilliard2DLinearForm_dof_map_0_0::~UFC_CahnHilliard2DLinearForm_dof_map_0_0()
13763
 
{
13764
 
    // Do nothing
13765
 
}
13766
 
 
13767
 
/// Return a string identifying the dof map
13768
 
const char* UFC_CahnHilliard2DLinearForm_dof_map_0_0::signature() const
13769
 
{
13770
 
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
13771
 
}
13772
 
 
13773
 
/// Return true iff mesh entities of topological dimension d are needed
13774
 
bool UFC_CahnHilliard2DLinearForm_dof_map_0_0::needs_mesh_entities(unsigned int d) const
13775
 
{
13776
 
    switch ( d )
13777
 
    {
13778
 
    case 0:
13779
 
      return true;
13780
 
      break;
13781
 
    case 1:
13782
 
      return false;
13783
 
      break;
13784
 
    case 2:
13785
 
      return false;
13786
 
      break;
13787
 
    }
13788
 
    return false;
13789
 
}
13790
 
 
13791
 
/// Initialize dof map for mesh (return true iff init_cell() is needed)
13792
 
bool UFC_CahnHilliard2DLinearForm_dof_map_0_0::init_mesh(const ufc::mesh& m)
13793
 
{
13794
 
    __global_dimension = m.num_entities[0];
13795
 
    return false;
13796
 
}
13797
 
 
13798
 
/// Initialize dof map for given cell
13799
 
void UFC_CahnHilliard2DLinearForm_dof_map_0_0::init_cell(const ufc::mesh& m,
13800
 
                              const ufc::cell& c)
13801
 
{
13802
 
    // Do nothing
13803
 
}
13804
 
 
13805
 
/// Finish initialization of dof map for cells
13806
 
void UFC_CahnHilliard2DLinearForm_dof_map_0_0::init_cell_finalize()
13807
 
{
13808
 
    // Do nothing
13809
 
}
13810
 
 
13811
 
/// Return the dimension of the global finite element function space
13812
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0_0::global_dimension() const
13813
 
{
13814
 
    return __global_dimension;
13815
 
}
13816
 
 
13817
 
/// Return the dimension of the local finite element function space
13818
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0_0::local_dimension() const
13819
 
{
13820
 
    return 3;
13821
 
}
13822
 
 
13823
 
// Return the geometric dimension of the coordinates this dof map provides
13824
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0_0::geometric_dimension() const
13825
 
{
13826
 
    return 2;
13827
 
}
13828
 
 
13829
 
/// Return the number of dofs on each cell facet
13830
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0_0::num_facet_dofs() const
13831
 
{
13832
 
    return 2;
13833
 
}
13834
 
 
13835
 
/// Return the number of dofs associated with each cell entity of dimension d
13836
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0_0::num_entity_dofs(unsigned int d) const
13837
 
{
13838
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
13839
 
}
13840
 
 
13841
 
/// Tabulate the local-to-global mapping of dofs on a cell
13842
 
void UFC_CahnHilliard2DLinearForm_dof_map_0_0::tabulate_dofs(unsigned int* dofs,
13843
 
                                  const ufc::mesh& m,
13844
 
                                  const ufc::cell& c) const
13845
 
{
13846
 
    dofs[0] = c.entity_indices[0][0];
13847
 
    dofs[1] = c.entity_indices[0][1];
13848
 
    dofs[2] = c.entity_indices[0][2];
13849
 
}
13850
 
 
13851
 
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
13852
 
void UFC_CahnHilliard2DLinearForm_dof_map_0_0::tabulate_facet_dofs(unsigned int* dofs,
13853
 
                                        unsigned int facet) const
13854
 
{
13855
 
    switch ( facet )
13856
 
    {
13857
 
    case 0:
13858
 
      dofs[0] = 1;
13859
 
      dofs[1] = 2;
13860
 
      break;
13861
 
    case 1:
13862
 
      dofs[0] = 0;
13863
 
      dofs[1] = 2;
13864
 
      break;
13865
 
    case 2:
13866
 
      dofs[0] = 0;
13867
 
      dofs[1] = 1;
13868
 
      break;
13869
 
    }
13870
 
}
13871
 
 
13872
 
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
13873
 
void UFC_CahnHilliard2DLinearForm_dof_map_0_0::tabulate_entity_dofs(unsigned int* dofs,
13874
 
                                  unsigned int d, unsigned int i) const
13875
 
{
13876
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
13877
 
}
13878
 
 
13879
 
/// Tabulate the coordinates of all dofs on a cell
13880
 
void UFC_CahnHilliard2DLinearForm_dof_map_0_0::tabulate_coordinates(double** coordinates,
13881
 
                                         const ufc::cell& c) const
13882
 
{
13883
 
    const double * const * x = c.coordinates;
13884
 
    coordinates[0][0] = x[0][0];
13885
 
    coordinates[0][1] = x[0][1];
13886
 
    coordinates[1][0] = x[1][0];
13887
 
    coordinates[1][1] = x[1][1];
13888
 
    coordinates[2][0] = x[2][0];
13889
 
    coordinates[2][1] = x[2][1];
13890
 
}
13891
 
 
13892
 
/// Return the number of sub dof maps (for a mixed element)
13893
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0_0::num_sub_dof_maps() const
13894
 
{
13895
 
    return 1;
13896
 
}
13897
 
 
13898
 
/// Create a new dof_map for sub dof map i (for a mixed element)
13899
 
ufc::dof_map* UFC_CahnHilliard2DLinearForm_dof_map_0_0::create_sub_dof_map(unsigned int i) const
13900
 
{
13901
 
    return new UFC_CahnHilliard2DLinearForm_dof_map_0_0();
13902
 
}
13903
 
 
13904
 
 
13905
 
/// Constructor
13906
 
UFC_CahnHilliard2DLinearForm_dof_map_0_1::UFC_CahnHilliard2DLinearForm_dof_map_0_1() : ufc::dof_map()
13907
 
{
13908
 
    __global_dimension = 0;
13909
 
}
13910
 
 
13911
 
/// Destructor
13912
 
UFC_CahnHilliard2DLinearForm_dof_map_0_1::~UFC_CahnHilliard2DLinearForm_dof_map_0_1()
13913
 
{
13914
 
    // Do nothing
13915
 
}
13916
 
 
13917
 
/// Return a string identifying the dof map
13918
 
const char* UFC_CahnHilliard2DLinearForm_dof_map_0_1::signature() const
13919
 
{
13920
 
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
13921
 
}
13922
 
 
13923
 
/// Return true iff mesh entities of topological dimension d are needed
13924
 
bool UFC_CahnHilliard2DLinearForm_dof_map_0_1::needs_mesh_entities(unsigned int d) const
13925
 
{
13926
 
    switch ( d )
13927
 
    {
13928
 
    case 0:
13929
 
      return true;
13930
 
      break;
13931
 
    case 1:
13932
 
      return false;
13933
 
      break;
13934
 
    case 2:
13935
 
      return false;
13936
 
      break;
13937
 
    }
13938
 
    return false;
13939
 
}
13940
 
 
13941
 
/// Initialize dof map for mesh (return true iff init_cell() is needed)
13942
 
bool UFC_CahnHilliard2DLinearForm_dof_map_0_1::init_mesh(const ufc::mesh& m)
13943
 
{
13944
 
    __global_dimension = m.num_entities[0];
13945
 
    return false;
13946
 
}
13947
 
 
13948
 
/// Initialize dof map for given cell
13949
 
void UFC_CahnHilliard2DLinearForm_dof_map_0_1::init_cell(const ufc::mesh& m,
13950
 
                              const ufc::cell& c)
13951
 
{
13952
 
    // Do nothing
13953
 
}
13954
 
 
13955
 
/// Finish initialization of dof map for cells
13956
 
void UFC_CahnHilliard2DLinearForm_dof_map_0_1::init_cell_finalize()
13957
 
{
13958
 
    // Do nothing
13959
 
}
13960
 
 
13961
 
/// Return the dimension of the global finite element function space
13962
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0_1::global_dimension() const
13963
 
{
13964
 
    return __global_dimension;
13965
 
}
13966
 
 
13967
 
/// Return the dimension of the local finite element function space
13968
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0_1::local_dimension() const
13969
 
{
13970
 
    return 3;
13971
 
}
13972
 
 
13973
 
// Return the geometric dimension of the coordinates this dof map provides
13974
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0_1::geometric_dimension() const
13975
 
{
13976
 
    return 2;
13977
 
}
13978
 
 
13979
 
/// Return the number of dofs on each cell facet
13980
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0_1::num_facet_dofs() const
13981
 
{
13982
 
    return 2;
13983
 
}
13984
 
 
13985
 
/// Return the number of dofs associated with each cell entity of dimension d
13986
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0_1::num_entity_dofs(unsigned int d) const
13987
 
{
13988
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
13989
 
}
13990
 
 
13991
 
/// Tabulate the local-to-global mapping of dofs on a cell
13992
 
void UFC_CahnHilliard2DLinearForm_dof_map_0_1::tabulate_dofs(unsigned int* dofs,
13993
 
                                  const ufc::mesh& m,
13994
 
                                  const ufc::cell& c) const
13995
 
{
13996
 
    dofs[0] = c.entity_indices[0][0];
13997
 
    dofs[1] = c.entity_indices[0][1];
13998
 
    dofs[2] = c.entity_indices[0][2];
13999
 
}
14000
 
 
14001
 
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
14002
 
void UFC_CahnHilliard2DLinearForm_dof_map_0_1::tabulate_facet_dofs(unsigned int* dofs,
14003
 
                                        unsigned int facet) const
14004
 
{
14005
 
    switch ( facet )
14006
 
    {
14007
 
    case 0:
14008
 
      dofs[0] = 1;
14009
 
      dofs[1] = 2;
14010
 
      break;
14011
 
    case 1:
14012
 
      dofs[0] = 0;
14013
 
      dofs[1] = 2;
14014
 
      break;
14015
 
    case 2:
14016
 
      dofs[0] = 0;
14017
 
      dofs[1] = 1;
14018
 
      break;
14019
 
    }
14020
 
}
14021
 
 
14022
 
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
14023
 
void UFC_CahnHilliard2DLinearForm_dof_map_0_1::tabulate_entity_dofs(unsigned int* dofs,
14024
 
                                  unsigned int d, unsigned int i) const
14025
 
{
14026
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14027
 
}
14028
 
 
14029
 
/// Tabulate the coordinates of all dofs on a cell
14030
 
void UFC_CahnHilliard2DLinearForm_dof_map_0_1::tabulate_coordinates(double** coordinates,
14031
 
                                         const ufc::cell& c) const
14032
 
{
14033
 
    const double * const * x = c.coordinates;
14034
 
    coordinates[0][0] = x[0][0];
14035
 
    coordinates[0][1] = x[0][1];
14036
 
    coordinates[1][0] = x[1][0];
14037
 
    coordinates[1][1] = x[1][1];
14038
 
    coordinates[2][0] = x[2][0];
14039
 
    coordinates[2][1] = x[2][1];
14040
 
}
14041
 
 
14042
 
/// Return the number of sub dof maps (for a mixed element)
14043
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0_1::num_sub_dof_maps() const
14044
 
{
14045
 
    return 1;
14046
 
}
14047
 
 
14048
 
/// Create a new dof_map for sub dof map i (for a mixed element)
14049
 
ufc::dof_map* UFC_CahnHilliard2DLinearForm_dof_map_0_1::create_sub_dof_map(unsigned int i) const
14050
 
{
14051
 
    return new UFC_CahnHilliard2DLinearForm_dof_map_0_1();
14052
 
}
14053
 
 
14054
 
 
14055
 
/// Constructor
14056
 
UFC_CahnHilliard2DLinearForm_dof_map_0::UFC_CahnHilliard2DLinearForm_dof_map_0() : ufc::dof_map()
14057
 
{
14058
 
    __global_dimension = 0;
14059
 
}
14060
 
 
14061
 
/// Destructor
14062
 
UFC_CahnHilliard2DLinearForm_dof_map_0::~UFC_CahnHilliard2DLinearForm_dof_map_0()
14063
 
{
14064
 
    // Do nothing
14065
 
}
14066
 
 
14067
 
/// Return a string identifying the dof map
14068
 
const char* UFC_CahnHilliard2DLinearForm_dof_map_0::signature() const
14069
 
{
14070
 
    return "FFC dof map for MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
14071
 
}
14072
 
 
14073
 
/// Return true iff mesh entities of topological dimension d are needed
14074
 
bool UFC_CahnHilliard2DLinearForm_dof_map_0::needs_mesh_entities(unsigned int d) const
14075
 
{
14076
 
    switch ( d )
14077
 
    {
14078
 
    case 0:
14079
 
      return true;
14080
 
      break;
14081
 
    case 1:
14082
 
      return false;
14083
 
      break;
14084
 
    case 2:
14085
 
      return false;
14086
 
      break;
14087
 
    }
14088
 
    return false;
14089
 
}
14090
 
 
14091
 
/// Initialize dof map for mesh (return true iff init_cell() is needed)
14092
 
bool UFC_CahnHilliard2DLinearForm_dof_map_0::init_mesh(const ufc::mesh& m)
14093
 
{
14094
 
    __global_dimension = 2*m.num_entities[0];
14095
 
    return false;
14096
 
}
14097
 
 
14098
 
/// Initialize dof map for given cell
14099
 
void UFC_CahnHilliard2DLinearForm_dof_map_0::init_cell(const ufc::mesh& m,
14100
 
                              const ufc::cell& c)
14101
 
{
14102
 
    // Do nothing
14103
 
}
14104
 
 
14105
 
/// Finish initialization of dof map for cells
14106
 
void UFC_CahnHilliard2DLinearForm_dof_map_0::init_cell_finalize()
14107
 
{
14108
 
    // Do nothing
14109
 
}
14110
 
 
14111
 
/// Return the dimension of the global finite element function space
14112
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0::global_dimension() const
14113
 
{
14114
 
    return __global_dimension;
14115
 
}
14116
 
 
14117
 
/// Return the dimension of the local finite element function space
14118
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0::local_dimension() const
14119
 
{
14120
 
    return 6;
14121
 
}
14122
 
 
14123
 
// Return the geometric dimension of the coordinates this dof map provides
14124
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0::geometric_dimension() const
14125
 
{
14126
 
    return 2;
14127
 
}
14128
 
 
14129
 
/// Return the number of dofs on each cell facet
14130
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0::num_facet_dofs() const
14131
 
{
14132
 
    return 4;
14133
 
}
14134
 
 
14135
 
/// Return the number of dofs associated with each cell entity of dimension d
14136
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0::num_entity_dofs(unsigned int d) const
14137
 
{
14138
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14139
 
}
14140
 
 
14141
 
/// Tabulate the local-to-global mapping of dofs on a cell
14142
 
void UFC_CahnHilliard2DLinearForm_dof_map_0::tabulate_dofs(unsigned int* dofs,
14143
 
                                  const ufc::mesh& m,
14144
 
                                  const ufc::cell& c) const
14145
 
{
14146
 
    dofs[0] = c.entity_indices[0][0];
14147
 
    dofs[1] = c.entity_indices[0][1];
14148
 
    dofs[2] = c.entity_indices[0][2];
14149
 
    unsigned int offset = m.num_entities[0];
14150
 
    dofs[3] = offset + c.entity_indices[0][0];
14151
 
    dofs[4] = offset + c.entity_indices[0][1];
14152
 
    dofs[5] = offset + c.entity_indices[0][2];
14153
 
}
14154
 
 
14155
 
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
14156
 
void UFC_CahnHilliard2DLinearForm_dof_map_0::tabulate_facet_dofs(unsigned int* dofs,
14157
 
                                        unsigned int facet) const
14158
 
{
14159
 
    switch ( facet )
14160
 
    {
14161
 
    case 0:
14162
 
      dofs[0] = 1;
14163
 
      dofs[1] = 2;
14164
 
      dofs[2] = 4;
14165
 
      dofs[3] = 5;
14166
 
      break;
14167
 
    case 1:
14168
 
      dofs[0] = 0;
14169
 
      dofs[1] = 2;
14170
 
      dofs[2] = 3;
14171
 
      dofs[3] = 5;
14172
 
      break;
14173
 
    case 2:
14174
 
      dofs[0] = 0;
14175
 
      dofs[1] = 1;
14176
 
      dofs[2] = 3;
14177
 
      dofs[3] = 4;
14178
 
      break;
14179
 
    }
14180
 
}
14181
 
 
14182
 
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
14183
 
void UFC_CahnHilliard2DLinearForm_dof_map_0::tabulate_entity_dofs(unsigned int* dofs,
14184
 
                                  unsigned int d, unsigned int i) const
14185
 
{
14186
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14187
 
}
14188
 
 
14189
 
/// Tabulate the coordinates of all dofs on a cell
14190
 
void UFC_CahnHilliard2DLinearForm_dof_map_0::tabulate_coordinates(double** coordinates,
14191
 
                                         const ufc::cell& c) const
14192
 
{
14193
 
    const double * const * x = c.coordinates;
14194
 
    coordinates[0][0] = x[0][0];
14195
 
    coordinates[0][1] = x[0][1];
14196
 
    coordinates[1][0] = x[1][0];
14197
 
    coordinates[1][1] = x[1][1];
14198
 
    coordinates[2][0] = x[2][0];
14199
 
    coordinates[2][1] = x[2][1];
14200
 
    coordinates[3][0] = x[0][0];
14201
 
    coordinates[3][1] = x[0][1];
14202
 
    coordinates[4][0] = x[1][0];
14203
 
    coordinates[4][1] = x[1][1];
14204
 
    coordinates[5][0] = x[2][0];
14205
 
    coordinates[5][1] = x[2][1];
14206
 
}
14207
 
 
14208
 
/// Return the number of sub dof maps (for a mixed element)
14209
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_0::num_sub_dof_maps() const
14210
 
{
14211
 
    return 2;
14212
 
}
14213
 
 
14214
 
/// Create a new dof_map for sub dof map i (for a mixed element)
14215
 
ufc::dof_map* UFC_CahnHilliard2DLinearForm_dof_map_0::create_sub_dof_map(unsigned int i) const
14216
 
{
14217
 
    switch ( i )
14218
 
    {
14219
 
    case 0:
14220
 
      return new UFC_CahnHilliard2DLinearForm_dof_map_0_0();
14221
 
      break;
14222
 
    case 1:
14223
 
      return new UFC_CahnHilliard2DLinearForm_dof_map_0_1();
14224
 
      break;
14225
 
    }
14226
 
    return 0;
14227
 
}
14228
 
 
14229
 
 
14230
 
/// Constructor
14231
 
UFC_CahnHilliard2DLinearForm_dof_map_1_0::UFC_CahnHilliard2DLinearForm_dof_map_1_0() : ufc::dof_map()
14232
 
{
14233
 
    __global_dimension = 0;
14234
 
}
14235
 
 
14236
 
/// Destructor
14237
 
UFC_CahnHilliard2DLinearForm_dof_map_1_0::~UFC_CahnHilliard2DLinearForm_dof_map_1_0()
14238
 
{
14239
 
    // Do nothing
14240
 
}
14241
 
 
14242
 
/// Return a string identifying the dof map
14243
 
const char* UFC_CahnHilliard2DLinearForm_dof_map_1_0::signature() const
14244
 
{
14245
 
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
14246
 
}
14247
 
 
14248
 
/// Return true iff mesh entities of topological dimension d are needed
14249
 
bool UFC_CahnHilliard2DLinearForm_dof_map_1_0::needs_mesh_entities(unsigned int d) const
14250
 
{
14251
 
    switch ( d )
14252
 
    {
14253
 
    case 0:
14254
 
      return true;
14255
 
      break;
14256
 
    case 1:
14257
 
      return false;
14258
 
      break;
14259
 
    case 2:
14260
 
      return false;
14261
 
      break;
14262
 
    }
14263
 
    return false;
14264
 
}
14265
 
 
14266
 
/// Initialize dof map for mesh (return true iff init_cell() is needed)
14267
 
bool UFC_CahnHilliard2DLinearForm_dof_map_1_0::init_mesh(const ufc::mesh& m)
14268
 
{
14269
 
    __global_dimension = m.num_entities[0];
14270
 
    return false;
14271
 
}
14272
 
 
14273
 
/// Initialize dof map for given cell
14274
 
void UFC_CahnHilliard2DLinearForm_dof_map_1_0::init_cell(const ufc::mesh& m,
14275
 
                              const ufc::cell& c)
14276
 
{
14277
 
    // Do nothing
14278
 
}
14279
 
 
14280
 
/// Finish initialization of dof map for cells
14281
 
void UFC_CahnHilliard2DLinearForm_dof_map_1_0::init_cell_finalize()
14282
 
{
14283
 
    // Do nothing
14284
 
}
14285
 
 
14286
 
/// Return the dimension of the global finite element function space
14287
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1_0::global_dimension() const
14288
 
{
14289
 
    return __global_dimension;
14290
 
}
14291
 
 
14292
 
/// Return the dimension of the local finite element function space
14293
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1_0::local_dimension() const
14294
 
{
14295
 
    return 3;
14296
 
}
14297
 
 
14298
 
// Return the geometric dimension of the coordinates this dof map provides
14299
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1_0::geometric_dimension() const
14300
 
{
14301
 
    return 2;
14302
 
}
14303
 
 
14304
 
/// Return the number of dofs on each cell facet
14305
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1_0::num_facet_dofs() const
14306
 
{
14307
 
    return 2;
14308
 
}
14309
 
 
14310
 
/// Return the number of dofs associated with each cell entity of dimension d
14311
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1_0::num_entity_dofs(unsigned int d) const
14312
 
{
14313
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14314
 
}
14315
 
 
14316
 
/// Tabulate the local-to-global mapping of dofs on a cell
14317
 
void UFC_CahnHilliard2DLinearForm_dof_map_1_0::tabulate_dofs(unsigned int* dofs,
14318
 
                                  const ufc::mesh& m,
14319
 
                                  const ufc::cell& c) const
14320
 
{
14321
 
    dofs[0] = c.entity_indices[0][0];
14322
 
    dofs[1] = c.entity_indices[0][1];
14323
 
    dofs[2] = c.entity_indices[0][2];
14324
 
}
14325
 
 
14326
 
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
14327
 
void UFC_CahnHilliard2DLinearForm_dof_map_1_0::tabulate_facet_dofs(unsigned int* dofs,
14328
 
                                        unsigned int facet) const
14329
 
{
14330
 
    switch ( facet )
14331
 
    {
14332
 
    case 0:
14333
 
      dofs[0] = 1;
14334
 
      dofs[1] = 2;
14335
 
      break;
14336
 
    case 1:
14337
 
      dofs[0] = 0;
14338
 
      dofs[1] = 2;
14339
 
      break;
14340
 
    case 2:
14341
 
      dofs[0] = 0;
14342
 
      dofs[1] = 1;
14343
 
      break;
14344
 
    }
14345
 
}
14346
 
 
14347
 
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
14348
 
void UFC_CahnHilliard2DLinearForm_dof_map_1_0::tabulate_entity_dofs(unsigned int* dofs,
14349
 
                                  unsigned int d, unsigned int i) const
14350
 
{
14351
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14352
 
}
14353
 
 
14354
 
/// Tabulate the coordinates of all dofs on a cell
14355
 
void UFC_CahnHilliard2DLinearForm_dof_map_1_0::tabulate_coordinates(double** coordinates,
14356
 
                                         const ufc::cell& c) const
14357
 
{
14358
 
    const double * const * x = c.coordinates;
14359
 
    coordinates[0][0] = x[0][0];
14360
 
    coordinates[0][1] = x[0][1];
14361
 
    coordinates[1][0] = x[1][0];
14362
 
    coordinates[1][1] = x[1][1];
14363
 
    coordinates[2][0] = x[2][0];
14364
 
    coordinates[2][1] = x[2][1];
14365
 
}
14366
 
 
14367
 
/// Return the number of sub dof maps (for a mixed element)
14368
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1_0::num_sub_dof_maps() const
14369
 
{
14370
 
    return 1;
14371
 
}
14372
 
 
14373
 
/// Create a new dof_map for sub dof map i (for a mixed element)
14374
 
ufc::dof_map* UFC_CahnHilliard2DLinearForm_dof_map_1_0::create_sub_dof_map(unsigned int i) const
14375
 
{
14376
 
    return new UFC_CahnHilliard2DLinearForm_dof_map_1_0();
14377
 
}
14378
 
 
14379
 
 
14380
 
/// Constructor
14381
 
UFC_CahnHilliard2DLinearForm_dof_map_1_1::UFC_CahnHilliard2DLinearForm_dof_map_1_1() : ufc::dof_map()
14382
 
{
14383
 
    __global_dimension = 0;
14384
 
}
14385
 
 
14386
 
/// Destructor
14387
 
UFC_CahnHilliard2DLinearForm_dof_map_1_1::~UFC_CahnHilliard2DLinearForm_dof_map_1_1()
14388
 
{
14389
 
    // Do nothing
14390
 
}
14391
 
 
14392
 
/// Return a string identifying the dof map
14393
 
const char* UFC_CahnHilliard2DLinearForm_dof_map_1_1::signature() const
14394
 
{
14395
 
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
14396
 
}
14397
 
 
14398
 
/// Return true iff mesh entities of topological dimension d are needed
14399
 
bool UFC_CahnHilliard2DLinearForm_dof_map_1_1::needs_mesh_entities(unsigned int d) const
14400
 
{
14401
 
    switch ( d )
14402
 
    {
14403
 
    case 0:
14404
 
      return true;
14405
 
      break;
14406
 
    case 1:
14407
 
      return false;
14408
 
      break;
14409
 
    case 2:
14410
 
      return false;
14411
 
      break;
14412
 
    }
14413
 
    return false;
14414
 
}
14415
 
 
14416
 
/// Initialize dof map for mesh (return true iff init_cell() is needed)
14417
 
bool UFC_CahnHilliard2DLinearForm_dof_map_1_1::init_mesh(const ufc::mesh& m)
14418
 
{
14419
 
    __global_dimension = m.num_entities[0];
14420
 
    return false;
14421
 
}
14422
 
 
14423
 
/// Initialize dof map for given cell
14424
 
void UFC_CahnHilliard2DLinearForm_dof_map_1_1::init_cell(const ufc::mesh& m,
14425
 
                              const ufc::cell& c)
14426
 
{
14427
 
    // Do nothing
14428
 
}
14429
 
 
14430
 
/// Finish initialization of dof map for cells
14431
 
void UFC_CahnHilliard2DLinearForm_dof_map_1_1::init_cell_finalize()
14432
 
{
14433
 
    // Do nothing
14434
 
}
14435
 
 
14436
 
/// Return the dimension of the global finite element function space
14437
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1_1::global_dimension() const
14438
 
{
14439
 
    return __global_dimension;
14440
 
}
14441
 
 
14442
 
/// Return the dimension of the local finite element function space
14443
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1_1::local_dimension() const
14444
 
{
14445
 
    return 3;
14446
 
}
14447
 
 
14448
 
// Return the geometric dimension of the coordinates this dof map provides
14449
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1_1::geometric_dimension() const
14450
 
{
14451
 
    return 2;
14452
 
}
14453
 
 
14454
 
/// Return the number of dofs on each cell facet
14455
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1_1::num_facet_dofs() const
14456
 
{
14457
 
    return 2;
14458
 
}
14459
 
 
14460
 
/// Return the number of dofs associated with each cell entity of dimension d
14461
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1_1::num_entity_dofs(unsigned int d) const
14462
 
{
14463
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14464
 
}
14465
 
 
14466
 
/// Tabulate the local-to-global mapping of dofs on a cell
14467
 
void UFC_CahnHilliard2DLinearForm_dof_map_1_1::tabulate_dofs(unsigned int* dofs,
14468
 
                                  const ufc::mesh& m,
14469
 
                                  const ufc::cell& c) const
14470
 
{
14471
 
    dofs[0] = c.entity_indices[0][0];
14472
 
    dofs[1] = c.entity_indices[0][1];
14473
 
    dofs[2] = c.entity_indices[0][2];
14474
 
}
14475
 
 
14476
 
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
14477
 
void UFC_CahnHilliard2DLinearForm_dof_map_1_1::tabulate_facet_dofs(unsigned int* dofs,
14478
 
                                        unsigned int facet) const
14479
 
{
14480
 
    switch ( facet )
14481
 
    {
14482
 
    case 0:
14483
 
      dofs[0] = 1;
14484
 
      dofs[1] = 2;
14485
 
      break;
14486
 
    case 1:
14487
 
      dofs[0] = 0;
14488
 
      dofs[1] = 2;
14489
 
      break;
14490
 
    case 2:
14491
 
      dofs[0] = 0;
14492
 
      dofs[1] = 1;
14493
 
      break;
14494
 
    }
14495
 
}
14496
 
 
14497
 
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
14498
 
void UFC_CahnHilliard2DLinearForm_dof_map_1_1::tabulate_entity_dofs(unsigned int* dofs,
14499
 
                                  unsigned int d, unsigned int i) const
14500
 
{
14501
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14502
 
}
14503
 
 
14504
 
/// Tabulate the coordinates of all dofs on a cell
14505
 
void UFC_CahnHilliard2DLinearForm_dof_map_1_1::tabulate_coordinates(double** coordinates,
14506
 
                                         const ufc::cell& c) const
14507
 
{
14508
 
    const double * const * x = c.coordinates;
14509
 
    coordinates[0][0] = x[0][0];
14510
 
    coordinates[0][1] = x[0][1];
14511
 
    coordinates[1][0] = x[1][0];
14512
 
    coordinates[1][1] = x[1][1];
14513
 
    coordinates[2][0] = x[2][0];
14514
 
    coordinates[2][1] = x[2][1];
14515
 
}
14516
 
 
14517
 
/// Return the number of sub dof maps (for a mixed element)
14518
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1_1::num_sub_dof_maps() const
14519
 
{
14520
 
    return 1;
14521
 
}
14522
 
 
14523
 
/// Create a new dof_map for sub dof map i (for a mixed element)
14524
 
ufc::dof_map* UFC_CahnHilliard2DLinearForm_dof_map_1_1::create_sub_dof_map(unsigned int i) const
14525
 
{
14526
 
    return new UFC_CahnHilliard2DLinearForm_dof_map_1_1();
14527
 
}
14528
 
 
14529
 
 
14530
 
/// Constructor
14531
 
UFC_CahnHilliard2DLinearForm_dof_map_1::UFC_CahnHilliard2DLinearForm_dof_map_1() : ufc::dof_map()
14532
 
{
14533
 
    __global_dimension = 0;
14534
 
}
14535
 
 
14536
 
/// Destructor
14537
 
UFC_CahnHilliard2DLinearForm_dof_map_1::~UFC_CahnHilliard2DLinearForm_dof_map_1()
14538
 
{
14539
 
    // Do nothing
14540
 
}
14541
 
 
14542
 
/// Return a string identifying the dof map
14543
 
const char* UFC_CahnHilliard2DLinearForm_dof_map_1::signature() const
14544
 
{
14545
 
    return "FFC dof map for MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
14546
 
}
14547
 
 
14548
 
/// Return true iff mesh entities of topological dimension d are needed
14549
 
bool UFC_CahnHilliard2DLinearForm_dof_map_1::needs_mesh_entities(unsigned int d) const
14550
 
{
14551
 
    switch ( d )
14552
 
    {
14553
 
    case 0:
14554
 
      return true;
14555
 
      break;
14556
 
    case 1:
14557
 
      return false;
14558
 
      break;
14559
 
    case 2:
14560
 
      return false;
14561
 
      break;
14562
 
    }
14563
 
    return false;
14564
 
}
14565
 
 
14566
 
/// Initialize dof map for mesh (return true iff init_cell() is needed)
14567
 
bool UFC_CahnHilliard2DLinearForm_dof_map_1::init_mesh(const ufc::mesh& m)
14568
 
{
14569
 
    __global_dimension = 2*m.num_entities[0];
14570
 
    return false;
14571
 
}
14572
 
 
14573
 
/// Initialize dof map for given cell
14574
 
void UFC_CahnHilliard2DLinearForm_dof_map_1::init_cell(const ufc::mesh& m,
14575
 
                              const ufc::cell& c)
14576
 
{
14577
 
    // Do nothing
14578
 
}
14579
 
 
14580
 
/// Finish initialization of dof map for cells
14581
 
void UFC_CahnHilliard2DLinearForm_dof_map_1::init_cell_finalize()
14582
 
{
14583
 
    // Do nothing
14584
 
}
14585
 
 
14586
 
/// Return the dimension of the global finite element function space
14587
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1::global_dimension() const
14588
 
{
14589
 
    return __global_dimension;
14590
 
}
14591
 
 
14592
 
/// Return the dimension of the local finite element function space
14593
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1::local_dimension() const
14594
 
{
14595
 
    return 6;
14596
 
}
14597
 
 
14598
 
// Return the geometric dimension of the coordinates this dof map provides
14599
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1::geometric_dimension() const
14600
 
{
14601
 
    return 2;
14602
 
}
14603
 
 
14604
 
/// Return the number of dofs on each cell facet
14605
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1::num_facet_dofs() const
14606
 
{
14607
 
    return 4;
14608
 
}
14609
 
 
14610
 
/// Return the number of dofs associated with each cell entity of dimension d
14611
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1::num_entity_dofs(unsigned int d) const
14612
 
{
14613
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14614
 
}
14615
 
 
14616
 
/// Tabulate the local-to-global mapping of dofs on a cell
14617
 
void UFC_CahnHilliard2DLinearForm_dof_map_1::tabulate_dofs(unsigned int* dofs,
14618
 
                                  const ufc::mesh& m,
14619
 
                                  const ufc::cell& c) const
14620
 
{
14621
 
    dofs[0] = c.entity_indices[0][0];
14622
 
    dofs[1] = c.entity_indices[0][1];
14623
 
    dofs[2] = c.entity_indices[0][2];
14624
 
    unsigned int offset = m.num_entities[0];
14625
 
    dofs[3] = offset + c.entity_indices[0][0];
14626
 
    dofs[4] = offset + c.entity_indices[0][1];
14627
 
    dofs[5] = offset + c.entity_indices[0][2];
14628
 
}
14629
 
 
14630
 
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
14631
 
void UFC_CahnHilliard2DLinearForm_dof_map_1::tabulate_facet_dofs(unsigned int* dofs,
14632
 
                                        unsigned int facet) const
14633
 
{
14634
 
    switch ( facet )
14635
 
    {
14636
 
    case 0:
14637
 
      dofs[0] = 1;
14638
 
      dofs[1] = 2;
14639
 
      dofs[2] = 4;
14640
 
      dofs[3] = 5;
14641
 
      break;
14642
 
    case 1:
14643
 
      dofs[0] = 0;
14644
 
      dofs[1] = 2;
14645
 
      dofs[2] = 3;
14646
 
      dofs[3] = 5;
14647
 
      break;
14648
 
    case 2:
14649
 
      dofs[0] = 0;
14650
 
      dofs[1] = 1;
14651
 
      dofs[2] = 3;
14652
 
      dofs[3] = 4;
14653
 
      break;
14654
 
    }
14655
 
}
14656
 
 
14657
 
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
14658
 
void UFC_CahnHilliard2DLinearForm_dof_map_1::tabulate_entity_dofs(unsigned int* dofs,
14659
 
                                  unsigned int d, unsigned int i) const
14660
 
{
14661
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14662
 
}
14663
 
 
14664
 
/// Tabulate the coordinates of all dofs on a cell
14665
 
void UFC_CahnHilliard2DLinearForm_dof_map_1::tabulate_coordinates(double** coordinates,
14666
 
                                         const ufc::cell& c) const
14667
 
{
14668
 
    const double * const * x = c.coordinates;
14669
 
    coordinates[0][0] = x[0][0];
14670
 
    coordinates[0][1] = x[0][1];
14671
 
    coordinates[1][0] = x[1][0];
14672
 
    coordinates[1][1] = x[1][1];
14673
 
    coordinates[2][0] = x[2][0];
14674
 
    coordinates[2][1] = x[2][1];
14675
 
    coordinates[3][0] = x[0][0];
14676
 
    coordinates[3][1] = x[0][1];
14677
 
    coordinates[4][0] = x[1][0];
14678
 
    coordinates[4][1] = x[1][1];
14679
 
    coordinates[5][0] = x[2][0];
14680
 
    coordinates[5][1] = x[2][1];
14681
 
}
14682
 
 
14683
 
/// Return the number of sub dof maps (for a mixed element)
14684
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_1::num_sub_dof_maps() const
14685
 
{
14686
 
    return 2;
14687
 
}
14688
 
 
14689
 
/// Create a new dof_map for sub dof map i (for a mixed element)
14690
 
ufc::dof_map* UFC_CahnHilliard2DLinearForm_dof_map_1::create_sub_dof_map(unsigned int i) const
14691
 
{
14692
 
    switch ( i )
14693
 
    {
14694
 
    case 0:
14695
 
      return new UFC_CahnHilliard2DLinearForm_dof_map_1_0();
14696
 
      break;
14697
 
    case 1:
14698
 
      return new UFC_CahnHilliard2DLinearForm_dof_map_1_1();
14699
 
      break;
14700
 
    }
14701
 
    return 0;
14702
 
}
14703
 
 
14704
 
 
14705
 
/// Constructor
14706
 
UFC_CahnHilliard2DLinearForm_dof_map_2_0::UFC_CahnHilliard2DLinearForm_dof_map_2_0() : ufc::dof_map()
14707
 
{
14708
 
    __global_dimension = 0;
14709
 
}
14710
 
 
14711
 
/// Destructor
14712
 
UFC_CahnHilliard2DLinearForm_dof_map_2_0::~UFC_CahnHilliard2DLinearForm_dof_map_2_0()
14713
 
{
14714
 
    // Do nothing
14715
 
}
14716
 
 
14717
 
/// Return a string identifying the dof map
14718
 
const char* UFC_CahnHilliard2DLinearForm_dof_map_2_0::signature() const
14719
 
{
14720
 
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
14721
 
}
14722
 
 
14723
 
/// Return true iff mesh entities of topological dimension d are needed
14724
 
bool UFC_CahnHilliard2DLinearForm_dof_map_2_0::needs_mesh_entities(unsigned int d) const
14725
 
{
14726
 
    switch ( d )
14727
 
    {
14728
 
    case 0:
14729
 
      return true;
14730
 
      break;
14731
 
    case 1:
14732
 
      return false;
14733
 
      break;
14734
 
    case 2:
14735
 
      return false;
14736
 
      break;
14737
 
    }
14738
 
    return false;
14739
 
}
14740
 
 
14741
 
/// Initialize dof map for mesh (return true iff init_cell() is needed)
14742
 
bool UFC_CahnHilliard2DLinearForm_dof_map_2_0::init_mesh(const ufc::mesh& m)
14743
 
{
14744
 
    __global_dimension = m.num_entities[0];
14745
 
    return false;
14746
 
}
14747
 
 
14748
 
/// Initialize dof map for given cell
14749
 
void UFC_CahnHilliard2DLinearForm_dof_map_2_0::init_cell(const ufc::mesh& m,
14750
 
                              const ufc::cell& c)
14751
 
{
14752
 
    // Do nothing
14753
 
}
14754
 
 
14755
 
/// Finish initialization of dof map for cells
14756
 
void UFC_CahnHilliard2DLinearForm_dof_map_2_0::init_cell_finalize()
14757
 
{
14758
 
    // Do nothing
14759
 
}
14760
 
 
14761
 
/// Return the dimension of the global finite element function space
14762
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2_0::global_dimension() const
14763
 
{
14764
 
    return __global_dimension;
14765
 
}
14766
 
 
14767
 
/// Return the dimension of the local finite element function space
14768
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2_0::local_dimension() const
14769
 
{
14770
 
    return 3;
14771
 
}
14772
 
 
14773
 
// Return the geometric dimension of the coordinates this dof map provides
14774
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2_0::geometric_dimension() const
14775
 
{
14776
 
    return 2;
14777
 
}
14778
 
 
14779
 
/// Return the number of dofs on each cell facet
14780
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2_0::num_facet_dofs() const
14781
 
{
14782
 
    return 2;
14783
 
}
14784
 
 
14785
 
/// Return the number of dofs associated with each cell entity of dimension d
14786
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2_0::num_entity_dofs(unsigned int d) const
14787
 
{
14788
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14789
 
}
14790
 
 
14791
 
/// Tabulate the local-to-global mapping of dofs on a cell
14792
 
void UFC_CahnHilliard2DLinearForm_dof_map_2_0::tabulate_dofs(unsigned int* dofs,
14793
 
                                  const ufc::mesh& m,
14794
 
                                  const ufc::cell& c) const
14795
 
{
14796
 
    dofs[0] = c.entity_indices[0][0];
14797
 
    dofs[1] = c.entity_indices[0][1];
14798
 
    dofs[2] = c.entity_indices[0][2];
14799
 
}
14800
 
 
14801
 
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
14802
 
void UFC_CahnHilliard2DLinearForm_dof_map_2_0::tabulate_facet_dofs(unsigned int* dofs,
14803
 
                                        unsigned int facet) const
14804
 
{
14805
 
    switch ( facet )
14806
 
    {
14807
 
    case 0:
14808
 
      dofs[0] = 1;
14809
 
      dofs[1] = 2;
14810
 
      break;
14811
 
    case 1:
14812
 
      dofs[0] = 0;
14813
 
      dofs[1] = 2;
14814
 
      break;
14815
 
    case 2:
14816
 
      dofs[0] = 0;
14817
 
      dofs[1] = 1;
14818
 
      break;
14819
 
    }
14820
 
}
14821
 
 
14822
 
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
14823
 
void UFC_CahnHilliard2DLinearForm_dof_map_2_0::tabulate_entity_dofs(unsigned int* dofs,
14824
 
                                  unsigned int d, unsigned int i) const
14825
 
{
14826
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14827
 
}
14828
 
 
14829
 
/// Tabulate the coordinates of all dofs on a cell
14830
 
void UFC_CahnHilliard2DLinearForm_dof_map_2_0::tabulate_coordinates(double** coordinates,
14831
 
                                         const ufc::cell& c) const
14832
 
{
14833
 
    const double * const * x = c.coordinates;
14834
 
    coordinates[0][0] = x[0][0];
14835
 
    coordinates[0][1] = x[0][1];
14836
 
    coordinates[1][0] = x[1][0];
14837
 
    coordinates[1][1] = x[1][1];
14838
 
    coordinates[2][0] = x[2][0];
14839
 
    coordinates[2][1] = x[2][1];
14840
 
}
14841
 
 
14842
 
/// Return the number of sub dof maps (for a mixed element)
14843
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2_0::num_sub_dof_maps() const
14844
 
{
14845
 
    return 1;
14846
 
}
14847
 
 
14848
 
/// Create a new dof_map for sub dof map i (for a mixed element)
14849
 
ufc::dof_map* UFC_CahnHilliard2DLinearForm_dof_map_2_0::create_sub_dof_map(unsigned int i) const
14850
 
{
14851
 
    return new UFC_CahnHilliard2DLinearForm_dof_map_2_0();
14852
 
}
14853
 
 
14854
 
 
14855
 
/// Constructor
14856
 
UFC_CahnHilliard2DLinearForm_dof_map_2_1::UFC_CahnHilliard2DLinearForm_dof_map_2_1() : ufc::dof_map()
14857
 
{
14858
 
    __global_dimension = 0;
14859
 
}
14860
 
 
14861
 
/// Destructor
14862
 
UFC_CahnHilliard2DLinearForm_dof_map_2_1::~UFC_CahnHilliard2DLinearForm_dof_map_2_1()
14863
 
{
14864
 
    // Do nothing
14865
 
}
14866
 
 
14867
 
/// Return a string identifying the dof map
14868
 
const char* UFC_CahnHilliard2DLinearForm_dof_map_2_1::signature() const
14869
 
{
14870
 
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
14871
 
}
14872
 
 
14873
 
/// Return true iff mesh entities of topological dimension d are needed
14874
 
bool UFC_CahnHilliard2DLinearForm_dof_map_2_1::needs_mesh_entities(unsigned int d) const
14875
 
{
14876
 
    switch ( d )
14877
 
    {
14878
 
    case 0:
14879
 
      return true;
14880
 
      break;
14881
 
    case 1:
14882
 
      return false;
14883
 
      break;
14884
 
    case 2:
14885
 
      return false;
14886
 
      break;
14887
 
    }
14888
 
    return false;
14889
 
}
14890
 
 
14891
 
/// Initialize dof map for mesh (return true iff init_cell() is needed)
14892
 
bool UFC_CahnHilliard2DLinearForm_dof_map_2_1::init_mesh(const ufc::mesh& m)
14893
 
{
14894
 
    __global_dimension = m.num_entities[0];
14895
 
    return false;
14896
 
}
14897
 
 
14898
 
/// Initialize dof map for given cell
14899
 
void UFC_CahnHilliard2DLinearForm_dof_map_2_1::init_cell(const ufc::mesh& m,
14900
 
                              const ufc::cell& c)
14901
 
{
14902
 
    // Do nothing
14903
 
}
14904
 
 
14905
 
/// Finish initialization of dof map for cells
14906
 
void UFC_CahnHilliard2DLinearForm_dof_map_2_1::init_cell_finalize()
14907
 
{
14908
 
    // Do nothing
14909
 
}
14910
 
 
14911
 
/// Return the dimension of the global finite element function space
14912
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2_1::global_dimension() const
14913
 
{
14914
 
    return __global_dimension;
14915
 
}
14916
 
 
14917
 
/// Return the dimension of the local finite element function space
14918
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2_1::local_dimension() const
14919
 
{
14920
 
    return 3;
14921
 
}
14922
 
 
14923
 
// Return the geometric dimension of the coordinates this dof map provides
14924
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2_1::geometric_dimension() const
14925
 
{
14926
 
    return 2;
14927
 
}
14928
 
 
14929
 
/// Return the number of dofs on each cell facet
14930
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2_1::num_facet_dofs() const
14931
 
{
14932
 
    return 2;
14933
 
}
14934
 
 
14935
 
/// Return the number of dofs associated with each cell entity of dimension d
14936
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2_1::num_entity_dofs(unsigned int d) const
14937
 
{
14938
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14939
 
}
14940
 
 
14941
 
/// Tabulate the local-to-global mapping of dofs on a cell
14942
 
void UFC_CahnHilliard2DLinearForm_dof_map_2_1::tabulate_dofs(unsigned int* dofs,
14943
 
                                  const ufc::mesh& m,
14944
 
                                  const ufc::cell& c) const
14945
 
{
14946
 
    dofs[0] = c.entity_indices[0][0];
14947
 
    dofs[1] = c.entity_indices[0][1];
14948
 
    dofs[2] = c.entity_indices[0][2];
14949
 
}
14950
 
 
14951
 
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
14952
 
void UFC_CahnHilliard2DLinearForm_dof_map_2_1::tabulate_facet_dofs(unsigned int* dofs,
14953
 
                                        unsigned int facet) const
14954
 
{
14955
 
    switch ( facet )
14956
 
    {
14957
 
    case 0:
14958
 
      dofs[0] = 1;
14959
 
      dofs[1] = 2;
14960
 
      break;
14961
 
    case 1:
14962
 
      dofs[0] = 0;
14963
 
      dofs[1] = 2;
14964
 
      break;
14965
 
    case 2:
14966
 
      dofs[0] = 0;
14967
 
      dofs[1] = 1;
14968
 
      break;
14969
 
    }
14970
 
}
14971
 
 
14972
 
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
14973
 
void UFC_CahnHilliard2DLinearForm_dof_map_2_1::tabulate_entity_dofs(unsigned int* dofs,
14974
 
                                  unsigned int d, unsigned int i) const
14975
 
{
14976
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
14977
 
}
14978
 
 
14979
 
/// Tabulate the coordinates of all dofs on a cell
14980
 
void UFC_CahnHilliard2DLinearForm_dof_map_2_1::tabulate_coordinates(double** coordinates,
14981
 
                                         const ufc::cell& c) const
14982
 
{
14983
 
    const double * const * x = c.coordinates;
14984
 
    coordinates[0][0] = x[0][0];
14985
 
    coordinates[0][1] = x[0][1];
14986
 
    coordinates[1][0] = x[1][0];
14987
 
    coordinates[1][1] = x[1][1];
14988
 
    coordinates[2][0] = x[2][0];
14989
 
    coordinates[2][1] = x[2][1];
14990
 
}
14991
 
 
14992
 
/// Return the number of sub dof maps (for a mixed element)
14993
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2_1::num_sub_dof_maps() const
14994
 
{
14995
 
    return 1;
14996
 
}
14997
 
 
14998
 
/// Create a new dof_map for sub dof map i (for a mixed element)
14999
 
ufc::dof_map* UFC_CahnHilliard2DLinearForm_dof_map_2_1::create_sub_dof_map(unsigned int i) const
15000
 
{
15001
 
    return new UFC_CahnHilliard2DLinearForm_dof_map_2_1();
15002
 
}
15003
 
 
15004
 
 
15005
 
/// Constructor
15006
 
UFC_CahnHilliard2DLinearForm_dof_map_2::UFC_CahnHilliard2DLinearForm_dof_map_2() : ufc::dof_map()
15007
 
{
15008
 
    __global_dimension = 0;
15009
 
}
15010
 
 
15011
 
/// Destructor
15012
 
UFC_CahnHilliard2DLinearForm_dof_map_2::~UFC_CahnHilliard2DLinearForm_dof_map_2()
15013
 
{
15014
 
    // Do nothing
15015
 
}
15016
 
 
15017
 
/// Return a string identifying the dof map
15018
 
const char* UFC_CahnHilliard2DLinearForm_dof_map_2::signature() const
15019
 
{
15020
 
    return "FFC dof map for MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
15021
 
}
15022
 
 
15023
 
/// Return true iff mesh entities of topological dimension d are needed
15024
 
bool UFC_CahnHilliard2DLinearForm_dof_map_2::needs_mesh_entities(unsigned int d) const
15025
 
{
15026
 
    switch ( d )
15027
 
    {
15028
 
    case 0:
15029
 
      return true;
15030
 
      break;
15031
 
    case 1:
15032
 
      return false;
15033
 
      break;
15034
 
    case 2:
15035
 
      return false;
15036
 
      break;
15037
 
    }
15038
 
    return false;
15039
 
}
15040
 
 
15041
 
/// Initialize dof map for mesh (return true iff init_cell() is needed)
15042
 
bool UFC_CahnHilliard2DLinearForm_dof_map_2::init_mesh(const ufc::mesh& m)
15043
 
{
15044
 
    __global_dimension = 2*m.num_entities[0];
15045
 
    return false;
15046
 
}
15047
 
 
15048
 
/// Initialize dof map for given cell
15049
 
void UFC_CahnHilliard2DLinearForm_dof_map_2::init_cell(const ufc::mesh& m,
15050
 
                              const ufc::cell& c)
15051
 
{
15052
 
    // Do nothing
15053
 
}
15054
 
 
15055
 
/// Finish initialization of dof map for cells
15056
 
void UFC_CahnHilliard2DLinearForm_dof_map_2::init_cell_finalize()
15057
 
{
15058
 
    // Do nothing
15059
 
}
15060
 
 
15061
 
/// Return the dimension of the global finite element function space
15062
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2::global_dimension() const
15063
 
{
15064
 
    return __global_dimension;
15065
 
}
15066
 
 
15067
 
/// Return the dimension of the local finite element function space
15068
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2::local_dimension() const
15069
 
{
15070
 
    return 6;
15071
 
}
15072
 
 
15073
 
// Return the geometric dimension of the coordinates this dof map provides
15074
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2::geometric_dimension() const
15075
 
{
15076
 
    return 2;
15077
 
}
15078
 
 
15079
 
/// Return the number of dofs on each cell facet
15080
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2::num_facet_dofs() const
15081
 
{
15082
 
    return 4;
15083
 
}
15084
 
 
15085
 
/// Return the number of dofs associated with each cell entity of dimension d
15086
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2::num_entity_dofs(unsigned int d) const
15087
 
{
15088
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15089
 
}
15090
 
 
15091
 
/// Tabulate the local-to-global mapping of dofs on a cell
15092
 
void UFC_CahnHilliard2DLinearForm_dof_map_2::tabulate_dofs(unsigned int* dofs,
15093
 
                                  const ufc::mesh& m,
15094
 
                                  const ufc::cell& c) const
15095
 
{
15096
 
    dofs[0] = c.entity_indices[0][0];
15097
 
    dofs[1] = c.entity_indices[0][1];
15098
 
    dofs[2] = c.entity_indices[0][2];
15099
 
    unsigned int offset = m.num_entities[0];
15100
 
    dofs[3] = offset + c.entity_indices[0][0];
15101
 
    dofs[4] = offset + c.entity_indices[0][1];
15102
 
    dofs[5] = offset + c.entity_indices[0][2];
15103
 
}
15104
 
 
15105
 
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
15106
 
void UFC_CahnHilliard2DLinearForm_dof_map_2::tabulate_facet_dofs(unsigned int* dofs,
15107
 
                                        unsigned int facet) const
15108
 
{
15109
 
    switch ( facet )
15110
 
    {
15111
 
    case 0:
15112
 
      dofs[0] = 1;
15113
 
      dofs[1] = 2;
15114
 
      dofs[2] = 4;
15115
 
      dofs[3] = 5;
15116
 
      break;
15117
 
    case 1:
15118
 
      dofs[0] = 0;
15119
 
      dofs[1] = 2;
15120
 
      dofs[2] = 3;
15121
 
      dofs[3] = 5;
15122
 
      break;
15123
 
    case 2:
15124
 
      dofs[0] = 0;
15125
 
      dofs[1] = 1;
15126
 
      dofs[2] = 3;
15127
 
      dofs[3] = 4;
15128
 
      break;
15129
 
    }
15130
 
}
15131
 
 
15132
 
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
15133
 
void UFC_CahnHilliard2DLinearForm_dof_map_2::tabulate_entity_dofs(unsigned int* dofs,
15134
 
                                  unsigned int d, unsigned int i) const
15135
 
{
15136
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15137
 
}
15138
 
 
15139
 
/// Tabulate the coordinates of all dofs on a cell
15140
 
void UFC_CahnHilliard2DLinearForm_dof_map_2::tabulate_coordinates(double** coordinates,
15141
 
                                         const ufc::cell& c) const
15142
 
{
15143
 
    const double * const * x = c.coordinates;
15144
 
    coordinates[0][0] = x[0][0];
15145
 
    coordinates[0][1] = x[0][1];
15146
 
    coordinates[1][0] = x[1][0];
15147
 
    coordinates[1][1] = x[1][1];
15148
 
    coordinates[2][0] = x[2][0];
15149
 
    coordinates[2][1] = x[2][1];
15150
 
    coordinates[3][0] = x[0][0];
15151
 
    coordinates[3][1] = x[0][1];
15152
 
    coordinates[4][0] = x[1][0];
15153
 
    coordinates[4][1] = x[1][1];
15154
 
    coordinates[5][0] = x[2][0];
15155
 
    coordinates[5][1] = x[2][1];
15156
 
}
15157
 
 
15158
 
/// Return the number of sub dof maps (for a mixed element)
15159
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_2::num_sub_dof_maps() const
15160
 
{
15161
 
    return 2;
15162
 
}
15163
 
 
15164
 
/// Create a new dof_map for sub dof map i (for a mixed element)
15165
 
ufc::dof_map* UFC_CahnHilliard2DLinearForm_dof_map_2::create_sub_dof_map(unsigned int i) const
15166
 
{
15167
 
    switch ( i )
15168
 
    {
15169
 
    case 0:
15170
 
      return new UFC_CahnHilliard2DLinearForm_dof_map_2_0();
15171
 
      break;
15172
 
    case 1:
15173
 
      return new UFC_CahnHilliard2DLinearForm_dof_map_2_1();
15174
 
      break;
15175
 
    }
15176
 
    return 0;
15177
 
}
15178
 
 
15179
 
 
15180
 
/// Constructor
15181
 
UFC_CahnHilliard2DLinearForm_dof_map_3::UFC_CahnHilliard2DLinearForm_dof_map_3() : ufc::dof_map()
15182
 
{
15183
 
    __global_dimension = 0;
15184
 
}
15185
 
 
15186
 
/// Destructor
15187
 
UFC_CahnHilliard2DLinearForm_dof_map_3::~UFC_CahnHilliard2DLinearForm_dof_map_3()
15188
 
{
15189
 
    // Do nothing
15190
 
}
15191
 
 
15192
 
/// Return a string identifying the dof map
15193
 
const char* UFC_CahnHilliard2DLinearForm_dof_map_3::signature() const
15194
 
{
15195
 
    return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
15196
 
}
15197
 
 
15198
 
/// Return true iff mesh entities of topological dimension d are needed
15199
 
bool UFC_CahnHilliard2DLinearForm_dof_map_3::needs_mesh_entities(unsigned int d) const
15200
 
{
15201
 
    switch ( d )
15202
 
    {
15203
 
    case 0:
15204
 
      return false;
15205
 
      break;
15206
 
    case 1:
15207
 
      return false;
15208
 
      break;
15209
 
    case 2:
15210
 
      return true;
15211
 
      break;
15212
 
    }
15213
 
    return false;
15214
 
}
15215
 
 
15216
 
/// Initialize dof map for mesh (return true iff init_cell() is needed)
15217
 
bool UFC_CahnHilliard2DLinearForm_dof_map_3::init_mesh(const ufc::mesh& m)
15218
 
{
15219
 
    __global_dimension = m.num_entities[2];
15220
 
    return false;
15221
 
}
15222
 
 
15223
 
/// Initialize dof map for given cell
15224
 
void UFC_CahnHilliard2DLinearForm_dof_map_3::init_cell(const ufc::mesh& m,
15225
 
                              const ufc::cell& c)
15226
 
{
15227
 
    // Do nothing
15228
 
}
15229
 
 
15230
 
/// Finish initialization of dof map for cells
15231
 
void UFC_CahnHilliard2DLinearForm_dof_map_3::init_cell_finalize()
15232
 
{
15233
 
    // Do nothing
15234
 
}
15235
 
 
15236
 
/// Return the dimension of the global finite element function space
15237
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_3::global_dimension() const
15238
 
{
15239
 
    return __global_dimension;
15240
 
}
15241
 
 
15242
 
/// Return the dimension of the local finite element function space
15243
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_3::local_dimension() const
15244
 
{
15245
 
    return 1;
15246
 
}
15247
 
 
15248
 
// Return the geometric dimension of the coordinates this dof map provides
15249
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_3::geometric_dimension() const
15250
 
{
15251
 
    return 2;
15252
 
}
15253
 
 
15254
 
/// Return the number of dofs on each cell facet
15255
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_3::num_facet_dofs() const
15256
 
{
15257
 
    return 0;
15258
 
}
15259
 
 
15260
 
/// Return the number of dofs associated with each cell entity of dimension d
15261
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_3::num_entity_dofs(unsigned int d) const
15262
 
{
15263
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15264
 
}
15265
 
 
15266
 
/// Tabulate the local-to-global mapping of dofs on a cell
15267
 
void UFC_CahnHilliard2DLinearForm_dof_map_3::tabulate_dofs(unsigned int* dofs,
15268
 
                                  const ufc::mesh& m,
15269
 
                                  const ufc::cell& c) const
15270
 
{
15271
 
    dofs[0] = c.entity_indices[2][0];
15272
 
}
15273
 
 
15274
 
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
15275
 
void UFC_CahnHilliard2DLinearForm_dof_map_3::tabulate_facet_dofs(unsigned int* dofs,
15276
 
                                        unsigned int facet) const
15277
 
{
15278
 
    switch ( facet )
15279
 
    {
15280
 
    case 0:
15281
 
      
15282
 
      break;
15283
 
    case 1:
15284
 
      
15285
 
      break;
15286
 
    case 2:
15287
 
      
15288
 
      break;
15289
 
    }
15290
 
}
15291
 
 
15292
 
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
15293
 
void UFC_CahnHilliard2DLinearForm_dof_map_3::tabulate_entity_dofs(unsigned int* dofs,
15294
 
                                  unsigned int d, unsigned int i) const
15295
 
{
15296
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15297
 
}
15298
 
 
15299
 
/// Tabulate the coordinates of all dofs on a cell
15300
 
void UFC_CahnHilliard2DLinearForm_dof_map_3::tabulate_coordinates(double** coordinates,
15301
 
                                         const ufc::cell& c) const
15302
 
{
15303
 
    const double * const * x = c.coordinates;
15304
 
    coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
15305
 
    coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
15306
 
}
15307
 
 
15308
 
/// Return the number of sub dof maps (for a mixed element)
15309
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_3::num_sub_dof_maps() const
15310
 
{
15311
 
    return 1;
15312
 
}
15313
 
 
15314
 
/// Create a new dof_map for sub dof map i (for a mixed element)
15315
 
ufc::dof_map* UFC_CahnHilliard2DLinearForm_dof_map_3::create_sub_dof_map(unsigned int i) const
15316
 
{
15317
 
    return new UFC_CahnHilliard2DLinearForm_dof_map_3();
15318
 
}
15319
 
 
15320
 
 
15321
 
/// Constructor
15322
 
UFC_CahnHilliard2DLinearForm_dof_map_4::UFC_CahnHilliard2DLinearForm_dof_map_4() : ufc::dof_map()
15323
 
{
15324
 
    __global_dimension = 0;
15325
 
}
15326
 
 
15327
 
/// Destructor
15328
 
UFC_CahnHilliard2DLinearForm_dof_map_4::~UFC_CahnHilliard2DLinearForm_dof_map_4()
15329
 
{
15330
 
    // Do nothing
15331
 
}
15332
 
 
15333
 
/// Return a string identifying the dof map
15334
 
const char* UFC_CahnHilliard2DLinearForm_dof_map_4::signature() const
15335
 
{
15336
 
    return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
15337
 
}
15338
 
 
15339
 
/// Return true iff mesh entities of topological dimension d are needed
15340
 
bool UFC_CahnHilliard2DLinearForm_dof_map_4::needs_mesh_entities(unsigned int d) const
15341
 
{
15342
 
    switch ( d )
15343
 
    {
15344
 
    case 0:
15345
 
      return false;
15346
 
      break;
15347
 
    case 1:
15348
 
      return false;
15349
 
      break;
15350
 
    case 2:
15351
 
      return true;
15352
 
      break;
15353
 
    }
15354
 
    return false;
15355
 
}
15356
 
 
15357
 
/// Initialize dof map for mesh (return true iff init_cell() is needed)
15358
 
bool UFC_CahnHilliard2DLinearForm_dof_map_4::init_mesh(const ufc::mesh& m)
15359
 
{
15360
 
    __global_dimension = m.num_entities[2];
15361
 
    return false;
15362
 
}
15363
 
 
15364
 
/// Initialize dof map for given cell
15365
 
void UFC_CahnHilliard2DLinearForm_dof_map_4::init_cell(const ufc::mesh& m,
15366
 
                              const ufc::cell& c)
15367
 
{
15368
 
    // Do nothing
15369
 
}
15370
 
 
15371
 
/// Finish initialization of dof map for cells
15372
 
void UFC_CahnHilliard2DLinearForm_dof_map_4::init_cell_finalize()
15373
 
{
15374
 
    // Do nothing
15375
 
}
15376
 
 
15377
 
/// Return the dimension of the global finite element function space
15378
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_4::global_dimension() const
15379
 
{
15380
 
    return __global_dimension;
15381
 
}
15382
 
 
15383
 
/// Return the dimension of the local finite element function space
15384
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_4::local_dimension() const
15385
 
{
15386
 
    return 1;
15387
 
}
15388
 
 
15389
 
// Return the geometric dimension of the coordinates this dof map provides
15390
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_4::geometric_dimension() const
15391
 
{
15392
 
    return 2;
15393
 
}
15394
 
 
15395
 
/// Return the number of dofs on each cell facet
15396
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_4::num_facet_dofs() const
15397
 
{
15398
 
    return 0;
15399
 
}
15400
 
 
15401
 
/// Return the number of dofs associated with each cell entity of dimension d
15402
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_4::num_entity_dofs(unsigned int d) const
15403
 
{
15404
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15405
 
}
15406
 
 
15407
 
/// Tabulate the local-to-global mapping of dofs on a cell
15408
 
void UFC_CahnHilliard2DLinearForm_dof_map_4::tabulate_dofs(unsigned int* dofs,
15409
 
                                  const ufc::mesh& m,
15410
 
                                  const ufc::cell& c) const
15411
 
{
15412
 
    dofs[0] = c.entity_indices[2][0];
15413
 
}
15414
 
 
15415
 
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
15416
 
void UFC_CahnHilliard2DLinearForm_dof_map_4::tabulate_facet_dofs(unsigned int* dofs,
15417
 
                                        unsigned int facet) const
15418
 
{
15419
 
    switch ( facet )
15420
 
    {
15421
 
    case 0:
15422
 
      
15423
 
      break;
15424
 
    case 1:
15425
 
      
15426
 
      break;
15427
 
    case 2:
15428
 
      
15429
 
      break;
15430
 
    }
15431
 
}
15432
 
 
15433
 
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
15434
 
void UFC_CahnHilliard2DLinearForm_dof_map_4::tabulate_entity_dofs(unsigned int* dofs,
15435
 
                                  unsigned int d, unsigned int i) const
15436
 
{
15437
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15438
 
}
15439
 
 
15440
 
/// Tabulate the coordinates of all dofs on a cell
15441
 
void UFC_CahnHilliard2DLinearForm_dof_map_4::tabulate_coordinates(double** coordinates,
15442
 
                                         const ufc::cell& c) const
15443
 
{
15444
 
    const double * const * x = c.coordinates;
15445
 
    coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
15446
 
    coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
15447
 
}
15448
 
 
15449
 
/// Return the number of sub dof maps (for a mixed element)
15450
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_4::num_sub_dof_maps() const
15451
 
{
15452
 
    return 1;
15453
 
}
15454
 
 
15455
 
/// Create a new dof_map for sub dof map i (for a mixed element)
15456
 
ufc::dof_map* UFC_CahnHilliard2DLinearForm_dof_map_4::create_sub_dof_map(unsigned int i) const
15457
 
{
15458
 
    return new UFC_CahnHilliard2DLinearForm_dof_map_4();
15459
 
}
15460
 
 
15461
 
 
15462
 
/// Constructor
15463
 
UFC_CahnHilliard2DLinearForm_dof_map_5::UFC_CahnHilliard2DLinearForm_dof_map_5() : ufc::dof_map()
15464
 
{
15465
 
    __global_dimension = 0;
15466
 
}
15467
 
 
15468
 
/// Destructor
15469
 
UFC_CahnHilliard2DLinearForm_dof_map_5::~UFC_CahnHilliard2DLinearForm_dof_map_5()
15470
 
{
15471
 
    // Do nothing
15472
 
}
15473
 
 
15474
 
/// Return a string identifying the dof map
15475
 
const char* UFC_CahnHilliard2DLinearForm_dof_map_5::signature() const
15476
 
{
15477
 
    return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
15478
 
}
15479
 
 
15480
 
/// Return true iff mesh entities of topological dimension d are needed
15481
 
bool UFC_CahnHilliard2DLinearForm_dof_map_5::needs_mesh_entities(unsigned int d) const
15482
 
{
15483
 
    switch ( d )
15484
 
    {
15485
 
    case 0:
15486
 
      return false;
15487
 
      break;
15488
 
    case 1:
15489
 
      return false;
15490
 
      break;
15491
 
    case 2:
15492
 
      return true;
15493
 
      break;
15494
 
    }
15495
 
    return false;
15496
 
}
15497
 
 
15498
 
/// Initialize dof map for mesh (return true iff init_cell() is needed)
15499
 
bool UFC_CahnHilliard2DLinearForm_dof_map_5::init_mesh(const ufc::mesh& m)
15500
 
{
15501
 
    __global_dimension = m.num_entities[2];
15502
 
    return false;
15503
 
}
15504
 
 
15505
 
/// Initialize dof map for given cell
15506
 
void UFC_CahnHilliard2DLinearForm_dof_map_5::init_cell(const ufc::mesh& m,
15507
 
                              const ufc::cell& c)
15508
 
{
15509
 
    // Do nothing
15510
 
}
15511
 
 
15512
 
/// Finish initialization of dof map for cells
15513
 
void UFC_CahnHilliard2DLinearForm_dof_map_5::init_cell_finalize()
15514
 
{
15515
 
    // Do nothing
15516
 
}
15517
 
 
15518
 
/// Return the dimension of the global finite element function space
15519
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_5::global_dimension() const
15520
 
{
15521
 
    return __global_dimension;
15522
 
}
15523
 
 
15524
 
/// Return the dimension of the local finite element function space
15525
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_5::local_dimension() const
15526
 
{
15527
 
    return 1;
15528
 
}
15529
 
 
15530
 
// Return the geometric dimension of the coordinates this dof map provides
15531
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_5::geometric_dimension() const
15532
 
{
15533
 
    return 2;
15534
 
}
15535
 
 
15536
 
/// Return the number of dofs on each cell facet
15537
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_5::num_facet_dofs() const
15538
 
{
15539
 
    return 0;
15540
 
}
15541
 
 
15542
 
/// Return the number of dofs associated with each cell entity of dimension d
15543
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_5::num_entity_dofs(unsigned int d) const
15544
 
{
15545
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15546
 
}
15547
 
 
15548
 
/// Tabulate the local-to-global mapping of dofs on a cell
15549
 
void UFC_CahnHilliard2DLinearForm_dof_map_5::tabulate_dofs(unsigned int* dofs,
15550
 
                                  const ufc::mesh& m,
15551
 
                                  const ufc::cell& c) const
15552
 
{
15553
 
    dofs[0] = c.entity_indices[2][0];
15554
 
}
15555
 
 
15556
 
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
15557
 
void UFC_CahnHilliard2DLinearForm_dof_map_5::tabulate_facet_dofs(unsigned int* dofs,
15558
 
                                        unsigned int facet) const
15559
 
{
15560
 
    switch ( facet )
15561
 
    {
15562
 
    case 0:
15563
 
      
15564
 
      break;
15565
 
    case 1:
15566
 
      
15567
 
      break;
15568
 
    case 2:
15569
 
      
15570
 
      break;
15571
 
    }
15572
 
}
15573
 
 
15574
 
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
15575
 
void UFC_CahnHilliard2DLinearForm_dof_map_5::tabulate_entity_dofs(unsigned int* dofs,
15576
 
                                  unsigned int d, unsigned int i) const
15577
 
{
15578
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15579
 
}
15580
 
 
15581
 
/// Tabulate the coordinates of all dofs on a cell
15582
 
void UFC_CahnHilliard2DLinearForm_dof_map_5::tabulate_coordinates(double** coordinates,
15583
 
                                         const ufc::cell& c) const
15584
 
{
15585
 
    const double * const * x = c.coordinates;
15586
 
    coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
15587
 
    coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
15588
 
}
15589
 
 
15590
 
/// Return the number of sub dof maps (for a mixed element)
15591
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_5::num_sub_dof_maps() const
15592
 
{
15593
 
    return 1;
15594
 
}
15595
 
 
15596
 
/// Create a new dof_map for sub dof map i (for a mixed element)
15597
 
ufc::dof_map* UFC_CahnHilliard2DLinearForm_dof_map_5::create_sub_dof_map(unsigned int i) const
15598
 
{
15599
 
    return new UFC_CahnHilliard2DLinearForm_dof_map_5();
15600
 
}
15601
 
 
15602
 
 
15603
 
/// Constructor
15604
 
UFC_CahnHilliard2DLinearForm_dof_map_6::UFC_CahnHilliard2DLinearForm_dof_map_6() : ufc::dof_map()
15605
 
{
15606
 
    __global_dimension = 0;
15607
 
}
15608
 
 
15609
 
/// Destructor
15610
 
UFC_CahnHilliard2DLinearForm_dof_map_6::~UFC_CahnHilliard2DLinearForm_dof_map_6()
15611
 
{
15612
 
    // Do nothing
15613
 
}
15614
 
 
15615
 
/// Return a string identifying the dof map
15616
 
const char* UFC_CahnHilliard2DLinearForm_dof_map_6::signature() const
15617
 
{
15618
 
    return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
15619
 
}
15620
 
 
15621
 
/// Return true iff mesh entities of topological dimension d are needed
15622
 
bool UFC_CahnHilliard2DLinearForm_dof_map_6::needs_mesh_entities(unsigned int d) const
15623
 
{
15624
 
    switch ( d )
15625
 
    {
15626
 
    case 0:
15627
 
      return false;
15628
 
      break;
15629
 
    case 1:
15630
 
      return false;
15631
 
      break;
15632
 
    case 2:
15633
 
      return true;
15634
 
      break;
15635
 
    }
15636
 
    return false;
15637
 
}
15638
 
 
15639
 
/// Initialize dof map for mesh (return true iff init_cell() is needed)
15640
 
bool UFC_CahnHilliard2DLinearForm_dof_map_6::init_mesh(const ufc::mesh& m)
15641
 
{
15642
 
    __global_dimension = m.num_entities[2];
15643
 
    return false;
15644
 
}
15645
 
 
15646
 
/// Initialize dof map for given cell
15647
 
void UFC_CahnHilliard2DLinearForm_dof_map_6::init_cell(const ufc::mesh& m,
15648
 
                              const ufc::cell& c)
15649
 
{
15650
 
    // Do nothing
15651
 
}
15652
 
 
15653
 
/// Finish initialization of dof map for cells
15654
 
void UFC_CahnHilliard2DLinearForm_dof_map_6::init_cell_finalize()
15655
 
{
15656
 
    // Do nothing
15657
 
}
15658
 
 
15659
 
/// Return the dimension of the global finite element function space
15660
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_6::global_dimension() const
15661
 
{
15662
 
    return __global_dimension;
15663
 
}
15664
 
 
15665
 
/// Return the dimension of the local finite element function space
15666
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_6::local_dimension() const
15667
 
{
15668
 
    return 1;
15669
 
}
15670
 
 
15671
 
// Return the geometric dimension of the coordinates this dof map provides
15672
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_6::geometric_dimension() const
15673
 
{
15674
 
    return 2;
15675
 
}
15676
 
 
15677
 
/// Return the number of dofs on each cell facet
15678
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_6::num_facet_dofs() const
15679
 
{
15680
 
    return 0;
15681
 
}
15682
 
 
15683
 
/// Return the number of dofs associated with each cell entity of dimension d
15684
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_6::num_entity_dofs(unsigned int d) const
15685
 
{
15686
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15687
 
}
15688
 
 
15689
 
/// Tabulate the local-to-global mapping of dofs on a cell
15690
 
void UFC_CahnHilliard2DLinearForm_dof_map_6::tabulate_dofs(unsigned int* dofs,
15691
 
                                  const ufc::mesh& m,
15692
 
                                  const ufc::cell& c) const
15693
 
{
15694
 
    dofs[0] = c.entity_indices[2][0];
15695
 
}
15696
 
 
15697
 
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
15698
 
void UFC_CahnHilliard2DLinearForm_dof_map_6::tabulate_facet_dofs(unsigned int* dofs,
15699
 
                                        unsigned int facet) const
15700
 
{
15701
 
    switch ( facet )
15702
 
    {
15703
 
    case 0:
15704
 
      
15705
 
      break;
15706
 
    case 1:
15707
 
      
15708
 
      break;
15709
 
    case 2:
15710
 
      
15711
 
      break;
15712
 
    }
15713
 
}
15714
 
 
15715
 
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
15716
 
void UFC_CahnHilliard2DLinearForm_dof_map_6::tabulate_entity_dofs(unsigned int* dofs,
15717
 
                                  unsigned int d, unsigned int i) const
15718
 
{
15719
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
15720
 
}
15721
 
 
15722
 
/// Tabulate the coordinates of all dofs on a cell
15723
 
void UFC_CahnHilliard2DLinearForm_dof_map_6::tabulate_coordinates(double** coordinates,
15724
 
                                         const ufc::cell& c) const
15725
 
{
15726
 
    const double * const * x = c.coordinates;
15727
 
    coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
15728
 
    coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
15729
 
}
15730
 
 
15731
 
/// Return the number of sub dof maps (for a mixed element)
15732
 
unsigned int UFC_CahnHilliard2DLinearForm_dof_map_6::num_sub_dof_maps() const
15733
 
{
15734
 
    return 1;
15735
 
}
15736
 
 
15737
 
/// Create a new dof_map for sub dof map i (for a mixed element)
15738
 
ufc::dof_map* UFC_CahnHilliard2DLinearForm_dof_map_6::create_sub_dof_map(unsigned int i) const
15739
 
{
15740
 
    return new UFC_CahnHilliard2DLinearForm_dof_map_6();
15741
 
}
15742
 
 
15743
 
 
15744
 
/// Constructor
15745
 
UFC_CahnHilliard2DLinearForm_cell_integral_0::UFC_CahnHilliard2DLinearForm_cell_integral_0() : ufc::cell_integral()
15746
 
{
15747
 
    // Do nothing
15748
 
}
15749
 
 
15750
 
/// Destructor
15751
 
UFC_CahnHilliard2DLinearForm_cell_integral_0::~UFC_CahnHilliard2DLinearForm_cell_integral_0()
 
8148
ufc::interior_facet_integral* cahnhilliard2d_form_0::create_interior_facet_integral(unsigned int i) const
 
8149
{
 
8150
    return 0;
 
8151
}
 
8152
 
 
8153
 
 
8154
/// Constructor
 
8155
cahnhilliard2d_1_finite_element_0_0::cahnhilliard2d_1_finite_element_0_0() : ufc::finite_element()
 
8156
{
 
8157
    // Do nothing
 
8158
}
 
8159
 
 
8160
/// Destructor
 
8161
cahnhilliard2d_1_finite_element_0_0::~cahnhilliard2d_1_finite_element_0_0()
 
8162
{
 
8163
    // Do nothing
 
8164
}
 
8165
 
 
8166
/// Return a string identifying the finite element
 
8167
const char* cahnhilliard2d_1_finite_element_0_0::signature() const
 
8168
{
 
8169
    return "FiniteElement('Lagrange', 'triangle', 1)";
 
8170
}
 
8171
 
 
8172
/// Return the cell shape
 
8173
ufc::shape cahnhilliard2d_1_finite_element_0_0::cell_shape() const
 
8174
{
 
8175
    return ufc::triangle;
 
8176
}
 
8177
 
 
8178
/// Return the dimension of the finite element function space
 
8179
unsigned int cahnhilliard2d_1_finite_element_0_0::space_dimension() const
 
8180
{
 
8181
    return 3;
 
8182
}
 
8183
 
 
8184
/// Return the rank of the value space
 
8185
unsigned int cahnhilliard2d_1_finite_element_0_0::value_rank() const
 
8186
{
 
8187
    return 0;
 
8188
}
 
8189
 
 
8190
/// Return the dimension of the value space for axis i
 
8191
unsigned int cahnhilliard2d_1_finite_element_0_0::value_dimension(unsigned int i) const
 
8192
{
 
8193
    return 1;
 
8194
}
 
8195
 
 
8196
/// Evaluate basis function i at given point in cell
 
8197
void cahnhilliard2d_1_finite_element_0_0::evaluate_basis(unsigned int i,
 
8198
                                   double* values,
 
8199
                                   const double* coordinates,
 
8200
                                   const ufc::cell& c) const
 
8201
{
 
8202
    // Extract vertex coordinates
 
8203
    const double * const * element_coordinates = c.coordinates;
 
8204
    
 
8205
    // Compute Jacobian of affine map from reference cell
 
8206
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
8207
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
8208
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
8209
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
8210
    
 
8211
    // Compute determinant of Jacobian
 
8212
    const double detJ = J_00*J_11 - J_01*J_10;
 
8213
    
 
8214
    // Compute inverse of Jacobian
 
8215
    
 
8216
    // Get coordinates and map to the reference (UFC) element
 
8217
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
8218
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
8219
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
8220
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
8221
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
8222
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
8223
    
 
8224
    // Map coordinates to the reference square
 
8225
    if (std::abs(y - 1.0) < 1e-14)
 
8226
      x = -1.0;
 
8227
    else
 
8228
      x = 2.0 *x/(1.0 - y) - 1.0;
 
8229
    y = 2.0*y - 1.0;
 
8230
    
 
8231
    // Reset values
 
8232
    *values = 0;
 
8233
    
 
8234
    // Map degree of freedom to element degree of freedom
 
8235
    const unsigned int dof = i;
 
8236
    
 
8237
    // Generate scalings
 
8238
    const double scalings_y_0 = 1;
 
8239
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
8240
    
 
8241
    // Compute psitilde_a
 
8242
    const double psitilde_a_0 = 1;
 
8243
    const double psitilde_a_1 = x;
 
8244
    
 
8245
    // Compute psitilde_bs
 
8246
    const double psitilde_bs_0_0 = 1;
 
8247
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
8248
    const double psitilde_bs_1_0 = 1;
 
8249
    
 
8250
    // Compute basisvalues
 
8251
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
8252
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
8253
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
8254
    
 
8255
    // Table(s) of coefficients
 
8256
    static const double coefficients0[3][3] = \
 
8257
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
8258
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
8259
    {0.471404520791032, 0, 0.333333333333333}};
 
8260
    
 
8261
    // Extract relevant coefficients
 
8262
    const double coeff0_0 = coefficients0[dof][0];
 
8263
    const double coeff0_1 = coefficients0[dof][1];
 
8264
    const double coeff0_2 = coefficients0[dof][2];
 
8265
    
 
8266
    // Compute value(s)
 
8267
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
8268
}
 
8269
 
 
8270
/// Evaluate all basis functions at given point in cell
 
8271
void cahnhilliard2d_1_finite_element_0_0::evaluate_basis_all(double* values,
 
8272
                                       const double* coordinates,
 
8273
                                       const ufc::cell& c) const
 
8274
{
 
8275
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
8276
}
 
8277
 
 
8278
/// Evaluate order n derivatives of basis function i at given point in cell
 
8279
void cahnhilliard2d_1_finite_element_0_0::evaluate_basis_derivatives(unsigned int i,
 
8280
                                               unsigned int n,
 
8281
                                               double* values,
 
8282
                                               const double* coordinates,
 
8283
                                               const ufc::cell& c) const
 
8284
{
 
8285
    // Extract vertex coordinates
 
8286
    const double * const * element_coordinates = c.coordinates;
 
8287
    
 
8288
    // Compute Jacobian of affine map from reference cell
 
8289
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
8290
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
8291
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
8292
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
8293
    
 
8294
    // Compute determinant of Jacobian
 
8295
    const double detJ = J_00*J_11 - J_01*J_10;
 
8296
    
 
8297
    // Compute inverse of Jacobian
 
8298
    
 
8299
    // Get coordinates and map to the reference (UFC) element
 
8300
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
8301
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
8302
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
8303
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
8304
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
8305
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
8306
    
 
8307
    // Map coordinates to the reference square
 
8308
    if (std::abs(y - 1.0) < 1e-14)
 
8309
      x = -1.0;
 
8310
    else
 
8311
      x = 2.0 *x/(1.0 - y) - 1.0;
 
8312
    y = 2.0*y - 1.0;
 
8313
    
 
8314
    // Compute number of derivatives
 
8315
    unsigned int num_derivatives = 1;
 
8316
    
 
8317
    for (unsigned int j = 0; j < n; j++)
 
8318
      num_derivatives *= 2;
 
8319
    
 
8320
    
 
8321
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
8322
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
8323
    
 
8324
    for (unsigned int j = 0; j < num_derivatives; j++)
 
8325
    {
 
8326
      combinations[j] = new unsigned int [n];
 
8327
      for (unsigned int k = 0; k < n; k++)
 
8328
        combinations[j][k] = 0;
 
8329
    }
 
8330
    
 
8331
    // Generate combinations of derivatives
 
8332
    for (unsigned int row = 1; row < num_derivatives; row++)
 
8333
    {
 
8334
      for (unsigned int num = 0; num < row; num++)
 
8335
      {
 
8336
        for (unsigned int col = n-1; col+1 > 0; col--)
 
8337
        {
 
8338
          if (combinations[row][col] + 1 > 1)
 
8339
            combinations[row][col] = 0;
 
8340
          else
 
8341
          {
 
8342
            combinations[row][col] += 1;
 
8343
            break;
 
8344
          }
 
8345
        }
 
8346
      }
 
8347
    }
 
8348
    
 
8349
    // Compute inverse of Jacobian
 
8350
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
8351
    
 
8352
    // Declare transformation matrix
 
8353
    // Declare pointer to two dimensional array and initialise
 
8354
    double **transform = new double *[num_derivatives];
 
8355
    
 
8356
    for (unsigned int j = 0; j < num_derivatives; j++)
 
8357
    {
 
8358
      transform[j] = new double [num_derivatives];
 
8359
      for (unsigned int k = 0; k < num_derivatives; k++)
 
8360
        transform[j][k] = 1;
 
8361
    }
 
8362
    
 
8363
    // Construct transformation matrix
 
8364
    for (unsigned int row = 0; row < num_derivatives; row++)
 
8365
    {
 
8366
      for (unsigned int col = 0; col < num_derivatives; col++)
 
8367
      {
 
8368
        for (unsigned int k = 0; k < n; k++)
 
8369
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
8370
      }
 
8371
    }
 
8372
    
 
8373
    // Reset values
 
8374
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
 
8375
      values[j] = 0;
 
8376
    
 
8377
    // Map degree of freedom to element degree of freedom
 
8378
    const unsigned int dof = i;
 
8379
    
 
8380
    // Generate scalings
 
8381
    const double scalings_y_0 = 1;
 
8382
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
8383
    
 
8384
    // Compute psitilde_a
 
8385
    const double psitilde_a_0 = 1;
 
8386
    const double psitilde_a_1 = x;
 
8387
    
 
8388
    // Compute psitilde_bs
 
8389
    const double psitilde_bs_0_0 = 1;
 
8390
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
8391
    const double psitilde_bs_1_0 = 1;
 
8392
    
 
8393
    // Compute basisvalues
 
8394
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
8395
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
8396
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
8397
    
 
8398
    // Table(s) of coefficients
 
8399
    static const double coefficients0[3][3] = \
 
8400
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
8401
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
8402
    {0.471404520791032, 0, 0.333333333333333}};
 
8403
    
 
8404
    // Interesting (new) part
 
8405
    // Tables of derivatives of the polynomial base (transpose)
 
8406
    static const double dmats0[3][3] = \
 
8407
    {{0, 0, 0},
 
8408
    {4.89897948556636, 0, 0},
 
8409
    {0, 0, 0}};
 
8410
    
 
8411
    static const double dmats1[3][3] = \
 
8412
    {{0, 0, 0},
 
8413
    {2.44948974278318, 0, 0},
 
8414
    {4.24264068711928, 0, 0}};
 
8415
    
 
8416
    // Compute reference derivatives
 
8417
    // Declare pointer to array of derivatives on FIAT element
 
8418
    double *derivatives = new double [num_derivatives];
 
8419
    
 
8420
    // Declare coefficients
 
8421
    double coeff0_0 = 0;
 
8422
    double coeff0_1 = 0;
 
8423
    double coeff0_2 = 0;
 
8424
    
 
8425
    // Declare new coefficients
 
8426
    double new_coeff0_0 = 0;
 
8427
    double new_coeff0_1 = 0;
 
8428
    double new_coeff0_2 = 0;
 
8429
    
 
8430
    // Loop possible derivatives
 
8431
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
8432
    {
 
8433
      // Get values from coefficients array
 
8434
      new_coeff0_0 = coefficients0[dof][0];
 
8435
      new_coeff0_1 = coefficients0[dof][1];
 
8436
      new_coeff0_2 = coefficients0[dof][2];
 
8437
    
 
8438
      // Loop derivative order
 
8439
      for (unsigned int j = 0; j < n; j++)
 
8440
      {
 
8441
        // Update old coefficients
 
8442
        coeff0_0 = new_coeff0_0;
 
8443
        coeff0_1 = new_coeff0_1;
 
8444
        coeff0_2 = new_coeff0_2;
 
8445
    
 
8446
        if(combinations[deriv_num][j] == 0)
 
8447
        {
 
8448
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
8449
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
8450
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
8451
        }
 
8452
        if(combinations[deriv_num][j] == 1)
 
8453
        {
 
8454
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
8455
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
8456
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
8457
        }
 
8458
    
 
8459
      }
 
8460
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
8461
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
8462
    }
 
8463
    
 
8464
    // Transform derivatives back to physical element
 
8465
    for (unsigned int row = 0; row < num_derivatives; row++)
 
8466
    {
 
8467
      for (unsigned int col = 0; col < num_derivatives; col++)
 
8468
      {
 
8469
        values[row] += transform[row][col]*derivatives[col];
 
8470
      }
 
8471
    }
 
8472
    // Delete pointer to array of derivatives on FIAT element
 
8473
    delete [] derivatives;
 
8474
    
 
8475
    // Delete pointer to array of combinations of derivatives and transform
 
8476
    for (unsigned int row = 0; row < num_derivatives; row++)
 
8477
    {
 
8478
      delete [] combinations[row];
 
8479
      delete [] transform[row];
 
8480
    }
 
8481
    
 
8482
    delete [] combinations;
 
8483
    delete [] transform;
 
8484
}
 
8485
 
 
8486
/// Evaluate order n derivatives of all basis functions at given point in cell
 
8487
void cahnhilliard2d_1_finite_element_0_0::evaluate_basis_derivatives_all(unsigned int n,
 
8488
                                                   double* values,
 
8489
                                                   const double* coordinates,
 
8490
                                                   const ufc::cell& c) const
 
8491
{
 
8492
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
8493
}
 
8494
 
 
8495
/// Evaluate linear functional for dof i on the function f
 
8496
double cahnhilliard2d_1_finite_element_0_0::evaluate_dof(unsigned int i,
 
8497
                                   const ufc::function& f,
 
8498
                                   const ufc::cell& c) const
 
8499
{
 
8500
    // The reference points, direction and weights:
 
8501
    static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
 
8502
    static const double W[3][1] = {{1}, {1}, {1}};
 
8503
    static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
 
8504
    
 
8505
    const double * const * x = c.coordinates;
 
8506
    double result = 0.0;
 
8507
    // Iterate over the points:
 
8508
    // Evaluate basis functions for affine mapping
 
8509
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
8510
    const double w1 = X[i][0][0];
 
8511
    const double w2 = X[i][0][1];
 
8512
    
 
8513
    // Compute affine mapping y = F(X)
 
8514
    double y[2];
 
8515
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
8516
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
8517
    
 
8518
    // Evaluate function at physical points
 
8519
    double values[1];
 
8520
    f.evaluate(values, y, c);
 
8521
    
 
8522
    // Map function values using appropriate mapping
 
8523
    // Affine map: Do nothing
 
8524
    
 
8525
    // Note that we do not map the weights (yet).
 
8526
    
 
8527
    // Take directional components
 
8528
    for(int k = 0; k < 1; k++)
 
8529
      result += values[k]*D[i][0][k];
 
8530
    // Multiply by weights
 
8531
    result *= W[i][0];
 
8532
    
 
8533
    return result;
 
8534
}
 
8535
 
 
8536
/// Evaluate linear functionals for all dofs on the function f
 
8537
void cahnhilliard2d_1_finite_element_0_0::evaluate_dofs(double* values,
 
8538
                                  const ufc::function& f,
 
8539
                                  const ufc::cell& c) const
 
8540
{
 
8541
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
8542
}
 
8543
 
 
8544
/// Interpolate vertex values from dof values
 
8545
void cahnhilliard2d_1_finite_element_0_0::interpolate_vertex_values(double* vertex_values,
 
8546
                                              const double* dof_values,
 
8547
                                              const ufc::cell& c) const
 
8548
{
 
8549
    // Evaluate at vertices and use affine mapping
 
8550
    vertex_values[0] = dof_values[0];
 
8551
    vertex_values[1] = dof_values[1];
 
8552
    vertex_values[2] = dof_values[2];
 
8553
}
 
8554
 
 
8555
/// Return the number of sub elements (for a mixed element)
 
8556
unsigned int cahnhilliard2d_1_finite_element_0_0::num_sub_elements() const
 
8557
{
 
8558
    return 1;
 
8559
}
 
8560
 
 
8561
/// Create a new finite element for sub element i (for a mixed element)
 
8562
ufc::finite_element* cahnhilliard2d_1_finite_element_0_0::create_sub_element(unsigned int i) const
 
8563
{
 
8564
    return new cahnhilliard2d_1_finite_element_0_0();
 
8565
}
 
8566
 
 
8567
 
 
8568
/// Constructor
 
8569
cahnhilliard2d_1_finite_element_0_1::cahnhilliard2d_1_finite_element_0_1() : ufc::finite_element()
 
8570
{
 
8571
    // Do nothing
 
8572
}
 
8573
 
 
8574
/// Destructor
 
8575
cahnhilliard2d_1_finite_element_0_1::~cahnhilliard2d_1_finite_element_0_1()
 
8576
{
 
8577
    // Do nothing
 
8578
}
 
8579
 
 
8580
/// Return a string identifying the finite element
 
8581
const char* cahnhilliard2d_1_finite_element_0_1::signature() const
 
8582
{
 
8583
    return "FiniteElement('Lagrange', 'triangle', 1)";
 
8584
}
 
8585
 
 
8586
/// Return the cell shape
 
8587
ufc::shape cahnhilliard2d_1_finite_element_0_1::cell_shape() const
 
8588
{
 
8589
    return ufc::triangle;
 
8590
}
 
8591
 
 
8592
/// Return the dimension of the finite element function space
 
8593
unsigned int cahnhilliard2d_1_finite_element_0_1::space_dimension() const
 
8594
{
 
8595
    return 3;
 
8596
}
 
8597
 
 
8598
/// Return the rank of the value space
 
8599
unsigned int cahnhilliard2d_1_finite_element_0_1::value_rank() const
 
8600
{
 
8601
    return 0;
 
8602
}
 
8603
 
 
8604
/// Return the dimension of the value space for axis i
 
8605
unsigned int cahnhilliard2d_1_finite_element_0_1::value_dimension(unsigned int i) const
 
8606
{
 
8607
    return 1;
 
8608
}
 
8609
 
 
8610
/// Evaluate basis function i at given point in cell
 
8611
void cahnhilliard2d_1_finite_element_0_1::evaluate_basis(unsigned int i,
 
8612
                                   double* values,
 
8613
                                   const double* coordinates,
 
8614
                                   const ufc::cell& c) const
 
8615
{
 
8616
    // Extract vertex coordinates
 
8617
    const double * const * element_coordinates = c.coordinates;
 
8618
    
 
8619
    // Compute Jacobian of affine map from reference cell
 
8620
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
8621
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
8622
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
8623
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
8624
    
 
8625
    // Compute determinant of Jacobian
 
8626
    const double detJ = J_00*J_11 - J_01*J_10;
 
8627
    
 
8628
    // Compute inverse of Jacobian
 
8629
    
 
8630
    // Get coordinates and map to the reference (UFC) element
 
8631
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
8632
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
8633
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
8634
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
8635
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
8636
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
8637
    
 
8638
    // Map coordinates to the reference square
 
8639
    if (std::abs(y - 1.0) < 1e-14)
 
8640
      x = -1.0;
 
8641
    else
 
8642
      x = 2.0 *x/(1.0 - y) - 1.0;
 
8643
    y = 2.0*y - 1.0;
 
8644
    
 
8645
    // Reset values
 
8646
    *values = 0;
 
8647
    
 
8648
    // Map degree of freedom to element degree of freedom
 
8649
    const unsigned int dof = i;
 
8650
    
 
8651
    // Generate scalings
 
8652
    const double scalings_y_0 = 1;
 
8653
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
8654
    
 
8655
    // Compute psitilde_a
 
8656
    const double psitilde_a_0 = 1;
 
8657
    const double psitilde_a_1 = x;
 
8658
    
 
8659
    // Compute psitilde_bs
 
8660
    const double psitilde_bs_0_0 = 1;
 
8661
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
8662
    const double psitilde_bs_1_0 = 1;
 
8663
    
 
8664
    // Compute basisvalues
 
8665
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
8666
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
8667
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
8668
    
 
8669
    // Table(s) of coefficients
 
8670
    static const double coefficients0[3][3] = \
 
8671
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
8672
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
8673
    {0.471404520791032, 0, 0.333333333333333}};
 
8674
    
 
8675
    // Extract relevant coefficients
 
8676
    const double coeff0_0 = coefficients0[dof][0];
 
8677
    const double coeff0_1 = coefficients0[dof][1];
 
8678
    const double coeff0_2 = coefficients0[dof][2];
 
8679
    
 
8680
    // Compute value(s)
 
8681
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
8682
}
 
8683
 
 
8684
/// Evaluate all basis functions at given point in cell
 
8685
void cahnhilliard2d_1_finite_element_0_1::evaluate_basis_all(double* values,
 
8686
                                       const double* coordinates,
 
8687
                                       const ufc::cell& c) const
 
8688
{
 
8689
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
8690
}
 
8691
 
 
8692
/// Evaluate order n derivatives of basis function i at given point in cell
 
8693
void cahnhilliard2d_1_finite_element_0_1::evaluate_basis_derivatives(unsigned int i,
 
8694
                                               unsigned int n,
 
8695
                                               double* values,
 
8696
                                               const double* coordinates,
 
8697
                                               const ufc::cell& c) const
 
8698
{
 
8699
    // Extract vertex coordinates
 
8700
    const double * const * element_coordinates = c.coordinates;
 
8701
    
 
8702
    // Compute Jacobian of affine map from reference cell
 
8703
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
8704
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
8705
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
8706
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
8707
    
 
8708
    // Compute determinant of Jacobian
 
8709
    const double detJ = J_00*J_11 - J_01*J_10;
 
8710
    
 
8711
    // Compute inverse of Jacobian
 
8712
    
 
8713
    // Get coordinates and map to the reference (UFC) element
 
8714
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
8715
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
8716
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
8717
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
8718
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
8719
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
8720
    
 
8721
    // Map coordinates to the reference square
 
8722
    if (std::abs(y - 1.0) < 1e-14)
 
8723
      x = -1.0;
 
8724
    else
 
8725
      x = 2.0 *x/(1.0 - y) - 1.0;
 
8726
    y = 2.0*y - 1.0;
 
8727
    
 
8728
    // Compute number of derivatives
 
8729
    unsigned int num_derivatives = 1;
 
8730
    
 
8731
    for (unsigned int j = 0; j < n; j++)
 
8732
      num_derivatives *= 2;
 
8733
    
 
8734
    
 
8735
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
8736
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
8737
    
 
8738
    for (unsigned int j = 0; j < num_derivatives; j++)
 
8739
    {
 
8740
      combinations[j] = new unsigned int [n];
 
8741
      for (unsigned int k = 0; k < n; k++)
 
8742
        combinations[j][k] = 0;
 
8743
    }
 
8744
    
 
8745
    // Generate combinations of derivatives
 
8746
    for (unsigned int row = 1; row < num_derivatives; row++)
 
8747
    {
 
8748
      for (unsigned int num = 0; num < row; num++)
 
8749
      {
 
8750
        for (unsigned int col = n-1; col+1 > 0; col--)
 
8751
        {
 
8752
          if (combinations[row][col] + 1 > 1)
 
8753
            combinations[row][col] = 0;
 
8754
          else
 
8755
          {
 
8756
            combinations[row][col] += 1;
 
8757
            break;
 
8758
          }
 
8759
        }
 
8760
      }
 
8761
    }
 
8762
    
 
8763
    // Compute inverse of Jacobian
 
8764
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
8765
    
 
8766
    // Declare transformation matrix
 
8767
    // Declare pointer to two dimensional array and initialise
 
8768
    double **transform = new double *[num_derivatives];
 
8769
    
 
8770
    for (unsigned int j = 0; j < num_derivatives; j++)
 
8771
    {
 
8772
      transform[j] = new double [num_derivatives];
 
8773
      for (unsigned int k = 0; k < num_derivatives; k++)
 
8774
        transform[j][k] = 1;
 
8775
    }
 
8776
    
 
8777
    // Construct transformation matrix
 
8778
    for (unsigned int row = 0; row < num_derivatives; row++)
 
8779
    {
 
8780
      for (unsigned int col = 0; col < num_derivatives; col++)
 
8781
      {
 
8782
        for (unsigned int k = 0; k < n; k++)
 
8783
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
8784
      }
 
8785
    }
 
8786
    
 
8787
    // Reset values
 
8788
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
 
8789
      values[j] = 0;
 
8790
    
 
8791
    // Map degree of freedom to element degree of freedom
 
8792
    const unsigned int dof = i;
 
8793
    
 
8794
    // Generate scalings
 
8795
    const double scalings_y_0 = 1;
 
8796
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
8797
    
 
8798
    // Compute psitilde_a
 
8799
    const double psitilde_a_0 = 1;
 
8800
    const double psitilde_a_1 = x;
 
8801
    
 
8802
    // Compute psitilde_bs
 
8803
    const double psitilde_bs_0_0 = 1;
 
8804
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
8805
    const double psitilde_bs_1_0 = 1;
 
8806
    
 
8807
    // Compute basisvalues
 
8808
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
8809
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
8810
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
8811
    
 
8812
    // Table(s) of coefficients
 
8813
    static const double coefficients0[3][3] = \
 
8814
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
8815
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
8816
    {0.471404520791032, 0, 0.333333333333333}};
 
8817
    
 
8818
    // Interesting (new) part
 
8819
    // Tables of derivatives of the polynomial base (transpose)
 
8820
    static const double dmats0[3][3] = \
 
8821
    {{0, 0, 0},
 
8822
    {4.89897948556636, 0, 0},
 
8823
    {0, 0, 0}};
 
8824
    
 
8825
    static const double dmats1[3][3] = \
 
8826
    {{0, 0, 0},
 
8827
    {2.44948974278318, 0, 0},
 
8828
    {4.24264068711928, 0, 0}};
 
8829
    
 
8830
    // Compute reference derivatives
 
8831
    // Declare pointer to array of derivatives on FIAT element
 
8832
    double *derivatives = new double [num_derivatives];
 
8833
    
 
8834
    // Declare coefficients
 
8835
    double coeff0_0 = 0;
 
8836
    double coeff0_1 = 0;
 
8837
    double coeff0_2 = 0;
 
8838
    
 
8839
    // Declare new coefficients
 
8840
    double new_coeff0_0 = 0;
 
8841
    double new_coeff0_1 = 0;
 
8842
    double new_coeff0_2 = 0;
 
8843
    
 
8844
    // Loop possible derivatives
 
8845
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
8846
    {
 
8847
      // Get values from coefficients array
 
8848
      new_coeff0_0 = coefficients0[dof][0];
 
8849
      new_coeff0_1 = coefficients0[dof][1];
 
8850
      new_coeff0_2 = coefficients0[dof][2];
 
8851
    
 
8852
      // Loop derivative order
 
8853
      for (unsigned int j = 0; j < n; j++)
 
8854
      {
 
8855
        // Update old coefficients
 
8856
        coeff0_0 = new_coeff0_0;
 
8857
        coeff0_1 = new_coeff0_1;
 
8858
        coeff0_2 = new_coeff0_2;
 
8859
    
 
8860
        if(combinations[deriv_num][j] == 0)
 
8861
        {
 
8862
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
8863
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
8864
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
8865
        }
 
8866
        if(combinations[deriv_num][j] == 1)
 
8867
        {
 
8868
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
8869
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
8870
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
8871
        }
 
8872
    
 
8873
      }
 
8874
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
8875
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
8876
    }
 
8877
    
 
8878
    // Transform derivatives back to physical element
 
8879
    for (unsigned int row = 0; row < num_derivatives; row++)
 
8880
    {
 
8881
      for (unsigned int col = 0; col < num_derivatives; col++)
 
8882
      {
 
8883
        values[row] += transform[row][col]*derivatives[col];
 
8884
      }
 
8885
    }
 
8886
    // Delete pointer to array of derivatives on FIAT element
 
8887
    delete [] derivatives;
 
8888
    
 
8889
    // Delete pointer to array of combinations of derivatives and transform
 
8890
    for (unsigned int row = 0; row < num_derivatives; row++)
 
8891
    {
 
8892
      delete [] combinations[row];
 
8893
      delete [] transform[row];
 
8894
    }
 
8895
    
 
8896
    delete [] combinations;
 
8897
    delete [] transform;
 
8898
}
 
8899
 
 
8900
/// Evaluate order n derivatives of all basis functions at given point in cell
 
8901
void cahnhilliard2d_1_finite_element_0_1::evaluate_basis_derivatives_all(unsigned int n,
 
8902
                                                   double* values,
 
8903
                                                   const double* coordinates,
 
8904
                                                   const ufc::cell& c) const
 
8905
{
 
8906
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
8907
}
 
8908
 
 
8909
/// Evaluate linear functional for dof i on the function f
 
8910
double cahnhilliard2d_1_finite_element_0_1::evaluate_dof(unsigned int i,
 
8911
                                   const ufc::function& f,
 
8912
                                   const ufc::cell& c) const
 
8913
{
 
8914
    // The reference points, direction and weights:
 
8915
    static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
 
8916
    static const double W[3][1] = {{1}, {1}, {1}};
 
8917
    static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
 
8918
    
 
8919
    const double * const * x = c.coordinates;
 
8920
    double result = 0.0;
 
8921
    // Iterate over the points:
 
8922
    // Evaluate basis functions for affine mapping
 
8923
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
8924
    const double w1 = X[i][0][0];
 
8925
    const double w2 = X[i][0][1];
 
8926
    
 
8927
    // Compute affine mapping y = F(X)
 
8928
    double y[2];
 
8929
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
8930
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
8931
    
 
8932
    // Evaluate function at physical points
 
8933
    double values[1];
 
8934
    f.evaluate(values, y, c);
 
8935
    
 
8936
    // Map function values using appropriate mapping
 
8937
    // Affine map: Do nothing
 
8938
    
 
8939
    // Note that we do not map the weights (yet).
 
8940
    
 
8941
    // Take directional components
 
8942
    for(int k = 0; k < 1; k++)
 
8943
      result += values[k]*D[i][0][k];
 
8944
    // Multiply by weights
 
8945
    result *= W[i][0];
 
8946
    
 
8947
    return result;
 
8948
}
 
8949
 
 
8950
/// Evaluate linear functionals for all dofs on the function f
 
8951
void cahnhilliard2d_1_finite_element_0_1::evaluate_dofs(double* values,
 
8952
                                  const ufc::function& f,
 
8953
                                  const ufc::cell& c) const
 
8954
{
 
8955
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
8956
}
 
8957
 
 
8958
/// Interpolate vertex values from dof values
 
8959
void cahnhilliard2d_1_finite_element_0_1::interpolate_vertex_values(double* vertex_values,
 
8960
                                              const double* dof_values,
 
8961
                                              const ufc::cell& c) const
 
8962
{
 
8963
    // Evaluate at vertices and use affine mapping
 
8964
    vertex_values[0] = dof_values[0];
 
8965
    vertex_values[1] = dof_values[1];
 
8966
    vertex_values[2] = dof_values[2];
 
8967
}
 
8968
 
 
8969
/// Return the number of sub elements (for a mixed element)
 
8970
unsigned int cahnhilliard2d_1_finite_element_0_1::num_sub_elements() const
 
8971
{
 
8972
    return 1;
 
8973
}
 
8974
 
 
8975
/// Create a new finite element for sub element i (for a mixed element)
 
8976
ufc::finite_element* cahnhilliard2d_1_finite_element_0_1::create_sub_element(unsigned int i) const
 
8977
{
 
8978
    return new cahnhilliard2d_1_finite_element_0_1();
 
8979
}
 
8980
 
 
8981
 
 
8982
/// Constructor
 
8983
cahnhilliard2d_1_finite_element_0::cahnhilliard2d_1_finite_element_0() : ufc::finite_element()
 
8984
{
 
8985
    // Do nothing
 
8986
}
 
8987
 
 
8988
/// Destructor
 
8989
cahnhilliard2d_1_finite_element_0::~cahnhilliard2d_1_finite_element_0()
 
8990
{
 
8991
    // Do nothing
 
8992
}
 
8993
 
 
8994
/// Return a string identifying the finite element
 
8995
const char* cahnhilliard2d_1_finite_element_0::signature() const
 
8996
{
 
8997
    return "MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
 
8998
}
 
8999
 
 
9000
/// Return the cell shape
 
9001
ufc::shape cahnhilliard2d_1_finite_element_0::cell_shape() const
 
9002
{
 
9003
    return ufc::triangle;
 
9004
}
 
9005
 
 
9006
/// Return the dimension of the finite element function space
 
9007
unsigned int cahnhilliard2d_1_finite_element_0::space_dimension() const
 
9008
{
 
9009
    return 6;
 
9010
}
 
9011
 
 
9012
/// Return the rank of the value space
 
9013
unsigned int cahnhilliard2d_1_finite_element_0::value_rank() const
 
9014
{
 
9015
    return 1;
 
9016
}
 
9017
 
 
9018
/// Return the dimension of the value space for axis i
 
9019
unsigned int cahnhilliard2d_1_finite_element_0::value_dimension(unsigned int i) const
 
9020
{
 
9021
    return 2;
 
9022
}
 
9023
 
 
9024
/// Evaluate basis function i at given point in cell
 
9025
void cahnhilliard2d_1_finite_element_0::evaluate_basis(unsigned int i,
 
9026
                                   double* values,
 
9027
                                   const double* coordinates,
 
9028
                                   const ufc::cell& c) const
 
9029
{
 
9030
    // Extract vertex coordinates
 
9031
    const double * const * element_coordinates = c.coordinates;
 
9032
    
 
9033
    // Compute Jacobian of affine map from reference cell
 
9034
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
9035
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
9036
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
9037
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
9038
    
 
9039
    // Compute determinant of Jacobian
 
9040
    const double detJ = J_00*J_11 - J_01*J_10;
 
9041
    
 
9042
    // Compute inverse of Jacobian
 
9043
    
 
9044
    // Get coordinates and map to the reference (UFC) element
 
9045
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
9046
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
9047
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
9048
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
9049
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
9050
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
9051
    
 
9052
    // Map coordinates to the reference square
 
9053
    if (std::abs(y - 1.0) < 1e-14)
 
9054
      x = -1.0;
 
9055
    else
 
9056
      x = 2.0 *x/(1.0 - y) - 1.0;
 
9057
    y = 2.0*y - 1.0;
 
9058
    
 
9059
    // Reset values
 
9060
    values[0] = 0;
 
9061
    values[1] = 0;
 
9062
    
 
9063
    if (0 <= i && i <= 2)
 
9064
    {
 
9065
      // Map degree of freedom to element degree of freedom
 
9066
      const unsigned int dof = i;
 
9067
    
 
9068
      // Generate scalings
 
9069
      const double scalings_y_0 = 1;
 
9070
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
9071
    
 
9072
      // Compute psitilde_a
 
9073
      const double psitilde_a_0 = 1;
 
9074
      const double psitilde_a_1 = x;
 
9075
    
 
9076
      // Compute psitilde_bs
 
9077
      const double psitilde_bs_0_0 = 1;
 
9078
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
9079
      const double psitilde_bs_1_0 = 1;
 
9080
    
 
9081
      // Compute basisvalues
 
9082
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
9083
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
9084
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
9085
    
 
9086
      // Table(s) of coefficients
 
9087
      static const double coefficients0[3][3] =   \
 
9088
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
9089
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
9090
      {0.471404520791032, 0, 0.333333333333333}};
 
9091
    
 
9092
      // Extract relevant coefficients
 
9093
      const double coeff0_0 =   coefficients0[dof][0];
 
9094
      const double coeff0_1 =   coefficients0[dof][1];
 
9095
      const double coeff0_2 =   coefficients0[dof][2];
 
9096
    
 
9097
      // Compute value(s)
 
9098
      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
9099
    }
 
9100
    
 
9101
    if (3 <= i && i <= 5)
 
9102
    {
 
9103
      // Map degree of freedom to element degree of freedom
 
9104
      const unsigned int dof = i - 3;
 
9105
    
 
9106
      // Generate scalings
 
9107
      const double scalings_y_0 = 1;
 
9108
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
9109
    
 
9110
      // Compute psitilde_a
 
9111
      const double psitilde_a_0 = 1;
 
9112
      const double psitilde_a_1 = x;
 
9113
    
 
9114
      // Compute psitilde_bs
 
9115
      const double psitilde_bs_0_0 = 1;
 
9116
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
9117
      const double psitilde_bs_1_0 = 1;
 
9118
    
 
9119
      // Compute basisvalues
 
9120
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
9121
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
9122
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
9123
    
 
9124
      // Table(s) of coefficients
 
9125
      static const double coefficients0[3][3] =   \
 
9126
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
9127
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
9128
      {0.471404520791032, 0, 0.333333333333333}};
 
9129
    
 
9130
      // Extract relevant coefficients
 
9131
      const double coeff0_0 =   coefficients0[dof][0];
 
9132
      const double coeff0_1 =   coefficients0[dof][1];
 
9133
      const double coeff0_2 =   coefficients0[dof][2];
 
9134
    
 
9135
      // Compute value(s)
 
9136
      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
9137
    }
 
9138
    
 
9139
}
 
9140
 
 
9141
/// Evaluate all basis functions at given point in cell
 
9142
void cahnhilliard2d_1_finite_element_0::evaluate_basis_all(double* values,
 
9143
                                       const double* coordinates,
 
9144
                                       const ufc::cell& c) const
 
9145
{
 
9146
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
9147
}
 
9148
 
 
9149
/// Evaluate order n derivatives of basis function i at given point in cell
 
9150
void cahnhilliard2d_1_finite_element_0::evaluate_basis_derivatives(unsigned int i,
 
9151
                                               unsigned int n,
 
9152
                                               double* values,
 
9153
                                               const double* coordinates,
 
9154
                                               const ufc::cell& c) const
 
9155
{
 
9156
    // Extract vertex coordinates
 
9157
    const double * const * element_coordinates = c.coordinates;
 
9158
    
 
9159
    // Compute Jacobian of affine map from reference cell
 
9160
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
9161
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
9162
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
9163
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
9164
    
 
9165
    // Compute determinant of Jacobian
 
9166
    const double detJ = J_00*J_11 - J_01*J_10;
 
9167
    
 
9168
    // Compute inverse of Jacobian
 
9169
    
 
9170
    // Get coordinates and map to the reference (UFC) element
 
9171
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
9172
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
9173
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
9174
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
9175
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
9176
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
9177
    
 
9178
    // Map coordinates to the reference square
 
9179
    if (std::abs(y - 1.0) < 1e-14)
 
9180
      x = -1.0;
 
9181
    else
 
9182
      x = 2.0 *x/(1.0 - y) - 1.0;
 
9183
    y = 2.0*y - 1.0;
 
9184
    
 
9185
    // Compute number of derivatives
 
9186
    unsigned int num_derivatives = 1;
 
9187
    
 
9188
    for (unsigned int j = 0; j < n; j++)
 
9189
      num_derivatives *= 2;
 
9190
    
 
9191
    
 
9192
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
9193
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
9194
    
 
9195
    for (unsigned int j = 0; j < num_derivatives; j++)
 
9196
    {
 
9197
      combinations[j] = new unsigned int [n];
 
9198
      for (unsigned int k = 0; k < n; k++)
 
9199
        combinations[j][k] = 0;
 
9200
    }
 
9201
    
 
9202
    // Generate combinations of derivatives
 
9203
    for (unsigned int row = 1; row < num_derivatives; row++)
 
9204
    {
 
9205
      for (unsigned int num = 0; num < row; num++)
 
9206
      {
 
9207
        for (unsigned int col = n-1; col+1 > 0; col--)
 
9208
        {
 
9209
          if (combinations[row][col] + 1 > 1)
 
9210
            combinations[row][col] = 0;
 
9211
          else
 
9212
          {
 
9213
            combinations[row][col] += 1;
 
9214
            break;
 
9215
          }
 
9216
        }
 
9217
      }
 
9218
    }
 
9219
    
 
9220
    // Compute inverse of Jacobian
 
9221
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
9222
    
 
9223
    // Declare transformation matrix
 
9224
    // Declare pointer to two dimensional array and initialise
 
9225
    double **transform = new double *[num_derivatives];
 
9226
    
 
9227
    for (unsigned int j = 0; j < num_derivatives; j++)
 
9228
    {
 
9229
      transform[j] = new double [num_derivatives];
 
9230
      for (unsigned int k = 0; k < num_derivatives; k++)
 
9231
        transform[j][k] = 1;
 
9232
    }
 
9233
    
 
9234
    // Construct transformation matrix
 
9235
    for (unsigned int row = 0; row < num_derivatives; row++)
 
9236
    {
 
9237
      for (unsigned int col = 0; col < num_derivatives; col++)
 
9238
      {
 
9239
        for (unsigned int k = 0; k < n; k++)
 
9240
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
9241
      }
 
9242
    }
 
9243
    
 
9244
    // Reset values
 
9245
    for (unsigned int j = 0; j < 2*num_derivatives; j++)
 
9246
      values[j] = 0;
 
9247
    
 
9248
    if (0 <= i && i <= 2)
 
9249
    {
 
9250
      // Map degree of freedom to element degree of freedom
 
9251
      const unsigned int dof = i;
 
9252
    
 
9253
      // Generate scalings
 
9254
      const double scalings_y_0 = 1;
 
9255
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
9256
    
 
9257
      // Compute psitilde_a
 
9258
      const double psitilde_a_0 = 1;
 
9259
      const double psitilde_a_1 = x;
 
9260
    
 
9261
      // Compute psitilde_bs
 
9262
      const double psitilde_bs_0_0 = 1;
 
9263
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
9264
      const double psitilde_bs_1_0 = 1;
 
9265
    
 
9266
      // Compute basisvalues
 
9267
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
9268
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
9269
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
9270
    
 
9271
      // Table(s) of coefficients
 
9272
      static const double coefficients0[3][3] =   \
 
9273
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
9274
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
9275
      {0.471404520791032, 0, 0.333333333333333}};
 
9276
    
 
9277
      // Interesting (new) part
 
9278
      // Tables of derivatives of the polynomial base (transpose)
 
9279
      static const double dmats0[3][3] =   \
 
9280
      {{0, 0, 0},
 
9281
      {4.89897948556636, 0, 0},
 
9282
      {0, 0, 0}};
 
9283
    
 
9284
      static const double dmats1[3][3] =   \
 
9285
      {{0, 0, 0},
 
9286
      {2.44948974278318, 0, 0},
 
9287
      {4.24264068711928, 0, 0}};
 
9288
    
 
9289
      // Compute reference derivatives
 
9290
      // Declare pointer to array of derivatives on FIAT element
 
9291
      double *derivatives = new double [num_derivatives];
 
9292
    
 
9293
      // Declare coefficients
 
9294
      double coeff0_0 = 0;
 
9295
      double coeff0_1 = 0;
 
9296
      double coeff0_2 = 0;
 
9297
    
 
9298
      // Declare new coefficients
 
9299
      double new_coeff0_0 = 0;
 
9300
      double new_coeff0_1 = 0;
 
9301
      double new_coeff0_2 = 0;
 
9302
    
 
9303
      // Loop possible derivatives
 
9304
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
9305
      {
 
9306
        // Get values from coefficients array
 
9307
        new_coeff0_0 = coefficients0[dof][0];
 
9308
        new_coeff0_1 = coefficients0[dof][1];
 
9309
        new_coeff0_2 = coefficients0[dof][2];
 
9310
    
 
9311
        // Loop derivative order
 
9312
        for (unsigned int j = 0; j < n; j++)
 
9313
        {
 
9314
          // Update old coefficients
 
9315
          coeff0_0 = new_coeff0_0;
 
9316
          coeff0_1 = new_coeff0_1;
 
9317
          coeff0_2 = new_coeff0_2;
 
9318
    
 
9319
          if(combinations[deriv_num][j] == 0)
 
9320
          {
 
9321
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
9322
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
9323
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
9324
          }
 
9325
          if(combinations[deriv_num][j] == 1)
 
9326
          {
 
9327
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
9328
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
9329
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
9330
          }
 
9331
    
 
9332
        }
 
9333
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
9334
        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
9335
      }
 
9336
    
 
9337
      // Transform derivatives back to physical element
 
9338
      for (unsigned int row = 0; row < num_derivatives; row++)
 
9339
      {
 
9340
        for (unsigned int col = 0; col < num_derivatives; col++)
 
9341
        {
 
9342
          values[row] += transform[row][col]*derivatives[col];
 
9343
        }
 
9344
      }
 
9345
      // Delete pointer to array of derivatives on FIAT element
 
9346
      delete [] derivatives;
 
9347
    
 
9348
      // Delete pointer to array of combinations of derivatives and transform
 
9349
      for (unsigned int row = 0; row < num_derivatives; row++)
 
9350
      {
 
9351
        delete [] combinations[row];
 
9352
        delete [] transform[row];
 
9353
      }
 
9354
    
 
9355
      delete [] combinations;
 
9356
      delete [] transform;
 
9357
    }
 
9358
    
 
9359
    if (3 <= i && i <= 5)
 
9360
    {
 
9361
      // Map degree of freedom to element degree of freedom
 
9362
      const unsigned int dof = i - 3;
 
9363
    
 
9364
      // Generate scalings
 
9365
      const double scalings_y_0 = 1;
 
9366
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
9367
    
 
9368
      // Compute psitilde_a
 
9369
      const double psitilde_a_0 = 1;
 
9370
      const double psitilde_a_1 = x;
 
9371
    
 
9372
      // Compute psitilde_bs
 
9373
      const double psitilde_bs_0_0 = 1;
 
9374
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
9375
      const double psitilde_bs_1_0 = 1;
 
9376
    
 
9377
      // Compute basisvalues
 
9378
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
9379
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
9380
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
9381
    
 
9382
      // Table(s) of coefficients
 
9383
      static const double coefficients0[3][3] =   \
 
9384
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
9385
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
9386
      {0.471404520791032, 0, 0.333333333333333}};
 
9387
    
 
9388
      // Interesting (new) part
 
9389
      // Tables of derivatives of the polynomial base (transpose)
 
9390
      static const double dmats0[3][3] =   \
 
9391
      {{0, 0, 0},
 
9392
      {4.89897948556636, 0, 0},
 
9393
      {0, 0, 0}};
 
9394
    
 
9395
      static const double dmats1[3][3] =   \
 
9396
      {{0, 0, 0},
 
9397
      {2.44948974278318, 0, 0},
 
9398
      {4.24264068711928, 0, 0}};
 
9399
    
 
9400
      // Compute reference derivatives
 
9401
      // Declare pointer to array of derivatives on FIAT element
 
9402
      double *derivatives = new double [num_derivatives];
 
9403
    
 
9404
      // Declare coefficients
 
9405
      double coeff0_0 = 0;
 
9406
      double coeff0_1 = 0;
 
9407
      double coeff0_2 = 0;
 
9408
    
 
9409
      // Declare new coefficients
 
9410
      double new_coeff0_0 = 0;
 
9411
      double new_coeff0_1 = 0;
 
9412
      double new_coeff0_2 = 0;
 
9413
    
 
9414
      // Loop possible derivatives
 
9415
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
9416
      {
 
9417
        // Get values from coefficients array
 
9418
        new_coeff0_0 = coefficients0[dof][0];
 
9419
        new_coeff0_1 = coefficients0[dof][1];
 
9420
        new_coeff0_2 = coefficients0[dof][2];
 
9421
    
 
9422
        // Loop derivative order
 
9423
        for (unsigned int j = 0; j < n; j++)
 
9424
        {
 
9425
          // Update old coefficients
 
9426
          coeff0_0 = new_coeff0_0;
 
9427
          coeff0_1 = new_coeff0_1;
 
9428
          coeff0_2 = new_coeff0_2;
 
9429
    
 
9430
          if(combinations[deriv_num][j] == 0)
 
9431
          {
 
9432
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
9433
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
9434
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
9435
          }
 
9436
          if(combinations[deriv_num][j] == 1)
 
9437
          {
 
9438
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
9439
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
9440
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
9441
          }
 
9442
    
 
9443
        }
 
9444
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
9445
        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
9446
      }
 
9447
    
 
9448
      // Transform derivatives back to physical element
 
9449
      for (unsigned int row = 0; row < num_derivatives; row++)
 
9450
      {
 
9451
        for (unsigned int col = 0; col < num_derivatives; col++)
 
9452
        {
 
9453
          values[num_derivatives + row] += transform[row][col]*derivatives[col];
 
9454
        }
 
9455
      }
 
9456
      // Delete pointer to array of derivatives on FIAT element
 
9457
      delete [] derivatives;
 
9458
    
 
9459
      // Delete pointer to array of combinations of derivatives and transform
 
9460
      for (unsigned int row = 0; row < num_derivatives; row++)
 
9461
      {
 
9462
        delete [] combinations[row];
 
9463
        delete [] transform[row];
 
9464
      }
 
9465
    
 
9466
      delete [] combinations;
 
9467
      delete [] transform;
 
9468
    }
 
9469
    
 
9470
}
 
9471
 
 
9472
/// Evaluate order n derivatives of all basis functions at given point in cell
 
9473
void cahnhilliard2d_1_finite_element_0::evaluate_basis_derivatives_all(unsigned int n,
 
9474
                                                   double* values,
 
9475
                                                   const double* coordinates,
 
9476
                                                   const ufc::cell& c) const
 
9477
{
 
9478
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
9479
}
 
9480
 
 
9481
/// Evaluate linear functional for dof i on the function f
 
9482
double cahnhilliard2d_1_finite_element_0::evaluate_dof(unsigned int i,
 
9483
                                   const ufc::function& f,
 
9484
                                   const ufc::cell& c) const
 
9485
{
 
9486
    // The reference points, direction and weights:
 
9487
    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
 
9488
    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
 
9489
    static const double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
 
9490
    
 
9491
    const double * const * x = c.coordinates;
 
9492
    double result = 0.0;
 
9493
    // Iterate over the points:
 
9494
    // Evaluate basis functions for affine mapping
 
9495
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
9496
    const double w1 = X[i][0][0];
 
9497
    const double w2 = X[i][0][1];
 
9498
    
 
9499
    // Compute affine mapping y = F(X)
 
9500
    double y[2];
 
9501
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
9502
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
9503
    
 
9504
    // Evaluate function at physical points
 
9505
    double values[2];
 
9506
    f.evaluate(values, y, c);
 
9507
    
 
9508
    // Map function values using appropriate mapping
 
9509
    // Affine map: Do nothing
 
9510
    
 
9511
    // Note that we do not map the weights (yet).
 
9512
    
 
9513
    // Take directional components
 
9514
    for(int k = 0; k < 2; k++)
 
9515
      result += values[k]*D[i][0][k];
 
9516
    // Multiply by weights
 
9517
    result *= W[i][0];
 
9518
    
 
9519
    return result;
 
9520
}
 
9521
 
 
9522
/// Evaluate linear functionals for all dofs on the function f
 
9523
void cahnhilliard2d_1_finite_element_0::evaluate_dofs(double* values,
 
9524
                                  const ufc::function& f,
 
9525
                                  const ufc::cell& c) const
 
9526
{
 
9527
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
9528
}
 
9529
 
 
9530
/// Interpolate vertex values from dof values
 
9531
void cahnhilliard2d_1_finite_element_0::interpolate_vertex_values(double* vertex_values,
 
9532
                                              const double* dof_values,
 
9533
                                              const ufc::cell& c) const
 
9534
{
 
9535
    // Evaluate at vertices and use affine mapping
 
9536
    vertex_values[0] = dof_values[0];
 
9537
    vertex_values[2] = dof_values[1];
 
9538
    vertex_values[4] = dof_values[2];
 
9539
    // Evaluate at vertices and use affine mapping
 
9540
    vertex_values[1] = dof_values[3];
 
9541
    vertex_values[3] = dof_values[4];
 
9542
    vertex_values[5] = dof_values[5];
 
9543
}
 
9544
 
 
9545
/// Return the number of sub elements (for a mixed element)
 
9546
unsigned int cahnhilliard2d_1_finite_element_0::num_sub_elements() const
 
9547
{
 
9548
    return 2;
 
9549
}
 
9550
 
 
9551
/// Create a new finite element for sub element i (for a mixed element)
 
9552
ufc::finite_element* cahnhilliard2d_1_finite_element_0::create_sub_element(unsigned int i) const
 
9553
{
 
9554
    switch ( i )
 
9555
    {
 
9556
    case 0:
 
9557
      return new cahnhilliard2d_1_finite_element_0_0();
 
9558
      break;
 
9559
    case 1:
 
9560
      return new cahnhilliard2d_1_finite_element_0_1();
 
9561
      break;
 
9562
    }
 
9563
    return 0;
 
9564
}
 
9565
 
 
9566
 
 
9567
/// Constructor
 
9568
cahnhilliard2d_1_finite_element_1_0::cahnhilliard2d_1_finite_element_1_0() : ufc::finite_element()
 
9569
{
 
9570
    // Do nothing
 
9571
}
 
9572
 
 
9573
/// Destructor
 
9574
cahnhilliard2d_1_finite_element_1_0::~cahnhilliard2d_1_finite_element_1_0()
 
9575
{
 
9576
    // Do nothing
 
9577
}
 
9578
 
 
9579
/// Return a string identifying the finite element
 
9580
const char* cahnhilliard2d_1_finite_element_1_0::signature() const
 
9581
{
 
9582
    return "FiniteElement('Lagrange', 'triangle', 1)";
 
9583
}
 
9584
 
 
9585
/// Return the cell shape
 
9586
ufc::shape cahnhilliard2d_1_finite_element_1_0::cell_shape() const
 
9587
{
 
9588
    return ufc::triangle;
 
9589
}
 
9590
 
 
9591
/// Return the dimension of the finite element function space
 
9592
unsigned int cahnhilliard2d_1_finite_element_1_0::space_dimension() const
 
9593
{
 
9594
    return 3;
 
9595
}
 
9596
 
 
9597
/// Return the rank of the value space
 
9598
unsigned int cahnhilliard2d_1_finite_element_1_0::value_rank() const
 
9599
{
 
9600
    return 0;
 
9601
}
 
9602
 
 
9603
/// Return the dimension of the value space for axis i
 
9604
unsigned int cahnhilliard2d_1_finite_element_1_0::value_dimension(unsigned int i) const
 
9605
{
 
9606
    return 1;
 
9607
}
 
9608
 
 
9609
/// Evaluate basis function i at given point in cell
 
9610
void cahnhilliard2d_1_finite_element_1_0::evaluate_basis(unsigned int i,
 
9611
                                   double* values,
 
9612
                                   const double* coordinates,
 
9613
                                   const ufc::cell& c) const
 
9614
{
 
9615
    // Extract vertex coordinates
 
9616
    const double * const * element_coordinates = c.coordinates;
 
9617
    
 
9618
    // Compute Jacobian of affine map from reference cell
 
9619
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
9620
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
9621
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
9622
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
9623
    
 
9624
    // Compute determinant of Jacobian
 
9625
    const double detJ = J_00*J_11 - J_01*J_10;
 
9626
    
 
9627
    // Compute inverse of Jacobian
 
9628
    
 
9629
    // Get coordinates and map to the reference (UFC) element
 
9630
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
9631
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
9632
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
9633
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
9634
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
9635
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
9636
    
 
9637
    // Map coordinates to the reference square
 
9638
    if (std::abs(y - 1.0) < 1e-14)
 
9639
      x = -1.0;
 
9640
    else
 
9641
      x = 2.0 *x/(1.0 - y) - 1.0;
 
9642
    y = 2.0*y - 1.0;
 
9643
    
 
9644
    // Reset values
 
9645
    *values = 0;
 
9646
    
 
9647
    // Map degree of freedom to element degree of freedom
 
9648
    const unsigned int dof = i;
 
9649
    
 
9650
    // Generate scalings
 
9651
    const double scalings_y_0 = 1;
 
9652
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
9653
    
 
9654
    // Compute psitilde_a
 
9655
    const double psitilde_a_0 = 1;
 
9656
    const double psitilde_a_1 = x;
 
9657
    
 
9658
    // Compute psitilde_bs
 
9659
    const double psitilde_bs_0_0 = 1;
 
9660
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
9661
    const double psitilde_bs_1_0 = 1;
 
9662
    
 
9663
    // Compute basisvalues
 
9664
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
9665
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
9666
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
9667
    
 
9668
    // Table(s) of coefficients
 
9669
    static const double coefficients0[3][3] = \
 
9670
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
9671
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
9672
    {0.471404520791032, 0, 0.333333333333333}};
 
9673
    
 
9674
    // Extract relevant coefficients
 
9675
    const double coeff0_0 = coefficients0[dof][0];
 
9676
    const double coeff0_1 = coefficients0[dof][1];
 
9677
    const double coeff0_2 = coefficients0[dof][2];
 
9678
    
 
9679
    // Compute value(s)
 
9680
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
9681
}
 
9682
 
 
9683
/// Evaluate all basis functions at given point in cell
 
9684
void cahnhilliard2d_1_finite_element_1_0::evaluate_basis_all(double* values,
 
9685
                                       const double* coordinates,
 
9686
                                       const ufc::cell& c) const
 
9687
{
 
9688
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
9689
}
 
9690
 
 
9691
/// Evaluate order n derivatives of basis function i at given point in cell
 
9692
void cahnhilliard2d_1_finite_element_1_0::evaluate_basis_derivatives(unsigned int i,
 
9693
                                               unsigned int n,
 
9694
                                               double* values,
 
9695
                                               const double* coordinates,
 
9696
                                               const ufc::cell& c) const
 
9697
{
 
9698
    // Extract vertex coordinates
 
9699
    const double * const * element_coordinates = c.coordinates;
 
9700
    
 
9701
    // Compute Jacobian of affine map from reference cell
 
9702
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
9703
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
9704
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
9705
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
9706
    
 
9707
    // Compute determinant of Jacobian
 
9708
    const double detJ = J_00*J_11 - J_01*J_10;
 
9709
    
 
9710
    // Compute inverse of Jacobian
 
9711
    
 
9712
    // Get coordinates and map to the reference (UFC) element
 
9713
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
9714
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
9715
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
9716
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
9717
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
9718
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
9719
    
 
9720
    // Map coordinates to the reference square
 
9721
    if (std::abs(y - 1.0) < 1e-14)
 
9722
      x = -1.0;
 
9723
    else
 
9724
      x = 2.0 *x/(1.0 - y) - 1.0;
 
9725
    y = 2.0*y - 1.0;
 
9726
    
 
9727
    // Compute number of derivatives
 
9728
    unsigned int num_derivatives = 1;
 
9729
    
 
9730
    for (unsigned int j = 0; j < n; j++)
 
9731
      num_derivatives *= 2;
 
9732
    
 
9733
    
 
9734
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
9735
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
9736
    
 
9737
    for (unsigned int j = 0; j < num_derivatives; j++)
 
9738
    {
 
9739
      combinations[j] = new unsigned int [n];
 
9740
      for (unsigned int k = 0; k < n; k++)
 
9741
        combinations[j][k] = 0;
 
9742
    }
 
9743
    
 
9744
    // Generate combinations of derivatives
 
9745
    for (unsigned int row = 1; row < num_derivatives; row++)
 
9746
    {
 
9747
      for (unsigned int num = 0; num < row; num++)
 
9748
      {
 
9749
        for (unsigned int col = n-1; col+1 > 0; col--)
 
9750
        {
 
9751
          if (combinations[row][col] + 1 > 1)
 
9752
            combinations[row][col] = 0;
 
9753
          else
 
9754
          {
 
9755
            combinations[row][col] += 1;
 
9756
            break;
 
9757
          }
 
9758
        }
 
9759
      }
 
9760
    }
 
9761
    
 
9762
    // Compute inverse of Jacobian
 
9763
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
9764
    
 
9765
    // Declare transformation matrix
 
9766
    // Declare pointer to two dimensional array and initialise
 
9767
    double **transform = new double *[num_derivatives];
 
9768
    
 
9769
    for (unsigned int j = 0; j < num_derivatives; j++)
 
9770
    {
 
9771
      transform[j] = new double [num_derivatives];
 
9772
      for (unsigned int k = 0; k < num_derivatives; k++)
 
9773
        transform[j][k] = 1;
 
9774
    }
 
9775
    
 
9776
    // Construct transformation matrix
 
9777
    for (unsigned int row = 0; row < num_derivatives; row++)
 
9778
    {
 
9779
      for (unsigned int col = 0; col < num_derivatives; col++)
 
9780
      {
 
9781
        for (unsigned int k = 0; k < n; k++)
 
9782
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
9783
      }
 
9784
    }
 
9785
    
 
9786
    // Reset values
 
9787
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
 
9788
      values[j] = 0;
 
9789
    
 
9790
    // Map degree of freedom to element degree of freedom
 
9791
    const unsigned int dof = i;
 
9792
    
 
9793
    // Generate scalings
 
9794
    const double scalings_y_0 = 1;
 
9795
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
9796
    
 
9797
    // Compute psitilde_a
 
9798
    const double psitilde_a_0 = 1;
 
9799
    const double psitilde_a_1 = x;
 
9800
    
 
9801
    // Compute psitilde_bs
 
9802
    const double psitilde_bs_0_0 = 1;
 
9803
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
9804
    const double psitilde_bs_1_0 = 1;
 
9805
    
 
9806
    // Compute basisvalues
 
9807
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
9808
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
9809
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
9810
    
 
9811
    // Table(s) of coefficients
 
9812
    static const double coefficients0[3][3] = \
 
9813
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
9814
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
9815
    {0.471404520791032, 0, 0.333333333333333}};
 
9816
    
 
9817
    // Interesting (new) part
 
9818
    // Tables of derivatives of the polynomial base (transpose)
 
9819
    static const double dmats0[3][3] = \
 
9820
    {{0, 0, 0},
 
9821
    {4.89897948556636, 0, 0},
 
9822
    {0, 0, 0}};
 
9823
    
 
9824
    static const double dmats1[3][3] = \
 
9825
    {{0, 0, 0},
 
9826
    {2.44948974278318, 0, 0},
 
9827
    {4.24264068711928, 0, 0}};
 
9828
    
 
9829
    // Compute reference derivatives
 
9830
    // Declare pointer to array of derivatives on FIAT element
 
9831
    double *derivatives = new double [num_derivatives];
 
9832
    
 
9833
    // Declare coefficients
 
9834
    double coeff0_0 = 0;
 
9835
    double coeff0_1 = 0;
 
9836
    double coeff0_2 = 0;
 
9837
    
 
9838
    // Declare new coefficients
 
9839
    double new_coeff0_0 = 0;
 
9840
    double new_coeff0_1 = 0;
 
9841
    double new_coeff0_2 = 0;
 
9842
    
 
9843
    // Loop possible derivatives
 
9844
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
9845
    {
 
9846
      // Get values from coefficients array
 
9847
      new_coeff0_0 = coefficients0[dof][0];
 
9848
      new_coeff0_1 = coefficients0[dof][1];
 
9849
      new_coeff0_2 = coefficients0[dof][2];
 
9850
    
 
9851
      // Loop derivative order
 
9852
      for (unsigned int j = 0; j < n; j++)
 
9853
      {
 
9854
        // Update old coefficients
 
9855
        coeff0_0 = new_coeff0_0;
 
9856
        coeff0_1 = new_coeff0_1;
 
9857
        coeff0_2 = new_coeff0_2;
 
9858
    
 
9859
        if(combinations[deriv_num][j] == 0)
 
9860
        {
 
9861
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
9862
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
9863
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
9864
        }
 
9865
        if(combinations[deriv_num][j] == 1)
 
9866
        {
 
9867
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
9868
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
9869
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
9870
        }
 
9871
    
 
9872
      }
 
9873
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
9874
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
9875
    }
 
9876
    
 
9877
    // Transform derivatives back to physical element
 
9878
    for (unsigned int row = 0; row < num_derivatives; row++)
 
9879
    {
 
9880
      for (unsigned int col = 0; col < num_derivatives; col++)
 
9881
      {
 
9882
        values[row] += transform[row][col]*derivatives[col];
 
9883
      }
 
9884
    }
 
9885
    // Delete pointer to array of derivatives on FIAT element
 
9886
    delete [] derivatives;
 
9887
    
 
9888
    // Delete pointer to array of combinations of derivatives and transform
 
9889
    for (unsigned int row = 0; row < num_derivatives; row++)
 
9890
    {
 
9891
      delete [] combinations[row];
 
9892
      delete [] transform[row];
 
9893
    }
 
9894
    
 
9895
    delete [] combinations;
 
9896
    delete [] transform;
 
9897
}
 
9898
 
 
9899
/// Evaluate order n derivatives of all basis functions at given point in cell
 
9900
void cahnhilliard2d_1_finite_element_1_0::evaluate_basis_derivatives_all(unsigned int n,
 
9901
                                                   double* values,
 
9902
                                                   const double* coordinates,
 
9903
                                                   const ufc::cell& c) const
 
9904
{
 
9905
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
9906
}
 
9907
 
 
9908
/// Evaluate linear functional for dof i on the function f
 
9909
double cahnhilliard2d_1_finite_element_1_0::evaluate_dof(unsigned int i,
 
9910
                                   const ufc::function& f,
 
9911
                                   const ufc::cell& c) const
 
9912
{
 
9913
    // The reference points, direction and weights:
 
9914
    static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
 
9915
    static const double W[3][1] = {{1}, {1}, {1}};
 
9916
    static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
 
9917
    
 
9918
    const double * const * x = c.coordinates;
 
9919
    double result = 0.0;
 
9920
    // Iterate over the points:
 
9921
    // Evaluate basis functions for affine mapping
 
9922
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
9923
    const double w1 = X[i][0][0];
 
9924
    const double w2 = X[i][0][1];
 
9925
    
 
9926
    // Compute affine mapping y = F(X)
 
9927
    double y[2];
 
9928
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
9929
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
9930
    
 
9931
    // Evaluate function at physical points
 
9932
    double values[1];
 
9933
    f.evaluate(values, y, c);
 
9934
    
 
9935
    // Map function values using appropriate mapping
 
9936
    // Affine map: Do nothing
 
9937
    
 
9938
    // Note that we do not map the weights (yet).
 
9939
    
 
9940
    // Take directional components
 
9941
    for(int k = 0; k < 1; k++)
 
9942
      result += values[k]*D[i][0][k];
 
9943
    // Multiply by weights
 
9944
    result *= W[i][0];
 
9945
    
 
9946
    return result;
 
9947
}
 
9948
 
 
9949
/// Evaluate linear functionals for all dofs on the function f
 
9950
void cahnhilliard2d_1_finite_element_1_0::evaluate_dofs(double* values,
 
9951
                                  const ufc::function& f,
 
9952
                                  const ufc::cell& c) const
 
9953
{
 
9954
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
9955
}
 
9956
 
 
9957
/// Interpolate vertex values from dof values
 
9958
void cahnhilliard2d_1_finite_element_1_0::interpolate_vertex_values(double* vertex_values,
 
9959
                                              const double* dof_values,
 
9960
                                              const ufc::cell& c) const
 
9961
{
 
9962
    // Evaluate at vertices and use affine mapping
 
9963
    vertex_values[0] = dof_values[0];
 
9964
    vertex_values[1] = dof_values[1];
 
9965
    vertex_values[2] = dof_values[2];
 
9966
}
 
9967
 
 
9968
/// Return the number of sub elements (for a mixed element)
 
9969
unsigned int cahnhilliard2d_1_finite_element_1_0::num_sub_elements() const
 
9970
{
 
9971
    return 1;
 
9972
}
 
9973
 
 
9974
/// Create a new finite element for sub element i (for a mixed element)
 
9975
ufc::finite_element* cahnhilliard2d_1_finite_element_1_0::create_sub_element(unsigned int i) const
 
9976
{
 
9977
    return new cahnhilliard2d_1_finite_element_1_0();
 
9978
}
 
9979
 
 
9980
 
 
9981
/// Constructor
 
9982
cahnhilliard2d_1_finite_element_1_1::cahnhilliard2d_1_finite_element_1_1() : ufc::finite_element()
 
9983
{
 
9984
    // Do nothing
 
9985
}
 
9986
 
 
9987
/// Destructor
 
9988
cahnhilliard2d_1_finite_element_1_1::~cahnhilliard2d_1_finite_element_1_1()
 
9989
{
 
9990
    // Do nothing
 
9991
}
 
9992
 
 
9993
/// Return a string identifying the finite element
 
9994
const char* cahnhilliard2d_1_finite_element_1_1::signature() const
 
9995
{
 
9996
    return "FiniteElement('Lagrange', 'triangle', 1)";
 
9997
}
 
9998
 
 
9999
/// Return the cell shape
 
10000
ufc::shape cahnhilliard2d_1_finite_element_1_1::cell_shape() const
 
10001
{
 
10002
    return ufc::triangle;
 
10003
}
 
10004
 
 
10005
/// Return the dimension of the finite element function space
 
10006
unsigned int cahnhilliard2d_1_finite_element_1_1::space_dimension() const
 
10007
{
 
10008
    return 3;
 
10009
}
 
10010
 
 
10011
/// Return the rank of the value space
 
10012
unsigned int cahnhilliard2d_1_finite_element_1_1::value_rank() const
 
10013
{
 
10014
    return 0;
 
10015
}
 
10016
 
 
10017
/// Return the dimension of the value space for axis i
 
10018
unsigned int cahnhilliard2d_1_finite_element_1_1::value_dimension(unsigned int i) const
 
10019
{
 
10020
    return 1;
 
10021
}
 
10022
 
 
10023
/// Evaluate basis function i at given point in cell
 
10024
void cahnhilliard2d_1_finite_element_1_1::evaluate_basis(unsigned int i,
 
10025
                                   double* values,
 
10026
                                   const double* coordinates,
 
10027
                                   const ufc::cell& c) const
 
10028
{
 
10029
    // Extract vertex coordinates
 
10030
    const double * const * element_coordinates = c.coordinates;
 
10031
    
 
10032
    // Compute Jacobian of affine map from reference cell
 
10033
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
10034
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
10035
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
10036
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
10037
    
 
10038
    // Compute determinant of Jacobian
 
10039
    const double detJ = J_00*J_11 - J_01*J_10;
 
10040
    
 
10041
    // Compute inverse of Jacobian
 
10042
    
 
10043
    // Get coordinates and map to the reference (UFC) element
 
10044
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
10045
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
10046
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
10047
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
10048
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
10049
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
10050
    
 
10051
    // Map coordinates to the reference square
 
10052
    if (std::abs(y - 1.0) < 1e-14)
 
10053
      x = -1.0;
 
10054
    else
 
10055
      x = 2.0 *x/(1.0 - y) - 1.0;
 
10056
    y = 2.0*y - 1.0;
 
10057
    
 
10058
    // Reset values
 
10059
    *values = 0;
 
10060
    
 
10061
    // Map degree of freedom to element degree of freedom
 
10062
    const unsigned int dof = i;
 
10063
    
 
10064
    // Generate scalings
 
10065
    const double scalings_y_0 = 1;
 
10066
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
10067
    
 
10068
    // Compute psitilde_a
 
10069
    const double psitilde_a_0 = 1;
 
10070
    const double psitilde_a_1 = x;
 
10071
    
 
10072
    // Compute psitilde_bs
 
10073
    const double psitilde_bs_0_0 = 1;
 
10074
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
10075
    const double psitilde_bs_1_0 = 1;
 
10076
    
 
10077
    // Compute basisvalues
 
10078
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
10079
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
10080
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
10081
    
 
10082
    // Table(s) of coefficients
 
10083
    static const double coefficients0[3][3] = \
 
10084
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
10085
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
10086
    {0.471404520791032, 0, 0.333333333333333}};
 
10087
    
 
10088
    // Extract relevant coefficients
 
10089
    const double coeff0_0 = coefficients0[dof][0];
 
10090
    const double coeff0_1 = coefficients0[dof][1];
 
10091
    const double coeff0_2 = coefficients0[dof][2];
 
10092
    
 
10093
    // Compute value(s)
 
10094
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
10095
}
 
10096
 
 
10097
/// Evaluate all basis functions at given point in cell
 
10098
void cahnhilliard2d_1_finite_element_1_1::evaluate_basis_all(double* values,
 
10099
                                       const double* coordinates,
 
10100
                                       const ufc::cell& c) const
 
10101
{
 
10102
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
10103
}
 
10104
 
 
10105
/// Evaluate order n derivatives of basis function i at given point in cell
 
10106
void cahnhilliard2d_1_finite_element_1_1::evaluate_basis_derivatives(unsigned int i,
 
10107
                                               unsigned int n,
 
10108
                                               double* values,
 
10109
                                               const double* coordinates,
 
10110
                                               const ufc::cell& c) const
 
10111
{
 
10112
    // Extract vertex coordinates
 
10113
    const double * const * element_coordinates = c.coordinates;
 
10114
    
 
10115
    // Compute Jacobian of affine map from reference cell
 
10116
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
10117
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
10118
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
10119
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
10120
    
 
10121
    // Compute determinant of Jacobian
 
10122
    const double detJ = J_00*J_11 - J_01*J_10;
 
10123
    
 
10124
    // Compute inverse of Jacobian
 
10125
    
 
10126
    // Get coordinates and map to the reference (UFC) element
 
10127
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
10128
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
10129
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
10130
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
10131
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
10132
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
10133
    
 
10134
    // Map coordinates to the reference square
 
10135
    if (std::abs(y - 1.0) < 1e-14)
 
10136
      x = -1.0;
 
10137
    else
 
10138
      x = 2.0 *x/(1.0 - y) - 1.0;
 
10139
    y = 2.0*y - 1.0;
 
10140
    
 
10141
    // Compute number of derivatives
 
10142
    unsigned int num_derivatives = 1;
 
10143
    
 
10144
    for (unsigned int j = 0; j < n; j++)
 
10145
      num_derivatives *= 2;
 
10146
    
 
10147
    
 
10148
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
10149
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
10150
    
 
10151
    for (unsigned int j = 0; j < num_derivatives; j++)
 
10152
    {
 
10153
      combinations[j] = new unsigned int [n];
 
10154
      for (unsigned int k = 0; k < n; k++)
 
10155
        combinations[j][k] = 0;
 
10156
    }
 
10157
    
 
10158
    // Generate combinations of derivatives
 
10159
    for (unsigned int row = 1; row < num_derivatives; row++)
 
10160
    {
 
10161
      for (unsigned int num = 0; num < row; num++)
 
10162
      {
 
10163
        for (unsigned int col = n-1; col+1 > 0; col--)
 
10164
        {
 
10165
          if (combinations[row][col] + 1 > 1)
 
10166
            combinations[row][col] = 0;
 
10167
          else
 
10168
          {
 
10169
            combinations[row][col] += 1;
 
10170
            break;
 
10171
          }
 
10172
        }
 
10173
      }
 
10174
    }
 
10175
    
 
10176
    // Compute inverse of Jacobian
 
10177
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
10178
    
 
10179
    // Declare transformation matrix
 
10180
    // Declare pointer to two dimensional array and initialise
 
10181
    double **transform = new double *[num_derivatives];
 
10182
    
 
10183
    for (unsigned int j = 0; j < num_derivatives; j++)
 
10184
    {
 
10185
      transform[j] = new double [num_derivatives];
 
10186
      for (unsigned int k = 0; k < num_derivatives; k++)
 
10187
        transform[j][k] = 1;
 
10188
    }
 
10189
    
 
10190
    // Construct transformation matrix
 
10191
    for (unsigned int row = 0; row < num_derivatives; row++)
 
10192
    {
 
10193
      for (unsigned int col = 0; col < num_derivatives; col++)
 
10194
      {
 
10195
        for (unsigned int k = 0; k < n; k++)
 
10196
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
10197
      }
 
10198
    }
 
10199
    
 
10200
    // Reset values
 
10201
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
 
10202
      values[j] = 0;
 
10203
    
 
10204
    // Map degree of freedom to element degree of freedom
 
10205
    const unsigned int dof = i;
 
10206
    
 
10207
    // Generate scalings
 
10208
    const double scalings_y_0 = 1;
 
10209
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
10210
    
 
10211
    // Compute psitilde_a
 
10212
    const double psitilde_a_0 = 1;
 
10213
    const double psitilde_a_1 = x;
 
10214
    
 
10215
    // Compute psitilde_bs
 
10216
    const double psitilde_bs_0_0 = 1;
 
10217
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
10218
    const double psitilde_bs_1_0 = 1;
 
10219
    
 
10220
    // Compute basisvalues
 
10221
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
10222
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
10223
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
10224
    
 
10225
    // Table(s) of coefficients
 
10226
    static const double coefficients0[3][3] = \
 
10227
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
10228
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
10229
    {0.471404520791032, 0, 0.333333333333333}};
 
10230
    
 
10231
    // Interesting (new) part
 
10232
    // Tables of derivatives of the polynomial base (transpose)
 
10233
    static const double dmats0[3][3] = \
 
10234
    {{0, 0, 0},
 
10235
    {4.89897948556636, 0, 0},
 
10236
    {0, 0, 0}};
 
10237
    
 
10238
    static const double dmats1[3][3] = \
 
10239
    {{0, 0, 0},
 
10240
    {2.44948974278318, 0, 0},
 
10241
    {4.24264068711928, 0, 0}};
 
10242
    
 
10243
    // Compute reference derivatives
 
10244
    // Declare pointer to array of derivatives on FIAT element
 
10245
    double *derivatives = new double [num_derivatives];
 
10246
    
 
10247
    // Declare coefficients
 
10248
    double coeff0_0 = 0;
 
10249
    double coeff0_1 = 0;
 
10250
    double coeff0_2 = 0;
 
10251
    
 
10252
    // Declare new coefficients
 
10253
    double new_coeff0_0 = 0;
 
10254
    double new_coeff0_1 = 0;
 
10255
    double new_coeff0_2 = 0;
 
10256
    
 
10257
    // Loop possible derivatives
 
10258
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
10259
    {
 
10260
      // Get values from coefficients array
 
10261
      new_coeff0_0 = coefficients0[dof][0];
 
10262
      new_coeff0_1 = coefficients0[dof][1];
 
10263
      new_coeff0_2 = coefficients0[dof][2];
 
10264
    
 
10265
      // Loop derivative order
 
10266
      for (unsigned int j = 0; j < n; j++)
 
10267
      {
 
10268
        // Update old coefficients
 
10269
        coeff0_0 = new_coeff0_0;
 
10270
        coeff0_1 = new_coeff0_1;
 
10271
        coeff0_2 = new_coeff0_2;
 
10272
    
 
10273
        if(combinations[deriv_num][j] == 0)
 
10274
        {
 
10275
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
10276
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
10277
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
10278
        }
 
10279
        if(combinations[deriv_num][j] == 1)
 
10280
        {
 
10281
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
10282
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
10283
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
10284
        }
 
10285
    
 
10286
      }
 
10287
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
10288
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
10289
    }
 
10290
    
 
10291
    // Transform derivatives back to physical element
 
10292
    for (unsigned int row = 0; row < num_derivatives; row++)
 
10293
    {
 
10294
      for (unsigned int col = 0; col < num_derivatives; col++)
 
10295
      {
 
10296
        values[row] += transform[row][col]*derivatives[col];
 
10297
      }
 
10298
    }
 
10299
    // Delete pointer to array of derivatives on FIAT element
 
10300
    delete [] derivatives;
 
10301
    
 
10302
    // Delete pointer to array of combinations of derivatives and transform
 
10303
    for (unsigned int row = 0; row < num_derivatives; row++)
 
10304
    {
 
10305
      delete [] combinations[row];
 
10306
      delete [] transform[row];
 
10307
    }
 
10308
    
 
10309
    delete [] combinations;
 
10310
    delete [] transform;
 
10311
}
 
10312
 
 
10313
/// Evaluate order n derivatives of all basis functions at given point in cell
 
10314
void cahnhilliard2d_1_finite_element_1_1::evaluate_basis_derivatives_all(unsigned int n,
 
10315
                                                   double* values,
 
10316
                                                   const double* coordinates,
 
10317
                                                   const ufc::cell& c) const
 
10318
{
 
10319
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
10320
}
 
10321
 
 
10322
/// Evaluate linear functional for dof i on the function f
 
10323
double cahnhilliard2d_1_finite_element_1_1::evaluate_dof(unsigned int i,
 
10324
                                   const ufc::function& f,
 
10325
                                   const ufc::cell& c) const
 
10326
{
 
10327
    // The reference points, direction and weights:
 
10328
    static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
 
10329
    static const double W[3][1] = {{1}, {1}, {1}};
 
10330
    static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
 
10331
    
 
10332
    const double * const * x = c.coordinates;
 
10333
    double result = 0.0;
 
10334
    // Iterate over the points:
 
10335
    // Evaluate basis functions for affine mapping
 
10336
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
10337
    const double w1 = X[i][0][0];
 
10338
    const double w2 = X[i][0][1];
 
10339
    
 
10340
    // Compute affine mapping y = F(X)
 
10341
    double y[2];
 
10342
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
10343
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
10344
    
 
10345
    // Evaluate function at physical points
 
10346
    double values[1];
 
10347
    f.evaluate(values, y, c);
 
10348
    
 
10349
    // Map function values using appropriate mapping
 
10350
    // Affine map: Do nothing
 
10351
    
 
10352
    // Note that we do not map the weights (yet).
 
10353
    
 
10354
    // Take directional components
 
10355
    for(int k = 0; k < 1; k++)
 
10356
      result += values[k]*D[i][0][k];
 
10357
    // Multiply by weights
 
10358
    result *= W[i][0];
 
10359
    
 
10360
    return result;
 
10361
}
 
10362
 
 
10363
/// Evaluate linear functionals for all dofs on the function f
 
10364
void cahnhilliard2d_1_finite_element_1_1::evaluate_dofs(double* values,
 
10365
                                  const ufc::function& f,
 
10366
                                  const ufc::cell& c) const
 
10367
{
 
10368
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
10369
}
 
10370
 
 
10371
/// Interpolate vertex values from dof values
 
10372
void cahnhilliard2d_1_finite_element_1_1::interpolate_vertex_values(double* vertex_values,
 
10373
                                              const double* dof_values,
 
10374
                                              const ufc::cell& c) const
 
10375
{
 
10376
    // Evaluate at vertices and use affine mapping
 
10377
    vertex_values[0] = dof_values[0];
 
10378
    vertex_values[1] = dof_values[1];
 
10379
    vertex_values[2] = dof_values[2];
 
10380
}
 
10381
 
 
10382
/// Return the number of sub elements (for a mixed element)
 
10383
unsigned int cahnhilliard2d_1_finite_element_1_1::num_sub_elements() const
 
10384
{
 
10385
    return 1;
 
10386
}
 
10387
 
 
10388
/// Create a new finite element for sub element i (for a mixed element)
 
10389
ufc::finite_element* cahnhilliard2d_1_finite_element_1_1::create_sub_element(unsigned int i) const
 
10390
{
 
10391
    return new cahnhilliard2d_1_finite_element_1_1();
 
10392
}
 
10393
 
 
10394
 
 
10395
/// Constructor
 
10396
cahnhilliard2d_1_finite_element_1::cahnhilliard2d_1_finite_element_1() : ufc::finite_element()
 
10397
{
 
10398
    // Do nothing
 
10399
}
 
10400
 
 
10401
/// Destructor
 
10402
cahnhilliard2d_1_finite_element_1::~cahnhilliard2d_1_finite_element_1()
 
10403
{
 
10404
    // Do nothing
 
10405
}
 
10406
 
 
10407
/// Return a string identifying the finite element
 
10408
const char* cahnhilliard2d_1_finite_element_1::signature() const
 
10409
{
 
10410
    return "MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
 
10411
}
 
10412
 
 
10413
/// Return the cell shape
 
10414
ufc::shape cahnhilliard2d_1_finite_element_1::cell_shape() const
 
10415
{
 
10416
    return ufc::triangle;
 
10417
}
 
10418
 
 
10419
/// Return the dimension of the finite element function space
 
10420
unsigned int cahnhilliard2d_1_finite_element_1::space_dimension() const
 
10421
{
 
10422
    return 6;
 
10423
}
 
10424
 
 
10425
/// Return the rank of the value space
 
10426
unsigned int cahnhilliard2d_1_finite_element_1::value_rank() const
 
10427
{
 
10428
    return 1;
 
10429
}
 
10430
 
 
10431
/// Return the dimension of the value space for axis i
 
10432
unsigned int cahnhilliard2d_1_finite_element_1::value_dimension(unsigned int i) const
 
10433
{
 
10434
    return 2;
 
10435
}
 
10436
 
 
10437
/// Evaluate basis function i at given point in cell
 
10438
void cahnhilliard2d_1_finite_element_1::evaluate_basis(unsigned int i,
 
10439
                                   double* values,
 
10440
                                   const double* coordinates,
 
10441
                                   const ufc::cell& c) const
 
10442
{
 
10443
    // Extract vertex coordinates
 
10444
    const double * const * element_coordinates = c.coordinates;
 
10445
    
 
10446
    // Compute Jacobian of affine map from reference cell
 
10447
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
10448
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
10449
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
10450
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
10451
    
 
10452
    // Compute determinant of Jacobian
 
10453
    const double detJ = J_00*J_11 - J_01*J_10;
 
10454
    
 
10455
    // Compute inverse of Jacobian
 
10456
    
 
10457
    // Get coordinates and map to the reference (UFC) element
 
10458
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
10459
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
10460
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
10461
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
10462
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
10463
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
10464
    
 
10465
    // Map coordinates to the reference square
 
10466
    if (std::abs(y - 1.0) < 1e-14)
 
10467
      x = -1.0;
 
10468
    else
 
10469
      x = 2.0 *x/(1.0 - y) - 1.0;
 
10470
    y = 2.0*y - 1.0;
 
10471
    
 
10472
    // Reset values
 
10473
    values[0] = 0;
 
10474
    values[1] = 0;
 
10475
    
 
10476
    if (0 <= i && i <= 2)
 
10477
    {
 
10478
      // Map degree of freedom to element degree of freedom
 
10479
      const unsigned int dof = i;
 
10480
    
 
10481
      // Generate scalings
 
10482
      const double scalings_y_0 = 1;
 
10483
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
10484
    
 
10485
      // Compute psitilde_a
 
10486
      const double psitilde_a_0 = 1;
 
10487
      const double psitilde_a_1 = x;
 
10488
    
 
10489
      // Compute psitilde_bs
 
10490
      const double psitilde_bs_0_0 = 1;
 
10491
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
10492
      const double psitilde_bs_1_0 = 1;
 
10493
    
 
10494
      // Compute basisvalues
 
10495
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
10496
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
10497
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
10498
    
 
10499
      // Table(s) of coefficients
 
10500
      static const double coefficients0[3][3] =   \
 
10501
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
10502
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
10503
      {0.471404520791032, 0, 0.333333333333333}};
 
10504
    
 
10505
      // Extract relevant coefficients
 
10506
      const double coeff0_0 =   coefficients0[dof][0];
 
10507
      const double coeff0_1 =   coefficients0[dof][1];
 
10508
      const double coeff0_2 =   coefficients0[dof][2];
 
10509
    
 
10510
      // Compute value(s)
 
10511
      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
10512
    }
 
10513
    
 
10514
    if (3 <= i && i <= 5)
 
10515
    {
 
10516
      // Map degree of freedom to element degree of freedom
 
10517
      const unsigned int dof = i - 3;
 
10518
    
 
10519
      // Generate scalings
 
10520
      const double scalings_y_0 = 1;
 
10521
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
10522
    
 
10523
      // Compute psitilde_a
 
10524
      const double psitilde_a_0 = 1;
 
10525
      const double psitilde_a_1 = x;
 
10526
    
 
10527
      // Compute psitilde_bs
 
10528
      const double psitilde_bs_0_0 = 1;
 
10529
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
10530
      const double psitilde_bs_1_0 = 1;
 
10531
    
 
10532
      // Compute basisvalues
 
10533
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
10534
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
10535
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
10536
    
 
10537
      // Table(s) of coefficients
 
10538
      static const double coefficients0[3][3] =   \
 
10539
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
10540
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
10541
      {0.471404520791032, 0, 0.333333333333333}};
 
10542
    
 
10543
      // Extract relevant coefficients
 
10544
      const double coeff0_0 =   coefficients0[dof][0];
 
10545
      const double coeff0_1 =   coefficients0[dof][1];
 
10546
      const double coeff0_2 =   coefficients0[dof][2];
 
10547
    
 
10548
      // Compute value(s)
 
10549
      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
10550
    }
 
10551
    
 
10552
}
 
10553
 
 
10554
/// Evaluate all basis functions at given point in cell
 
10555
void cahnhilliard2d_1_finite_element_1::evaluate_basis_all(double* values,
 
10556
                                       const double* coordinates,
 
10557
                                       const ufc::cell& c) const
 
10558
{
 
10559
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
10560
}
 
10561
 
 
10562
/// Evaluate order n derivatives of basis function i at given point in cell
 
10563
void cahnhilliard2d_1_finite_element_1::evaluate_basis_derivatives(unsigned int i,
 
10564
                                               unsigned int n,
 
10565
                                               double* values,
 
10566
                                               const double* coordinates,
 
10567
                                               const ufc::cell& c) const
 
10568
{
 
10569
    // Extract vertex coordinates
 
10570
    const double * const * element_coordinates = c.coordinates;
 
10571
    
 
10572
    // Compute Jacobian of affine map from reference cell
 
10573
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
10574
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
10575
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
10576
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
10577
    
 
10578
    // Compute determinant of Jacobian
 
10579
    const double detJ = J_00*J_11 - J_01*J_10;
 
10580
    
 
10581
    // Compute inverse of Jacobian
 
10582
    
 
10583
    // Get coordinates and map to the reference (UFC) element
 
10584
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
10585
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
10586
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
10587
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
10588
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
10589
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
10590
    
 
10591
    // Map coordinates to the reference square
 
10592
    if (std::abs(y - 1.0) < 1e-14)
 
10593
      x = -1.0;
 
10594
    else
 
10595
      x = 2.0 *x/(1.0 - y) - 1.0;
 
10596
    y = 2.0*y - 1.0;
 
10597
    
 
10598
    // Compute number of derivatives
 
10599
    unsigned int num_derivatives = 1;
 
10600
    
 
10601
    for (unsigned int j = 0; j < n; j++)
 
10602
      num_derivatives *= 2;
 
10603
    
 
10604
    
 
10605
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
10606
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
10607
    
 
10608
    for (unsigned int j = 0; j < num_derivatives; j++)
 
10609
    {
 
10610
      combinations[j] = new unsigned int [n];
 
10611
      for (unsigned int k = 0; k < n; k++)
 
10612
        combinations[j][k] = 0;
 
10613
    }
 
10614
    
 
10615
    // Generate combinations of derivatives
 
10616
    for (unsigned int row = 1; row < num_derivatives; row++)
 
10617
    {
 
10618
      for (unsigned int num = 0; num < row; num++)
 
10619
      {
 
10620
        for (unsigned int col = n-1; col+1 > 0; col--)
 
10621
        {
 
10622
          if (combinations[row][col] + 1 > 1)
 
10623
            combinations[row][col] = 0;
 
10624
          else
 
10625
          {
 
10626
            combinations[row][col] += 1;
 
10627
            break;
 
10628
          }
 
10629
        }
 
10630
      }
 
10631
    }
 
10632
    
 
10633
    // Compute inverse of Jacobian
 
10634
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
10635
    
 
10636
    // Declare transformation matrix
 
10637
    // Declare pointer to two dimensional array and initialise
 
10638
    double **transform = new double *[num_derivatives];
 
10639
    
 
10640
    for (unsigned int j = 0; j < num_derivatives; j++)
 
10641
    {
 
10642
      transform[j] = new double [num_derivatives];
 
10643
      for (unsigned int k = 0; k < num_derivatives; k++)
 
10644
        transform[j][k] = 1;
 
10645
    }
 
10646
    
 
10647
    // Construct transformation matrix
 
10648
    for (unsigned int row = 0; row < num_derivatives; row++)
 
10649
    {
 
10650
      for (unsigned int col = 0; col < num_derivatives; col++)
 
10651
      {
 
10652
        for (unsigned int k = 0; k < n; k++)
 
10653
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
10654
      }
 
10655
    }
 
10656
    
 
10657
    // Reset values
 
10658
    for (unsigned int j = 0; j < 2*num_derivatives; j++)
 
10659
      values[j] = 0;
 
10660
    
 
10661
    if (0 <= i && i <= 2)
 
10662
    {
 
10663
      // Map degree of freedom to element degree of freedom
 
10664
      const unsigned int dof = i;
 
10665
    
 
10666
      // Generate scalings
 
10667
      const double scalings_y_0 = 1;
 
10668
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
10669
    
 
10670
      // Compute psitilde_a
 
10671
      const double psitilde_a_0 = 1;
 
10672
      const double psitilde_a_1 = x;
 
10673
    
 
10674
      // Compute psitilde_bs
 
10675
      const double psitilde_bs_0_0 = 1;
 
10676
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
10677
      const double psitilde_bs_1_0 = 1;
 
10678
    
 
10679
      // Compute basisvalues
 
10680
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
10681
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
10682
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
10683
    
 
10684
      // Table(s) of coefficients
 
10685
      static const double coefficients0[3][3] =   \
 
10686
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
10687
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
10688
      {0.471404520791032, 0, 0.333333333333333}};
 
10689
    
 
10690
      // Interesting (new) part
 
10691
      // Tables of derivatives of the polynomial base (transpose)
 
10692
      static const double dmats0[3][3] =   \
 
10693
      {{0, 0, 0},
 
10694
      {4.89897948556636, 0, 0},
 
10695
      {0, 0, 0}};
 
10696
    
 
10697
      static const double dmats1[3][3] =   \
 
10698
      {{0, 0, 0},
 
10699
      {2.44948974278318, 0, 0},
 
10700
      {4.24264068711928, 0, 0}};
 
10701
    
 
10702
      // Compute reference derivatives
 
10703
      // Declare pointer to array of derivatives on FIAT element
 
10704
      double *derivatives = new double [num_derivatives];
 
10705
    
 
10706
      // Declare coefficients
 
10707
      double coeff0_0 = 0;
 
10708
      double coeff0_1 = 0;
 
10709
      double coeff0_2 = 0;
 
10710
    
 
10711
      // Declare new coefficients
 
10712
      double new_coeff0_0 = 0;
 
10713
      double new_coeff0_1 = 0;
 
10714
      double new_coeff0_2 = 0;
 
10715
    
 
10716
      // Loop possible derivatives
 
10717
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
10718
      {
 
10719
        // Get values from coefficients array
 
10720
        new_coeff0_0 = coefficients0[dof][0];
 
10721
        new_coeff0_1 = coefficients0[dof][1];
 
10722
        new_coeff0_2 = coefficients0[dof][2];
 
10723
    
 
10724
        // Loop derivative order
 
10725
        for (unsigned int j = 0; j < n; j++)
 
10726
        {
 
10727
          // Update old coefficients
 
10728
          coeff0_0 = new_coeff0_0;
 
10729
          coeff0_1 = new_coeff0_1;
 
10730
          coeff0_2 = new_coeff0_2;
 
10731
    
 
10732
          if(combinations[deriv_num][j] == 0)
 
10733
          {
 
10734
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
10735
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
10736
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
10737
          }
 
10738
          if(combinations[deriv_num][j] == 1)
 
10739
          {
 
10740
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
10741
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
10742
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
10743
          }
 
10744
    
 
10745
        }
 
10746
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
10747
        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
10748
      }
 
10749
    
 
10750
      // Transform derivatives back to physical element
 
10751
      for (unsigned int row = 0; row < num_derivatives; row++)
 
10752
      {
 
10753
        for (unsigned int col = 0; col < num_derivatives; col++)
 
10754
        {
 
10755
          values[row] += transform[row][col]*derivatives[col];
 
10756
        }
 
10757
      }
 
10758
      // Delete pointer to array of derivatives on FIAT element
 
10759
      delete [] derivatives;
 
10760
    
 
10761
      // Delete pointer to array of combinations of derivatives and transform
 
10762
      for (unsigned int row = 0; row < num_derivatives; row++)
 
10763
      {
 
10764
        delete [] combinations[row];
 
10765
        delete [] transform[row];
 
10766
      }
 
10767
    
 
10768
      delete [] combinations;
 
10769
      delete [] transform;
 
10770
    }
 
10771
    
 
10772
    if (3 <= i && i <= 5)
 
10773
    {
 
10774
      // Map degree of freedom to element degree of freedom
 
10775
      const unsigned int dof = i - 3;
 
10776
    
 
10777
      // Generate scalings
 
10778
      const double scalings_y_0 = 1;
 
10779
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
10780
    
 
10781
      // Compute psitilde_a
 
10782
      const double psitilde_a_0 = 1;
 
10783
      const double psitilde_a_1 = x;
 
10784
    
 
10785
      // Compute psitilde_bs
 
10786
      const double psitilde_bs_0_0 = 1;
 
10787
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
10788
      const double psitilde_bs_1_0 = 1;
 
10789
    
 
10790
      // Compute basisvalues
 
10791
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
10792
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
10793
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
10794
    
 
10795
      // Table(s) of coefficients
 
10796
      static const double coefficients0[3][3] =   \
 
10797
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
10798
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
10799
      {0.471404520791032, 0, 0.333333333333333}};
 
10800
    
 
10801
      // Interesting (new) part
 
10802
      // Tables of derivatives of the polynomial base (transpose)
 
10803
      static const double dmats0[3][3] =   \
 
10804
      {{0, 0, 0},
 
10805
      {4.89897948556636, 0, 0},
 
10806
      {0, 0, 0}};
 
10807
    
 
10808
      static const double dmats1[3][3] =   \
 
10809
      {{0, 0, 0},
 
10810
      {2.44948974278318, 0, 0},
 
10811
      {4.24264068711928, 0, 0}};
 
10812
    
 
10813
      // Compute reference derivatives
 
10814
      // Declare pointer to array of derivatives on FIAT element
 
10815
      double *derivatives = new double [num_derivatives];
 
10816
    
 
10817
      // Declare coefficients
 
10818
      double coeff0_0 = 0;
 
10819
      double coeff0_1 = 0;
 
10820
      double coeff0_2 = 0;
 
10821
    
 
10822
      // Declare new coefficients
 
10823
      double new_coeff0_0 = 0;
 
10824
      double new_coeff0_1 = 0;
 
10825
      double new_coeff0_2 = 0;
 
10826
    
 
10827
      // Loop possible derivatives
 
10828
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
10829
      {
 
10830
        // Get values from coefficients array
 
10831
        new_coeff0_0 = coefficients0[dof][0];
 
10832
        new_coeff0_1 = coefficients0[dof][1];
 
10833
        new_coeff0_2 = coefficients0[dof][2];
 
10834
    
 
10835
        // Loop derivative order
 
10836
        for (unsigned int j = 0; j < n; j++)
 
10837
        {
 
10838
          // Update old coefficients
 
10839
          coeff0_0 = new_coeff0_0;
 
10840
          coeff0_1 = new_coeff0_1;
 
10841
          coeff0_2 = new_coeff0_2;
 
10842
    
 
10843
          if(combinations[deriv_num][j] == 0)
 
10844
          {
 
10845
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
10846
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
10847
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
10848
          }
 
10849
          if(combinations[deriv_num][j] == 1)
 
10850
          {
 
10851
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
10852
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
10853
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
10854
          }
 
10855
    
 
10856
        }
 
10857
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
10858
        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
10859
      }
 
10860
    
 
10861
      // Transform derivatives back to physical element
 
10862
      for (unsigned int row = 0; row < num_derivatives; row++)
 
10863
      {
 
10864
        for (unsigned int col = 0; col < num_derivatives; col++)
 
10865
        {
 
10866
          values[num_derivatives + row] += transform[row][col]*derivatives[col];
 
10867
        }
 
10868
      }
 
10869
      // Delete pointer to array of derivatives on FIAT element
 
10870
      delete [] derivatives;
 
10871
    
 
10872
      // Delete pointer to array of combinations of derivatives and transform
 
10873
      for (unsigned int row = 0; row < num_derivatives; row++)
 
10874
      {
 
10875
        delete [] combinations[row];
 
10876
        delete [] transform[row];
 
10877
      }
 
10878
    
 
10879
      delete [] combinations;
 
10880
      delete [] transform;
 
10881
    }
 
10882
    
 
10883
}
 
10884
 
 
10885
/// Evaluate order n derivatives of all basis functions at given point in cell
 
10886
void cahnhilliard2d_1_finite_element_1::evaluate_basis_derivatives_all(unsigned int n,
 
10887
                                                   double* values,
 
10888
                                                   const double* coordinates,
 
10889
                                                   const ufc::cell& c) const
 
10890
{
 
10891
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
10892
}
 
10893
 
 
10894
/// Evaluate linear functional for dof i on the function f
 
10895
double cahnhilliard2d_1_finite_element_1::evaluate_dof(unsigned int i,
 
10896
                                   const ufc::function& f,
 
10897
                                   const ufc::cell& c) const
 
10898
{
 
10899
    // The reference points, direction and weights:
 
10900
    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
 
10901
    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
 
10902
    static const double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
 
10903
    
 
10904
    const double * const * x = c.coordinates;
 
10905
    double result = 0.0;
 
10906
    // Iterate over the points:
 
10907
    // Evaluate basis functions for affine mapping
 
10908
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
10909
    const double w1 = X[i][0][0];
 
10910
    const double w2 = X[i][0][1];
 
10911
    
 
10912
    // Compute affine mapping y = F(X)
 
10913
    double y[2];
 
10914
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
10915
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
10916
    
 
10917
    // Evaluate function at physical points
 
10918
    double values[2];
 
10919
    f.evaluate(values, y, c);
 
10920
    
 
10921
    // Map function values using appropriate mapping
 
10922
    // Affine map: Do nothing
 
10923
    
 
10924
    // Note that we do not map the weights (yet).
 
10925
    
 
10926
    // Take directional components
 
10927
    for(int k = 0; k < 2; k++)
 
10928
      result += values[k]*D[i][0][k];
 
10929
    // Multiply by weights
 
10930
    result *= W[i][0];
 
10931
    
 
10932
    return result;
 
10933
}
 
10934
 
 
10935
/// Evaluate linear functionals for all dofs on the function f
 
10936
void cahnhilliard2d_1_finite_element_1::evaluate_dofs(double* values,
 
10937
                                  const ufc::function& f,
 
10938
                                  const ufc::cell& c) const
 
10939
{
 
10940
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
10941
}
 
10942
 
 
10943
/// Interpolate vertex values from dof values
 
10944
void cahnhilliard2d_1_finite_element_1::interpolate_vertex_values(double* vertex_values,
 
10945
                                              const double* dof_values,
 
10946
                                              const ufc::cell& c) const
 
10947
{
 
10948
    // Evaluate at vertices and use affine mapping
 
10949
    vertex_values[0] = dof_values[0];
 
10950
    vertex_values[2] = dof_values[1];
 
10951
    vertex_values[4] = dof_values[2];
 
10952
    // Evaluate at vertices and use affine mapping
 
10953
    vertex_values[1] = dof_values[3];
 
10954
    vertex_values[3] = dof_values[4];
 
10955
    vertex_values[5] = dof_values[5];
 
10956
}
 
10957
 
 
10958
/// Return the number of sub elements (for a mixed element)
 
10959
unsigned int cahnhilliard2d_1_finite_element_1::num_sub_elements() const
 
10960
{
 
10961
    return 2;
 
10962
}
 
10963
 
 
10964
/// Create a new finite element for sub element i (for a mixed element)
 
10965
ufc::finite_element* cahnhilliard2d_1_finite_element_1::create_sub_element(unsigned int i) const
 
10966
{
 
10967
    switch ( i )
 
10968
    {
 
10969
    case 0:
 
10970
      return new cahnhilliard2d_1_finite_element_1_0();
 
10971
      break;
 
10972
    case 1:
 
10973
      return new cahnhilliard2d_1_finite_element_1_1();
 
10974
      break;
 
10975
    }
 
10976
    return 0;
 
10977
}
 
10978
 
 
10979
 
 
10980
/// Constructor
 
10981
cahnhilliard2d_1_finite_element_2_0::cahnhilliard2d_1_finite_element_2_0() : ufc::finite_element()
 
10982
{
 
10983
    // Do nothing
 
10984
}
 
10985
 
 
10986
/// Destructor
 
10987
cahnhilliard2d_1_finite_element_2_0::~cahnhilliard2d_1_finite_element_2_0()
 
10988
{
 
10989
    // Do nothing
 
10990
}
 
10991
 
 
10992
/// Return a string identifying the finite element
 
10993
const char* cahnhilliard2d_1_finite_element_2_0::signature() const
 
10994
{
 
10995
    return "FiniteElement('Lagrange', 'triangle', 1)";
 
10996
}
 
10997
 
 
10998
/// Return the cell shape
 
10999
ufc::shape cahnhilliard2d_1_finite_element_2_0::cell_shape() const
 
11000
{
 
11001
    return ufc::triangle;
 
11002
}
 
11003
 
 
11004
/// Return the dimension of the finite element function space
 
11005
unsigned int cahnhilliard2d_1_finite_element_2_0::space_dimension() const
 
11006
{
 
11007
    return 3;
 
11008
}
 
11009
 
 
11010
/// Return the rank of the value space
 
11011
unsigned int cahnhilliard2d_1_finite_element_2_0::value_rank() const
 
11012
{
 
11013
    return 0;
 
11014
}
 
11015
 
 
11016
/// Return the dimension of the value space for axis i
 
11017
unsigned int cahnhilliard2d_1_finite_element_2_0::value_dimension(unsigned int i) const
 
11018
{
 
11019
    return 1;
 
11020
}
 
11021
 
 
11022
/// Evaluate basis function i at given point in cell
 
11023
void cahnhilliard2d_1_finite_element_2_0::evaluate_basis(unsigned int i,
 
11024
                                   double* values,
 
11025
                                   const double* coordinates,
 
11026
                                   const ufc::cell& c) const
 
11027
{
 
11028
    // Extract vertex coordinates
 
11029
    const double * const * element_coordinates = c.coordinates;
 
11030
    
 
11031
    // Compute Jacobian of affine map from reference cell
 
11032
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
11033
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
11034
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
11035
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
11036
    
 
11037
    // Compute determinant of Jacobian
 
11038
    const double detJ = J_00*J_11 - J_01*J_10;
 
11039
    
 
11040
    // Compute inverse of Jacobian
 
11041
    
 
11042
    // Get coordinates and map to the reference (UFC) element
 
11043
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
11044
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
11045
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
11046
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
11047
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
11048
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
11049
    
 
11050
    // Map coordinates to the reference square
 
11051
    if (std::abs(y - 1.0) < 1e-14)
 
11052
      x = -1.0;
 
11053
    else
 
11054
      x = 2.0 *x/(1.0 - y) - 1.0;
 
11055
    y = 2.0*y - 1.0;
 
11056
    
 
11057
    // Reset values
 
11058
    *values = 0;
 
11059
    
 
11060
    // Map degree of freedom to element degree of freedom
 
11061
    const unsigned int dof = i;
 
11062
    
 
11063
    // Generate scalings
 
11064
    const double scalings_y_0 = 1;
 
11065
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
11066
    
 
11067
    // Compute psitilde_a
 
11068
    const double psitilde_a_0 = 1;
 
11069
    const double psitilde_a_1 = x;
 
11070
    
 
11071
    // Compute psitilde_bs
 
11072
    const double psitilde_bs_0_0 = 1;
 
11073
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
11074
    const double psitilde_bs_1_0 = 1;
 
11075
    
 
11076
    // Compute basisvalues
 
11077
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
11078
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
11079
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
11080
    
 
11081
    // Table(s) of coefficients
 
11082
    static const double coefficients0[3][3] = \
 
11083
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
11084
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
11085
    {0.471404520791032, 0, 0.333333333333333}};
 
11086
    
 
11087
    // Extract relevant coefficients
 
11088
    const double coeff0_0 = coefficients0[dof][0];
 
11089
    const double coeff0_1 = coefficients0[dof][1];
 
11090
    const double coeff0_2 = coefficients0[dof][2];
 
11091
    
 
11092
    // Compute value(s)
 
11093
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
11094
}
 
11095
 
 
11096
/// Evaluate all basis functions at given point in cell
 
11097
void cahnhilliard2d_1_finite_element_2_0::evaluate_basis_all(double* values,
 
11098
                                       const double* coordinates,
 
11099
                                       const ufc::cell& c) const
 
11100
{
 
11101
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
11102
}
 
11103
 
 
11104
/// Evaluate order n derivatives of basis function i at given point in cell
 
11105
void cahnhilliard2d_1_finite_element_2_0::evaluate_basis_derivatives(unsigned int i,
 
11106
                                               unsigned int n,
 
11107
                                               double* values,
 
11108
                                               const double* coordinates,
 
11109
                                               const ufc::cell& c) const
 
11110
{
 
11111
    // Extract vertex coordinates
 
11112
    const double * const * element_coordinates = c.coordinates;
 
11113
    
 
11114
    // Compute Jacobian of affine map from reference cell
 
11115
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
11116
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
11117
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
11118
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
11119
    
 
11120
    // Compute determinant of Jacobian
 
11121
    const double detJ = J_00*J_11 - J_01*J_10;
 
11122
    
 
11123
    // Compute inverse of Jacobian
 
11124
    
 
11125
    // Get coordinates and map to the reference (UFC) element
 
11126
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
11127
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
11128
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
11129
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
11130
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
11131
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
11132
    
 
11133
    // Map coordinates to the reference square
 
11134
    if (std::abs(y - 1.0) < 1e-14)
 
11135
      x = -1.0;
 
11136
    else
 
11137
      x = 2.0 *x/(1.0 - y) - 1.0;
 
11138
    y = 2.0*y - 1.0;
 
11139
    
 
11140
    // Compute number of derivatives
 
11141
    unsigned int num_derivatives = 1;
 
11142
    
 
11143
    for (unsigned int j = 0; j < n; j++)
 
11144
      num_derivatives *= 2;
 
11145
    
 
11146
    
 
11147
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
11148
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
11149
    
 
11150
    for (unsigned int j = 0; j < num_derivatives; j++)
 
11151
    {
 
11152
      combinations[j] = new unsigned int [n];
 
11153
      for (unsigned int k = 0; k < n; k++)
 
11154
        combinations[j][k] = 0;
 
11155
    }
 
11156
    
 
11157
    // Generate combinations of derivatives
 
11158
    for (unsigned int row = 1; row < num_derivatives; row++)
 
11159
    {
 
11160
      for (unsigned int num = 0; num < row; num++)
 
11161
      {
 
11162
        for (unsigned int col = n-1; col+1 > 0; col--)
 
11163
        {
 
11164
          if (combinations[row][col] + 1 > 1)
 
11165
            combinations[row][col] = 0;
 
11166
          else
 
11167
          {
 
11168
            combinations[row][col] += 1;
 
11169
            break;
 
11170
          }
 
11171
        }
 
11172
      }
 
11173
    }
 
11174
    
 
11175
    // Compute inverse of Jacobian
 
11176
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
11177
    
 
11178
    // Declare transformation matrix
 
11179
    // Declare pointer to two dimensional array and initialise
 
11180
    double **transform = new double *[num_derivatives];
 
11181
    
 
11182
    for (unsigned int j = 0; j < num_derivatives; j++)
 
11183
    {
 
11184
      transform[j] = new double [num_derivatives];
 
11185
      for (unsigned int k = 0; k < num_derivatives; k++)
 
11186
        transform[j][k] = 1;
 
11187
    }
 
11188
    
 
11189
    // Construct transformation matrix
 
11190
    for (unsigned int row = 0; row < num_derivatives; row++)
 
11191
    {
 
11192
      for (unsigned int col = 0; col < num_derivatives; col++)
 
11193
      {
 
11194
        for (unsigned int k = 0; k < n; k++)
 
11195
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
11196
      }
 
11197
    }
 
11198
    
 
11199
    // Reset values
 
11200
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
 
11201
      values[j] = 0;
 
11202
    
 
11203
    // Map degree of freedom to element degree of freedom
 
11204
    const unsigned int dof = i;
 
11205
    
 
11206
    // Generate scalings
 
11207
    const double scalings_y_0 = 1;
 
11208
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
11209
    
 
11210
    // Compute psitilde_a
 
11211
    const double psitilde_a_0 = 1;
 
11212
    const double psitilde_a_1 = x;
 
11213
    
 
11214
    // Compute psitilde_bs
 
11215
    const double psitilde_bs_0_0 = 1;
 
11216
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
11217
    const double psitilde_bs_1_0 = 1;
 
11218
    
 
11219
    // Compute basisvalues
 
11220
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
11221
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
11222
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
11223
    
 
11224
    // Table(s) of coefficients
 
11225
    static const double coefficients0[3][3] = \
 
11226
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
11227
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
11228
    {0.471404520791032, 0, 0.333333333333333}};
 
11229
    
 
11230
    // Interesting (new) part
 
11231
    // Tables of derivatives of the polynomial base (transpose)
 
11232
    static const double dmats0[3][3] = \
 
11233
    {{0, 0, 0},
 
11234
    {4.89897948556636, 0, 0},
 
11235
    {0, 0, 0}};
 
11236
    
 
11237
    static const double dmats1[3][3] = \
 
11238
    {{0, 0, 0},
 
11239
    {2.44948974278318, 0, 0},
 
11240
    {4.24264068711928, 0, 0}};
 
11241
    
 
11242
    // Compute reference derivatives
 
11243
    // Declare pointer to array of derivatives on FIAT element
 
11244
    double *derivatives = new double [num_derivatives];
 
11245
    
 
11246
    // Declare coefficients
 
11247
    double coeff0_0 = 0;
 
11248
    double coeff0_1 = 0;
 
11249
    double coeff0_2 = 0;
 
11250
    
 
11251
    // Declare new coefficients
 
11252
    double new_coeff0_0 = 0;
 
11253
    double new_coeff0_1 = 0;
 
11254
    double new_coeff0_2 = 0;
 
11255
    
 
11256
    // Loop possible derivatives
 
11257
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
11258
    {
 
11259
      // Get values from coefficients array
 
11260
      new_coeff0_0 = coefficients0[dof][0];
 
11261
      new_coeff0_1 = coefficients0[dof][1];
 
11262
      new_coeff0_2 = coefficients0[dof][2];
 
11263
    
 
11264
      // Loop derivative order
 
11265
      for (unsigned int j = 0; j < n; j++)
 
11266
      {
 
11267
        // Update old coefficients
 
11268
        coeff0_0 = new_coeff0_0;
 
11269
        coeff0_1 = new_coeff0_1;
 
11270
        coeff0_2 = new_coeff0_2;
 
11271
    
 
11272
        if(combinations[deriv_num][j] == 0)
 
11273
        {
 
11274
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
11275
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
11276
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
11277
        }
 
11278
        if(combinations[deriv_num][j] == 1)
 
11279
        {
 
11280
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
11281
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
11282
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
11283
        }
 
11284
    
 
11285
      }
 
11286
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
11287
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
11288
    }
 
11289
    
 
11290
    // Transform derivatives back to physical element
 
11291
    for (unsigned int row = 0; row < num_derivatives; row++)
 
11292
    {
 
11293
      for (unsigned int col = 0; col < num_derivatives; col++)
 
11294
      {
 
11295
        values[row] += transform[row][col]*derivatives[col];
 
11296
      }
 
11297
    }
 
11298
    // Delete pointer to array of derivatives on FIAT element
 
11299
    delete [] derivatives;
 
11300
    
 
11301
    // Delete pointer to array of combinations of derivatives and transform
 
11302
    for (unsigned int row = 0; row < num_derivatives; row++)
 
11303
    {
 
11304
      delete [] combinations[row];
 
11305
      delete [] transform[row];
 
11306
    }
 
11307
    
 
11308
    delete [] combinations;
 
11309
    delete [] transform;
 
11310
}
 
11311
 
 
11312
/// Evaluate order n derivatives of all basis functions at given point in cell
 
11313
void cahnhilliard2d_1_finite_element_2_0::evaluate_basis_derivatives_all(unsigned int n,
 
11314
                                                   double* values,
 
11315
                                                   const double* coordinates,
 
11316
                                                   const ufc::cell& c) const
 
11317
{
 
11318
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
11319
}
 
11320
 
 
11321
/// Evaluate linear functional for dof i on the function f
 
11322
double cahnhilliard2d_1_finite_element_2_0::evaluate_dof(unsigned int i,
 
11323
                                   const ufc::function& f,
 
11324
                                   const ufc::cell& c) const
 
11325
{
 
11326
    // The reference points, direction and weights:
 
11327
    static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
 
11328
    static const double W[3][1] = {{1}, {1}, {1}};
 
11329
    static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
 
11330
    
 
11331
    const double * const * x = c.coordinates;
 
11332
    double result = 0.0;
 
11333
    // Iterate over the points:
 
11334
    // Evaluate basis functions for affine mapping
 
11335
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
11336
    const double w1 = X[i][0][0];
 
11337
    const double w2 = X[i][0][1];
 
11338
    
 
11339
    // Compute affine mapping y = F(X)
 
11340
    double y[2];
 
11341
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
11342
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
11343
    
 
11344
    // Evaluate function at physical points
 
11345
    double values[1];
 
11346
    f.evaluate(values, y, c);
 
11347
    
 
11348
    // Map function values using appropriate mapping
 
11349
    // Affine map: Do nothing
 
11350
    
 
11351
    // Note that we do not map the weights (yet).
 
11352
    
 
11353
    // Take directional components
 
11354
    for(int k = 0; k < 1; k++)
 
11355
      result += values[k]*D[i][0][k];
 
11356
    // Multiply by weights
 
11357
    result *= W[i][0];
 
11358
    
 
11359
    return result;
 
11360
}
 
11361
 
 
11362
/// Evaluate linear functionals for all dofs on the function f
 
11363
void cahnhilliard2d_1_finite_element_2_0::evaluate_dofs(double* values,
 
11364
                                  const ufc::function& f,
 
11365
                                  const ufc::cell& c) const
 
11366
{
 
11367
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
11368
}
 
11369
 
 
11370
/// Interpolate vertex values from dof values
 
11371
void cahnhilliard2d_1_finite_element_2_0::interpolate_vertex_values(double* vertex_values,
 
11372
                                              const double* dof_values,
 
11373
                                              const ufc::cell& c) const
 
11374
{
 
11375
    // Evaluate at vertices and use affine mapping
 
11376
    vertex_values[0] = dof_values[0];
 
11377
    vertex_values[1] = dof_values[1];
 
11378
    vertex_values[2] = dof_values[2];
 
11379
}
 
11380
 
 
11381
/// Return the number of sub elements (for a mixed element)
 
11382
unsigned int cahnhilliard2d_1_finite_element_2_0::num_sub_elements() const
 
11383
{
 
11384
    return 1;
 
11385
}
 
11386
 
 
11387
/// Create a new finite element for sub element i (for a mixed element)
 
11388
ufc::finite_element* cahnhilliard2d_1_finite_element_2_0::create_sub_element(unsigned int i) const
 
11389
{
 
11390
    return new cahnhilliard2d_1_finite_element_2_0();
 
11391
}
 
11392
 
 
11393
 
 
11394
/// Constructor
 
11395
cahnhilliard2d_1_finite_element_2_1::cahnhilliard2d_1_finite_element_2_1() : ufc::finite_element()
 
11396
{
 
11397
    // Do nothing
 
11398
}
 
11399
 
 
11400
/// Destructor
 
11401
cahnhilliard2d_1_finite_element_2_1::~cahnhilliard2d_1_finite_element_2_1()
 
11402
{
 
11403
    // Do nothing
 
11404
}
 
11405
 
 
11406
/// Return a string identifying the finite element
 
11407
const char* cahnhilliard2d_1_finite_element_2_1::signature() const
 
11408
{
 
11409
    return "FiniteElement('Lagrange', 'triangle', 1)";
 
11410
}
 
11411
 
 
11412
/// Return the cell shape
 
11413
ufc::shape cahnhilliard2d_1_finite_element_2_1::cell_shape() const
 
11414
{
 
11415
    return ufc::triangle;
 
11416
}
 
11417
 
 
11418
/// Return the dimension of the finite element function space
 
11419
unsigned int cahnhilliard2d_1_finite_element_2_1::space_dimension() const
 
11420
{
 
11421
    return 3;
 
11422
}
 
11423
 
 
11424
/// Return the rank of the value space
 
11425
unsigned int cahnhilliard2d_1_finite_element_2_1::value_rank() const
 
11426
{
 
11427
    return 0;
 
11428
}
 
11429
 
 
11430
/// Return the dimension of the value space for axis i
 
11431
unsigned int cahnhilliard2d_1_finite_element_2_1::value_dimension(unsigned int i) const
 
11432
{
 
11433
    return 1;
 
11434
}
 
11435
 
 
11436
/// Evaluate basis function i at given point in cell
 
11437
void cahnhilliard2d_1_finite_element_2_1::evaluate_basis(unsigned int i,
 
11438
                                   double* values,
 
11439
                                   const double* coordinates,
 
11440
                                   const ufc::cell& c) const
 
11441
{
 
11442
    // Extract vertex coordinates
 
11443
    const double * const * element_coordinates = c.coordinates;
 
11444
    
 
11445
    // Compute Jacobian of affine map from reference cell
 
11446
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
11447
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
11448
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
11449
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
11450
    
 
11451
    // Compute determinant of Jacobian
 
11452
    const double detJ = J_00*J_11 - J_01*J_10;
 
11453
    
 
11454
    // Compute inverse of Jacobian
 
11455
    
 
11456
    // Get coordinates and map to the reference (UFC) element
 
11457
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
11458
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
11459
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
11460
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
11461
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
11462
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
11463
    
 
11464
    // Map coordinates to the reference square
 
11465
    if (std::abs(y - 1.0) < 1e-14)
 
11466
      x = -1.0;
 
11467
    else
 
11468
      x = 2.0 *x/(1.0 - y) - 1.0;
 
11469
    y = 2.0*y - 1.0;
 
11470
    
 
11471
    // Reset values
 
11472
    *values = 0;
 
11473
    
 
11474
    // Map degree of freedom to element degree of freedom
 
11475
    const unsigned int dof = i;
 
11476
    
 
11477
    // Generate scalings
 
11478
    const double scalings_y_0 = 1;
 
11479
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
11480
    
 
11481
    // Compute psitilde_a
 
11482
    const double psitilde_a_0 = 1;
 
11483
    const double psitilde_a_1 = x;
 
11484
    
 
11485
    // Compute psitilde_bs
 
11486
    const double psitilde_bs_0_0 = 1;
 
11487
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
11488
    const double psitilde_bs_1_0 = 1;
 
11489
    
 
11490
    // Compute basisvalues
 
11491
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
11492
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
11493
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
11494
    
 
11495
    // Table(s) of coefficients
 
11496
    static const double coefficients0[3][3] = \
 
11497
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
11498
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
11499
    {0.471404520791032, 0, 0.333333333333333}};
 
11500
    
 
11501
    // Extract relevant coefficients
 
11502
    const double coeff0_0 = coefficients0[dof][0];
 
11503
    const double coeff0_1 = coefficients0[dof][1];
 
11504
    const double coeff0_2 = coefficients0[dof][2];
 
11505
    
 
11506
    // Compute value(s)
 
11507
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
11508
}
 
11509
 
 
11510
/// Evaluate all basis functions at given point in cell
 
11511
void cahnhilliard2d_1_finite_element_2_1::evaluate_basis_all(double* values,
 
11512
                                       const double* coordinates,
 
11513
                                       const ufc::cell& c) const
 
11514
{
 
11515
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
11516
}
 
11517
 
 
11518
/// Evaluate order n derivatives of basis function i at given point in cell
 
11519
void cahnhilliard2d_1_finite_element_2_1::evaluate_basis_derivatives(unsigned int i,
 
11520
                                               unsigned int n,
 
11521
                                               double* values,
 
11522
                                               const double* coordinates,
 
11523
                                               const ufc::cell& c) const
 
11524
{
 
11525
    // Extract vertex coordinates
 
11526
    const double * const * element_coordinates = c.coordinates;
 
11527
    
 
11528
    // Compute Jacobian of affine map from reference cell
 
11529
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
11530
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
11531
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
11532
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
11533
    
 
11534
    // Compute determinant of Jacobian
 
11535
    const double detJ = J_00*J_11 - J_01*J_10;
 
11536
    
 
11537
    // Compute inverse of Jacobian
 
11538
    
 
11539
    // Get coordinates and map to the reference (UFC) element
 
11540
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
11541
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
11542
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
11543
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
11544
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
11545
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
11546
    
 
11547
    // Map coordinates to the reference square
 
11548
    if (std::abs(y - 1.0) < 1e-14)
 
11549
      x = -1.0;
 
11550
    else
 
11551
      x = 2.0 *x/(1.0 - y) - 1.0;
 
11552
    y = 2.0*y - 1.0;
 
11553
    
 
11554
    // Compute number of derivatives
 
11555
    unsigned int num_derivatives = 1;
 
11556
    
 
11557
    for (unsigned int j = 0; j < n; j++)
 
11558
      num_derivatives *= 2;
 
11559
    
 
11560
    
 
11561
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
11562
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
11563
    
 
11564
    for (unsigned int j = 0; j < num_derivatives; j++)
 
11565
    {
 
11566
      combinations[j] = new unsigned int [n];
 
11567
      for (unsigned int k = 0; k < n; k++)
 
11568
        combinations[j][k] = 0;
 
11569
    }
 
11570
    
 
11571
    // Generate combinations of derivatives
 
11572
    for (unsigned int row = 1; row < num_derivatives; row++)
 
11573
    {
 
11574
      for (unsigned int num = 0; num < row; num++)
 
11575
      {
 
11576
        for (unsigned int col = n-1; col+1 > 0; col--)
 
11577
        {
 
11578
          if (combinations[row][col] + 1 > 1)
 
11579
            combinations[row][col] = 0;
 
11580
          else
 
11581
          {
 
11582
            combinations[row][col] += 1;
 
11583
            break;
 
11584
          }
 
11585
        }
 
11586
      }
 
11587
    }
 
11588
    
 
11589
    // Compute inverse of Jacobian
 
11590
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
11591
    
 
11592
    // Declare transformation matrix
 
11593
    // Declare pointer to two dimensional array and initialise
 
11594
    double **transform = new double *[num_derivatives];
 
11595
    
 
11596
    for (unsigned int j = 0; j < num_derivatives; j++)
 
11597
    {
 
11598
      transform[j] = new double [num_derivatives];
 
11599
      for (unsigned int k = 0; k < num_derivatives; k++)
 
11600
        transform[j][k] = 1;
 
11601
    }
 
11602
    
 
11603
    // Construct transformation matrix
 
11604
    for (unsigned int row = 0; row < num_derivatives; row++)
 
11605
    {
 
11606
      for (unsigned int col = 0; col < num_derivatives; col++)
 
11607
      {
 
11608
        for (unsigned int k = 0; k < n; k++)
 
11609
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
11610
      }
 
11611
    }
 
11612
    
 
11613
    // Reset values
 
11614
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
 
11615
      values[j] = 0;
 
11616
    
 
11617
    // Map degree of freedom to element degree of freedom
 
11618
    const unsigned int dof = i;
 
11619
    
 
11620
    // Generate scalings
 
11621
    const double scalings_y_0 = 1;
 
11622
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
11623
    
 
11624
    // Compute psitilde_a
 
11625
    const double psitilde_a_0 = 1;
 
11626
    const double psitilde_a_1 = x;
 
11627
    
 
11628
    // Compute psitilde_bs
 
11629
    const double psitilde_bs_0_0 = 1;
 
11630
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
11631
    const double psitilde_bs_1_0 = 1;
 
11632
    
 
11633
    // Compute basisvalues
 
11634
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
11635
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
11636
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
11637
    
 
11638
    // Table(s) of coefficients
 
11639
    static const double coefficients0[3][3] = \
 
11640
    {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
11641
    {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
11642
    {0.471404520791032, 0, 0.333333333333333}};
 
11643
    
 
11644
    // Interesting (new) part
 
11645
    // Tables of derivatives of the polynomial base (transpose)
 
11646
    static const double dmats0[3][3] = \
 
11647
    {{0, 0, 0},
 
11648
    {4.89897948556636, 0, 0},
 
11649
    {0, 0, 0}};
 
11650
    
 
11651
    static const double dmats1[3][3] = \
 
11652
    {{0, 0, 0},
 
11653
    {2.44948974278318, 0, 0},
 
11654
    {4.24264068711928, 0, 0}};
 
11655
    
 
11656
    // Compute reference derivatives
 
11657
    // Declare pointer to array of derivatives on FIAT element
 
11658
    double *derivatives = new double [num_derivatives];
 
11659
    
 
11660
    // Declare coefficients
 
11661
    double coeff0_0 = 0;
 
11662
    double coeff0_1 = 0;
 
11663
    double coeff0_2 = 0;
 
11664
    
 
11665
    // Declare new coefficients
 
11666
    double new_coeff0_0 = 0;
 
11667
    double new_coeff0_1 = 0;
 
11668
    double new_coeff0_2 = 0;
 
11669
    
 
11670
    // Loop possible derivatives
 
11671
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
11672
    {
 
11673
      // Get values from coefficients array
 
11674
      new_coeff0_0 = coefficients0[dof][0];
 
11675
      new_coeff0_1 = coefficients0[dof][1];
 
11676
      new_coeff0_2 = coefficients0[dof][2];
 
11677
    
 
11678
      // Loop derivative order
 
11679
      for (unsigned int j = 0; j < n; j++)
 
11680
      {
 
11681
        // Update old coefficients
 
11682
        coeff0_0 = new_coeff0_0;
 
11683
        coeff0_1 = new_coeff0_1;
 
11684
        coeff0_2 = new_coeff0_2;
 
11685
    
 
11686
        if(combinations[deriv_num][j] == 0)
 
11687
        {
 
11688
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
11689
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
11690
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
11691
        }
 
11692
        if(combinations[deriv_num][j] == 1)
 
11693
        {
 
11694
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
11695
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
11696
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
11697
        }
 
11698
    
 
11699
      }
 
11700
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
11701
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
11702
    }
 
11703
    
 
11704
    // Transform derivatives back to physical element
 
11705
    for (unsigned int row = 0; row < num_derivatives; row++)
 
11706
    {
 
11707
      for (unsigned int col = 0; col < num_derivatives; col++)
 
11708
      {
 
11709
        values[row] += transform[row][col]*derivatives[col];
 
11710
      }
 
11711
    }
 
11712
    // Delete pointer to array of derivatives on FIAT element
 
11713
    delete [] derivatives;
 
11714
    
 
11715
    // Delete pointer to array of combinations of derivatives and transform
 
11716
    for (unsigned int row = 0; row < num_derivatives; row++)
 
11717
    {
 
11718
      delete [] combinations[row];
 
11719
      delete [] transform[row];
 
11720
    }
 
11721
    
 
11722
    delete [] combinations;
 
11723
    delete [] transform;
 
11724
}
 
11725
 
 
11726
/// Evaluate order n derivatives of all basis functions at given point in cell
 
11727
void cahnhilliard2d_1_finite_element_2_1::evaluate_basis_derivatives_all(unsigned int n,
 
11728
                                                   double* values,
 
11729
                                                   const double* coordinates,
 
11730
                                                   const ufc::cell& c) const
 
11731
{
 
11732
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
11733
}
 
11734
 
 
11735
/// Evaluate linear functional for dof i on the function f
 
11736
double cahnhilliard2d_1_finite_element_2_1::evaluate_dof(unsigned int i,
 
11737
                                   const ufc::function& f,
 
11738
                                   const ufc::cell& c) const
 
11739
{
 
11740
    // The reference points, direction and weights:
 
11741
    static const double X[3][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}};
 
11742
    static const double W[3][1] = {{1}, {1}, {1}};
 
11743
    static const double D[3][1][1] = {{{1}}, {{1}}, {{1}}};
 
11744
    
 
11745
    const double * const * x = c.coordinates;
 
11746
    double result = 0.0;
 
11747
    // Iterate over the points:
 
11748
    // Evaluate basis functions for affine mapping
 
11749
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
11750
    const double w1 = X[i][0][0];
 
11751
    const double w2 = X[i][0][1];
 
11752
    
 
11753
    // Compute affine mapping y = F(X)
 
11754
    double y[2];
 
11755
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
11756
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
11757
    
 
11758
    // Evaluate function at physical points
 
11759
    double values[1];
 
11760
    f.evaluate(values, y, c);
 
11761
    
 
11762
    // Map function values using appropriate mapping
 
11763
    // Affine map: Do nothing
 
11764
    
 
11765
    // Note that we do not map the weights (yet).
 
11766
    
 
11767
    // Take directional components
 
11768
    for(int k = 0; k < 1; k++)
 
11769
      result += values[k]*D[i][0][k];
 
11770
    // Multiply by weights
 
11771
    result *= W[i][0];
 
11772
    
 
11773
    return result;
 
11774
}
 
11775
 
 
11776
/// Evaluate linear functionals for all dofs on the function f
 
11777
void cahnhilliard2d_1_finite_element_2_1::evaluate_dofs(double* values,
 
11778
                                  const ufc::function& f,
 
11779
                                  const ufc::cell& c) const
 
11780
{
 
11781
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
11782
}
 
11783
 
 
11784
/// Interpolate vertex values from dof values
 
11785
void cahnhilliard2d_1_finite_element_2_1::interpolate_vertex_values(double* vertex_values,
 
11786
                                              const double* dof_values,
 
11787
                                              const ufc::cell& c) const
 
11788
{
 
11789
    // Evaluate at vertices and use affine mapping
 
11790
    vertex_values[0] = dof_values[0];
 
11791
    vertex_values[1] = dof_values[1];
 
11792
    vertex_values[2] = dof_values[2];
 
11793
}
 
11794
 
 
11795
/// Return the number of sub elements (for a mixed element)
 
11796
unsigned int cahnhilliard2d_1_finite_element_2_1::num_sub_elements() const
 
11797
{
 
11798
    return 1;
 
11799
}
 
11800
 
 
11801
/// Create a new finite element for sub element i (for a mixed element)
 
11802
ufc::finite_element* cahnhilliard2d_1_finite_element_2_1::create_sub_element(unsigned int i) const
 
11803
{
 
11804
    return new cahnhilliard2d_1_finite_element_2_1();
 
11805
}
 
11806
 
 
11807
 
 
11808
/// Constructor
 
11809
cahnhilliard2d_1_finite_element_2::cahnhilliard2d_1_finite_element_2() : ufc::finite_element()
 
11810
{
 
11811
    // Do nothing
 
11812
}
 
11813
 
 
11814
/// Destructor
 
11815
cahnhilliard2d_1_finite_element_2::~cahnhilliard2d_1_finite_element_2()
 
11816
{
 
11817
    // Do nothing
 
11818
}
 
11819
 
 
11820
/// Return a string identifying the finite element
 
11821
const char* cahnhilliard2d_1_finite_element_2::signature() const
 
11822
{
 
11823
    return "MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
 
11824
}
 
11825
 
 
11826
/// Return the cell shape
 
11827
ufc::shape cahnhilliard2d_1_finite_element_2::cell_shape() const
 
11828
{
 
11829
    return ufc::triangle;
 
11830
}
 
11831
 
 
11832
/// Return the dimension of the finite element function space
 
11833
unsigned int cahnhilliard2d_1_finite_element_2::space_dimension() const
 
11834
{
 
11835
    return 6;
 
11836
}
 
11837
 
 
11838
/// Return the rank of the value space
 
11839
unsigned int cahnhilliard2d_1_finite_element_2::value_rank() const
 
11840
{
 
11841
    return 1;
 
11842
}
 
11843
 
 
11844
/// Return the dimension of the value space for axis i
 
11845
unsigned int cahnhilliard2d_1_finite_element_2::value_dimension(unsigned int i) const
 
11846
{
 
11847
    return 2;
 
11848
}
 
11849
 
 
11850
/// Evaluate basis function i at given point in cell
 
11851
void cahnhilliard2d_1_finite_element_2::evaluate_basis(unsigned int i,
 
11852
                                   double* values,
 
11853
                                   const double* coordinates,
 
11854
                                   const ufc::cell& c) const
 
11855
{
 
11856
    // Extract vertex coordinates
 
11857
    const double * const * element_coordinates = c.coordinates;
 
11858
    
 
11859
    // Compute Jacobian of affine map from reference cell
 
11860
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
11861
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
11862
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
11863
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
11864
    
 
11865
    // Compute determinant of Jacobian
 
11866
    const double detJ = J_00*J_11 - J_01*J_10;
 
11867
    
 
11868
    // Compute inverse of Jacobian
 
11869
    
 
11870
    // Get coordinates and map to the reference (UFC) element
 
11871
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
11872
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
11873
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
11874
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
11875
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
11876
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
11877
    
 
11878
    // Map coordinates to the reference square
 
11879
    if (std::abs(y - 1.0) < 1e-14)
 
11880
      x = -1.0;
 
11881
    else
 
11882
      x = 2.0 *x/(1.0 - y) - 1.0;
 
11883
    y = 2.0*y - 1.0;
 
11884
    
 
11885
    // Reset values
 
11886
    values[0] = 0;
 
11887
    values[1] = 0;
 
11888
    
 
11889
    if (0 <= i && i <= 2)
 
11890
    {
 
11891
      // Map degree of freedom to element degree of freedom
 
11892
      const unsigned int dof = i;
 
11893
    
 
11894
      // Generate scalings
 
11895
      const double scalings_y_0 = 1;
 
11896
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
11897
    
 
11898
      // Compute psitilde_a
 
11899
      const double psitilde_a_0 = 1;
 
11900
      const double psitilde_a_1 = x;
 
11901
    
 
11902
      // Compute psitilde_bs
 
11903
      const double psitilde_bs_0_0 = 1;
 
11904
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
11905
      const double psitilde_bs_1_0 = 1;
 
11906
    
 
11907
      // Compute basisvalues
 
11908
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
11909
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
11910
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
11911
    
 
11912
      // Table(s) of coefficients
 
11913
      static const double coefficients0[3][3] =   \
 
11914
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
11915
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
11916
      {0.471404520791032, 0, 0.333333333333333}};
 
11917
    
 
11918
      // Extract relevant coefficients
 
11919
      const double coeff0_0 =   coefficients0[dof][0];
 
11920
      const double coeff0_1 =   coefficients0[dof][1];
 
11921
      const double coeff0_2 =   coefficients0[dof][2];
 
11922
    
 
11923
      // Compute value(s)
 
11924
      values[0] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
11925
    }
 
11926
    
 
11927
    if (3 <= i && i <= 5)
 
11928
    {
 
11929
      // Map degree of freedom to element degree of freedom
 
11930
      const unsigned int dof = i - 3;
 
11931
    
 
11932
      // Generate scalings
 
11933
      const double scalings_y_0 = 1;
 
11934
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
11935
    
 
11936
      // Compute psitilde_a
 
11937
      const double psitilde_a_0 = 1;
 
11938
      const double psitilde_a_1 = x;
 
11939
    
 
11940
      // Compute psitilde_bs
 
11941
      const double psitilde_bs_0_0 = 1;
 
11942
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
11943
      const double psitilde_bs_1_0 = 1;
 
11944
    
 
11945
      // Compute basisvalues
 
11946
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
11947
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
11948
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
11949
    
 
11950
      // Table(s) of coefficients
 
11951
      static const double coefficients0[3][3] =   \
 
11952
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
11953
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
11954
      {0.471404520791032, 0, 0.333333333333333}};
 
11955
    
 
11956
      // Extract relevant coefficients
 
11957
      const double coeff0_0 =   coefficients0[dof][0];
 
11958
      const double coeff0_1 =   coefficients0[dof][1];
 
11959
      const double coeff0_2 =   coefficients0[dof][2];
 
11960
    
 
11961
      // Compute value(s)
 
11962
      values[1] = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
11963
    }
 
11964
    
 
11965
}
 
11966
 
 
11967
/// Evaluate all basis functions at given point in cell
 
11968
void cahnhilliard2d_1_finite_element_2::evaluate_basis_all(double* values,
 
11969
                                       const double* coordinates,
 
11970
                                       const ufc::cell& c) const
 
11971
{
 
11972
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
11973
}
 
11974
 
 
11975
/// Evaluate order n derivatives of basis function i at given point in cell
 
11976
void cahnhilliard2d_1_finite_element_2::evaluate_basis_derivatives(unsigned int i,
 
11977
                                               unsigned int n,
 
11978
                                               double* values,
 
11979
                                               const double* coordinates,
 
11980
                                               const ufc::cell& c) const
 
11981
{
 
11982
    // Extract vertex coordinates
 
11983
    const double * const * element_coordinates = c.coordinates;
 
11984
    
 
11985
    // Compute Jacobian of affine map from reference cell
 
11986
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
11987
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
11988
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
11989
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
11990
    
 
11991
    // Compute determinant of Jacobian
 
11992
    const double detJ = J_00*J_11 - J_01*J_10;
 
11993
    
 
11994
    // Compute inverse of Jacobian
 
11995
    
 
11996
    // Get coordinates and map to the reference (UFC) element
 
11997
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
11998
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
11999
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
12000
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
12001
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
12002
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
12003
    
 
12004
    // Map coordinates to the reference square
 
12005
    if (std::abs(y - 1.0) < 1e-14)
 
12006
      x = -1.0;
 
12007
    else
 
12008
      x = 2.0 *x/(1.0 - y) - 1.0;
 
12009
    y = 2.0*y - 1.0;
 
12010
    
 
12011
    // Compute number of derivatives
 
12012
    unsigned int num_derivatives = 1;
 
12013
    
 
12014
    for (unsigned int j = 0; j < n; j++)
 
12015
      num_derivatives *= 2;
 
12016
    
 
12017
    
 
12018
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
12019
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
12020
    
 
12021
    for (unsigned int j = 0; j < num_derivatives; j++)
 
12022
    {
 
12023
      combinations[j] = new unsigned int [n];
 
12024
      for (unsigned int k = 0; k < n; k++)
 
12025
        combinations[j][k] = 0;
 
12026
    }
 
12027
    
 
12028
    // Generate combinations of derivatives
 
12029
    for (unsigned int row = 1; row < num_derivatives; row++)
 
12030
    {
 
12031
      for (unsigned int num = 0; num < row; num++)
 
12032
      {
 
12033
        for (unsigned int col = n-1; col+1 > 0; col--)
 
12034
        {
 
12035
          if (combinations[row][col] + 1 > 1)
 
12036
            combinations[row][col] = 0;
 
12037
          else
 
12038
          {
 
12039
            combinations[row][col] += 1;
 
12040
            break;
 
12041
          }
 
12042
        }
 
12043
      }
 
12044
    }
 
12045
    
 
12046
    // Compute inverse of Jacobian
 
12047
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
12048
    
 
12049
    // Declare transformation matrix
 
12050
    // Declare pointer to two dimensional array and initialise
 
12051
    double **transform = new double *[num_derivatives];
 
12052
    
 
12053
    for (unsigned int j = 0; j < num_derivatives; j++)
 
12054
    {
 
12055
      transform[j] = new double [num_derivatives];
 
12056
      for (unsigned int k = 0; k < num_derivatives; k++)
 
12057
        transform[j][k] = 1;
 
12058
    }
 
12059
    
 
12060
    // Construct transformation matrix
 
12061
    for (unsigned int row = 0; row < num_derivatives; row++)
 
12062
    {
 
12063
      for (unsigned int col = 0; col < num_derivatives; col++)
 
12064
      {
 
12065
        for (unsigned int k = 0; k < n; k++)
 
12066
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
12067
      }
 
12068
    }
 
12069
    
 
12070
    // Reset values
 
12071
    for (unsigned int j = 0; j < 2*num_derivatives; j++)
 
12072
      values[j] = 0;
 
12073
    
 
12074
    if (0 <= i && i <= 2)
 
12075
    {
 
12076
      // Map degree of freedom to element degree of freedom
 
12077
      const unsigned int dof = i;
 
12078
    
 
12079
      // Generate scalings
 
12080
      const double scalings_y_0 = 1;
 
12081
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
12082
    
 
12083
      // Compute psitilde_a
 
12084
      const double psitilde_a_0 = 1;
 
12085
      const double psitilde_a_1 = x;
 
12086
    
 
12087
      // Compute psitilde_bs
 
12088
      const double psitilde_bs_0_0 = 1;
 
12089
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
12090
      const double psitilde_bs_1_0 = 1;
 
12091
    
 
12092
      // Compute basisvalues
 
12093
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
12094
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
12095
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
12096
    
 
12097
      // Table(s) of coefficients
 
12098
      static const double coefficients0[3][3] =   \
 
12099
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
12100
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
12101
      {0.471404520791032, 0, 0.333333333333333}};
 
12102
    
 
12103
      // Interesting (new) part
 
12104
      // Tables of derivatives of the polynomial base (transpose)
 
12105
      static const double dmats0[3][3] =   \
 
12106
      {{0, 0, 0},
 
12107
      {4.89897948556636, 0, 0},
 
12108
      {0, 0, 0}};
 
12109
    
 
12110
      static const double dmats1[3][3] =   \
 
12111
      {{0, 0, 0},
 
12112
      {2.44948974278318, 0, 0},
 
12113
      {4.24264068711928, 0, 0}};
 
12114
    
 
12115
      // Compute reference derivatives
 
12116
      // Declare pointer to array of derivatives on FIAT element
 
12117
      double *derivatives = new double [num_derivatives];
 
12118
    
 
12119
      // Declare coefficients
 
12120
      double coeff0_0 = 0;
 
12121
      double coeff0_1 = 0;
 
12122
      double coeff0_2 = 0;
 
12123
    
 
12124
      // Declare new coefficients
 
12125
      double new_coeff0_0 = 0;
 
12126
      double new_coeff0_1 = 0;
 
12127
      double new_coeff0_2 = 0;
 
12128
    
 
12129
      // Loop possible derivatives
 
12130
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
12131
      {
 
12132
        // Get values from coefficients array
 
12133
        new_coeff0_0 = coefficients0[dof][0];
 
12134
        new_coeff0_1 = coefficients0[dof][1];
 
12135
        new_coeff0_2 = coefficients0[dof][2];
 
12136
    
 
12137
        // Loop derivative order
 
12138
        for (unsigned int j = 0; j < n; j++)
 
12139
        {
 
12140
          // Update old coefficients
 
12141
          coeff0_0 = new_coeff0_0;
 
12142
          coeff0_1 = new_coeff0_1;
 
12143
          coeff0_2 = new_coeff0_2;
 
12144
    
 
12145
          if(combinations[deriv_num][j] == 0)
 
12146
          {
 
12147
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
12148
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
12149
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
12150
          }
 
12151
          if(combinations[deriv_num][j] == 1)
 
12152
          {
 
12153
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
12154
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
12155
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
12156
          }
 
12157
    
 
12158
        }
 
12159
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
12160
        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
12161
      }
 
12162
    
 
12163
      // Transform derivatives back to physical element
 
12164
      for (unsigned int row = 0; row < num_derivatives; row++)
 
12165
      {
 
12166
        for (unsigned int col = 0; col < num_derivatives; col++)
 
12167
        {
 
12168
          values[row] += transform[row][col]*derivatives[col];
 
12169
        }
 
12170
      }
 
12171
      // Delete pointer to array of derivatives on FIAT element
 
12172
      delete [] derivatives;
 
12173
    
 
12174
      // Delete pointer to array of combinations of derivatives and transform
 
12175
      for (unsigned int row = 0; row < num_derivatives; row++)
 
12176
      {
 
12177
        delete [] combinations[row];
 
12178
        delete [] transform[row];
 
12179
      }
 
12180
    
 
12181
      delete [] combinations;
 
12182
      delete [] transform;
 
12183
    }
 
12184
    
 
12185
    if (3 <= i && i <= 5)
 
12186
    {
 
12187
      // Map degree of freedom to element degree of freedom
 
12188
      const unsigned int dof = i - 3;
 
12189
    
 
12190
      // Generate scalings
 
12191
      const double scalings_y_0 = 1;
 
12192
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
12193
    
 
12194
      // Compute psitilde_a
 
12195
      const double psitilde_a_0 = 1;
 
12196
      const double psitilde_a_1 = x;
 
12197
    
 
12198
      // Compute psitilde_bs
 
12199
      const double psitilde_bs_0_0 = 1;
 
12200
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
12201
      const double psitilde_bs_1_0 = 1;
 
12202
    
 
12203
      // Compute basisvalues
 
12204
      const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
12205
      const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
12206
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
12207
    
 
12208
      // Table(s) of coefficients
 
12209
      static const double coefficients0[3][3] =   \
 
12210
      {{0.471404520791032, -0.288675134594813, -0.166666666666667},
 
12211
      {0.471404520791032, 0.288675134594813, -0.166666666666667},
 
12212
      {0.471404520791032, 0, 0.333333333333333}};
 
12213
    
 
12214
      // Interesting (new) part
 
12215
      // Tables of derivatives of the polynomial base (transpose)
 
12216
      static const double dmats0[3][3] =   \
 
12217
      {{0, 0, 0},
 
12218
      {4.89897948556636, 0, 0},
 
12219
      {0, 0, 0}};
 
12220
    
 
12221
      static const double dmats1[3][3] =   \
 
12222
      {{0, 0, 0},
 
12223
      {2.44948974278318, 0, 0},
 
12224
      {4.24264068711928, 0, 0}};
 
12225
    
 
12226
      // Compute reference derivatives
 
12227
      // Declare pointer to array of derivatives on FIAT element
 
12228
      double *derivatives = new double [num_derivatives];
 
12229
    
 
12230
      // Declare coefficients
 
12231
      double coeff0_0 = 0;
 
12232
      double coeff0_1 = 0;
 
12233
      double coeff0_2 = 0;
 
12234
    
 
12235
      // Declare new coefficients
 
12236
      double new_coeff0_0 = 0;
 
12237
      double new_coeff0_1 = 0;
 
12238
      double new_coeff0_2 = 0;
 
12239
    
 
12240
      // Loop possible derivatives
 
12241
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
12242
      {
 
12243
        // Get values from coefficients array
 
12244
        new_coeff0_0 = coefficients0[dof][0];
 
12245
        new_coeff0_1 = coefficients0[dof][1];
 
12246
        new_coeff0_2 = coefficients0[dof][2];
 
12247
    
 
12248
        // Loop derivative order
 
12249
        for (unsigned int j = 0; j < n; j++)
 
12250
        {
 
12251
          // Update old coefficients
 
12252
          coeff0_0 = new_coeff0_0;
 
12253
          coeff0_1 = new_coeff0_1;
 
12254
          coeff0_2 = new_coeff0_2;
 
12255
    
 
12256
          if(combinations[deriv_num][j] == 0)
 
12257
          {
 
12258
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
12259
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
12260
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
12261
          }
 
12262
          if(combinations[deriv_num][j] == 1)
 
12263
          {
 
12264
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
12265
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
12266
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
12267
          }
 
12268
    
 
12269
        }
 
12270
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
12271
        derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
12272
      }
 
12273
    
 
12274
      // Transform derivatives back to physical element
 
12275
      for (unsigned int row = 0; row < num_derivatives; row++)
 
12276
      {
 
12277
        for (unsigned int col = 0; col < num_derivatives; col++)
 
12278
        {
 
12279
          values[num_derivatives + row] += transform[row][col]*derivatives[col];
 
12280
        }
 
12281
      }
 
12282
      // Delete pointer to array of derivatives on FIAT element
 
12283
      delete [] derivatives;
 
12284
    
 
12285
      // Delete pointer to array of combinations of derivatives and transform
 
12286
      for (unsigned int row = 0; row < num_derivatives; row++)
 
12287
      {
 
12288
        delete [] combinations[row];
 
12289
        delete [] transform[row];
 
12290
      }
 
12291
    
 
12292
      delete [] combinations;
 
12293
      delete [] transform;
 
12294
    }
 
12295
    
 
12296
}
 
12297
 
 
12298
/// Evaluate order n derivatives of all basis functions at given point in cell
 
12299
void cahnhilliard2d_1_finite_element_2::evaluate_basis_derivatives_all(unsigned int n,
 
12300
                                                   double* values,
 
12301
                                                   const double* coordinates,
 
12302
                                                   const ufc::cell& c) const
 
12303
{
 
12304
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
12305
}
 
12306
 
 
12307
/// Evaluate linear functional for dof i on the function f
 
12308
double cahnhilliard2d_1_finite_element_2::evaluate_dof(unsigned int i,
 
12309
                                   const ufc::function& f,
 
12310
                                   const ufc::cell& c) const
 
12311
{
 
12312
    // The reference points, direction and weights:
 
12313
    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0, 0}}, {{1, 0}}, {{0, 1}}};
 
12314
    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
 
12315
    static const double D[6][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
 
12316
    
 
12317
    const double * const * x = c.coordinates;
 
12318
    double result = 0.0;
 
12319
    // Iterate over the points:
 
12320
    // Evaluate basis functions for affine mapping
 
12321
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
12322
    const double w1 = X[i][0][0];
 
12323
    const double w2 = X[i][0][1];
 
12324
    
 
12325
    // Compute affine mapping y = F(X)
 
12326
    double y[2];
 
12327
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
12328
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
12329
    
 
12330
    // Evaluate function at physical points
 
12331
    double values[2];
 
12332
    f.evaluate(values, y, c);
 
12333
    
 
12334
    // Map function values using appropriate mapping
 
12335
    // Affine map: Do nothing
 
12336
    
 
12337
    // Note that we do not map the weights (yet).
 
12338
    
 
12339
    // Take directional components
 
12340
    for(int k = 0; k < 2; k++)
 
12341
      result += values[k]*D[i][0][k];
 
12342
    // Multiply by weights
 
12343
    result *= W[i][0];
 
12344
    
 
12345
    return result;
 
12346
}
 
12347
 
 
12348
/// Evaluate linear functionals for all dofs on the function f
 
12349
void cahnhilliard2d_1_finite_element_2::evaluate_dofs(double* values,
 
12350
                                  const ufc::function& f,
 
12351
                                  const ufc::cell& c) const
 
12352
{
 
12353
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
12354
}
 
12355
 
 
12356
/// Interpolate vertex values from dof values
 
12357
void cahnhilliard2d_1_finite_element_2::interpolate_vertex_values(double* vertex_values,
 
12358
                                              const double* dof_values,
 
12359
                                              const ufc::cell& c) const
 
12360
{
 
12361
    // Evaluate at vertices and use affine mapping
 
12362
    vertex_values[0] = dof_values[0];
 
12363
    vertex_values[2] = dof_values[1];
 
12364
    vertex_values[4] = dof_values[2];
 
12365
    // Evaluate at vertices and use affine mapping
 
12366
    vertex_values[1] = dof_values[3];
 
12367
    vertex_values[3] = dof_values[4];
 
12368
    vertex_values[5] = dof_values[5];
 
12369
}
 
12370
 
 
12371
/// Return the number of sub elements (for a mixed element)
 
12372
unsigned int cahnhilliard2d_1_finite_element_2::num_sub_elements() const
 
12373
{
 
12374
    return 2;
 
12375
}
 
12376
 
 
12377
/// Create a new finite element for sub element i (for a mixed element)
 
12378
ufc::finite_element* cahnhilliard2d_1_finite_element_2::create_sub_element(unsigned int i) const
 
12379
{
 
12380
    switch ( i )
 
12381
    {
 
12382
    case 0:
 
12383
      return new cahnhilliard2d_1_finite_element_2_0();
 
12384
      break;
 
12385
    case 1:
 
12386
      return new cahnhilliard2d_1_finite_element_2_1();
 
12387
      break;
 
12388
    }
 
12389
    return 0;
 
12390
}
 
12391
 
 
12392
 
 
12393
/// Constructor
 
12394
cahnhilliard2d_1_finite_element_3::cahnhilliard2d_1_finite_element_3() : ufc::finite_element()
 
12395
{
 
12396
    // Do nothing
 
12397
}
 
12398
 
 
12399
/// Destructor
 
12400
cahnhilliard2d_1_finite_element_3::~cahnhilliard2d_1_finite_element_3()
 
12401
{
 
12402
    // Do nothing
 
12403
}
 
12404
 
 
12405
/// Return a string identifying the finite element
 
12406
const char* cahnhilliard2d_1_finite_element_3::signature() const
 
12407
{
 
12408
    return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
 
12409
}
 
12410
 
 
12411
/// Return the cell shape
 
12412
ufc::shape cahnhilliard2d_1_finite_element_3::cell_shape() const
 
12413
{
 
12414
    return ufc::triangle;
 
12415
}
 
12416
 
 
12417
/// Return the dimension of the finite element function space
 
12418
unsigned int cahnhilliard2d_1_finite_element_3::space_dimension() const
 
12419
{
 
12420
    return 1;
 
12421
}
 
12422
 
 
12423
/// Return the rank of the value space
 
12424
unsigned int cahnhilliard2d_1_finite_element_3::value_rank() const
 
12425
{
 
12426
    return 0;
 
12427
}
 
12428
 
 
12429
/// Return the dimension of the value space for axis i
 
12430
unsigned int cahnhilliard2d_1_finite_element_3::value_dimension(unsigned int i) const
 
12431
{
 
12432
    return 1;
 
12433
}
 
12434
 
 
12435
/// Evaluate basis function i at given point in cell
 
12436
void cahnhilliard2d_1_finite_element_3::evaluate_basis(unsigned int i,
 
12437
                                   double* values,
 
12438
                                   const double* coordinates,
 
12439
                                   const ufc::cell& c) const
 
12440
{
 
12441
    // Extract vertex coordinates
 
12442
    const double * const * element_coordinates = c.coordinates;
 
12443
    
 
12444
    // Compute Jacobian of affine map from reference cell
 
12445
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
12446
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
12447
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
12448
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
12449
    
 
12450
    // Compute determinant of Jacobian
 
12451
    const double detJ = J_00*J_11 - J_01*J_10;
 
12452
    
 
12453
    // Compute inverse of Jacobian
 
12454
    
 
12455
    // Get coordinates and map to the reference (UFC) element
 
12456
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
12457
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
12458
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
12459
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
12460
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
12461
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
12462
    
 
12463
    // Map coordinates to the reference square
 
12464
    if (std::abs(y - 1.0) < 1e-14)
 
12465
      x = -1.0;
 
12466
    else
 
12467
      x = 2.0 *x/(1.0 - y) - 1.0;
 
12468
    y = 2.0*y - 1.0;
 
12469
    
 
12470
    // Reset values
 
12471
    *values = 0;
 
12472
    
 
12473
    // Map degree of freedom to element degree of freedom
 
12474
    const unsigned int dof = i;
 
12475
    
 
12476
    // Generate scalings
 
12477
    const double scalings_y_0 = 1;
 
12478
    
 
12479
    // Compute psitilde_a
 
12480
    const double psitilde_a_0 = 1;
 
12481
    
 
12482
    // Compute psitilde_bs
 
12483
    const double psitilde_bs_0_0 = 1;
 
12484
    
 
12485
    // Compute basisvalues
 
12486
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
12487
    
 
12488
    // Table(s) of coefficients
 
12489
    static const double coefficients0[1][1] = \
 
12490
    {{1.41421356237309}};
 
12491
    
 
12492
    // Extract relevant coefficients
 
12493
    const double coeff0_0 = coefficients0[dof][0];
 
12494
    
 
12495
    // Compute value(s)
 
12496
    *values = coeff0_0*basisvalue0;
 
12497
}
 
12498
 
 
12499
/// Evaluate all basis functions at given point in cell
 
12500
void cahnhilliard2d_1_finite_element_3::evaluate_basis_all(double* values,
 
12501
                                       const double* coordinates,
 
12502
                                       const ufc::cell& c) const
 
12503
{
 
12504
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
12505
}
 
12506
 
 
12507
/// Evaluate order n derivatives of basis function i at given point in cell
 
12508
void cahnhilliard2d_1_finite_element_3::evaluate_basis_derivatives(unsigned int i,
 
12509
                                               unsigned int n,
 
12510
                                               double* values,
 
12511
                                               const double* coordinates,
 
12512
                                               const ufc::cell& c) const
 
12513
{
 
12514
    // Extract vertex coordinates
 
12515
    const double * const * element_coordinates = c.coordinates;
 
12516
    
 
12517
    // Compute Jacobian of affine map from reference cell
 
12518
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
12519
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
12520
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
12521
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
12522
    
 
12523
    // Compute determinant of Jacobian
 
12524
    const double detJ = J_00*J_11 - J_01*J_10;
 
12525
    
 
12526
    // Compute inverse of Jacobian
 
12527
    
 
12528
    // Get coordinates and map to the reference (UFC) element
 
12529
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
12530
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
12531
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
12532
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
12533
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
12534
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
12535
    
 
12536
    // Map coordinates to the reference square
 
12537
    if (std::abs(y - 1.0) < 1e-14)
 
12538
      x = -1.0;
 
12539
    else
 
12540
      x = 2.0 *x/(1.0 - y) - 1.0;
 
12541
    y = 2.0*y - 1.0;
 
12542
    
 
12543
    // Compute number of derivatives
 
12544
    unsigned int num_derivatives = 1;
 
12545
    
 
12546
    for (unsigned int j = 0; j < n; j++)
 
12547
      num_derivatives *= 2;
 
12548
    
 
12549
    
 
12550
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
12551
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
12552
    
 
12553
    for (unsigned int j = 0; j < num_derivatives; j++)
 
12554
    {
 
12555
      combinations[j] = new unsigned int [n];
 
12556
      for (unsigned int k = 0; k < n; k++)
 
12557
        combinations[j][k] = 0;
 
12558
    }
 
12559
    
 
12560
    // Generate combinations of derivatives
 
12561
    for (unsigned int row = 1; row < num_derivatives; row++)
 
12562
    {
 
12563
      for (unsigned int num = 0; num < row; num++)
 
12564
      {
 
12565
        for (unsigned int col = n-1; col+1 > 0; col--)
 
12566
        {
 
12567
          if (combinations[row][col] + 1 > 1)
 
12568
            combinations[row][col] = 0;
 
12569
          else
 
12570
          {
 
12571
            combinations[row][col] += 1;
 
12572
            break;
 
12573
          }
 
12574
        }
 
12575
      }
 
12576
    }
 
12577
    
 
12578
    // Compute inverse of Jacobian
 
12579
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
12580
    
 
12581
    // Declare transformation matrix
 
12582
    // Declare pointer to two dimensional array and initialise
 
12583
    double **transform = new double *[num_derivatives];
 
12584
    
 
12585
    for (unsigned int j = 0; j < num_derivatives; j++)
 
12586
    {
 
12587
      transform[j] = new double [num_derivatives];
 
12588
      for (unsigned int k = 0; k < num_derivatives; k++)
 
12589
        transform[j][k] = 1;
 
12590
    }
 
12591
    
 
12592
    // Construct transformation matrix
 
12593
    for (unsigned int row = 0; row < num_derivatives; row++)
 
12594
    {
 
12595
      for (unsigned int col = 0; col < num_derivatives; col++)
 
12596
      {
 
12597
        for (unsigned int k = 0; k < n; k++)
 
12598
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
12599
      }
 
12600
    }
 
12601
    
 
12602
    // Reset values
 
12603
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
 
12604
      values[j] = 0;
 
12605
    
 
12606
    // Map degree of freedom to element degree of freedom
 
12607
    const unsigned int dof = i;
 
12608
    
 
12609
    // Generate scalings
 
12610
    const double scalings_y_0 = 1;
 
12611
    
 
12612
    // Compute psitilde_a
 
12613
    const double psitilde_a_0 = 1;
 
12614
    
 
12615
    // Compute psitilde_bs
 
12616
    const double psitilde_bs_0_0 = 1;
 
12617
    
 
12618
    // Compute basisvalues
 
12619
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
12620
    
 
12621
    // Table(s) of coefficients
 
12622
    static const double coefficients0[1][1] = \
 
12623
    {{1.41421356237309}};
 
12624
    
 
12625
    // Interesting (new) part
 
12626
    // Tables of derivatives of the polynomial base (transpose)
 
12627
    static const double dmats0[1][1] = \
 
12628
    {{0}};
 
12629
    
 
12630
    static const double dmats1[1][1] = \
 
12631
    {{0}};
 
12632
    
 
12633
    // Compute reference derivatives
 
12634
    // Declare pointer to array of derivatives on FIAT element
 
12635
    double *derivatives = new double [num_derivatives];
 
12636
    
 
12637
    // Declare coefficients
 
12638
    double coeff0_0 = 0;
 
12639
    
 
12640
    // Declare new coefficients
 
12641
    double new_coeff0_0 = 0;
 
12642
    
 
12643
    // Loop possible derivatives
 
12644
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
12645
    {
 
12646
      // Get values from coefficients array
 
12647
      new_coeff0_0 = coefficients0[dof][0];
 
12648
    
 
12649
      // Loop derivative order
 
12650
      for (unsigned int j = 0; j < n; j++)
 
12651
      {
 
12652
        // Update old coefficients
 
12653
        coeff0_0 = new_coeff0_0;
 
12654
    
 
12655
        if(combinations[deriv_num][j] == 0)
 
12656
        {
 
12657
          new_coeff0_0 = coeff0_0*dmats0[0][0];
 
12658
        }
 
12659
        if(combinations[deriv_num][j] == 1)
 
12660
        {
 
12661
          new_coeff0_0 = coeff0_0*dmats1[0][0];
 
12662
        }
 
12663
    
 
12664
      }
 
12665
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
12666
      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
 
12667
    }
 
12668
    
 
12669
    // Transform derivatives back to physical element
 
12670
    for (unsigned int row = 0; row < num_derivatives; row++)
 
12671
    {
 
12672
      for (unsigned int col = 0; col < num_derivatives; col++)
 
12673
      {
 
12674
        values[row] += transform[row][col]*derivatives[col];
 
12675
      }
 
12676
    }
 
12677
    // Delete pointer to array of derivatives on FIAT element
 
12678
    delete [] derivatives;
 
12679
    
 
12680
    // Delete pointer to array of combinations of derivatives and transform
 
12681
    for (unsigned int row = 0; row < num_derivatives; row++)
 
12682
    {
 
12683
      delete [] combinations[row];
 
12684
      delete [] transform[row];
 
12685
    }
 
12686
    
 
12687
    delete [] combinations;
 
12688
    delete [] transform;
 
12689
}
 
12690
 
 
12691
/// Evaluate order n derivatives of all basis functions at given point in cell
 
12692
void cahnhilliard2d_1_finite_element_3::evaluate_basis_derivatives_all(unsigned int n,
 
12693
                                                   double* values,
 
12694
                                                   const double* coordinates,
 
12695
                                                   const ufc::cell& c) const
 
12696
{
 
12697
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
12698
}
 
12699
 
 
12700
/// Evaluate linear functional for dof i on the function f
 
12701
double cahnhilliard2d_1_finite_element_3::evaluate_dof(unsigned int i,
 
12702
                                   const ufc::function& f,
 
12703
                                   const ufc::cell& c) const
 
12704
{
 
12705
    // The reference points, direction and weights:
 
12706
    static const double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
 
12707
    static const double W[1][1] = {{1}};
 
12708
    static const double D[1][1][1] = {{{1}}};
 
12709
    
 
12710
    const double * const * x = c.coordinates;
 
12711
    double result = 0.0;
 
12712
    // Iterate over the points:
 
12713
    // Evaluate basis functions for affine mapping
 
12714
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
12715
    const double w1 = X[i][0][0];
 
12716
    const double w2 = X[i][0][1];
 
12717
    
 
12718
    // Compute affine mapping y = F(X)
 
12719
    double y[2];
 
12720
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
12721
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
12722
    
 
12723
    // Evaluate function at physical points
 
12724
    double values[1];
 
12725
    f.evaluate(values, y, c);
 
12726
    
 
12727
    // Map function values using appropriate mapping
 
12728
    // Affine map: Do nothing
 
12729
    
 
12730
    // Note that we do not map the weights (yet).
 
12731
    
 
12732
    // Take directional components
 
12733
    for(int k = 0; k < 1; k++)
 
12734
      result += values[k]*D[i][0][k];
 
12735
    // Multiply by weights
 
12736
    result *= W[i][0];
 
12737
    
 
12738
    return result;
 
12739
}
 
12740
 
 
12741
/// Evaluate linear functionals for all dofs on the function f
 
12742
void cahnhilliard2d_1_finite_element_3::evaluate_dofs(double* values,
 
12743
                                  const ufc::function& f,
 
12744
                                  const ufc::cell& c) const
 
12745
{
 
12746
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
12747
}
 
12748
 
 
12749
/// Interpolate vertex values from dof values
 
12750
void cahnhilliard2d_1_finite_element_3::interpolate_vertex_values(double* vertex_values,
 
12751
                                              const double* dof_values,
 
12752
                                              const ufc::cell& c) const
 
12753
{
 
12754
    // Evaluate at vertices and use affine mapping
 
12755
    vertex_values[0] = dof_values[0];
 
12756
    vertex_values[1] = dof_values[0];
 
12757
    vertex_values[2] = dof_values[0];
 
12758
}
 
12759
 
 
12760
/// Return the number of sub elements (for a mixed element)
 
12761
unsigned int cahnhilliard2d_1_finite_element_3::num_sub_elements() const
 
12762
{
 
12763
    return 1;
 
12764
}
 
12765
 
 
12766
/// Create a new finite element for sub element i (for a mixed element)
 
12767
ufc::finite_element* cahnhilliard2d_1_finite_element_3::create_sub_element(unsigned int i) const
 
12768
{
 
12769
    return new cahnhilliard2d_1_finite_element_3();
 
12770
}
 
12771
 
 
12772
 
 
12773
/// Constructor
 
12774
cahnhilliard2d_1_finite_element_4::cahnhilliard2d_1_finite_element_4() : ufc::finite_element()
 
12775
{
 
12776
    // Do nothing
 
12777
}
 
12778
 
 
12779
/// Destructor
 
12780
cahnhilliard2d_1_finite_element_4::~cahnhilliard2d_1_finite_element_4()
 
12781
{
 
12782
    // Do nothing
 
12783
}
 
12784
 
 
12785
/// Return a string identifying the finite element
 
12786
const char* cahnhilliard2d_1_finite_element_4::signature() const
 
12787
{
 
12788
    return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
 
12789
}
 
12790
 
 
12791
/// Return the cell shape
 
12792
ufc::shape cahnhilliard2d_1_finite_element_4::cell_shape() const
 
12793
{
 
12794
    return ufc::triangle;
 
12795
}
 
12796
 
 
12797
/// Return the dimension of the finite element function space
 
12798
unsigned int cahnhilliard2d_1_finite_element_4::space_dimension() const
 
12799
{
 
12800
    return 1;
 
12801
}
 
12802
 
 
12803
/// Return the rank of the value space
 
12804
unsigned int cahnhilliard2d_1_finite_element_4::value_rank() const
 
12805
{
 
12806
    return 0;
 
12807
}
 
12808
 
 
12809
/// Return the dimension of the value space for axis i
 
12810
unsigned int cahnhilliard2d_1_finite_element_4::value_dimension(unsigned int i) const
 
12811
{
 
12812
    return 1;
 
12813
}
 
12814
 
 
12815
/// Evaluate basis function i at given point in cell
 
12816
void cahnhilliard2d_1_finite_element_4::evaluate_basis(unsigned int i,
 
12817
                                   double* values,
 
12818
                                   const double* coordinates,
 
12819
                                   const ufc::cell& c) const
 
12820
{
 
12821
    // Extract vertex coordinates
 
12822
    const double * const * element_coordinates = c.coordinates;
 
12823
    
 
12824
    // Compute Jacobian of affine map from reference cell
 
12825
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
12826
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
12827
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
12828
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
12829
    
 
12830
    // Compute determinant of Jacobian
 
12831
    const double detJ = J_00*J_11 - J_01*J_10;
 
12832
    
 
12833
    // Compute inverse of Jacobian
 
12834
    
 
12835
    // Get coordinates and map to the reference (UFC) element
 
12836
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
12837
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
12838
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
12839
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
12840
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
12841
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
12842
    
 
12843
    // Map coordinates to the reference square
 
12844
    if (std::abs(y - 1.0) < 1e-14)
 
12845
      x = -1.0;
 
12846
    else
 
12847
      x = 2.0 *x/(1.0 - y) - 1.0;
 
12848
    y = 2.0*y - 1.0;
 
12849
    
 
12850
    // Reset values
 
12851
    *values = 0;
 
12852
    
 
12853
    // Map degree of freedom to element degree of freedom
 
12854
    const unsigned int dof = i;
 
12855
    
 
12856
    // Generate scalings
 
12857
    const double scalings_y_0 = 1;
 
12858
    
 
12859
    // Compute psitilde_a
 
12860
    const double psitilde_a_0 = 1;
 
12861
    
 
12862
    // Compute psitilde_bs
 
12863
    const double psitilde_bs_0_0 = 1;
 
12864
    
 
12865
    // Compute basisvalues
 
12866
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
12867
    
 
12868
    // Table(s) of coefficients
 
12869
    static const double coefficients0[1][1] = \
 
12870
    {{1.41421356237309}};
 
12871
    
 
12872
    // Extract relevant coefficients
 
12873
    const double coeff0_0 = coefficients0[dof][0];
 
12874
    
 
12875
    // Compute value(s)
 
12876
    *values = coeff0_0*basisvalue0;
 
12877
}
 
12878
 
 
12879
/// Evaluate all basis functions at given point in cell
 
12880
void cahnhilliard2d_1_finite_element_4::evaluate_basis_all(double* values,
 
12881
                                       const double* coordinates,
 
12882
                                       const ufc::cell& c) const
 
12883
{
 
12884
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
12885
}
 
12886
 
 
12887
/// Evaluate order n derivatives of basis function i at given point in cell
 
12888
void cahnhilliard2d_1_finite_element_4::evaluate_basis_derivatives(unsigned int i,
 
12889
                                               unsigned int n,
 
12890
                                               double* values,
 
12891
                                               const double* coordinates,
 
12892
                                               const ufc::cell& c) const
 
12893
{
 
12894
    // Extract vertex coordinates
 
12895
    const double * const * element_coordinates = c.coordinates;
 
12896
    
 
12897
    // Compute Jacobian of affine map from reference cell
 
12898
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
12899
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
12900
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
12901
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
12902
    
 
12903
    // Compute determinant of Jacobian
 
12904
    const double detJ = J_00*J_11 - J_01*J_10;
 
12905
    
 
12906
    // Compute inverse of Jacobian
 
12907
    
 
12908
    // Get coordinates and map to the reference (UFC) element
 
12909
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
12910
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
12911
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
12912
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
12913
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
12914
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
12915
    
 
12916
    // Map coordinates to the reference square
 
12917
    if (std::abs(y - 1.0) < 1e-14)
 
12918
      x = -1.0;
 
12919
    else
 
12920
      x = 2.0 *x/(1.0 - y) - 1.0;
 
12921
    y = 2.0*y - 1.0;
 
12922
    
 
12923
    // Compute number of derivatives
 
12924
    unsigned int num_derivatives = 1;
 
12925
    
 
12926
    for (unsigned int j = 0; j < n; j++)
 
12927
      num_derivatives *= 2;
 
12928
    
 
12929
    
 
12930
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
12931
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
12932
    
 
12933
    for (unsigned int j = 0; j < num_derivatives; j++)
 
12934
    {
 
12935
      combinations[j] = new unsigned int [n];
 
12936
      for (unsigned int k = 0; k < n; k++)
 
12937
        combinations[j][k] = 0;
 
12938
    }
 
12939
    
 
12940
    // Generate combinations of derivatives
 
12941
    for (unsigned int row = 1; row < num_derivatives; row++)
 
12942
    {
 
12943
      for (unsigned int num = 0; num < row; num++)
 
12944
      {
 
12945
        for (unsigned int col = n-1; col+1 > 0; col--)
 
12946
        {
 
12947
          if (combinations[row][col] + 1 > 1)
 
12948
            combinations[row][col] = 0;
 
12949
          else
 
12950
          {
 
12951
            combinations[row][col] += 1;
 
12952
            break;
 
12953
          }
 
12954
        }
 
12955
      }
 
12956
    }
 
12957
    
 
12958
    // Compute inverse of Jacobian
 
12959
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
12960
    
 
12961
    // Declare transformation matrix
 
12962
    // Declare pointer to two dimensional array and initialise
 
12963
    double **transform = new double *[num_derivatives];
 
12964
    
 
12965
    for (unsigned int j = 0; j < num_derivatives; j++)
 
12966
    {
 
12967
      transform[j] = new double [num_derivatives];
 
12968
      for (unsigned int k = 0; k < num_derivatives; k++)
 
12969
        transform[j][k] = 1;
 
12970
    }
 
12971
    
 
12972
    // Construct transformation matrix
 
12973
    for (unsigned int row = 0; row < num_derivatives; row++)
 
12974
    {
 
12975
      for (unsigned int col = 0; col < num_derivatives; col++)
 
12976
      {
 
12977
        for (unsigned int k = 0; k < n; k++)
 
12978
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
12979
      }
 
12980
    }
 
12981
    
 
12982
    // Reset values
 
12983
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
 
12984
      values[j] = 0;
 
12985
    
 
12986
    // Map degree of freedom to element degree of freedom
 
12987
    const unsigned int dof = i;
 
12988
    
 
12989
    // Generate scalings
 
12990
    const double scalings_y_0 = 1;
 
12991
    
 
12992
    // Compute psitilde_a
 
12993
    const double psitilde_a_0 = 1;
 
12994
    
 
12995
    // Compute psitilde_bs
 
12996
    const double psitilde_bs_0_0 = 1;
 
12997
    
 
12998
    // Compute basisvalues
 
12999
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
13000
    
 
13001
    // Table(s) of coefficients
 
13002
    static const double coefficients0[1][1] = \
 
13003
    {{1.41421356237309}};
 
13004
    
 
13005
    // Interesting (new) part
 
13006
    // Tables of derivatives of the polynomial base (transpose)
 
13007
    static const double dmats0[1][1] = \
 
13008
    {{0}};
 
13009
    
 
13010
    static const double dmats1[1][1] = \
 
13011
    {{0}};
 
13012
    
 
13013
    // Compute reference derivatives
 
13014
    // Declare pointer to array of derivatives on FIAT element
 
13015
    double *derivatives = new double [num_derivatives];
 
13016
    
 
13017
    // Declare coefficients
 
13018
    double coeff0_0 = 0;
 
13019
    
 
13020
    // Declare new coefficients
 
13021
    double new_coeff0_0 = 0;
 
13022
    
 
13023
    // Loop possible derivatives
 
13024
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
13025
    {
 
13026
      // Get values from coefficients array
 
13027
      new_coeff0_0 = coefficients0[dof][0];
 
13028
    
 
13029
      // Loop derivative order
 
13030
      for (unsigned int j = 0; j < n; j++)
 
13031
      {
 
13032
        // Update old coefficients
 
13033
        coeff0_0 = new_coeff0_0;
 
13034
    
 
13035
        if(combinations[deriv_num][j] == 0)
 
13036
        {
 
13037
          new_coeff0_0 = coeff0_0*dmats0[0][0];
 
13038
        }
 
13039
        if(combinations[deriv_num][j] == 1)
 
13040
        {
 
13041
          new_coeff0_0 = coeff0_0*dmats1[0][0];
 
13042
        }
 
13043
    
 
13044
      }
 
13045
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
13046
      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
 
13047
    }
 
13048
    
 
13049
    // Transform derivatives back to physical element
 
13050
    for (unsigned int row = 0; row < num_derivatives; row++)
 
13051
    {
 
13052
      for (unsigned int col = 0; col < num_derivatives; col++)
 
13053
      {
 
13054
        values[row] += transform[row][col]*derivatives[col];
 
13055
      }
 
13056
    }
 
13057
    // Delete pointer to array of derivatives on FIAT element
 
13058
    delete [] derivatives;
 
13059
    
 
13060
    // Delete pointer to array of combinations of derivatives and transform
 
13061
    for (unsigned int row = 0; row < num_derivatives; row++)
 
13062
    {
 
13063
      delete [] combinations[row];
 
13064
      delete [] transform[row];
 
13065
    }
 
13066
    
 
13067
    delete [] combinations;
 
13068
    delete [] transform;
 
13069
}
 
13070
 
 
13071
/// Evaluate order n derivatives of all basis functions at given point in cell
 
13072
void cahnhilliard2d_1_finite_element_4::evaluate_basis_derivatives_all(unsigned int n,
 
13073
                                                   double* values,
 
13074
                                                   const double* coordinates,
 
13075
                                                   const ufc::cell& c) const
 
13076
{
 
13077
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
13078
}
 
13079
 
 
13080
/// Evaluate linear functional for dof i on the function f
 
13081
double cahnhilliard2d_1_finite_element_4::evaluate_dof(unsigned int i,
 
13082
                                   const ufc::function& f,
 
13083
                                   const ufc::cell& c) const
 
13084
{
 
13085
    // The reference points, direction and weights:
 
13086
    static const double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
 
13087
    static const double W[1][1] = {{1}};
 
13088
    static const double D[1][1][1] = {{{1}}};
 
13089
    
 
13090
    const double * const * x = c.coordinates;
 
13091
    double result = 0.0;
 
13092
    // Iterate over the points:
 
13093
    // Evaluate basis functions for affine mapping
 
13094
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
13095
    const double w1 = X[i][0][0];
 
13096
    const double w2 = X[i][0][1];
 
13097
    
 
13098
    // Compute affine mapping y = F(X)
 
13099
    double y[2];
 
13100
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
13101
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
13102
    
 
13103
    // Evaluate function at physical points
 
13104
    double values[1];
 
13105
    f.evaluate(values, y, c);
 
13106
    
 
13107
    // Map function values using appropriate mapping
 
13108
    // Affine map: Do nothing
 
13109
    
 
13110
    // Note that we do not map the weights (yet).
 
13111
    
 
13112
    // Take directional components
 
13113
    for(int k = 0; k < 1; k++)
 
13114
      result += values[k]*D[i][0][k];
 
13115
    // Multiply by weights
 
13116
    result *= W[i][0];
 
13117
    
 
13118
    return result;
 
13119
}
 
13120
 
 
13121
/// Evaluate linear functionals for all dofs on the function f
 
13122
void cahnhilliard2d_1_finite_element_4::evaluate_dofs(double* values,
 
13123
                                  const ufc::function& f,
 
13124
                                  const ufc::cell& c) const
 
13125
{
 
13126
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
13127
}
 
13128
 
 
13129
/// Interpolate vertex values from dof values
 
13130
void cahnhilliard2d_1_finite_element_4::interpolate_vertex_values(double* vertex_values,
 
13131
                                              const double* dof_values,
 
13132
                                              const ufc::cell& c) const
 
13133
{
 
13134
    // Evaluate at vertices and use affine mapping
 
13135
    vertex_values[0] = dof_values[0];
 
13136
    vertex_values[1] = dof_values[0];
 
13137
    vertex_values[2] = dof_values[0];
 
13138
}
 
13139
 
 
13140
/// Return the number of sub elements (for a mixed element)
 
13141
unsigned int cahnhilliard2d_1_finite_element_4::num_sub_elements() const
 
13142
{
 
13143
    return 1;
 
13144
}
 
13145
 
 
13146
/// Create a new finite element for sub element i (for a mixed element)
 
13147
ufc::finite_element* cahnhilliard2d_1_finite_element_4::create_sub_element(unsigned int i) const
 
13148
{
 
13149
    return new cahnhilliard2d_1_finite_element_4();
 
13150
}
 
13151
 
 
13152
 
 
13153
/// Constructor
 
13154
cahnhilliard2d_1_finite_element_5::cahnhilliard2d_1_finite_element_5() : ufc::finite_element()
 
13155
{
 
13156
    // Do nothing
 
13157
}
 
13158
 
 
13159
/// Destructor
 
13160
cahnhilliard2d_1_finite_element_5::~cahnhilliard2d_1_finite_element_5()
 
13161
{
 
13162
    // Do nothing
 
13163
}
 
13164
 
 
13165
/// Return a string identifying the finite element
 
13166
const char* cahnhilliard2d_1_finite_element_5::signature() const
 
13167
{
 
13168
    return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
 
13169
}
 
13170
 
 
13171
/// Return the cell shape
 
13172
ufc::shape cahnhilliard2d_1_finite_element_5::cell_shape() const
 
13173
{
 
13174
    return ufc::triangle;
 
13175
}
 
13176
 
 
13177
/// Return the dimension of the finite element function space
 
13178
unsigned int cahnhilliard2d_1_finite_element_5::space_dimension() const
 
13179
{
 
13180
    return 1;
 
13181
}
 
13182
 
 
13183
/// Return the rank of the value space
 
13184
unsigned int cahnhilliard2d_1_finite_element_5::value_rank() const
 
13185
{
 
13186
    return 0;
 
13187
}
 
13188
 
 
13189
/// Return the dimension of the value space for axis i
 
13190
unsigned int cahnhilliard2d_1_finite_element_5::value_dimension(unsigned int i) const
 
13191
{
 
13192
    return 1;
 
13193
}
 
13194
 
 
13195
/// Evaluate basis function i at given point in cell
 
13196
void cahnhilliard2d_1_finite_element_5::evaluate_basis(unsigned int i,
 
13197
                                   double* values,
 
13198
                                   const double* coordinates,
 
13199
                                   const ufc::cell& c) const
 
13200
{
 
13201
    // Extract vertex coordinates
 
13202
    const double * const * element_coordinates = c.coordinates;
 
13203
    
 
13204
    // Compute Jacobian of affine map from reference cell
 
13205
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
13206
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
13207
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
13208
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
13209
    
 
13210
    // Compute determinant of Jacobian
 
13211
    const double detJ = J_00*J_11 - J_01*J_10;
 
13212
    
 
13213
    // Compute inverse of Jacobian
 
13214
    
 
13215
    // Get coordinates and map to the reference (UFC) element
 
13216
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
13217
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
13218
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
13219
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
13220
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
13221
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
13222
    
 
13223
    // Map coordinates to the reference square
 
13224
    if (std::abs(y - 1.0) < 1e-14)
 
13225
      x = -1.0;
 
13226
    else
 
13227
      x = 2.0 *x/(1.0 - y) - 1.0;
 
13228
    y = 2.0*y - 1.0;
 
13229
    
 
13230
    // Reset values
 
13231
    *values = 0;
 
13232
    
 
13233
    // Map degree of freedom to element degree of freedom
 
13234
    const unsigned int dof = i;
 
13235
    
 
13236
    // Generate scalings
 
13237
    const double scalings_y_0 = 1;
 
13238
    
 
13239
    // Compute psitilde_a
 
13240
    const double psitilde_a_0 = 1;
 
13241
    
 
13242
    // Compute psitilde_bs
 
13243
    const double psitilde_bs_0_0 = 1;
 
13244
    
 
13245
    // Compute basisvalues
 
13246
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
13247
    
 
13248
    // Table(s) of coefficients
 
13249
    static const double coefficients0[1][1] = \
 
13250
    {{1.41421356237309}};
 
13251
    
 
13252
    // Extract relevant coefficients
 
13253
    const double coeff0_0 = coefficients0[dof][0];
 
13254
    
 
13255
    // Compute value(s)
 
13256
    *values = coeff0_0*basisvalue0;
 
13257
}
 
13258
 
 
13259
/// Evaluate all basis functions at given point in cell
 
13260
void cahnhilliard2d_1_finite_element_5::evaluate_basis_all(double* values,
 
13261
                                       const double* coordinates,
 
13262
                                       const ufc::cell& c) const
 
13263
{
 
13264
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
13265
}
 
13266
 
 
13267
/// Evaluate order n derivatives of basis function i at given point in cell
 
13268
void cahnhilliard2d_1_finite_element_5::evaluate_basis_derivatives(unsigned int i,
 
13269
                                               unsigned int n,
 
13270
                                               double* values,
 
13271
                                               const double* coordinates,
 
13272
                                               const ufc::cell& c) const
 
13273
{
 
13274
    // Extract vertex coordinates
 
13275
    const double * const * element_coordinates = c.coordinates;
 
13276
    
 
13277
    // Compute Jacobian of affine map from reference cell
 
13278
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
13279
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
13280
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
13281
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
13282
    
 
13283
    // Compute determinant of Jacobian
 
13284
    const double detJ = J_00*J_11 - J_01*J_10;
 
13285
    
 
13286
    // Compute inverse of Jacobian
 
13287
    
 
13288
    // Get coordinates and map to the reference (UFC) element
 
13289
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
13290
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
13291
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
13292
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
13293
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
13294
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
13295
    
 
13296
    // Map coordinates to the reference square
 
13297
    if (std::abs(y - 1.0) < 1e-14)
 
13298
      x = -1.0;
 
13299
    else
 
13300
      x = 2.0 *x/(1.0 - y) - 1.0;
 
13301
    y = 2.0*y - 1.0;
 
13302
    
 
13303
    // Compute number of derivatives
 
13304
    unsigned int num_derivatives = 1;
 
13305
    
 
13306
    for (unsigned int j = 0; j < n; j++)
 
13307
      num_derivatives *= 2;
 
13308
    
 
13309
    
 
13310
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
13311
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
13312
    
 
13313
    for (unsigned int j = 0; j < num_derivatives; j++)
 
13314
    {
 
13315
      combinations[j] = new unsigned int [n];
 
13316
      for (unsigned int k = 0; k < n; k++)
 
13317
        combinations[j][k] = 0;
 
13318
    }
 
13319
    
 
13320
    // Generate combinations of derivatives
 
13321
    for (unsigned int row = 1; row < num_derivatives; row++)
 
13322
    {
 
13323
      for (unsigned int num = 0; num < row; num++)
 
13324
      {
 
13325
        for (unsigned int col = n-1; col+1 > 0; col--)
 
13326
        {
 
13327
          if (combinations[row][col] + 1 > 1)
 
13328
            combinations[row][col] = 0;
 
13329
          else
 
13330
          {
 
13331
            combinations[row][col] += 1;
 
13332
            break;
 
13333
          }
 
13334
        }
 
13335
      }
 
13336
    }
 
13337
    
 
13338
    // Compute inverse of Jacobian
 
13339
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
13340
    
 
13341
    // Declare transformation matrix
 
13342
    // Declare pointer to two dimensional array and initialise
 
13343
    double **transform = new double *[num_derivatives];
 
13344
    
 
13345
    for (unsigned int j = 0; j < num_derivatives; j++)
 
13346
    {
 
13347
      transform[j] = new double [num_derivatives];
 
13348
      for (unsigned int k = 0; k < num_derivatives; k++)
 
13349
        transform[j][k] = 1;
 
13350
    }
 
13351
    
 
13352
    // Construct transformation matrix
 
13353
    for (unsigned int row = 0; row < num_derivatives; row++)
 
13354
    {
 
13355
      for (unsigned int col = 0; col < num_derivatives; col++)
 
13356
      {
 
13357
        for (unsigned int k = 0; k < n; k++)
 
13358
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
13359
      }
 
13360
    }
 
13361
    
 
13362
    // Reset values
 
13363
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
 
13364
      values[j] = 0;
 
13365
    
 
13366
    // Map degree of freedom to element degree of freedom
 
13367
    const unsigned int dof = i;
 
13368
    
 
13369
    // Generate scalings
 
13370
    const double scalings_y_0 = 1;
 
13371
    
 
13372
    // Compute psitilde_a
 
13373
    const double psitilde_a_0 = 1;
 
13374
    
 
13375
    // Compute psitilde_bs
 
13376
    const double psitilde_bs_0_0 = 1;
 
13377
    
 
13378
    // Compute basisvalues
 
13379
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
13380
    
 
13381
    // Table(s) of coefficients
 
13382
    static const double coefficients0[1][1] = \
 
13383
    {{1.41421356237309}};
 
13384
    
 
13385
    // Interesting (new) part
 
13386
    // Tables of derivatives of the polynomial base (transpose)
 
13387
    static const double dmats0[1][1] = \
 
13388
    {{0}};
 
13389
    
 
13390
    static const double dmats1[1][1] = \
 
13391
    {{0}};
 
13392
    
 
13393
    // Compute reference derivatives
 
13394
    // Declare pointer to array of derivatives on FIAT element
 
13395
    double *derivatives = new double [num_derivatives];
 
13396
    
 
13397
    // Declare coefficients
 
13398
    double coeff0_0 = 0;
 
13399
    
 
13400
    // Declare new coefficients
 
13401
    double new_coeff0_0 = 0;
 
13402
    
 
13403
    // Loop possible derivatives
 
13404
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
13405
    {
 
13406
      // Get values from coefficients array
 
13407
      new_coeff0_0 = coefficients0[dof][0];
 
13408
    
 
13409
      // Loop derivative order
 
13410
      for (unsigned int j = 0; j < n; j++)
 
13411
      {
 
13412
        // Update old coefficients
 
13413
        coeff0_0 = new_coeff0_0;
 
13414
    
 
13415
        if(combinations[deriv_num][j] == 0)
 
13416
        {
 
13417
          new_coeff0_0 = coeff0_0*dmats0[0][0];
 
13418
        }
 
13419
        if(combinations[deriv_num][j] == 1)
 
13420
        {
 
13421
          new_coeff0_0 = coeff0_0*dmats1[0][0];
 
13422
        }
 
13423
    
 
13424
      }
 
13425
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
13426
      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
 
13427
    }
 
13428
    
 
13429
    // Transform derivatives back to physical element
 
13430
    for (unsigned int row = 0; row < num_derivatives; row++)
 
13431
    {
 
13432
      for (unsigned int col = 0; col < num_derivatives; col++)
 
13433
      {
 
13434
        values[row] += transform[row][col]*derivatives[col];
 
13435
      }
 
13436
    }
 
13437
    // Delete pointer to array of derivatives on FIAT element
 
13438
    delete [] derivatives;
 
13439
    
 
13440
    // Delete pointer to array of combinations of derivatives and transform
 
13441
    for (unsigned int row = 0; row < num_derivatives; row++)
 
13442
    {
 
13443
      delete [] combinations[row];
 
13444
      delete [] transform[row];
 
13445
    }
 
13446
    
 
13447
    delete [] combinations;
 
13448
    delete [] transform;
 
13449
}
 
13450
 
 
13451
/// Evaluate order n derivatives of all basis functions at given point in cell
 
13452
void cahnhilliard2d_1_finite_element_5::evaluate_basis_derivatives_all(unsigned int n,
 
13453
                                                   double* values,
 
13454
                                                   const double* coordinates,
 
13455
                                                   const ufc::cell& c) const
 
13456
{
 
13457
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
13458
}
 
13459
 
 
13460
/// Evaluate linear functional for dof i on the function f
 
13461
double cahnhilliard2d_1_finite_element_5::evaluate_dof(unsigned int i,
 
13462
                                   const ufc::function& f,
 
13463
                                   const ufc::cell& c) const
 
13464
{
 
13465
    // The reference points, direction and weights:
 
13466
    static const double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
 
13467
    static const double W[1][1] = {{1}};
 
13468
    static const double D[1][1][1] = {{{1}}};
 
13469
    
 
13470
    const double * const * x = c.coordinates;
 
13471
    double result = 0.0;
 
13472
    // Iterate over the points:
 
13473
    // Evaluate basis functions for affine mapping
 
13474
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
13475
    const double w1 = X[i][0][0];
 
13476
    const double w2 = X[i][0][1];
 
13477
    
 
13478
    // Compute affine mapping y = F(X)
 
13479
    double y[2];
 
13480
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
13481
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
13482
    
 
13483
    // Evaluate function at physical points
 
13484
    double values[1];
 
13485
    f.evaluate(values, y, c);
 
13486
    
 
13487
    // Map function values using appropriate mapping
 
13488
    // Affine map: Do nothing
 
13489
    
 
13490
    // Note that we do not map the weights (yet).
 
13491
    
 
13492
    // Take directional components
 
13493
    for(int k = 0; k < 1; k++)
 
13494
      result += values[k]*D[i][0][k];
 
13495
    // Multiply by weights
 
13496
    result *= W[i][0];
 
13497
    
 
13498
    return result;
 
13499
}
 
13500
 
 
13501
/// Evaluate linear functionals for all dofs on the function f
 
13502
void cahnhilliard2d_1_finite_element_5::evaluate_dofs(double* values,
 
13503
                                  const ufc::function& f,
 
13504
                                  const ufc::cell& c) const
 
13505
{
 
13506
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
13507
}
 
13508
 
 
13509
/// Interpolate vertex values from dof values
 
13510
void cahnhilliard2d_1_finite_element_5::interpolate_vertex_values(double* vertex_values,
 
13511
                                              const double* dof_values,
 
13512
                                              const ufc::cell& c) const
 
13513
{
 
13514
    // Evaluate at vertices and use affine mapping
 
13515
    vertex_values[0] = dof_values[0];
 
13516
    vertex_values[1] = dof_values[0];
 
13517
    vertex_values[2] = dof_values[0];
 
13518
}
 
13519
 
 
13520
/// Return the number of sub elements (for a mixed element)
 
13521
unsigned int cahnhilliard2d_1_finite_element_5::num_sub_elements() const
 
13522
{
 
13523
    return 1;
 
13524
}
 
13525
 
 
13526
/// Create a new finite element for sub element i (for a mixed element)
 
13527
ufc::finite_element* cahnhilliard2d_1_finite_element_5::create_sub_element(unsigned int i) const
 
13528
{
 
13529
    return new cahnhilliard2d_1_finite_element_5();
 
13530
}
 
13531
 
 
13532
 
 
13533
/// Constructor
 
13534
cahnhilliard2d_1_finite_element_6::cahnhilliard2d_1_finite_element_6() : ufc::finite_element()
 
13535
{
 
13536
    // Do nothing
 
13537
}
 
13538
 
 
13539
/// Destructor
 
13540
cahnhilliard2d_1_finite_element_6::~cahnhilliard2d_1_finite_element_6()
 
13541
{
 
13542
    // Do nothing
 
13543
}
 
13544
 
 
13545
/// Return a string identifying the finite element
 
13546
const char* cahnhilliard2d_1_finite_element_6::signature() const
 
13547
{
 
13548
    return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
 
13549
}
 
13550
 
 
13551
/// Return the cell shape
 
13552
ufc::shape cahnhilliard2d_1_finite_element_6::cell_shape() const
 
13553
{
 
13554
    return ufc::triangle;
 
13555
}
 
13556
 
 
13557
/// Return the dimension of the finite element function space
 
13558
unsigned int cahnhilliard2d_1_finite_element_6::space_dimension() const
 
13559
{
 
13560
    return 1;
 
13561
}
 
13562
 
 
13563
/// Return the rank of the value space
 
13564
unsigned int cahnhilliard2d_1_finite_element_6::value_rank() const
 
13565
{
 
13566
    return 0;
 
13567
}
 
13568
 
 
13569
/// Return the dimension of the value space for axis i
 
13570
unsigned int cahnhilliard2d_1_finite_element_6::value_dimension(unsigned int i) const
 
13571
{
 
13572
    return 1;
 
13573
}
 
13574
 
 
13575
/// Evaluate basis function i at given point in cell
 
13576
void cahnhilliard2d_1_finite_element_6::evaluate_basis(unsigned int i,
 
13577
                                   double* values,
 
13578
                                   const double* coordinates,
 
13579
                                   const ufc::cell& c) const
 
13580
{
 
13581
    // Extract vertex coordinates
 
13582
    const double * const * element_coordinates = c.coordinates;
 
13583
    
 
13584
    // Compute Jacobian of affine map from reference cell
 
13585
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
13586
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
13587
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
13588
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
13589
    
 
13590
    // Compute determinant of Jacobian
 
13591
    const double detJ = J_00*J_11 - J_01*J_10;
 
13592
    
 
13593
    // Compute inverse of Jacobian
 
13594
    
 
13595
    // Get coordinates and map to the reference (UFC) element
 
13596
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
13597
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
13598
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
13599
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
13600
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
13601
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
13602
    
 
13603
    // Map coordinates to the reference square
 
13604
    if (std::abs(y - 1.0) < 1e-14)
 
13605
      x = -1.0;
 
13606
    else
 
13607
      x = 2.0 *x/(1.0 - y) - 1.0;
 
13608
    y = 2.0*y - 1.0;
 
13609
    
 
13610
    // Reset values
 
13611
    *values = 0;
 
13612
    
 
13613
    // Map degree of freedom to element degree of freedom
 
13614
    const unsigned int dof = i;
 
13615
    
 
13616
    // Generate scalings
 
13617
    const double scalings_y_0 = 1;
 
13618
    
 
13619
    // Compute psitilde_a
 
13620
    const double psitilde_a_0 = 1;
 
13621
    
 
13622
    // Compute psitilde_bs
 
13623
    const double psitilde_bs_0_0 = 1;
 
13624
    
 
13625
    // Compute basisvalues
 
13626
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
13627
    
 
13628
    // Table(s) of coefficients
 
13629
    static const double coefficients0[1][1] = \
 
13630
    {{1.41421356237309}};
 
13631
    
 
13632
    // Extract relevant coefficients
 
13633
    const double coeff0_0 = coefficients0[dof][0];
 
13634
    
 
13635
    // Compute value(s)
 
13636
    *values = coeff0_0*basisvalue0;
 
13637
}
 
13638
 
 
13639
/// Evaluate all basis functions at given point in cell
 
13640
void cahnhilliard2d_1_finite_element_6::evaluate_basis_all(double* values,
 
13641
                                       const double* coordinates,
 
13642
                                       const ufc::cell& c) const
 
13643
{
 
13644
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
13645
}
 
13646
 
 
13647
/// Evaluate order n derivatives of basis function i at given point in cell
 
13648
void cahnhilliard2d_1_finite_element_6::evaluate_basis_derivatives(unsigned int i,
 
13649
                                               unsigned int n,
 
13650
                                               double* values,
 
13651
                                               const double* coordinates,
 
13652
                                               const ufc::cell& c) const
 
13653
{
 
13654
    // Extract vertex coordinates
 
13655
    const double * const * element_coordinates = c.coordinates;
 
13656
    
 
13657
    // Compute Jacobian of affine map from reference cell
 
13658
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
13659
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
13660
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
13661
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
13662
    
 
13663
    // Compute determinant of Jacobian
 
13664
    const double detJ = J_00*J_11 - J_01*J_10;
 
13665
    
 
13666
    // Compute inverse of Jacobian
 
13667
    
 
13668
    // Get coordinates and map to the reference (UFC) element
 
13669
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
13670
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
13671
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
13672
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
13673
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
13674
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
13675
    
 
13676
    // Map coordinates to the reference square
 
13677
    if (std::abs(y - 1.0) < 1e-14)
 
13678
      x = -1.0;
 
13679
    else
 
13680
      x = 2.0 *x/(1.0 - y) - 1.0;
 
13681
    y = 2.0*y - 1.0;
 
13682
    
 
13683
    // Compute number of derivatives
 
13684
    unsigned int num_derivatives = 1;
 
13685
    
 
13686
    for (unsigned int j = 0; j < n; j++)
 
13687
      num_derivatives *= 2;
 
13688
    
 
13689
    
 
13690
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
13691
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
13692
    
 
13693
    for (unsigned int j = 0; j < num_derivatives; j++)
 
13694
    {
 
13695
      combinations[j] = new unsigned int [n];
 
13696
      for (unsigned int k = 0; k < n; k++)
 
13697
        combinations[j][k] = 0;
 
13698
    }
 
13699
    
 
13700
    // Generate combinations of derivatives
 
13701
    for (unsigned int row = 1; row < num_derivatives; row++)
 
13702
    {
 
13703
      for (unsigned int num = 0; num < row; num++)
 
13704
      {
 
13705
        for (unsigned int col = n-1; col+1 > 0; col--)
 
13706
        {
 
13707
          if (combinations[row][col] + 1 > 1)
 
13708
            combinations[row][col] = 0;
 
13709
          else
 
13710
          {
 
13711
            combinations[row][col] += 1;
 
13712
            break;
 
13713
          }
 
13714
        }
 
13715
      }
 
13716
    }
 
13717
    
 
13718
    // Compute inverse of Jacobian
 
13719
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
13720
    
 
13721
    // Declare transformation matrix
 
13722
    // Declare pointer to two dimensional array and initialise
 
13723
    double **transform = new double *[num_derivatives];
 
13724
    
 
13725
    for (unsigned int j = 0; j < num_derivatives; j++)
 
13726
    {
 
13727
      transform[j] = new double [num_derivatives];
 
13728
      for (unsigned int k = 0; k < num_derivatives; k++)
 
13729
        transform[j][k] = 1;
 
13730
    }
 
13731
    
 
13732
    // Construct transformation matrix
 
13733
    for (unsigned int row = 0; row < num_derivatives; row++)
 
13734
    {
 
13735
      for (unsigned int col = 0; col < num_derivatives; col++)
 
13736
      {
 
13737
        for (unsigned int k = 0; k < n; k++)
 
13738
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
13739
      }
 
13740
    }
 
13741
    
 
13742
    // Reset values
 
13743
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
 
13744
      values[j] = 0;
 
13745
    
 
13746
    // Map degree of freedom to element degree of freedom
 
13747
    const unsigned int dof = i;
 
13748
    
 
13749
    // Generate scalings
 
13750
    const double scalings_y_0 = 1;
 
13751
    
 
13752
    // Compute psitilde_a
 
13753
    const double psitilde_a_0 = 1;
 
13754
    
 
13755
    // Compute psitilde_bs
 
13756
    const double psitilde_bs_0_0 = 1;
 
13757
    
 
13758
    // Compute basisvalues
 
13759
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
13760
    
 
13761
    // Table(s) of coefficients
 
13762
    static const double coefficients0[1][1] = \
 
13763
    {{1.41421356237309}};
 
13764
    
 
13765
    // Interesting (new) part
 
13766
    // Tables of derivatives of the polynomial base (transpose)
 
13767
    static const double dmats0[1][1] = \
 
13768
    {{0}};
 
13769
    
 
13770
    static const double dmats1[1][1] = \
 
13771
    {{0}};
 
13772
    
 
13773
    // Compute reference derivatives
 
13774
    // Declare pointer to array of derivatives on FIAT element
 
13775
    double *derivatives = new double [num_derivatives];
 
13776
    
 
13777
    // Declare coefficients
 
13778
    double coeff0_0 = 0;
 
13779
    
 
13780
    // Declare new coefficients
 
13781
    double new_coeff0_0 = 0;
 
13782
    
 
13783
    // Loop possible derivatives
 
13784
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
13785
    {
 
13786
      // Get values from coefficients array
 
13787
      new_coeff0_0 = coefficients0[dof][0];
 
13788
    
 
13789
      // Loop derivative order
 
13790
      for (unsigned int j = 0; j < n; j++)
 
13791
      {
 
13792
        // Update old coefficients
 
13793
        coeff0_0 = new_coeff0_0;
 
13794
    
 
13795
        if(combinations[deriv_num][j] == 0)
 
13796
        {
 
13797
          new_coeff0_0 = coeff0_0*dmats0[0][0];
 
13798
        }
 
13799
        if(combinations[deriv_num][j] == 1)
 
13800
        {
 
13801
          new_coeff0_0 = coeff0_0*dmats1[0][0];
 
13802
        }
 
13803
    
 
13804
      }
 
13805
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
13806
      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
 
13807
    }
 
13808
    
 
13809
    // Transform derivatives back to physical element
 
13810
    for (unsigned int row = 0; row < num_derivatives; row++)
 
13811
    {
 
13812
      for (unsigned int col = 0; col < num_derivatives; col++)
 
13813
      {
 
13814
        values[row] += transform[row][col]*derivatives[col];
 
13815
      }
 
13816
    }
 
13817
    // Delete pointer to array of derivatives on FIAT element
 
13818
    delete [] derivatives;
 
13819
    
 
13820
    // Delete pointer to array of combinations of derivatives and transform
 
13821
    for (unsigned int row = 0; row < num_derivatives; row++)
 
13822
    {
 
13823
      delete [] combinations[row];
 
13824
      delete [] transform[row];
 
13825
    }
 
13826
    
 
13827
    delete [] combinations;
 
13828
    delete [] transform;
 
13829
}
 
13830
 
 
13831
/// Evaluate order n derivatives of all basis functions at given point in cell
 
13832
void cahnhilliard2d_1_finite_element_6::evaluate_basis_derivatives_all(unsigned int n,
 
13833
                                                   double* values,
 
13834
                                                   const double* coordinates,
 
13835
                                                   const ufc::cell& c) const
 
13836
{
 
13837
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
13838
}
 
13839
 
 
13840
/// Evaluate linear functional for dof i on the function f
 
13841
double cahnhilliard2d_1_finite_element_6::evaluate_dof(unsigned int i,
 
13842
                                   const ufc::function& f,
 
13843
                                   const ufc::cell& c) const
 
13844
{
 
13845
    // The reference points, direction and weights:
 
13846
    static const double X[1][1][2] = {{{0.333333333333333, 0.333333333333333}}};
 
13847
    static const double W[1][1] = {{1}};
 
13848
    static const double D[1][1][1] = {{{1}}};
 
13849
    
 
13850
    const double * const * x = c.coordinates;
 
13851
    double result = 0.0;
 
13852
    // Iterate over the points:
 
13853
    // Evaluate basis functions for affine mapping
 
13854
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
13855
    const double w1 = X[i][0][0];
 
13856
    const double w2 = X[i][0][1];
 
13857
    
 
13858
    // Compute affine mapping y = F(X)
 
13859
    double y[2];
 
13860
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
13861
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
13862
    
 
13863
    // Evaluate function at physical points
 
13864
    double values[1];
 
13865
    f.evaluate(values, y, c);
 
13866
    
 
13867
    // Map function values using appropriate mapping
 
13868
    // Affine map: Do nothing
 
13869
    
 
13870
    // Note that we do not map the weights (yet).
 
13871
    
 
13872
    // Take directional components
 
13873
    for(int k = 0; k < 1; k++)
 
13874
      result += values[k]*D[i][0][k];
 
13875
    // Multiply by weights
 
13876
    result *= W[i][0];
 
13877
    
 
13878
    return result;
 
13879
}
 
13880
 
 
13881
/// Evaluate linear functionals for all dofs on the function f
 
13882
void cahnhilliard2d_1_finite_element_6::evaluate_dofs(double* values,
 
13883
                                  const ufc::function& f,
 
13884
                                  const ufc::cell& c) const
 
13885
{
 
13886
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
13887
}
 
13888
 
 
13889
/// Interpolate vertex values from dof values
 
13890
void cahnhilliard2d_1_finite_element_6::interpolate_vertex_values(double* vertex_values,
 
13891
                                              const double* dof_values,
 
13892
                                              const ufc::cell& c) const
 
13893
{
 
13894
    // Evaluate at vertices and use affine mapping
 
13895
    vertex_values[0] = dof_values[0];
 
13896
    vertex_values[1] = dof_values[0];
 
13897
    vertex_values[2] = dof_values[0];
 
13898
}
 
13899
 
 
13900
/// Return the number of sub elements (for a mixed element)
 
13901
unsigned int cahnhilliard2d_1_finite_element_6::num_sub_elements() const
 
13902
{
 
13903
    return 1;
 
13904
}
 
13905
 
 
13906
/// Create a new finite element for sub element i (for a mixed element)
 
13907
ufc::finite_element* cahnhilliard2d_1_finite_element_6::create_sub_element(unsigned int i) const
 
13908
{
 
13909
    return new cahnhilliard2d_1_finite_element_6();
 
13910
}
 
13911
 
 
13912
/// Constructor
 
13913
cahnhilliard2d_1_dof_map_0_0::cahnhilliard2d_1_dof_map_0_0() : ufc::dof_map()
 
13914
{
 
13915
    __global_dimension = 0;
 
13916
}
 
13917
 
 
13918
/// Destructor
 
13919
cahnhilliard2d_1_dof_map_0_0::~cahnhilliard2d_1_dof_map_0_0()
 
13920
{
 
13921
    // Do nothing
 
13922
}
 
13923
 
 
13924
/// Return a string identifying the dof map
 
13925
const char* cahnhilliard2d_1_dof_map_0_0::signature() const
 
13926
{
 
13927
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
 
13928
}
 
13929
 
 
13930
/// Return true iff mesh entities of topological dimension d are needed
 
13931
bool cahnhilliard2d_1_dof_map_0_0::needs_mesh_entities(unsigned int d) const
 
13932
{
 
13933
    switch ( d )
 
13934
    {
 
13935
    case 0:
 
13936
      return true;
 
13937
      break;
 
13938
    case 1:
 
13939
      return false;
 
13940
      break;
 
13941
    case 2:
 
13942
      return false;
 
13943
      break;
 
13944
    }
 
13945
    return false;
 
13946
}
 
13947
 
 
13948
/// Initialize dof map for mesh (return true iff init_cell() is needed)
 
13949
bool cahnhilliard2d_1_dof_map_0_0::init_mesh(const ufc::mesh& m)
 
13950
{
 
13951
    __global_dimension = m.num_entities[0];
 
13952
    return false;
 
13953
}
 
13954
 
 
13955
/// Initialize dof map for given cell
 
13956
void cahnhilliard2d_1_dof_map_0_0::init_cell(const ufc::mesh& m,
 
13957
                              const ufc::cell& c)
 
13958
{
 
13959
    // Do nothing
 
13960
}
 
13961
 
 
13962
/// Finish initialization of dof map for cells
 
13963
void cahnhilliard2d_1_dof_map_0_0::init_cell_finalize()
 
13964
{
 
13965
    // Do nothing
 
13966
}
 
13967
 
 
13968
/// Return the dimension of the global finite element function space
 
13969
unsigned int cahnhilliard2d_1_dof_map_0_0::global_dimension() const
 
13970
{
 
13971
    return __global_dimension;
 
13972
}
 
13973
 
 
13974
/// Return the dimension of the local finite element function space for a cell
 
13975
unsigned int cahnhilliard2d_1_dof_map_0_0::local_dimension(const ufc::cell& c) const
 
13976
{
 
13977
    return 3;
 
13978
}
 
13979
 
 
13980
/// Return the maximum dimension of the local finite element function space
 
13981
unsigned int cahnhilliard2d_1_dof_map_0_0::max_local_dimension() const
 
13982
{
 
13983
    return 3;
 
13984
}
 
13985
 
 
13986
// Return the geometric dimension of the coordinates this dof map provides
 
13987
unsigned int cahnhilliard2d_1_dof_map_0_0::geometric_dimension() const
 
13988
{
 
13989
    return 2;
 
13990
}
 
13991
 
 
13992
/// Return the number of dofs on each cell facet
 
13993
unsigned int cahnhilliard2d_1_dof_map_0_0::num_facet_dofs() const
 
13994
{
 
13995
    return 2;
 
13996
}
 
13997
 
 
13998
/// Return the number of dofs associated with each cell entity of dimension d
 
13999
unsigned int cahnhilliard2d_1_dof_map_0_0::num_entity_dofs(unsigned int d) const
 
14000
{
 
14001
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
14002
}
 
14003
 
 
14004
/// Tabulate the local-to-global mapping of dofs on a cell
 
14005
void cahnhilliard2d_1_dof_map_0_0::tabulate_dofs(unsigned int* dofs,
 
14006
                                  const ufc::mesh& m,
 
14007
                                  const ufc::cell& c) const
 
14008
{
 
14009
    dofs[0] = c.entity_indices[0][0];
 
14010
    dofs[1] = c.entity_indices[0][1];
 
14011
    dofs[2] = c.entity_indices[0][2];
 
14012
}
 
14013
 
 
14014
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
14015
void cahnhilliard2d_1_dof_map_0_0::tabulate_facet_dofs(unsigned int* dofs,
 
14016
                                        unsigned int facet) const
 
14017
{
 
14018
    switch ( facet )
 
14019
    {
 
14020
    case 0:
 
14021
      dofs[0] = 1;
 
14022
      dofs[1] = 2;
 
14023
      break;
 
14024
    case 1:
 
14025
      dofs[0] = 0;
 
14026
      dofs[1] = 2;
 
14027
      break;
 
14028
    case 2:
 
14029
      dofs[0] = 0;
 
14030
      dofs[1] = 1;
 
14031
      break;
 
14032
    }
 
14033
}
 
14034
 
 
14035
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
14036
void cahnhilliard2d_1_dof_map_0_0::tabulate_entity_dofs(unsigned int* dofs,
 
14037
                                  unsigned int d, unsigned int i) const
 
14038
{
 
14039
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
14040
}
 
14041
 
 
14042
/// Tabulate the coordinates of all dofs on a cell
 
14043
void cahnhilliard2d_1_dof_map_0_0::tabulate_coordinates(double** coordinates,
 
14044
                                         const ufc::cell& c) const
 
14045
{
 
14046
    const double * const * x = c.coordinates;
 
14047
    coordinates[0][0] = x[0][0];
 
14048
    coordinates[0][1] = x[0][1];
 
14049
    coordinates[1][0] = x[1][0];
 
14050
    coordinates[1][1] = x[1][1];
 
14051
    coordinates[2][0] = x[2][0];
 
14052
    coordinates[2][1] = x[2][1];
 
14053
}
 
14054
 
 
14055
/// Return the number of sub dof maps (for a mixed element)
 
14056
unsigned int cahnhilliard2d_1_dof_map_0_0::num_sub_dof_maps() const
 
14057
{
 
14058
    return 1;
 
14059
}
 
14060
 
 
14061
/// Create a new dof_map for sub dof map i (for a mixed element)
 
14062
ufc::dof_map* cahnhilliard2d_1_dof_map_0_0::create_sub_dof_map(unsigned int i) const
 
14063
{
 
14064
    return new cahnhilliard2d_1_dof_map_0_0();
 
14065
}
 
14066
 
 
14067
 
 
14068
/// Constructor
 
14069
cahnhilliard2d_1_dof_map_0_1::cahnhilliard2d_1_dof_map_0_1() : ufc::dof_map()
 
14070
{
 
14071
    __global_dimension = 0;
 
14072
}
 
14073
 
 
14074
/// Destructor
 
14075
cahnhilliard2d_1_dof_map_0_1::~cahnhilliard2d_1_dof_map_0_1()
 
14076
{
 
14077
    // Do nothing
 
14078
}
 
14079
 
 
14080
/// Return a string identifying the dof map
 
14081
const char* cahnhilliard2d_1_dof_map_0_1::signature() const
 
14082
{
 
14083
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
 
14084
}
 
14085
 
 
14086
/// Return true iff mesh entities of topological dimension d are needed
 
14087
bool cahnhilliard2d_1_dof_map_0_1::needs_mesh_entities(unsigned int d) const
 
14088
{
 
14089
    switch ( d )
 
14090
    {
 
14091
    case 0:
 
14092
      return true;
 
14093
      break;
 
14094
    case 1:
 
14095
      return false;
 
14096
      break;
 
14097
    case 2:
 
14098
      return false;
 
14099
      break;
 
14100
    }
 
14101
    return false;
 
14102
}
 
14103
 
 
14104
/// Initialize dof map for mesh (return true iff init_cell() is needed)
 
14105
bool cahnhilliard2d_1_dof_map_0_1::init_mesh(const ufc::mesh& m)
 
14106
{
 
14107
    __global_dimension = m.num_entities[0];
 
14108
    return false;
 
14109
}
 
14110
 
 
14111
/// Initialize dof map for given cell
 
14112
void cahnhilliard2d_1_dof_map_0_1::init_cell(const ufc::mesh& m,
 
14113
                              const ufc::cell& c)
 
14114
{
 
14115
    // Do nothing
 
14116
}
 
14117
 
 
14118
/// Finish initialization of dof map for cells
 
14119
void cahnhilliard2d_1_dof_map_0_1::init_cell_finalize()
 
14120
{
 
14121
    // Do nothing
 
14122
}
 
14123
 
 
14124
/// Return the dimension of the global finite element function space
 
14125
unsigned int cahnhilliard2d_1_dof_map_0_1::global_dimension() const
 
14126
{
 
14127
    return __global_dimension;
 
14128
}
 
14129
 
 
14130
/// Return the dimension of the local finite element function space for a cell
 
14131
unsigned int cahnhilliard2d_1_dof_map_0_1::local_dimension(const ufc::cell& c) const
 
14132
{
 
14133
    return 3;
 
14134
}
 
14135
 
 
14136
/// Return the maximum dimension of the local finite element function space
 
14137
unsigned int cahnhilliard2d_1_dof_map_0_1::max_local_dimension() const
 
14138
{
 
14139
    return 3;
 
14140
}
 
14141
 
 
14142
// Return the geometric dimension of the coordinates this dof map provides
 
14143
unsigned int cahnhilliard2d_1_dof_map_0_1::geometric_dimension() const
 
14144
{
 
14145
    return 2;
 
14146
}
 
14147
 
 
14148
/// Return the number of dofs on each cell facet
 
14149
unsigned int cahnhilliard2d_1_dof_map_0_1::num_facet_dofs() const
 
14150
{
 
14151
    return 2;
 
14152
}
 
14153
 
 
14154
/// Return the number of dofs associated with each cell entity of dimension d
 
14155
unsigned int cahnhilliard2d_1_dof_map_0_1::num_entity_dofs(unsigned int d) const
 
14156
{
 
14157
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
14158
}
 
14159
 
 
14160
/// Tabulate the local-to-global mapping of dofs on a cell
 
14161
void cahnhilliard2d_1_dof_map_0_1::tabulate_dofs(unsigned int* dofs,
 
14162
                                  const ufc::mesh& m,
 
14163
                                  const ufc::cell& c) const
 
14164
{
 
14165
    dofs[0] = c.entity_indices[0][0];
 
14166
    dofs[1] = c.entity_indices[0][1];
 
14167
    dofs[2] = c.entity_indices[0][2];
 
14168
}
 
14169
 
 
14170
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
14171
void cahnhilliard2d_1_dof_map_0_1::tabulate_facet_dofs(unsigned int* dofs,
 
14172
                                        unsigned int facet) const
 
14173
{
 
14174
    switch ( facet )
 
14175
    {
 
14176
    case 0:
 
14177
      dofs[0] = 1;
 
14178
      dofs[1] = 2;
 
14179
      break;
 
14180
    case 1:
 
14181
      dofs[0] = 0;
 
14182
      dofs[1] = 2;
 
14183
      break;
 
14184
    case 2:
 
14185
      dofs[0] = 0;
 
14186
      dofs[1] = 1;
 
14187
      break;
 
14188
    }
 
14189
}
 
14190
 
 
14191
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
14192
void cahnhilliard2d_1_dof_map_0_1::tabulate_entity_dofs(unsigned int* dofs,
 
14193
                                  unsigned int d, unsigned int i) const
 
14194
{
 
14195
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
14196
}
 
14197
 
 
14198
/// Tabulate the coordinates of all dofs on a cell
 
14199
void cahnhilliard2d_1_dof_map_0_1::tabulate_coordinates(double** coordinates,
 
14200
                                         const ufc::cell& c) const
 
14201
{
 
14202
    const double * const * x = c.coordinates;
 
14203
    coordinates[0][0] = x[0][0];
 
14204
    coordinates[0][1] = x[0][1];
 
14205
    coordinates[1][0] = x[1][0];
 
14206
    coordinates[1][1] = x[1][1];
 
14207
    coordinates[2][0] = x[2][0];
 
14208
    coordinates[2][1] = x[2][1];
 
14209
}
 
14210
 
 
14211
/// Return the number of sub dof maps (for a mixed element)
 
14212
unsigned int cahnhilliard2d_1_dof_map_0_1::num_sub_dof_maps() const
 
14213
{
 
14214
    return 1;
 
14215
}
 
14216
 
 
14217
/// Create a new dof_map for sub dof map i (for a mixed element)
 
14218
ufc::dof_map* cahnhilliard2d_1_dof_map_0_1::create_sub_dof_map(unsigned int i) const
 
14219
{
 
14220
    return new cahnhilliard2d_1_dof_map_0_1();
 
14221
}
 
14222
 
 
14223
 
 
14224
/// Constructor
 
14225
cahnhilliard2d_1_dof_map_0::cahnhilliard2d_1_dof_map_0() : ufc::dof_map()
 
14226
{
 
14227
    __global_dimension = 0;
 
14228
}
 
14229
 
 
14230
/// Destructor
 
14231
cahnhilliard2d_1_dof_map_0::~cahnhilliard2d_1_dof_map_0()
 
14232
{
 
14233
    // Do nothing
 
14234
}
 
14235
 
 
14236
/// Return a string identifying the dof map
 
14237
const char* cahnhilliard2d_1_dof_map_0::signature() const
 
14238
{
 
14239
    return "FFC dof map for MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
 
14240
}
 
14241
 
 
14242
/// Return true iff mesh entities of topological dimension d are needed
 
14243
bool cahnhilliard2d_1_dof_map_0::needs_mesh_entities(unsigned int d) const
 
14244
{
 
14245
    switch ( d )
 
14246
    {
 
14247
    case 0:
 
14248
      return true;
 
14249
      break;
 
14250
    case 1:
 
14251
      return false;
 
14252
      break;
 
14253
    case 2:
 
14254
      return false;
 
14255
      break;
 
14256
    }
 
14257
    return false;
 
14258
}
 
14259
 
 
14260
/// Initialize dof map for mesh (return true iff init_cell() is needed)
 
14261
bool cahnhilliard2d_1_dof_map_0::init_mesh(const ufc::mesh& m)
 
14262
{
 
14263
    __global_dimension = 2*m.num_entities[0];
 
14264
    return false;
 
14265
}
 
14266
 
 
14267
/// Initialize dof map for given cell
 
14268
void cahnhilliard2d_1_dof_map_0::init_cell(const ufc::mesh& m,
 
14269
                              const ufc::cell& c)
 
14270
{
 
14271
    // Do nothing
 
14272
}
 
14273
 
 
14274
/// Finish initialization of dof map for cells
 
14275
void cahnhilliard2d_1_dof_map_0::init_cell_finalize()
 
14276
{
 
14277
    // Do nothing
 
14278
}
 
14279
 
 
14280
/// Return the dimension of the global finite element function space
 
14281
unsigned int cahnhilliard2d_1_dof_map_0::global_dimension() const
 
14282
{
 
14283
    return __global_dimension;
 
14284
}
 
14285
 
 
14286
/// Return the dimension of the local finite element function space for a cell
 
14287
unsigned int cahnhilliard2d_1_dof_map_0::local_dimension(const ufc::cell& c) const
 
14288
{
 
14289
    return 6;
 
14290
}
 
14291
 
 
14292
/// Return the maximum dimension of the local finite element function space
 
14293
unsigned int cahnhilliard2d_1_dof_map_0::max_local_dimension() const
 
14294
{
 
14295
    return 6;
 
14296
}
 
14297
 
 
14298
// Return the geometric dimension of the coordinates this dof map provides
 
14299
unsigned int cahnhilliard2d_1_dof_map_0::geometric_dimension() const
 
14300
{
 
14301
    return 2;
 
14302
}
 
14303
 
 
14304
/// Return the number of dofs on each cell facet
 
14305
unsigned int cahnhilliard2d_1_dof_map_0::num_facet_dofs() const
 
14306
{
 
14307
    return 4;
 
14308
}
 
14309
 
 
14310
/// Return the number of dofs associated with each cell entity of dimension d
 
14311
unsigned int cahnhilliard2d_1_dof_map_0::num_entity_dofs(unsigned int d) const
 
14312
{
 
14313
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
14314
}
 
14315
 
 
14316
/// Tabulate the local-to-global mapping of dofs on a cell
 
14317
void cahnhilliard2d_1_dof_map_0::tabulate_dofs(unsigned int* dofs,
 
14318
                                  const ufc::mesh& m,
 
14319
                                  const ufc::cell& c) const
 
14320
{
 
14321
    dofs[0] = c.entity_indices[0][0];
 
14322
    dofs[1] = c.entity_indices[0][1];
 
14323
    dofs[2] = c.entity_indices[0][2];
 
14324
    unsigned int offset = m.num_entities[0];
 
14325
    dofs[3] = offset + c.entity_indices[0][0];
 
14326
    dofs[4] = offset + c.entity_indices[0][1];
 
14327
    dofs[5] = offset + c.entity_indices[0][2];
 
14328
}
 
14329
 
 
14330
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
14331
void cahnhilliard2d_1_dof_map_0::tabulate_facet_dofs(unsigned int* dofs,
 
14332
                                        unsigned int facet) const
 
14333
{
 
14334
    switch ( facet )
 
14335
    {
 
14336
    case 0:
 
14337
      dofs[0] = 1;
 
14338
      dofs[1] = 2;
 
14339
      dofs[2] = 4;
 
14340
      dofs[3] = 5;
 
14341
      break;
 
14342
    case 1:
 
14343
      dofs[0] = 0;
 
14344
      dofs[1] = 2;
 
14345
      dofs[2] = 3;
 
14346
      dofs[3] = 5;
 
14347
      break;
 
14348
    case 2:
 
14349
      dofs[0] = 0;
 
14350
      dofs[1] = 1;
 
14351
      dofs[2] = 3;
 
14352
      dofs[3] = 4;
 
14353
      break;
 
14354
    }
 
14355
}
 
14356
 
 
14357
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
14358
void cahnhilliard2d_1_dof_map_0::tabulate_entity_dofs(unsigned int* dofs,
 
14359
                                  unsigned int d, unsigned int i) const
 
14360
{
 
14361
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
14362
}
 
14363
 
 
14364
/// Tabulate the coordinates of all dofs on a cell
 
14365
void cahnhilliard2d_1_dof_map_0::tabulate_coordinates(double** coordinates,
 
14366
                                         const ufc::cell& c) const
 
14367
{
 
14368
    const double * const * x = c.coordinates;
 
14369
    coordinates[0][0] = x[0][0];
 
14370
    coordinates[0][1] = x[0][1];
 
14371
    coordinates[1][0] = x[1][0];
 
14372
    coordinates[1][1] = x[1][1];
 
14373
    coordinates[2][0] = x[2][0];
 
14374
    coordinates[2][1] = x[2][1];
 
14375
    coordinates[3][0] = x[0][0];
 
14376
    coordinates[3][1] = x[0][1];
 
14377
    coordinates[4][0] = x[1][0];
 
14378
    coordinates[4][1] = x[1][1];
 
14379
    coordinates[5][0] = x[2][0];
 
14380
    coordinates[5][1] = x[2][1];
 
14381
}
 
14382
 
 
14383
/// Return the number of sub dof maps (for a mixed element)
 
14384
unsigned int cahnhilliard2d_1_dof_map_0::num_sub_dof_maps() const
 
14385
{
 
14386
    return 2;
 
14387
}
 
14388
 
 
14389
/// Create a new dof_map for sub dof map i (for a mixed element)
 
14390
ufc::dof_map* cahnhilliard2d_1_dof_map_0::create_sub_dof_map(unsigned int i) const
 
14391
{
 
14392
    switch ( i )
 
14393
    {
 
14394
    case 0:
 
14395
      return new cahnhilliard2d_1_dof_map_0_0();
 
14396
      break;
 
14397
    case 1:
 
14398
      return new cahnhilliard2d_1_dof_map_0_1();
 
14399
      break;
 
14400
    }
 
14401
    return 0;
 
14402
}
 
14403
 
 
14404
 
 
14405
/// Constructor
 
14406
cahnhilliard2d_1_dof_map_1_0::cahnhilliard2d_1_dof_map_1_0() : ufc::dof_map()
 
14407
{
 
14408
    __global_dimension = 0;
 
14409
}
 
14410
 
 
14411
/// Destructor
 
14412
cahnhilliard2d_1_dof_map_1_0::~cahnhilliard2d_1_dof_map_1_0()
 
14413
{
 
14414
    // Do nothing
 
14415
}
 
14416
 
 
14417
/// Return a string identifying the dof map
 
14418
const char* cahnhilliard2d_1_dof_map_1_0::signature() const
 
14419
{
 
14420
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
 
14421
}
 
14422
 
 
14423
/// Return true iff mesh entities of topological dimension d are needed
 
14424
bool cahnhilliard2d_1_dof_map_1_0::needs_mesh_entities(unsigned int d) const
 
14425
{
 
14426
    switch ( d )
 
14427
    {
 
14428
    case 0:
 
14429
      return true;
 
14430
      break;
 
14431
    case 1:
 
14432
      return false;
 
14433
      break;
 
14434
    case 2:
 
14435
      return false;
 
14436
      break;
 
14437
    }
 
14438
    return false;
 
14439
}
 
14440
 
 
14441
/// Initialize dof map for mesh (return true iff init_cell() is needed)
 
14442
bool cahnhilliard2d_1_dof_map_1_0::init_mesh(const ufc::mesh& m)
 
14443
{
 
14444
    __global_dimension = m.num_entities[0];
 
14445
    return false;
 
14446
}
 
14447
 
 
14448
/// Initialize dof map for given cell
 
14449
void cahnhilliard2d_1_dof_map_1_0::init_cell(const ufc::mesh& m,
 
14450
                              const ufc::cell& c)
 
14451
{
 
14452
    // Do nothing
 
14453
}
 
14454
 
 
14455
/// Finish initialization of dof map for cells
 
14456
void cahnhilliard2d_1_dof_map_1_0::init_cell_finalize()
 
14457
{
 
14458
    // Do nothing
 
14459
}
 
14460
 
 
14461
/// Return the dimension of the global finite element function space
 
14462
unsigned int cahnhilliard2d_1_dof_map_1_0::global_dimension() const
 
14463
{
 
14464
    return __global_dimension;
 
14465
}
 
14466
 
 
14467
/// Return the dimension of the local finite element function space for a cell
 
14468
unsigned int cahnhilliard2d_1_dof_map_1_0::local_dimension(const ufc::cell& c) const
 
14469
{
 
14470
    return 3;
 
14471
}
 
14472
 
 
14473
/// Return the maximum dimension of the local finite element function space
 
14474
unsigned int cahnhilliard2d_1_dof_map_1_0::max_local_dimension() const
 
14475
{
 
14476
    return 3;
 
14477
}
 
14478
 
 
14479
// Return the geometric dimension of the coordinates this dof map provides
 
14480
unsigned int cahnhilliard2d_1_dof_map_1_0::geometric_dimension() const
 
14481
{
 
14482
    return 2;
 
14483
}
 
14484
 
 
14485
/// Return the number of dofs on each cell facet
 
14486
unsigned int cahnhilliard2d_1_dof_map_1_0::num_facet_dofs() const
 
14487
{
 
14488
    return 2;
 
14489
}
 
14490
 
 
14491
/// Return the number of dofs associated with each cell entity of dimension d
 
14492
unsigned int cahnhilliard2d_1_dof_map_1_0::num_entity_dofs(unsigned int d) const
 
14493
{
 
14494
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
14495
}
 
14496
 
 
14497
/// Tabulate the local-to-global mapping of dofs on a cell
 
14498
void cahnhilliard2d_1_dof_map_1_0::tabulate_dofs(unsigned int* dofs,
 
14499
                                  const ufc::mesh& m,
 
14500
                                  const ufc::cell& c) const
 
14501
{
 
14502
    dofs[0] = c.entity_indices[0][0];
 
14503
    dofs[1] = c.entity_indices[0][1];
 
14504
    dofs[2] = c.entity_indices[0][2];
 
14505
}
 
14506
 
 
14507
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
14508
void cahnhilliard2d_1_dof_map_1_0::tabulate_facet_dofs(unsigned int* dofs,
 
14509
                                        unsigned int facet) const
 
14510
{
 
14511
    switch ( facet )
 
14512
    {
 
14513
    case 0:
 
14514
      dofs[0] = 1;
 
14515
      dofs[1] = 2;
 
14516
      break;
 
14517
    case 1:
 
14518
      dofs[0] = 0;
 
14519
      dofs[1] = 2;
 
14520
      break;
 
14521
    case 2:
 
14522
      dofs[0] = 0;
 
14523
      dofs[1] = 1;
 
14524
      break;
 
14525
    }
 
14526
}
 
14527
 
 
14528
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
14529
void cahnhilliard2d_1_dof_map_1_0::tabulate_entity_dofs(unsigned int* dofs,
 
14530
                                  unsigned int d, unsigned int i) const
 
14531
{
 
14532
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
14533
}
 
14534
 
 
14535
/// Tabulate the coordinates of all dofs on a cell
 
14536
void cahnhilliard2d_1_dof_map_1_0::tabulate_coordinates(double** coordinates,
 
14537
                                         const ufc::cell& c) const
 
14538
{
 
14539
    const double * const * x = c.coordinates;
 
14540
    coordinates[0][0] = x[0][0];
 
14541
    coordinates[0][1] = x[0][1];
 
14542
    coordinates[1][0] = x[1][0];
 
14543
    coordinates[1][1] = x[1][1];
 
14544
    coordinates[2][0] = x[2][0];
 
14545
    coordinates[2][1] = x[2][1];
 
14546
}
 
14547
 
 
14548
/// Return the number of sub dof maps (for a mixed element)
 
14549
unsigned int cahnhilliard2d_1_dof_map_1_0::num_sub_dof_maps() const
 
14550
{
 
14551
    return 1;
 
14552
}
 
14553
 
 
14554
/// Create a new dof_map for sub dof map i (for a mixed element)
 
14555
ufc::dof_map* cahnhilliard2d_1_dof_map_1_0::create_sub_dof_map(unsigned int i) const
 
14556
{
 
14557
    return new cahnhilliard2d_1_dof_map_1_0();
 
14558
}
 
14559
 
 
14560
 
 
14561
/// Constructor
 
14562
cahnhilliard2d_1_dof_map_1_1::cahnhilliard2d_1_dof_map_1_1() : ufc::dof_map()
 
14563
{
 
14564
    __global_dimension = 0;
 
14565
}
 
14566
 
 
14567
/// Destructor
 
14568
cahnhilliard2d_1_dof_map_1_1::~cahnhilliard2d_1_dof_map_1_1()
 
14569
{
 
14570
    // Do nothing
 
14571
}
 
14572
 
 
14573
/// Return a string identifying the dof map
 
14574
const char* cahnhilliard2d_1_dof_map_1_1::signature() const
 
14575
{
 
14576
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
 
14577
}
 
14578
 
 
14579
/// Return true iff mesh entities of topological dimension d are needed
 
14580
bool cahnhilliard2d_1_dof_map_1_1::needs_mesh_entities(unsigned int d) const
 
14581
{
 
14582
    switch ( d )
 
14583
    {
 
14584
    case 0:
 
14585
      return true;
 
14586
      break;
 
14587
    case 1:
 
14588
      return false;
 
14589
      break;
 
14590
    case 2:
 
14591
      return false;
 
14592
      break;
 
14593
    }
 
14594
    return false;
 
14595
}
 
14596
 
 
14597
/// Initialize dof map for mesh (return true iff init_cell() is needed)
 
14598
bool cahnhilliard2d_1_dof_map_1_1::init_mesh(const ufc::mesh& m)
 
14599
{
 
14600
    __global_dimension = m.num_entities[0];
 
14601
    return false;
 
14602
}
 
14603
 
 
14604
/// Initialize dof map for given cell
 
14605
void cahnhilliard2d_1_dof_map_1_1::init_cell(const ufc::mesh& m,
 
14606
                              const ufc::cell& c)
 
14607
{
 
14608
    // Do nothing
 
14609
}
 
14610
 
 
14611
/// Finish initialization of dof map for cells
 
14612
void cahnhilliard2d_1_dof_map_1_1::init_cell_finalize()
 
14613
{
 
14614
    // Do nothing
 
14615
}
 
14616
 
 
14617
/// Return the dimension of the global finite element function space
 
14618
unsigned int cahnhilliard2d_1_dof_map_1_1::global_dimension() const
 
14619
{
 
14620
    return __global_dimension;
 
14621
}
 
14622
 
 
14623
/// Return the dimension of the local finite element function space for a cell
 
14624
unsigned int cahnhilliard2d_1_dof_map_1_1::local_dimension(const ufc::cell& c) const
 
14625
{
 
14626
    return 3;
 
14627
}
 
14628
 
 
14629
/// Return the maximum dimension of the local finite element function space
 
14630
unsigned int cahnhilliard2d_1_dof_map_1_1::max_local_dimension() const
 
14631
{
 
14632
    return 3;
 
14633
}
 
14634
 
 
14635
// Return the geometric dimension of the coordinates this dof map provides
 
14636
unsigned int cahnhilliard2d_1_dof_map_1_1::geometric_dimension() const
 
14637
{
 
14638
    return 2;
 
14639
}
 
14640
 
 
14641
/// Return the number of dofs on each cell facet
 
14642
unsigned int cahnhilliard2d_1_dof_map_1_1::num_facet_dofs() const
 
14643
{
 
14644
    return 2;
 
14645
}
 
14646
 
 
14647
/// Return the number of dofs associated with each cell entity of dimension d
 
14648
unsigned int cahnhilliard2d_1_dof_map_1_1::num_entity_dofs(unsigned int d) const
 
14649
{
 
14650
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
14651
}
 
14652
 
 
14653
/// Tabulate the local-to-global mapping of dofs on a cell
 
14654
void cahnhilliard2d_1_dof_map_1_1::tabulate_dofs(unsigned int* dofs,
 
14655
                                  const ufc::mesh& m,
 
14656
                                  const ufc::cell& c) const
 
14657
{
 
14658
    dofs[0] = c.entity_indices[0][0];
 
14659
    dofs[1] = c.entity_indices[0][1];
 
14660
    dofs[2] = c.entity_indices[0][2];
 
14661
}
 
14662
 
 
14663
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
14664
void cahnhilliard2d_1_dof_map_1_1::tabulate_facet_dofs(unsigned int* dofs,
 
14665
                                        unsigned int facet) const
 
14666
{
 
14667
    switch ( facet )
 
14668
    {
 
14669
    case 0:
 
14670
      dofs[0] = 1;
 
14671
      dofs[1] = 2;
 
14672
      break;
 
14673
    case 1:
 
14674
      dofs[0] = 0;
 
14675
      dofs[1] = 2;
 
14676
      break;
 
14677
    case 2:
 
14678
      dofs[0] = 0;
 
14679
      dofs[1] = 1;
 
14680
      break;
 
14681
    }
 
14682
}
 
14683
 
 
14684
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
14685
void cahnhilliard2d_1_dof_map_1_1::tabulate_entity_dofs(unsigned int* dofs,
 
14686
                                  unsigned int d, unsigned int i) const
 
14687
{
 
14688
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
14689
}
 
14690
 
 
14691
/// Tabulate the coordinates of all dofs on a cell
 
14692
void cahnhilliard2d_1_dof_map_1_1::tabulate_coordinates(double** coordinates,
 
14693
                                         const ufc::cell& c) const
 
14694
{
 
14695
    const double * const * x = c.coordinates;
 
14696
    coordinates[0][0] = x[0][0];
 
14697
    coordinates[0][1] = x[0][1];
 
14698
    coordinates[1][0] = x[1][0];
 
14699
    coordinates[1][1] = x[1][1];
 
14700
    coordinates[2][0] = x[2][0];
 
14701
    coordinates[2][1] = x[2][1];
 
14702
}
 
14703
 
 
14704
/// Return the number of sub dof maps (for a mixed element)
 
14705
unsigned int cahnhilliard2d_1_dof_map_1_1::num_sub_dof_maps() const
 
14706
{
 
14707
    return 1;
 
14708
}
 
14709
 
 
14710
/// Create a new dof_map for sub dof map i (for a mixed element)
 
14711
ufc::dof_map* cahnhilliard2d_1_dof_map_1_1::create_sub_dof_map(unsigned int i) const
 
14712
{
 
14713
    return new cahnhilliard2d_1_dof_map_1_1();
 
14714
}
 
14715
 
 
14716
 
 
14717
/// Constructor
 
14718
cahnhilliard2d_1_dof_map_1::cahnhilliard2d_1_dof_map_1() : ufc::dof_map()
 
14719
{
 
14720
    __global_dimension = 0;
 
14721
}
 
14722
 
 
14723
/// Destructor
 
14724
cahnhilliard2d_1_dof_map_1::~cahnhilliard2d_1_dof_map_1()
 
14725
{
 
14726
    // Do nothing
 
14727
}
 
14728
 
 
14729
/// Return a string identifying the dof map
 
14730
const char* cahnhilliard2d_1_dof_map_1::signature() const
 
14731
{
 
14732
    return "FFC dof map for MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
 
14733
}
 
14734
 
 
14735
/// Return true iff mesh entities of topological dimension d are needed
 
14736
bool cahnhilliard2d_1_dof_map_1::needs_mesh_entities(unsigned int d) const
 
14737
{
 
14738
    switch ( d )
 
14739
    {
 
14740
    case 0:
 
14741
      return true;
 
14742
      break;
 
14743
    case 1:
 
14744
      return false;
 
14745
      break;
 
14746
    case 2:
 
14747
      return false;
 
14748
      break;
 
14749
    }
 
14750
    return false;
 
14751
}
 
14752
 
 
14753
/// Initialize dof map for mesh (return true iff init_cell() is needed)
 
14754
bool cahnhilliard2d_1_dof_map_1::init_mesh(const ufc::mesh& m)
 
14755
{
 
14756
    __global_dimension = 2*m.num_entities[0];
 
14757
    return false;
 
14758
}
 
14759
 
 
14760
/// Initialize dof map for given cell
 
14761
void cahnhilliard2d_1_dof_map_1::init_cell(const ufc::mesh& m,
 
14762
                              const ufc::cell& c)
 
14763
{
 
14764
    // Do nothing
 
14765
}
 
14766
 
 
14767
/// Finish initialization of dof map for cells
 
14768
void cahnhilliard2d_1_dof_map_1::init_cell_finalize()
 
14769
{
 
14770
    // Do nothing
 
14771
}
 
14772
 
 
14773
/// Return the dimension of the global finite element function space
 
14774
unsigned int cahnhilliard2d_1_dof_map_1::global_dimension() const
 
14775
{
 
14776
    return __global_dimension;
 
14777
}
 
14778
 
 
14779
/// Return the dimension of the local finite element function space for a cell
 
14780
unsigned int cahnhilliard2d_1_dof_map_1::local_dimension(const ufc::cell& c) const
 
14781
{
 
14782
    return 6;
 
14783
}
 
14784
 
 
14785
/// Return the maximum dimension of the local finite element function space
 
14786
unsigned int cahnhilliard2d_1_dof_map_1::max_local_dimension() const
 
14787
{
 
14788
    return 6;
 
14789
}
 
14790
 
 
14791
// Return the geometric dimension of the coordinates this dof map provides
 
14792
unsigned int cahnhilliard2d_1_dof_map_1::geometric_dimension() const
 
14793
{
 
14794
    return 2;
 
14795
}
 
14796
 
 
14797
/// Return the number of dofs on each cell facet
 
14798
unsigned int cahnhilliard2d_1_dof_map_1::num_facet_dofs() const
 
14799
{
 
14800
    return 4;
 
14801
}
 
14802
 
 
14803
/// Return the number of dofs associated with each cell entity of dimension d
 
14804
unsigned int cahnhilliard2d_1_dof_map_1::num_entity_dofs(unsigned int d) const
 
14805
{
 
14806
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
14807
}
 
14808
 
 
14809
/// Tabulate the local-to-global mapping of dofs on a cell
 
14810
void cahnhilliard2d_1_dof_map_1::tabulate_dofs(unsigned int* dofs,
 
14811
                                  const ufc::mesh& m,
 
14812
                                  const ufc::cell& c) const
 
14813
{
 
14814
    dofs[0] = c.entity_indices[0][0];
 
14815
    dofs[1] = c.entity_indices[0][1];
 
14816
    dofs[2] = c.entity_indices[0][2];
 
14817
    unsigned int offset = m.num_entities[0];
 
14818
    dofs[3] = offset + c.entity_indices[0][0];
 
14819
    dofs[4] = offset + c.entity_indices[0][1];
 
14820
    dofs[5] = offset + c.entity_indices[0][2];
 
14821
}
 
14822
 
 
14823
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
14824
void cahnhilliard2d_1_dof_map_1::tabulate_facet_dofs(unsigned int* dofs,
 
14825
                                        unsigned int facet) const
 
14826
{
 
14827
    switch ( facet )
 
14828
    {
 
14829
    case 0:
 
14830
      dofs[0] = 1;
 
14831
      dofs[1] = 2;
 
14832
      dofs[2] = 4;
 
14833
      dofs[3] = 5;
 
14834
      break;
 
14835
    case 1:
 
14836
      dofs[0] = 0;
 
14837
      dofs[1] = 2;
 
14838
      dofs[2] = 3;
 
14839
      dofs[3] = 5;
 
14840
      break;
 
14841
    case 2:
 
14842
      dofs[0] = 0;
 
14843
      dofs[1] = 1;
 
14844
      dofs[2] = 3;
 
14845
      dofs[3] = 4;
 
14846
      break;
 
14847
    }
 
14848
}
 
14849
 
 
14850
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
14851
void cahnhilliard2d_1_dof_map_1::tabulate_entity_dofs(unsigned int* dofs,
 
14852
                                  unsigned int d, unsigned int i) const
 
14853
{
 
14854
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
14855
}
 
14856
 
 
14857
/// Tabulate the coordinates of all dofs on a cell
 
14858
void cahnhilliard2d_1_dof_map_1::tabulate_coordinates(double** coordinates,
 
14859
                                         const ufc::cell& c) const
 
14860
{
 
14861
    const double * const * x = c.coordinates;
 
14862
    coordinates[0][0] = x[0][0];
 
14863
    coordinates[0][1] = x[0][1];
 
14864
    coordinates[1][0] = x[1][0];
 
14865
    coordinates[1][1] = x[1][1];
 
14866
    coordinates[2][0] = x[2][0];
 
14867
    coordinates[2][1] = x[2][1];
 
14868
    coordinates[3][0] = x[0][0];
 
14869
    coordinates[3][1] = x[0][1];
 
14870
    coordinates[4][0] = x[1][0];
 
14871
    coordinates[4][1] = x[1][1];
 
14872
    coordinates[5][0] = x[2][0];
 
14873
    coordinates[5][1] = x[2][1];
 
14874
}
 
14875
 
 
14876
/// Return the number of sub dof maps (for a mixed element)
 
14877
unsigned int cahnhilliard2d_1_dof_map_1::num_sub_dof_maps() const
 
14878
{
 
14879
    return 2;
 
14880
}
 
14881
 
 
14882
/// Create a new dof_map for sub dof map i (for a mixed element)
 
14883
ufc::dof_map* cahnhilliard2d_1_dof_map_1::create_sub_dof_map(unsigned int i) const
 
14884
{
 
14885
    switch ( i )
 
14886
    {
 
14887
    case 0:
 
14888
      return new cahnhilliard2d_1_dof_map_1_0();
 
14889
      break;
 
14890
    case 1:
 
14891
      return new cahnhilliard2d_1_dof_map_1_1();
 
14892
      break;
 
14893
    }
 
14894
    return 0;
 
14895
}
 
14896
 
 
14897
 
 
14898
/// Constructor
 
14899
cahnhilliard2d_1_dof_map_2_0::cahnhilliard2d_1_dof_map_2_0() : ufc::dof_map()
 
14900
{
 
14901
    __global_dimension = 0;
 
14902
}
 
14903
 
 
14904
/// Destructor
 
14905
cahnhilliard2d_1_dof_map_2_0::~cahnhilliard2d_1_dof_map_2_0()
 
14906
{
 
14907
    // Do nothing
 
14908
}
 
14909
 
 
14910
/// Return a string identifying the dof map
 
14911
const char* cahnhilliard2d_1_dof_map_2_0::signature() const
 
14912
{
 
14913
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
 
14914
}
 
14915
 
 
14916
/// Return true iff mesh entities of topological dimension d are needed
 
14917
bool cahnhilliard2d_1_dof_map_2_0::needs_mesh_entities(unsigned int d) const
 
14918
{
 
14919
    switch ( d )
 
14920
    {
 
14921
    case 0:
 
14922
      return true;
 
14923
      break;
 
14924
    case 1:
 
14925
      return false;
 
14926
      break;
 
14927
    case 2:
 
14928
      return false;
 
14929
      break;
 
14930
    }
 
14931
    return false;
 
14932
}
 
14933
 
 
14934
/// Initialize dof map for mesh (return true iff init_cell() is needed)
 
14935
bool cahnhilliard2d_1_dof_map_2_0::init_mesh(const ufc::mesh& m)
 
14936
{
 
14937
    __global_dimension = m.num_entities[0];
 
14938
    return false;
 
14939
}
 
14940
 
 
14941
/// Initialize dof map for given cell
 
14942
void cahnhilliard2d_1_dof_map_2_0::init_cell(const ufc::mesh& m,
 
14943
                              const ufc::cell& c)
 
14944
{
 
14945
    // Do nothing
 
14946
}
 
14947
 
 
14948
/// Finish initialization of dof map for cells
 
14949
void cahnhilliard2d_1_dof_map_2_0::init_cell_finalize()
 
14950
{
 
14951
    // Do nothing
 
14952
}
 
14953
 
 
14954
/// Return the dimension of the global finite element function space
 
14955
unsigned int cahnhilliard2d_1_dof_map_2_0::global_dimension() const
 
14956
{
 
14957
    return __global_dimension;
 
14958
}
 
14959
 
 
14960
/// Return the dimension of the local finite element function space for a cell
 
14961
unsigned int cahnhilliard2d_1_dof_map_2_0::local_dimension(const ufc::cell& c) const
 
14962
{
 
14963
    return 3;
 
14964
}
 
14965
 
 
14966
/// Return the maximum dimension of the local finite element function space
 
14967
unsigned int cahnhilliard2d_1_dof_map_2_0::max_local_dimension() const
 
14968
{
 
14969
    return 3;
 
14970
}
 
14971
 
 
14972
// Return the geometric dimension of the coordinates this dof map provides
 
14973
unsigned int cahnhilliard2d_1_dof_map_2_0::geometric_dimension() const
 
14974
{
 
14975
    return 2;
 
14976
}
 
14977
 
 
14978
/// Return the number of dofs on each cell facet
 
14979
unsigned int cahnhilliard2d_1_dof_map_2_0::num_facet_dofs() const
 
14980
{
 
14981
    return 2;
 
14982
}
 
14983
 
 
14984
/// Return the number of dofs associated with each cell entity of dimension d
 
14985
unsigned int cahnhilliard2d_1_dof_map_2_0::num_entity_dofs(unsigned int d) const
 
14986
{
 
14987
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
14988
}
 
14989
 
 
14990
/// Tabulate the local-to-global mapping of dofs on a cell
 
14991
void cahnhilliard2d_1_dof_map_2_0::tabulate_dofs(unsigned int* dofs,
 
14992
                                  const ufc::mesh& m,
 
14993
                                  const ufc::cell& c) const
 
14994
{
 
14995
    dofs[0] = c.entity_indices[0][0];
 
14996
    dofs[1] = c.entity_indices[0][1];
 
14997
    dofs[2] = c.entity_indices[0][2];
 
14998
}
 
14999
 
 
15000
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
15001
void cahnhilliard2d_1_dof_map_2_0::tabulate_facet_dofs(unsigned int* dofs,
 
15002
                                        unsigned int facet) const
 
15003
{
 
15004
    switch ( facet )
 
15005
    {
 
15006
    case 0:
 
15007
      dofs[0] = 1;
 
15008
      dofs[1] = 2;
 
15009
      break;
 
15010
    case 1:
 
15011
      dofs[0] = 0;
 
15012
      dofs[1] = 2;
 
15013
      break;
 
15014
    case 2:
 
15015
      dofs[0] = 0;
 
15016
      dofs[1] = 1;
 
15017
      break;
 
15018
    }
 
15019
}
 
15020
 
 
15021
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
15022
void cahnhilliard2d_1_dof_map_2_0::tabulate_entity_dofs(unsigned int* dofs,
 
15023
                                  unsigned int d, unsigned int i) const
 
15024
{
 
15025
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
15026
}
 
15027
 
 
15028
/// Tabulate the coordinates of all dofs on a cell
 
15029
void cahnhilliard2d_1_dof_map_2_0::tabulate_coordinates(double** coordinates,
 
15030
                                         const ufc::cell& c) const
 
15031
{
 
15032
    const double * const * x = c.coordinates;
 
15033
    coordinates[0][0] = x[0][0];
 
15034
    coordinates[0][1] = x[0][1];
 
15035
    coordinates[1][0] = x[1][0];
 
15036
    coordinates[1][1] = x[1][1];
 
15037
    coordinates[2][0] = x[2][0];
 
15038
    coordinates[2][1] = x[2][1];
 
15039
}
 
15040
 
 
15041
/// Return the number of sub dof maps (for a mixed element)
 
15042
unsigned int cahnhilliard2d_1_dof_map_2_0::num_sub_dof_maps() const
 
15043
{
 
15044
    return 1;
 
15045
}
 
15046
 
 
15047
/// Create a new dof_map for sub dof map i (for a mixed element)
 
15048
ufc::dof_map* cahnhilliard2d_1_dof_map_2_0::create_sub_dof_map(unsigned int i) const
 
15049
{
 
15050
    return new cahnhilliard2d_1_dof_map_2_0();
 
15051
}
 
15052
 
 
15053
 
 
15054
/// Constructor
 
15055
cahnhilliard2d_1_dof_map_2_1::cahnhilliard2d_1_dof_map_2_1() : ufc::dof_map()
 
15056
{
 
15057
    __global_dimension = 0;
 
15058
}
 
15059
 
 
15060
/// Destructor
 
15061
cahnhilliard2d_1_dof_map_2_1::~cahnhilliard2d_1_dof_map_2_1()
 
15062
{
 
15063
    // Do nothing
 
15064
}
 
15065
 
 
15066
/// Return a string identifying the dof map
 
15067
const char* cahnhilliard2d_1_dof_map_2_1::signature() const
 
15068
{
 
15069
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 1)";
 
15070
}
 
15071
 
 
15072
/// Return true iff mesh entities of topological dimension d are needed
 
15073
bool cahnhilliard2d_1_dof_map_2_1::needs_mesh_entities(unsigned int d) const
 
15074
{
 
15075
    switch ( d )
 
15076
    {
 
15077
    case 0:
 
15078
      return true;
 
15079
      break;
 
15080
    case 1:
 
15081
      return false;
 
15082
      break;
 
15083
    case 2:
 
15084
      return false;
 
15085
      break;
 
15086
    }
 
15087
    return false;
 
15088
}
 
15089
 
 
15090
/// Initialize dof map for mesh (return true iff init_cell() is needed)
 
15091
bool cahnhilliard2d_1_dof_map_2_1::init_mesh(const ufc::mesh& m)
 
15092
{
 
15093
    __global_dimension = m.num_entities[0];
 
15094
    return false;
 
15095
}
 
15096
 
 
15097
/// Initialize dof map for given cell
 
15098
void cahnhilliard2d_1_dof_map_2_1::init_cell(const ufc::mesh& m,
 
15099
                              const ufc::cell& c)
 
15100
{
 
15101
    // Do nothing
 
15102
}
 
15103
 
 
15104
/// Finish initialization of dof map for cells
 
15105
void cahnhilliard2d_1_dof_map_2_1::init_cell_finalize()
 
15106
{
 
15107
    // Do nothing
 
15108
}
 
15109
 
 
15110
/// Return the dimension of the global finite element function space
 
15111
unsigned int cahnhilliard2d_1_dof_map_2_1::global_dimension() const
 
15112
{
 
15113
    return __global_dimension;
 
15114
}
 
15115
 
 
15116
/// Return the dimension of the local finite element function space for a cell
 
15117
unsigned int cahnhilliard2d_1_dof_map_2_1::local_dimension(const ufc::cell& c) const
 
15118
{
 
15119
    return 3;
 
15120
}
 
15121
 
 
15122
/// Return the maximum dimension of the local finite element function space
 
15123
unsigned int cahnhilliard2d_1_dof_map_2_1::max_local_dimension() const
 
15124
{
 
15125
    return 3;
 
15126
}
 
15127
 
 
15128
// Return the geometric dimension of the coordinates this dof map provides
 
15129
unsigned int cahnhilliard2d_1_dof_map_2_1::geometric_dimension() const
 
15130
{
 
15131
    return 2;
 
15132
}
 
15133
 
 
15134
/// Return the number of dofs on each cell facet
 
15135
unsigned int cahnhilliard2d_1_dof_map_2_1::num_facet_dofs() const
 
15136
{
 
15137
    return 2;
 
15138
}
 
15139
 
 
15140
/// Return the number of dofs associated with each cell entity of dimension d
 
15141
unsigned int cahnhilliard2d_1_dof_map_2_1::num_entity_dofs(unsigned int d) const
 
15142
{
 
15143
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
15144
}
 
15145
 
 
15146
/// Tabulate the local-to-global mapping of dofs on a cell
 
15147
void cahnhilliard2d_1_dof_map_2_1::tabulate_dofs(unsigned int* dofs,
 
15148
                                  const ufc::mesh& m,
 
15149
                                  const ufc::cell& c) const
 
15150
{
 
15151
    dofs[0] = c.entity_indices[0][0];
 
15152
    dofs[1] = c.entity_indices[0][1];
 
15153
    dofs[2] = c.entity_indices[0][2];
 
15154
}
 
15155
 
 
15156
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
15157
void cahnhilliard2d_1_dof_map_2_1::tabulate_facet_dofs(unsigned int* dofs,
 
15158
                                        unsigned int facet) const
 
15159
{
 
15160
    switch ( facet )
 
15161
    {
 
15162
    case 0:
 
15163
      dofs[0] = 1;
 
15164
      dofs[1] = 2;
 
15165
      break;
 
15166
    case 1:
 
15167
      dofs[0] = 0;
 
15168
      dofs[1] = 2;
 
15169
      break;
 
15170
    case 2:
 
15171
      dofs[0] = 0;
 
15172
      dofs[1] = 1;
 
15173
      break;
 
15174
    }
 
15175
}
 
15176
 
 
15177
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
15178
void cahnhilliard2d_1_dof_map_2_1::tabulate_entity_dofs(unsigned int* dofs,
 
15179
                                  unsigned int d, unsigned int i) const
 
15180
{
 
15181
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
15182
}
 
15183
 
 
15184
/// Tabulate the coordinates of all dofs on a cell
 
15185
void cahnhilliard2d_1_dof_map_2_1::tabulate_coordinates(double** coordinates,
 
15186
                                         const ufc::cell& c) const
 
15187
{
 
15188
    const double * const * x = c.coordinates;
 
15189
    coordinates[0][0] = x[0][0];
 
15190
    coordinates[0][1] = x[0][1];
 
15191
    coordinates[1][0] = x[1][0];
 
15192
    coordinates[1][1] = x[1][1];
 
15193
    coordinates[2][0] = x[2][0];
 
15194
    coordinates[2][1] = x[2][1];
 
15195
}
 
15196
 
 
15197
/// Return the number of sub dof maps (for a mixed element)
 
15198
unsigned int cahnhilliard2d_1_dof_map_2_1::num_sub_dof_maps() const
 
15199
{
 
15200
    return 1;
 
15201
}
 
15202
 
 
15203
/// Create a new dof_map for sub dof map i (for a mixed element)
 
15204
ufc::dof_map* cahnhilliard2d_1_dof_map_2_1::create_sub_dof_map(unsigned int i) const
 
15205
{
 
15206
    return new cahnhilliard2d_1_dof_map_2_1();
 
15207
}
 
15208
 
 
15209
 
 
15210
/// Constructor
 
15211
cahnhilliard2d_1_dof_map_2::cahnhilliard2d_1_dof_map_2() : ufc::dof_map()
 
15212
{
 
15213
    __global_dimension = 0;
 
15214
}
 
15215
 
 
15216
/// Destructor
 
15217
cahnhilliard2d_1_dof_map_2::~cahnhilliard2d_1_dof_map_2()
 
15218
{
 
15219
    // Do nothing
 
15220
}
 
15221
 
 
15222
/// Return a string identifying the dof map
 
15223
const char* cahnhilliard2d_1_dof_map_2::signature() const
 
15224
{
 
15225
    return "FFC dof map for MixedElement([FiniteElement('Lagrange', 'triangle', 1), FiniteElement('Lagrange', 'triangle', 1)])";
 
15226
}
 
15227
 
 
15228
/// Return true iff mesh entities of topological dimension d are needed
 
15229
bool cahnhilliard2d_1_dof_map_2::needs_mesh_entities(unsigned int d) const
 
15230
{
 
15231
    switch ( d )
 
15232
    {
 
15233
    case 0:
 
15234
      return true;
 
15235
      break;
 
15236
    case 1:
 
15237
      return false;
 
15238
      break;
 
15239
    case 2:
 
15240
      return false;
 
15241
      break;
 
15242
    }
 
15243
    return false;
 
15244
}
 
15245
 
 
15246
/// Initialize dof map for mesh (return true iff init_cell() is needed)
 
15247
bool cahnhilliard2d_1_dof_map_2::init_mesh(const ufc::mesh& m)
 
15248
{
 
15249
    __global_dimension = 2*m.num_entities[0];
 
15250
    return false;
 
15251
}
 
15252
 
 
15253
/// Initialize dof map for given cell
 
15254
void cahnhilliard2d_1_dof_map_2::init_cell(const ufc::mesh& m,
 
15255
                              const ufc::cell& c)
 
15256
{
 
15257
    // Do nothing
 
15258
}
 
15259
 
 
15260
/// Finish initialization of dof map for cells
 
15261
void cahnhilliard2d_1_dof_map_2::init_cell_finalize()
 
15262
{
 
15263
    // Do nothing
 
15264
}
 
15265
 
 
15266
/// Return the dimension of the global finite element function space
 
15267
unsigned int cahnhilliard2d_1_dof_map_2::global_dimension() const
 
15268
{
 
15269
    return __global_dimension;
 
15270
}
 
15271
 
 
15272
/// Return the dimension of the local finite element function space for a cell
 
15273
unsigned int cahnhilliard2d_1_dof_map_2::local_dimension(const ufc::cell& c) const
 
15274
{
 
15275
    return 6;
 
15276
}
 
15277
 
 
15278
/// Return the maximum dimension of the local finite element function space
 
15279
unsigned int cahnhilliard2d_1_dof_map_2::max_local_dimension() const
 
15280
{
 
15281
    return 6;
 
15282
}
 
15283
 
 
15284
// Return the geometric dimension of the coordinates this dof map provides
 
15285
unsigned int cahnhilliard2d_1_dof_map_2::geometric_dimension() const
 
15286
{
 
15287
    return 2;
 
15288
}
 
15289
 
 
15290
/// Return the number of dofs on each cell facet
 
15291
unsigned int cahnhilliard2d_1_dof_map_2::num_facet_dofs() const
 
15292
{
 
15293
    return 4;
 
15294
}
 
15295
 
 
15296
/// Return the number of dofs associated with each cell entity of dimension d
 
15297
unsigned int cahnhilliard2d_1_dof_map_2::num_entity_dofs(unsigned int d) const
 
15298
{
 
15299
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
15300
}
 
15301
 
 
15302
/// Tabulate the local-to-global mapping of dofs on a cell
 
15303
void cahnhilliard2d_1_dof_map_2::tabulate_dofs(unsigned int* dofs,
 
15304
                                  const ufc::mesh& m,
 
15305
                                  const ufc::cell& c) const
 
15306
{
 
15307
    dofs[0] = c.entity_indices[0][0];
 
15308
    dofs[1] = c.entity_indices[0][1];
 
15309
    dofs[2] = c.entity_indices[0][2];
 
15310
    unsigned int offset = m.num_entities[0];
 
15311
    dofs[3] = offset + c.entity_indices[0][0];
 
15312
    dofs[4] = offset + c.entity_indices[0][1];
 
15313
    dofs[5] = offset + c.entity_indices[0][2];
 
15314
}
 
15315
 
 
15316
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
15317
void cahnhilliard2d_1_dof_map_2::tabulate_facet_dofs(unsigned int* dofs,
 
15318
                                        unsigned int facet) const
 
15319
{
 
15320
    switch ( facet )
 
15321
    {
 
15322
    case 0:
 
15323
      dofs[0] = 1;
 
15324
      dofs[1] = 2;
 
15325
      dofs[2] = 4;
 
15326
      dofs[3] = 5;
 
15327
      break;
 
15328
    case 1:
 
15329
      dofs[0] = 0;
 
15330
      dofs[1] = 2;
 
15331
      dofs[2] = 3;
 
15332
      dofs[3] = 5;
 
15333
      break;
 
15334
    case 2:
 
15335
      dofs[0] = 0;
 
15336
      dofs[1] = 1;
 
15337
      dofs[2] = 3;
 
15338
      dofs[3] = 4;
 
15339
      break;
 
15340
    }
 
15341
}
 
15342
 
 
15343
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
15344
void cahnhilliard2d_1_dof_map_2::tabulate_entity_dofs(unsigned int* dofs,
 
15345
                                  unsigned int d, unsigned int i) const
 
15346
{
 
15347
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
15348
}
 
15349
 
 
15350
/// Tabulate the coordinates of all dofs on a cell
 
15351
void cahnhilliard2d_1_dof_map_2::tabulate_coordinates(double** coordinates,
 
15352
                                         const ufc::cell& c) const
 
15353
{
 
15354
    const double * const * x = c.coordinates;
 
15355
    coordinates[0][0] = x[0][0];
 
15356
    coordinates[0][1] = x[0][1];
 
15357
    coordinates[1][0] = x[1][0];
 
15358
    coordinates[1][1] = x[1][1];
 
15359
    coordinates[2][0] = x[2][0];
 
15360
    coordinates[2][1] = x[2][1];
 
15361
    coordinates[3][0] = x[0][0];
 
15362
    coordinates[3][1] = x[0][1];
 
15363
    coordinates[4][0] = x[1][0];
 
15364
    coordinates[4][1] = x[1][1];
 
15365
    coordinates[5][0] = x[2][0];
 
15366
    coordinates[5][1] = x[2][1];
 
15367
}
 
15368
 
 
15369
/// Return the number of sub dof maps (for a mixed element)
 
15370
unsigned int cahnhilliard2d_1_dof_map_2::num_sub_dof_maps() const
 
15371
{
 
15372
    return 2;
 
15373
}
 
15374
 
 
15375
/// Create a new dof_map for sub dof map i (for a mixed element)
 
15376
ufc::dof_map* cahnhilliard2d_1_dof_map_2::create_sub_dof_map(unsigned int i) const
 
15377
{
 
15378
    switch ( i )
 
15379
    {
 
15380
    case 0:
 
15381
      return new cahnhilliard2d_1_dof_map_2_0();
 
15382
      break;
 
15383
    case 1:
 
15384
      return new cahnhilliard2d_1_dof_map_2_1();
 
15385
      break;
 
15386
    }
 
15387
    return 0;
 
15388
}
 
15389
 
 
15390
 
 
15391
/// Constructor
 
15392
cahnhilliard2d_1_dof_map_3::cahnhilliard2d_1_dof_map_3() : ufc::dof_map()
 
15393
{
 
15394
    __global_dimension = 0;
 
15395
}
 
15396
 
 
15397
/// Destructor
 
15398
cahnhilliard2d_1_dof_map_3::~cahnhilliard2d_1_dof_map_3()
 
15399
{
 
15400
    // Do nothing
 
15401
}
 
15402
 
 
15403
/// Return a string identifying the dof map
 
15404
const char* cahnhilliard2d_1_dof_map_3::signature() const
 
15405
{
 
15406
    return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
 
15407
}
 
15408
 
 
15409
/// Return true iff mesh entities of topological dimension d are needed
 
15410
bool cahnhilliard2d_1_dof_map_3::needs_mesh_entities(unsigned int d) const
 
15411
{
 
15412
    switch ( d )
 
15413
    {
 
15414
    case 0:
 
15415
      return false;
 
15416
      break;
 
15417
    case 1:
 
15418
      return false;
 
15419
      break;
 
15420
    case 2:
 
15421
      return true;
 
15422
      break;
 
15423
    }
 
15424
    return false;
 
15425
}
 
15426
 
 
15427
/// Initialize dof map for mesh (return true iff init_cell() is needed)
 
15428
bool cahnhilliard2d_1_dof_map_3::init_mesh(const ufc::mesh& m)
 
15429
{
 
15430
    __global_dimension = m.num_entities[2];
 
15431
    return false;
 
15432
}
 
15433
 
 
15434
/// Initialize dof map for given cell
 
15435
void cahnhilliard2d_1_dof_map_3::init_cell(const ufc::mesh& m,
 
15436
                              const ufc::cell& c)
 
15437
{
 
15438
    // Do nothing
 
15439
}
 
15440
 
 
15441
/// Finish initialization of dof map for cells
 
15442
void cahnhilliard2d_1_dof_map_3::init_cell_finalize()
 
15443
{
 
15444
    // Do nothing
 
15445
}
 
15446
 
 
15447
/// Return the dimension of the global finite element function space
 
15448
unsigned int cahnhilliard2d_1_dof_map_3::global_dimension() const
 
15449
{
 
15450
    return __global_dimension;
 
15451
}
 
15452
 
 
15453
/// Return the dimension of the local finite element function space for a cell
 
15454
unsigned int cahnhilliard2d_1_dof_map_3::local_dimension(const ufc::cell& c) const
 
15455
{
 
15456
    return 1;
 
15457
}
 
15458
 
 
15459
/// Return the maximum dimension of the local finite element function space
 
15460
unsigned int cahnhilliard2d_1_dof_map_3::max_local_dimension() const
 
15461
{
 
15462
    return 1;
 
15463
}
 
15464
 
 
15465
// Return the geometric dimension of the coordinates this dof map provides
 
15466
unsigned int cahnhilliard2d_1_dof_map_3::geometric_dimension() const
 
15467
{
 
15468
    return 2;
 
15469
}
 
15470
 
 
15471
/// Return the number of dofs on each cell facet
 
15472
unsigned int cahnhilliard2d_1_dof_map_3::num_facet_dofs() const
 
15473
{
 
15474
    return 0;
 
15475
}
 
15476
 
 
15477
/// Return the number of dofs associated with each cell entity of dimension d
 
15478
unsigned int cahnhilliard2d_1_dof_map_3::num_entity_dofs(unsigned int d) const
 
15479
{
 
15480
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
15481
}
 
15482
 
 
15483
/// Tabulate the local-to-global mapping of dofs on a cell
 
15484
void cahnhilliard2d_1_dof_map_3::tabulate_dofs(unsigned int* dofs,
 
15485
                                  const ufc::mesh& m,
 
15486
                                  const ufc::cell& c) const
 
15487
{
 
15488
    dofs[0] = c.entity_indices[2][0];
 
15489
}
 
15490
 
 
15491
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
15492
void cahnhilliard2d_1_dof_map_3::tabulate_facet_dofs(unsigned int* dofs,
 
15493
                                        unsigned int facet) const
 
15494
{
 
15495
    switch ( facet )
 
15496
    {
 
15497
    case 0:
 
15498
      
 
15499
      break;
 
15500
    case 1:
 
15501
      
 
15502
      break;
 
15503
    case 2:
 
15504
      
 
15505
      break;
 
15506
    }
 
15507
}
 
15508
 
 
15509
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
15510
void cahnhilliard2d_1_dof_map_3::tabulate_entity_dofs(unsigned int* dofs,
 
15511
                                  unsigned int d, unsigned int i) const
 
15512
{
 
15513
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
15514
}
 
15515
 
 
15516
/// Tabulate the coordinates of all dofs on a cell
 
15517
void cahnhilliard2d_1_dof_map_3::tabulate_coordinates(double** coordinates,
 
15518
                                         const ufc::cell& c) const
 
15519
{
 
15520
    const double * const * x = c.coordinates;
 
15521
    coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
 
15522
    coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
 
15523
}
 
15524
 
 
15525
/// Return the number of sub dof maps (for a mixed element)
 
15526
unsigned int cahnhilliard2d_1_dof_map_3::num_sub_dof_maps() const
 
15527
{
 
15528
    return 1;
 
15529
}
 
15530
 
 
15531
/// Create a new dof_map for sub dof map i (for a mixed element)
 
15532
ufc::dof_map* cahnhilliard2d_1_dof_map_3::create_sub_dof_map(unsigned int i) const
 
15533
{
 
15534
    return new cahnhilliard2d_1_dof_map_3();
 
15535
}
 
15536
 
 
15537
 
 
15538
/// Constructor
 
15539
cahnhilliard2d_1_dof_map_4::cahnhilliard2d_1_dof_map_4() : ufc::dof_map()
 
15540
{
 
15541
    __global_dimension = 0;
 
15542
}
 
15543
 
 
15544
/// Destructor
 
15545
cahnhilliard2d_1_dof_map_4::~cahnhilliard2d_1_dof_map_4()
 
15546
{
 
15547
    // Do nothing
 
15548
}
 
15549
 
 
15550
/// Return a string identifying the dof map
 
15551
const char* cahnhilliard2d_1_dof_map_4::signature() const
 
15552
{
 
15553
    return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
 
15554
}
 
15555
 
 
15556
/// Return true iff mesh entities of topological dimension d are needed
 
15557
bool cahnhilliard2d_1_dof_map_4::needs_mesh_entities(unsigned int d) const
 
15558
{
 
15559
    switch ( d )
 
15560
    {
 
15561
    case 0:
 
15562
      return false;
 
15563
      break;
 
15564
    case 1:
 
15565
      return false;
 
15566
      break;
 
15567
    case 2:
 
15568
      return true;
 
15569
      break;
 
15570
    }
 
15571
    return false;
 
15572
}
 
15573
 
 
15574
/// Initialize dof map for mesh (return true iff init_cell() is needed)
 
15575
bool cahnhilliard2d_1_dof_map_4::init_mesh(const ufc::mesh& m)
 
15576
{
 
15577
    __global_dimension = m.num_entities[2];
 
15578
    return false;
 
15579
}
 
15580
 
 
15581
/// Initialize dof map for given cell
 
15582
void cahnhilliard2d_1_dof_map_4::init_cell(const ufc::mesh& m,
 
15583
                              const ufc::cell& c)
 
15584
{
 
15585
    // Do nothing
 
15586
}
 
15587
 
 
15588
/// Finish initialization of dof map for cells
 
15589
void cahnhilliard2d_1_dof_map_4::init_cell_finalize()
 
15590
{
 
15591
    // Do nothing
 
15592
}
 
15593
 
 
15594
/// Return the dimension of the global finite element function space
 
15595
unsigned int cahnhilliard2d_1_dof_map_4::global_dimension() const
 
15596
{
 
15597
    return __global_dimension;
 
15598
}
 
15599
 
 
15600
/// Return the dimension of the local finite element function space for a cell
 
15601
unsigned int cahnhilliard2d_1_dof_map_4::local_dimension(const ufc::cell& c) const
 
15602
{
 
15603
    return 1;
 
15604
}
 
15605
 
 
15606
/// Return the maximum dimension of the local finite element function space
 
15607
unsigned int cahnhilliard2d_1_dof_map_4::max_local_dimension() const
 
15608
{
 
15609
    return 1;
 
15610
}
 
15611
 
 
15612
// Return the geometric dimension of the coordinates this dof map provides
 
15613
unsigned int cahnhilliard2d_1_dof_map_4::geometric_dimension() const
 
15614
{
 
15615
    return 2;
 
15616
}
 
15617
 
 
15618
/// Return the number of dofs on each cell facet
 
15619
unsigned int cahnhilliard2d_1_dof_map_4::num_facet_dofs() const
 
15620
{
 
15621
    return 0;
 
15622
}
 
15623
 
 
15624
/// Return the number of dofs associated with each cell entity of dimension d
 
15625
unsigned int cahnhilliard2d_1_dof_map_4::num_entity_dofs(unsigned int d) const
 
15626
{
 
15627
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
15628
}
 
15629
 
 
15630
/// Tabulate the local-to-global mapping of dofs on a cell
 
15631
void cahnhilliard2d_1_dof_map_4::tabulate_dofs(unsigned int* dofs,
 
15632
                                  const ufc::mesh& m,
 
15633
                                  const ufc::cell& c) const
 
15634
{
 
15635
    dofs[0] = c.entity_indices[2][0];
 
15636
}
 
15637
 
 
15638
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
15639
void cahnhilliard2d_1_dof_map_4::tabulate_facet_dofs(unsigned int* dofs,
 
15640
                                        unsigned int facet) const
 
15641
{
 
15642
    switch ( facet )
 
15643
    {
 
15644
    case 0:
 
15645
      
 
15646
      break;
 
15647
    case 1:
 
15648
      
 
15649
      break;
 
15650
    case 2:
 
15651
      
 
15652
      break;
 
15653
    }
 
15654
}
 
15655
 
 
15656
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
15657
void cahnhilliard2d_1_dof_map_4::tabulate_entity_dofs(unsigned int* dofs,
 
15658
                                  unsigned int d, unsigned int i) const
 
15659
{
 
15660
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
15661
}
 
15662
 
 
15663
/// Tabulate the coordinates of all dofs on a cell
 
15664
void cahnhilliard2d_1_dof_map_4::tabulate_coordinates(double** coordinates,
 
15665
                                         const ufc::cell& c) const
 
15666
{
 
15667
    const double * const * x = c.coordinates;
 
15668
    coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
 
15669
    coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
 
15670
}
 
15671
 
 
15672
/// Return the number of sub dof maps (for a mixed element)
 
15673
unsigned int cahnhilliard2d_1_dof_map_4::num_sub_dof_maps() const
 
15674
{
 
15675
    return 1;
 
15676
}
 
15677
 
 
15678
/// Create a new dof_map for sub dof map i (for a mixed element)
 
15679
ufc::dof_map* cahnhilliard2d_1_dof_map_4::create_sub_dof_map(unsigned int i) const
 
15680
{
 
15681
    return new cahnhilliard2d_1_dof_map_4();
 
15682
}
 
15683
 
 
15684
 
 
15685
/// Constructor
 
15686
cahnhilliard2d_1_dof_map_5::cahnhilliard2d_1_dof_map_5() : ufc::dof_map()
 
15687
{
 
15688
    __global_dimension = 0;
 
15689
}
 
15690
 
 
15691
/// Destructor
 
15692
cahnhilliard2d_1_dof_map_5::~cahnhilliard2d_1_dof_map_5()
 
15693
{
 
15694
    // Do nothing
 
15695
}
 
15696
 
 
15697
/// Return a string identifying the dof map
 
15698
const char* cahnhilliard2d_1_dof_map_5::signature() const
 
15699
{
 
15700
    return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
 
15701
}
 
15702
 
 
15703
/// Return true iff mesh entities of topological dimension d are needed
 
15704
bool cahnhilliard2d_1_dof_map_5::needs_mesh_entities(unsigned int d) const
 
15705
{
 
15706
    switch ( d )
 
15707
    {
 
15708
    case 0:
 
15709
      return false;
 
15710
      break;
 
15711
    case 1:
 
15712
      return false;
 
15713
      break;
 
15714
    case 2:
 
15715
      return true;
 
15716
      break;
 
15717
    }
 
15718
    return false;
 
15719
}
 
15720
 
 
15721
/// Initialize dof map for mesh (return true iff init_cell() is needed)
 
15722
bool cahnhilliard2d_1_dof_map_5::init_mesh(const ufc::mesh& m)
 
15723
{
 
15724
    __global_dimension = m.num_entities[2];
 
15725
    return false;
 
15726
}
 
15727
 
 
15728
/// Initialize dof map for given cell
 
15729
void cahnhilliard2d_1_dof_map_5::init_cell(const ufc::mesh& m,
 
15730
                              const ufc::cell& c)
 
15731
{
 
15732
    // Do nothing
 
15733
}
 
15734
 
 
15735
/// Finish initialization of dof map for cells
 
15736
void cahnhilliard2d_1_dof_map_5::init_cell_finalize()
 
15737
{
 
15738
    // Do nothing
 
15739
}
 
15740
 
 
15741
/// Return the dimension of the global finite element function space
 
15742
unsigned int cahnhilliard2d_1_dof_map_5::global_dimension() const
 
15743
{
 
15744
    return __global_dimension;
 
15745
}
 
15746
 
 
15747
/// Return the dimension of the local finite element function space for a cell
 
15748
unsigned int cahnhilliard2d_1_dof_map_5::local_dimension(const ufc::cell& c) const
 
15749
{
 
15750
    return 1;
 
15751
}
 
15752
 
 
15753
/// Return the maximum dimension of the local finite element function space
 
15754
unsigned int cahnhilliard2d_1_dof_map_5::max_local_dimension() const
 
15755
{
 
15756
    return 1;
 
15757
}
 
15758
 
 
15759
// Return the geometric dimension of the coordinates this dof map provides
 
15760
unsigned int cahnhilliard2d_1_dof_map_5::geometric_dimension() const
 
15761
{
 
15762
    return 2;
 
15763
}
 
15764
 
 
15765
/// Return the number of dofs on each cell facet
 
15766
unsigned int cahnhilliard2d_1_dof_map_5::num_facet_dofs() const
 
15767
{
 
15768
    return 0;
 
15769
}
 
15770
 
 
15771
/// Return the number of dofs associated with each cell entity of dimension d
 
15772
unsigned int cahnhilliard2d_1_dof_map_5::num_entity_dofs(unsigned int d) const
 
15773
{
 
15774
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
15775
}
 
15776
 
 
15777
/// Tabulate the local-to-global mapping of dofs on a cell
 
15778
void cahnhilliard2d_1_dof_map_5::tabulate_dofs(unsigned int* dofs,
 
15779
                                  const ufc::mesh& m,
 
15780
                                  const ufc::cell& c) const
 
15781
{
 
15782
    dofs[0] = c.entity_indices[2][0];
 
15783
}
 
15784
 
 
15785
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
15786
void cahnhilliard2d_1_dof_map_5::tabulate_facet_dofs(unsigned int* dofs,
 
15787
                                        unsigned int facet) const
 
15788
{
 
15789
    switch ( facet )
 
15790
    {
 
15791
    case 0:
 
15792
      
 
15793
      break;
 
15794
    case 1:
 
15795
      
 
15796
      break;
 
15797
    case 2:
 
15798
      
 
15799
      break;
 
15800
    }
 
15801
}
 
15802
 
 
15803
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
15804
void cahnhilliard2d_1_dof_map_5::tabulate_entity_dofs(unsigned int* dofs,
 
15805
                                  unsigned int d, unsigned int i) const
 
15806
{
 
15807
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
15808
}
 
15809
 
 
15810
/// Tabulate the coordinates of all dofs on a cell
 
15811
void cahnhilliard2d_1_dof_map_5::tabulate_coordinates(double** coordinates,
 
15812
                                         const ufc::cell& c) const
 
15813
{
 
15814
    const double * const * x = c.coordinates;
 
15815
    coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
 
15816
    coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
 
15817
}
 
15818
 
 
15819
/// Return the number of sub dof maps (for a mixed element)
 
15820
unsigned int cahnhilliard2d_1_dof_map_5::num_sub_dof_maps() const
 
15821
{
 
15822
    return 1;
 
15823
}
 
15824
 
 
15825
/// Create a new dof_map for sub dof map i (for a mixed element)
 
15826
ufc::dof_map* cahnhilliard2d_1_dof_map_5::create_sub_dof_map(unsigned int i) const
 
15827
{
 
15828
    return new cahnhilliard2d_1_dof_map_5();
 
15829
}
 
15830
 
 
15831
 
 
15832
/// Constructor
 
15833
cahnhilliard2d_1_dof_map_6::cahnhilliard2d_1_dof_map_6() : ufc::dof_map()
 
15834
{
 
15835
    __global_dimension = 0;
 
15836
}
 
15837
 
 
15838
/// Destructor
 
15839
cahnhilliard2d_1_dof_map_6::~cahnhilliard2d_1_dof_map_6()
 
15840
{
 
15841
    // Do nothing
 
15842
}
 
15843
 
 
15844
/// Return a string identifying the dof map
 
15845
const char* cahnhilliard2d_1_dof_map_6::signature() const
 
15846
{
 
15847
    return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
 
15848
}
 
15849
 
 
15850
/// Return true iff mesh entities of topological dimension d are needed
 
15851
bool cahnhilliard2d_1_dof_map_6::needs_mesh_entities(unsigned int d) const
 
15852
{
 
15853
    switch ( d )
 
15854
    {
 
15855
    case 0:
 
15856
      return false;
 
15857
      break;
 
15858
    case 1:
 
15859
      return false;
 
15860
      break;
 
15861
    case 2:
 
15862
      return true;
 
15863
      break;
 
15864
    }
 
15865
    return false;
 
15866
}
 
15867
 
 
15868
/// Initialize dof map for mesh (return true iff init_cell() is needed)
 
15869
bool cahnhilliard2d_1_dof_map_6::init_mesh(const ufc::mesh& m)
 
15870
{
 
15871
    __global_dimension = m.num_entities[2];
 
15872
    return false;
 
15873
}
 
15874
 
 
15875
/// Initialize dof map for given cell
 
15876
void cahnhilliard2d_1_dof_map_6::init_cell(const ufc::mesh& m,
 
15877
                              const ufc::cell& c)
 
15878
{
 
15879
    // Do nothing
 
15880
}
 
15881
 
 
15882
/// Finish initialization of dof map for cells
 
15883
void cahnhilliard2d_1_dof_map_6::init_cell_finalize()
 
15884
{
 
15885
    // Do nothing
 
15886
}
 
15887
 
 
15888
/// Return the dimension of the global finite element function space
 
15889
unsigned int cahnhilliard2d_1_dof_map_6::global_dimension() const
 
15890
{
 
15891
    return __global_dimension;
 
15892
}
 
15893
 
 
15894
/// Return the dimension of the local finite element function space for a cell
 
15895
unsigned int cahnhilliard2d_1_dof_map_6::local_dimension(const ufc::cell& c) const
 
15896
{
 
15897
    return 1;
 
15898
}
 
15899
 
 
15900
/// Return the maximum dimension of the local finite element function space
 
15901
unsigned int cahnhilliard2d_1_dof_map_6::max_local_dimension() const
 
15902
{
 
15903
    return 1;
 
15904
}
 
15905
 
 
15906
// Return the geometric dimension of the coordinates this dof map provides
 
15907
unsigned int cahnhilliard2d_1_dof_map_6::geometric_dimension() const
 
15908
{
 
15909
    return 2;
 
15910
}
 
15911
 
 
15912
/// Return the number of dofs on each cell facet
 
15913
unsigned int cahnhilliard2d_1_dof_map_6::num_facet_dofs() const
 
15914
{
 
15915
    return 0;
 
15916
}
 
15917
 
 
15918
/// Return the number of dofs associated with each cell entity of dimension d
 
15919
unsigned int cahnhilliard2d_1_dof_map_6::num_entity_dofs(unsigned int d) const
 
15920
{
 
15921
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
15922
}
 
15923
 
 
15924
/// Tabulate the local-to-global mapping of dofs on a cell
 
15925
void cahnhilliard2d_1_dof_map_6::tabulate_dofs(unsigned int* dofs,
 
15926
                                  const ufc::mesh& m,
 
15927
                                  const ufc::cell& c) const
 
15928
{
 
15929
    dofs[0] = c.entity_indices[2][0];
 
15930
}
 
15931
 
 
15932
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
15933
void cahnhilliard2d_1_dof_map_6::tabulate_facet_dofs(unsigned int* dofs,
 
15934
                                        unsigned int facet) const
 
15935
{
 
15936
    switch ( facet )
 
15937
    {
 
15938
    case 0:
 
15939
      
 
15940
      break;
 
15941
    case 1:
 
15942
      
 
15943
      break;
 
15944
    case 2:
 
15945
      
 
15946
      break;
 
15947
    }
 
15948
}
 
15949
 
 
15950
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
15951
void cahnhilliard2d_1_dof_map_6::tabulate_entity_dofs(unsigned int* dofs,
 
15952
                                  unsigned int d, unsigned int i) const
 
15953
{
 
15954
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
15955
}
 
15956
 
 
15957
/// Tabulate the coordinates of all dofs on a cell
 
15958
void cahnhilliard2d_1_dof_map_6::tabulate_coordinates(double** coordinates,
 
15959
                                         const ufc::cell& c) const
 
15960
{
 
15961
    const double * const * x = c.coordinates;
 
15962
    coordinates[0][0] = 0.333333333333333*x[0][0] + 0.333333333333333*x[1][0] + 0.333333333333333*x[2][0];
 
15963
    coordinates[0][1] = 0.333333333333333*x[0][1] + 0.333333333333333*x[1][1] + 0.333333333333333*x[2][1];
 
15964
}
 
15965
 
 
15966
/// Return the number of sub dof maps (for a mixed element)
 
15967
unsigned int cahnhilliard2d_1_dof_map_6::num_sub_dof_maps() const
 
15968
{
 
15969
    return 1;
 
15970
}
 
15971
 
 
15972
/// Create a new dof_map for sub dof map i (for a mixed element)
 
15973
ufc::dof_map* cahnhilliard2d_1_dof_map_6::create_sub_dof_map(unsigned int i) const
 
15974
{
 
15975
    return new cahnhilliard2d_1_dof_map_6();
 
15976
}
 
15977
 
 
15978
 
 
15979
/// Constructor
 
15980
cahnhilliard2d_1_cell_integral_0_quadrature::cahnhilliard2d_1_cell_integral_0_quadrature() : ufc::cell_integral()
 
15981
{
 
15982
    // Do nothing
 
15983
}
 
15984
 
 
15985
/// Destructor
 
15986
cahnhilliard2d_1_cell_integral_0_quadrature::~cahnhilliard2d_1_cell_integral_0_quadrature()
15752
15987
{
15753
15988
    // Do nothing
15754
15989
}
15755
15990
 
15756
15991
/// Tabulate the tensor for the contribution from a local cell
15757
 
void UFC_CahnHilliard2DLinearForm_cell_integral_0::tabulate_tensor(double* A,
 
15992
void cahnhilliard2d_1_cell_integral_0_quadrature::tabulate_tensor(double* A,
15758
15993
                                    const double * const * w,
15759
15994
                                    const ufc::cell& c) const
15760
15995
{
15766
16001
    const double J_01 = x[2][0] - x[0][0];
15767
16002
    const double J_10 = x[1][1] - x[0][1];
15768
16003
    const double J_11 = x[2][1] - x[0][1];
15769
 
      
 
16004
    
15770
16005
    // Compute determinant of Jacobian
15771
16006
    double detJ = J_00*J_11 - J_01*J_10;
15772
 
      
 
16007
    
15773
16008
    // Compute inverse of Jacobian
15774
16009
    const double Jinv_00 =  J_11 / detJ;
15775
16010
    const double Jinv_01 = -J_01 / detJ;
15779
16014
    // Set scale factor
15780
16015
    const double det = std::abs(detJ);
15781
16016
    
15782
 
    // Number of operations to compute element tensor = 768
15783
 
    // Compute coefficients
15784
 
    const double c0_0_0_0 = w[0][0];
15785
 
    const double c0_0_0_1 = w[0][1];
15786
 
    const double c0_0_0_2 = w[0][2];
15787
 
    const double c0_0_0_3 = w[0][3];
15788
 
    const double c0_0_0_4 = w[0][4];
15789
 
    const double c0_0_0_5 = w[0][5];
15790
 
    const double c1_1_0_3 = w[1][3];
15791
 
    const double c1_1_0_4 = w[1][4];
15792
 
    const double c1_1_0_5 = w[1][5];
15793
 
    const double c4_3_0_0 = w[4][0];
15794
 
    const double c5_3_1_0 = w[5][0];
15795
 
    const double c1_3_2_0 = w[1][0];
15796
 
    const double c1_3_2_1 = w[1][1];
15797
 
    const double c1_3_2_2 = w[1][2];
15798
 
    const double c4_4_0_0 = w[4][0];
15799
 
    const double c1_4_1_0 = w[1][0];
15800
 
    const double c1_4_1_1 = w[1][1];
15801
 
    const double c1_4_1_2 = w[1][2];
15802
 
    const double c4_6_0_0 = w[4][0];
15803
 
    const double c5_6_1_0 = w[5][0];
15804
 
    const double c0_6_2_0 = w[0][0];
15805
 
    const double c0_6_2_1 = w[0][1];
15806
 
    const double c0_6_2_2 = w[0][2];
15807
 
    const double c3_7_0_0 = w[3][0];
15808
 
    const double c0_7_1_3 = w[0][3];
15809
 
    const double c0_7_1_4 = w[0][4];
15810
 
    const double c0_7_1_5 = w[0][5];
15811
 
    const double c0_7_2_3 = w[0][3];
15812
 
    const double c0_7_2_4 = w[0][4];
15813
 
    const double c0_7_2_5 = w[0][5];
15814
 
    const double c0_7_3_3 = w[0][3];
15815
 
    const double c0_7_3_4 = w[0][4];
15816
 
    const double c0_7_3_5 = w[0][5];
15817
 
    const double c3_8_0_0 = w[3][0];
15818
 
    const double c0_8_1_3 = w[0][3];
15819
 
    const double c0_8_1_4 = w[0][4];
15820
 
    const double c0_8_1_5 = w[0][5];
15821
 
    const double c0_8_2_3 = w[0][3];
15822
 
    const double c0_8_2_4 = w[0][4];
15823
 
    const double c0_8_2_5 = w[0][5];
15824
 
    const double c3_9_0_0 = w[3][0];
15825
 
    const double c0_9_1_3 = w[0][3];
15826
 
    const double c0_9_1_4 = w[0][4];
15827
 
    const double c0_9_1_5 = w[0][5];
15828
 
    const double c2_10_0_0 = w[2][0];
15829
 
    const double c0_10_1_3 = w[0][3];
15830
 
    const double c0_10_1_4 = w[0][4];
15831
 
    const double c0_10_1_5 = w[0][5];
15832
 
    
15833
 
    // Compute geometry tensors
15834
 
    // Number of operations to compute decalrations = 358
15835
 
    const double G0_0 = det*c0_0_0_0;
15836
 
    const double G0_1 = det*c0_0_0_1;
15837
 
    const double G0_2 = det*c0_0_0_2;
15838
 
    const double G0_3 = det*c0_0_0_3;
15839
 
    const double G0_4 = det*c0_0_0_4;
15840
 
    const double G0_5 = det*c0_0_0_5;
15841
 
    const double G1_3 = det*c1_1_0_3;
15842
 
    const double G1_4 = det*c1_1_0_4;
15843
 
    const double G1_5 = det*c1_1_0_5;
15844
 
    const double G3_0_0_0_0_0 = det*c4_3_0_0*c5_3_1_0*c1_3_2_0*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
15845
 
    const double G3_0_0_0_0_1 = det*c4_3_0_0*c5_3_1_0*c1_3_2_0*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
15846
 
    const double G3_0_0_0_1_0 = det*c4_3_0_0*c5_3_1_0*c1_3_2_0*(Jinv_10*Jinv_00 + Jinv_11*Jinv_01);
15847
 
    const double G3_0_0_0_1_1 = det*c4_3_0_0*c5_3_1_0*c1_3_2_0*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
15848
 
    const double G3_0_0_1_0_0 = det*c4_3_0_0*c5_3_1_0*c1_3_2_1*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
15849
 
    const double G3_0_0_1_1_0 = det*c4_3_0_0*c5_3_1_0*c1_3_2_1*(Jinv_10*Jinv_00 + Jinv_11*Jinv_01);
15850
 
    const double G3_0_0_2_0_1 = det*c4_3_0_0*c5_3_1_0*c1_3_2_2*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
15851
 
    const double G3_0_0_2_1_1 = det*c4_3_0_0*c5_3_1_0*c1_3_2_2*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
15852
 
    const double G4_0_0_0_0 = det*c4_4_0_0*c1_4_1_0*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
15853
 
    const double G4_0_0_0_1 = det*c4_4_0_0*c1_4_1_0*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
15854
 
    const double G4_0_0_1_0 = det*c4_4_0_0*c1_4_1_0*(Jinv_10*Jinv_00 + Jinv_11*Jinv_01);
15855
 
    const double G4_0_0_1_1 = det*c4_4_0_0*c1_4_1_0*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
15856
 
    const double G4_0_1_0_0 = det*c4_4_0_0*c1_4_1_1*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
15857
 
    const double G4_0_1_1_0 = det*c4_4_0_0*c1_4_1_1*(Jinv_10*Jinv_00 + Jinv_11*Jinv_01);
15858
 
    const double G4_0_2_0_1 = det*c4_4_0_0*c1_4_1_2*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
15859
 
    const double G4_0_2_1_1 = det*c4_4_0_0*c1_4_1_2*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
15860
 
    const double G6_0_0_0_0_0 = det*c4_6_0_0*c5_6_1_0*c0_6_2_0*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
15861
 
    const double G6_0_0_0_0_1 = det*c4_6_0_0*c5_6_1_0*c0_6_2_0*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
15862
 
    const double G6_0_0_0_1_0 = det*c4_6_0_0*c5_6_1_0*c0_6_2_0*(Jinv_10*Jinv_00 + Jinv_11*Jinv_01);
15863
 
    const double G6_0_0_0_1_1 = det*c4_6_0_0*c5_6_1_0*c0_6_2_0*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
15864
 
    const double G6_0_0_1_0_0 = det*c4_6_0_0*c5_6_1_0*c0_6_2_1*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
15865
 
    const double G6_0_0_1_1_0 = det*c4_6_0_0*c5_6_1_0*c0_6_2_1*(Jinv_10*Jinv_00 + Jinv_11*Jinv_01);
15866
 
    const double G6_0_0_2_0_1 = det*c4_6_0_0*c5_6_1_0*c0_6_2_2*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
15867
 
    const double G6_0_0_2_1_1 = det*c4_6_0_0*c5_6_1_0*c0_6_2_2*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
15868
 
    const double G7_0_3_3_3 = det*c3_7_0_0*c0_7_1_3*c0_7_2_3*c0_7_3_3;
15869
 
    const double G7_0_3_3_4 = det*c3_7_0_0*c0_7_1_3*c0_7_2_3*c0_7_3_4;
15870
 
    const double G7_0_3_3_5 = det*c3_7_0_0*c0_7_1_3*c0_7_2_3*c0_7_3_5;
15871
 
    const double G7_0_3_4_3 = det*c3_7_0_0*c0_7_1_3*c0_7_2_4*c0_7_3_3;
15872
 
    const double G7_0_3_4_4 = det*c3_7_0_0*c0_7_1_3*c0_7_2_4*c0_7_3_4;
15873
 
    const double G7_0_3_4_5 = det*c3_7_0_0*c0_7_1_3*c0_7_2_4*c0_7_3_5;
15874
 
    const double G7_0_3_5_3 = det*c3_7_0_0*c0_7_1_3*c0_7_2_5*c0_7_3_3;
15875
 
    const double G7_0_3_5_4 = det*c3_7_0_0*c0_7_1_3*c0_7_2_5*c0_7_3_4;
15876
 
    const double G7_0_3_5_5 = det*c3_7_0_0*c0_7_1_3*c0_7_2_5*c0_7_3_5;
15877
 
    const double G7_0_4_3_3 = det*c3_7_0_0*c0_7_1_4*c0_7_2_3*c0_7_3_3;
15878
 
    const double G7_0_4_3_4 = det*c3_7_0_0*c0_7_1_4*c0_7_2_3*c0_7_3_4;
15879
 
    const double G7_0_4_3_5 = det*c3_7_0_0*c0_7_1_4*c0_7_2_3*c0_7_3_5;
15880
 
    const double G7_0_4_4_3 = det*c3_7_0_0*c0_7_1_4*c0_7_2_4*c0_7_3_3;
15881
 
    const double G7_0_4_4_4 = det*c3_7_0_0*c0_7_1_4*c0_7_2_4*c0_7_3_4;
15882
 
    const double G7_0_4_4_5 = det*c3_7_0_0*c0_7_1_4*c0_7_2_4*c0_7_3_5;
15883
 
    const double G7_0_4_5_3 = det*c3_7_0_0*c0_7_1_4*c0_7_2_5*c0_7_3_3;
15884
 
    const double G7_0_4_5_4 = det*c3_7_0_0*c0_7_1_4*c0_7_2_5*c0_7_3_4;
15885
 
    const double G7_0_4_5_5 = det*c3_7_0_0*c0_7_1_4*c0_7_2_5*c0_7_3_5;
15886
 
    const double G7_0_5_3_3 = det*c3_7_0_0*c0_7_1_5*c0_7_2_3*c0_7_3_3;
15887
 
    const double G7_0_5_3_4 = det*c3_7_0_0*c0_7_1_5*c0_7_2_3*c0_7_3_4;
15888
 
    const double G7_0_5_3_5 = det*c3_7_0_0*c0_7_1_5*c0_7_2_3*c0_7_3_5;
15889
 
    const double G7_0_5_4_3 = det*c3_7_0_0*c0_7_1_5*c0_7_2_4*c0_7_3_3;
15890
 
    const double G7_0_5_4_4 = det*c3_7_0_0*c0_7_1_5*c0_7_2_4*c0_7_3_4;
15891
 
    const double G7_0_5_4_5 = det*c3_7_0_0*c0_7_1_5*c0_7_2_4*c0_7_3_5;
15892
 
    const double G7_0_5_5_3 = det*c3_7_0_0*c0_7_1_5*c0_7_2_5*c0_7_3_3;
15893
 
    const double G7_0_5_5_4 = det*c3_7_0_0*c0_7_1_5*c0_7_2_5*c0_7_3_4;
15894
 
    const double G7_0_5_5_5 = det*c3_7_0_0*c0_7_1_5*c0_7_2_5*c0_7_3_5;
15895
 
    const double G8_0_3_3 = det*c3_8_0_0*c0_8_1_3*c0_8_2_3;
15896
 
    const double G8_0_3_4 = det*c3_8_0_0*c0_8_1_3*c0_8_2_4;
15897
 
    const double G8_0_3_5 = det*c3_8_0_0*c0_8_1_3*c0_8_2_5;
15898
 
    const double G8_0_4_3 = det*c3_8_0_0*c0_8_1_4*c0_8_2_3;
15899
 
    const double G8_0_4_4 = det*c3_8_0_0*c0_8_1_4*c0_8_2_4;
15900
 
    const double G8_0_4_5 = det*c3_8_0_0*c0_8_1_4*c0_8_2_5;
15901
 
    const double G8_0_5_3 = det*c3_8_0_0*c0_8_1_5*c0_8_2_3;
15902
 
    const double G8_0_5_4 = det*c3_8_0_0*c0_8_1_5*c0_8_2_4;
15903
 
    const double G8_0_5_5 = det*c3_8_0_0*c0_8_1_5*c0_8_2_5;
15904
 
    const double G9_0_3 = det*c3_9_0_0*c0_9_1_3;
15905
 
    const double G9_0_4 = det*c3_9_0_0*c0_9_1_4;
15906
 
    const double G9_0_5 = det*c3_9_0_0*c0_9_1_5;
15907
 
    const double G10_0_3_0_0 = det*c2_10_0_0*c0_10_1_3*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
15908
 
    const double G10_0_3_0_1 = det*c2_10_0_0*c0_10_1_3*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
15909
 
    const double G10_0_3_1_0 = det*c2_10_0_0*c0_10_1_3*(Jinv_10*Jinv_00 + Jinv_11*Jinv_01);
15910
 
    const double G10_0_3_1_1 = det*c2_10_0_0*c0_10_1_3*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
15911
 
    const double G10_0_4_0_0 = det*c2_10_0_0*c0_10_1_4*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
15912
 
    const double G10_0_4_1_0 = det*c2_10_0_0*c0_10_1_4*(Jinv_10*Jinv_00 + Jinv_11*Jinv_01);
15913
 
    const double G10_0_5_0_1 = det*c2_10_0_0*c0_10_1_5*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
15914
 
    const double G10_0_5_1_1 = det*c2_10_0_0*c0_10_1_5*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
15915
 
    
15916
 
    // Compute element tensor
15917
 
    // Number of operations to compute tensor = 410
15918
 
    A[0] = 0.0833333333333332*G0_0 + 0.0416666666666666*G0_1 + 0.0416666666666666*G0_2 - 0.133333333333333*G7_0_3_3_3 - 0.0333333333333333*G7_0_3_3_4 - 0.0333333333333333*G7_0_3_3_5 - 0.0333333333333333*G7_0_3_4_3 - 0.0222222222222222*G7_0_3_4_4 - 0.0111111111111111*G7_0_3_4_5 - 0.0333333333333333*G7_0_3_5_3 - 0.0111111111111111*G7_0_3_5_4 - 0.0222222222222222*G7_0_3_5_5 - 0.0333333333333333*G7_0_4_3_3 - 0.0222222222222222*G7_0_4_3_4 - 0.0111111111111111*G7_0_4_3_5 - 0.0222222222222222*G7_0_4_4_3 - 0.0333333333333333*G7_0_4_4_4 - 0.0111111111111111*G7_0_4_4_5 - 0.0111111111111111*G7_0_4_5_3 - 0.0111111111111111*G7_0_4_5_4 - 0.0111111111111111*G7_0_4_5_5 - 0.0333333333333333*G7_0_5_3_3 - 0.0111111111111111*G7_0_5_3_4 - 0.0222222222222222*G7_0_5_3_5 - 0.0111111111111111*G7_0_5_4_3 - 0.0111111111111111*G7_0_5_4_4 - 0.0111111111111111*G7_0_5_4_5 - 0.0222222222222222*G7_0_5_5_3 - 0.0111111111111111*G7_0_5_5_4 - 0.0333333333333333*G7_0_5_5_5 + 0.299999999999999*G8_0_3_3 + 0.0999999999999998*G8_0_3_4 + 0.0999999999999998*G8_0_3_5 + 0.0999999999999998*G8_0_4_3 + 0.0999999999999998*G8_0_4_4 + 0.0499999999999999*G8_0_4_5 + 0.0999999999999998*G8_0_5_3 + 0.0499999999999999*G8_0_5_4 + 0.0999999999999998*G8_0_5_5 - 0.166666666666666*G9_0_3 - 0.0833333333333332*G9_0_4 - 0.0833333333333332*G9_0_5 - 0.5*G10_0_3_0_0 - 0.5*G10_0_3_0_1 - 0.5*G10_0_3_1_0 - 0.5*G10_0_3_1_1 + 0.5*G10_0_4_0_0 + 0.5*G10_0_4_1_0 + 0.5*G10_0_5_0_1 + 0.5*G10_0_5_1_1;
15919
 
    A[1] = 0.0416666666666666*G0_0 + 0.0833333333333332*G0_1 + 0.0416666666666666*G0_2 - 0.0333333333333333*G7_0_3_3_3 - 0.0222222222222222*G7_0_3_3_4 - 0.0111111111111111*G7_0_3_3_5 - 0.0222222222222222*G7_0_3_4_3 - 0.0333333333333333*G7_0_3_4_4 - 0.0111111111111111*G7_0_3_4_5 - 0.0111111111111111*G7_0_3_5_3 - 0.0111111111111111*G7_0_3_5_4 - 0.0111111111111111*G7_0_3_5_5 - 0.0222222222222222*G7_0_4_3_3 - 0.0333333333333333*G7_0_4_3_4 - 0.0111111111111111*G7_0_4_3_5 - 0.0333333333333333*G7_0_4_4_3 - 0.133333333333333*G7_0_4_4_4 - 0.0333333333333333*G7_0_4_4_5 - 0.0111111111111111*G7_0_4_5_3 - 0.0333333333333333*G7_0_4_5_4 - 0.0222222222222222*G7_0_4_5_5 - 0.0111111111111111*G7_0_5_3_3 - 0.0111111111111111*G7_0_5_3_4 - 0.0111111111111111*G7_0_5_3_5 - 0.0111111111111111*G7_0_5_4_3 - 0.0333333333333333*G7_0_5_4_4 - 0.0222222222222222*G7_0_5_4_5 - 0.0111111111111111*G7_0_5_5_3 - 0.0222222222222222*G7_0_5_5_4 - 0.0333333333333333*G7_0_5_5_5 + 0.0999999999999998*G8_0_3_3 + 0.0999999999999998*G8_0_3_4 + 0.0499999999999999*G8_0_3_5 + 0.0999999999999998*G8_0_4_3 + 0.299999999999999*G8_0_4_4 + 0.0999999999999998*G8_0_4_5 + 0.0499999999999999*G8_0_5_3 + 0.0999999999999998*G8_0_5_4 + 0.0999999999999998*G8_0_5_5 - 0.0833333333333332*G9_0_3 - 0.166666666666666*G9_0_4 - 0.0833333333333332*G9_0_5 + 0.5*G10_0_3_0_0 + 0.5*G10_0_3_0_1 - 0.5*G10_0_4_0_0 - 0.5*G10_0_5_0_1;
15920
 
    A[2] = 0.0416666666666666*G0_0 + 0.0416666666666666*G0_1 + 0.0833333333333332*G0_2 - 0.0333333333333333*G7_0_3_3_3 - 0.0111111111111111*G7_0_3_3_4 - 0.0222222222222222*G7_0_3_3_5 - 0.0111111111111111*G7_0_3_4_3 - 0.0111111111111111*G7_0_3_4_4 - 0.0111111111111111*G7_0_3_4_5 - 0.0222222222222222*G7_0_3_5_3 - 0.0111111111111111*G7_0_3_5_4 - 0.0333333333333333*G7_0_3_5_5 - 0.0111111111111111*G7_0_4_3_3 - 0.0111111111111111*G7_0_4_3_4 - 0.0111111111111111*G7_0_4_3_5 - 0.0111111111111111*G7_0_4_4_3 - 0.0333333333333333*G7_0_4_4_4 - 0.0222222222222222*G7_0_4_4_5 - 0.0111111111111111*G7_0_4_5_3 - 0.0222222222222222*G7_0_4_5_4 - 0.0333333333333333*G7_0_4_5_5 - 0.0222222222222222*G7_0_5_3_3 - 0.0111111111111111*G7_0_5_3_4 - 0.0333333333333333*G7_0_5_3_5 - 0.0111111111111111*G7_0_5_4_3 - 0.0222222222222222*G7_0_5_4_4 - 0.0333333333333333*G7_0_5_4_5 - 0.0333333333333333*G7_0_5_5_3 - 0.0333333333333333*G7_0_5_5_4 - 0.133333333333333*G7_0_5_5_5 + 0.0999999999999998*G8_0_3_3 + 0.0499999999999999*G8_0_3_4 + 0.0999999999999998*G8_0_3_5 + 0.0499999999999999*G8_0_4_3 + 0.0999999999999998*G8_0_4_4 + 0.0999999999999998*G8_0_4_5 + 0.0999999999999998*G8_0_5_3 + 0.0999999999999999*G8_0_5_4 + 0.299999999999999*G8_0_5_5 - 0.0833333333333332*G9_0_3 - 0.0833333333333332*G9_0_4 - 0.166666666666666*G9_0_5 + 0.5*G10_0_3_1_0 + 0.5*G10_0_3_1_1 - 0.5*G10_0_4_1_0 - 0.5*G10_0_5_1_1;
15921
 
    A[3] = 0.0833333333333332*G0_3 + 0.0416666666666666*G0_4 + 0.0416666666666666*G0_5 - 0.0833333333333332*G1_3 - 0.0416666666666666*G1_4 - 0.0416666666666666*G1_5 - 0.5*G3_0_0_0_0_0 - 0.5*G3_0_0_0_0_1 - 0.5*G3_0_0_0_1_0 - 0.5*G3_0_0_0_1_1 + 0.5*G3_0_0_1_0_0 + 0.5*G3_0_0_1_1_0 + 0.5*G3_0_0_2_0_1 + 0.5*G3_0_0_2_1_1 + 0.5*G4_0_0_0_0 + 0.5*G4_0_0_0_1 + 0.5*G4_0_0_1_0 + 0.5*G4_0_0_1_1 - 0.5*G4_0_1_0_0 - 0.5*G4_0_1_1_0 - 0.5*G4_0_2_0_1 - 0.5*G4_0_2_1_1 + 0.5*G6_0_0_0_0_0 + 0.5*G6_0_0_0_0_1 + 0.5*G6_0_0_0_1_0 + 0.5*G6_0_0_0_1_1 - 0.5*G6_0_0_1_0_0 - 0.5*G6_0_0_1_1_0 - 0.5*G6_0_0_2_0_1 - 0.5*G6_0_0_2_1_1;
15922
 
    A[4] = 0.0416666666666666*G0_3 + 0.0833333333333332*G0_4 + 0.0416666666666666*G0_5 - 0.0416666666666666*G1_3 - 0.0833333333333332*G1_4 - 0.0416666666666666*G1_5 + 0.5*G3_0_0_0_0_0 + 0.5*G3_0_0_0_0_1 - 0.5*G3_0_0_1_0_0 - 0.5*G3_0_0_2_0_1 - 0.5*G4_0_0_0_0 - 0.5*G4_0_0_0_1 + 0.5*G4_0_1_0_0 + 0.5*G4_0_2_0_1 - 0.5*G6_0_0_0_0_0 - 0.5*G6_0_0_0_0_1 + 0.5*G6_0_0_1_0_0 + 0.5*G6_0_0_2_0_1;
15923
 
    A[5] = 0.0416666666666666*G0_3 + 0.0416666666666666*G0_4 + 0.0833333333333332*G0_5 - 0.0416666666666666*G1_3 - 0.0416666666666666*G1_4 - 0.0833333333333332*G1_5 + 0.5*G3_0_0_0_1_0 + 0.5*G3_0_0_0_1_1 - 0.5*G3_0_0_1_1_0 - 0.5*G3_0_0_2_1_1 - 0.5*G4_0_0_1_0 - 0.5*G4_0_0_1_1 + 0.5*G4_0_1_1_0 + 0.5*G4_0_2_1_1 - 0.5*G6_0_0_0_1_0 - 0.5*G6_0_0_0_1_1 + 0.5*G6_0_0_1_1_0 + 0.5*G6_0_0_2_1_1;
15924
 
}
15925
 
 
15926
 
/// Constructor
15927
 
UFC_CahnHilliard2DLinearForm::UFC_CahnHilliard2DLinearForm() : ufc::form()
15928
 
{
15929
 
    // Do nothing
15930
 
}
15931
 
 
15932
 
/// Destructor
15933
 
UFC_CahnHilliard2DLinearForm::~UFC_CahnHilliard2DLinearForm()
 
16017
    
 
16018
    // Array of quadrature weights
 
16019
    static const double W9[9] = {0.0558144204830443, 0.063678085099885, 0.0193963833059595, 0.0893030727728709, 0.101884936159816, 0.0310342132895351, 0.0558144204830443, 0.063678085099885, 0.0193963833059595};
 
16020
    // Quadrature points on the UFC reference element: (0.102717654809626, 0.088587959512704), (0.0665540678391645, 0.409466864440735), (0.0239311322870806, 0.787659461760847), (0.455706020243648, 0.088587959512704), (0.295266567779633, 0.409466864440735), (0.106170269119576, 0.787659461760847), (0.80869438567767, 0.088587959512704), (0.523979067720101, 0.409466864440735), (0.188409405952072, 0.787659461760847)
 
16021
    
 
16022
    // Value of basis functions at quadrature points.
 
16023
    static const double FE0_C1_D01[9][2] = \
 
16024
    {{-1, 1},
 
16025
    {-1, 1},
 
16026
    {-1, 1},
 
16027
    {-1, 1},
 
16028
    {-1, 1},
 
16029
    {-1, 1},
 
16030
    {-1, 1},
 
16031
    {-1, 1},
 
16032
    {-1, 1}};
 
16033
    
 
16034
    // Array of non-zero columns
 
16035
    static const unsigned int nzc0[2] = {3, 5};
 
16036
    // Array of non-zero columns
 
16037
    static const unsigned int nzc1[2] = {3, 4};
 
16038
    // Array of non-zero columns
 
16039
    static const unsigned int nzc2[2] = {0, 1};
 
16040
    // Array of non-zero columns
 
16041
    static const unsigned int nzc3[2] = {0, 2};
 
16042
    static const double FE0_C1[9][3] = \
 
16043
    {{0.80869438567767, 0.102717654809626, 0.088587959512704},
 
16044
    {0.523979067720101, 0.0665540678391645, 0.409466864440735},
 
16045
    {0.188409405952072, 0.0239311322870807, 0.787659461760847},
 
16046
    {0.455706020243648, 0.455706020243648, 0.088587959512704},
 
16047
    {0.295266567779633, 0.295266567779633, 0.409466864440735},
 
16048
    {0.106170269119576, 0.106170269119577, 0.787659461760847},
 
16049
    {0.102717654809626, 0.80869438567767, 0.088587959512704},
 
16050
    {0.0665540678391645, 0.523979067720101, 0.409466864440735},
 
16051
    {0.0239311322870807, 0.188409405952072, 0.787659461760847}};
 
16052
    
 
16053
    // Array of non-zero columns
 
16054
    static const unsigned int nzc4[3] = {3, 4, 5};
 
16055
    // Array of non-zero columns
 
16056
    static const unsigned int nzc5[3] = {0, 1, 2};
 
16057
    
 
16058
    // Number of operations to compute geometry constants: 68
 
16059
    const double G0 = 6*det*w[3][0];
 
16060
    const double G1 = -4*det*w[3][0];
 
16061
    const double G2 = -2*det*w[3][0];
 
16062
    const double G3 = det*w[4][0]*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01-w[5][0]*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01));
 
16063
    const double G4 = det*w[4][0]*(Jinv_00*Jinv_10*(1-w[5][0]) + Jinv_01*Jinv_11*(1-w[5][0]));
 
16064
    const double G5 = det*w[4][0]*w[5][0]*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
 
16065
    const double G6 = det*w[4][0]*w[5][0]*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
 
16066
    const double G7 = -det*w[2][0]*(Jinv_00*Jinv_00 + Jinv_01*Jinv_01);
 
16067
    const double G8 = -det*w[2][0]*(Jinv_00*Jinv_10 + Jinv_01*Jinv_11);
 
16068
    const double G9 = -det*w[2][0]*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
 
16069
    const double G10 = det*w[4][0]*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11-w[5][0]*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11));
 
16070
    const double G11 = det*w[4][0]*w[5][0]*(Jinv_10*Jinv_10 + Jinv_11*Jinv_11);
 
16071
    
 
16072
    // Compute element tensor using UFL quadrature representation
 
16073
    // Optimisations: ('simplify expressions', True), ('ignore zero tables', True), ('non zero columns', True), ('remove zero terms', True), ('ignore ones', True)
 
16074
    // Total number of operations to compute element tensor: 1013
 
16075
    
 
16076
    // Loop quadrature points for integral
 
16077
    // Number of operations to compute element tensor for following IP loop = 945
 
16078
    for (unsigned int ip = 0; ip < 9; ip++)
 
16079
    {
 
16080
      
 
16081
      // Function declarations
 
16082
      double F0 = 0;
 
16083
      double F1 = 0;
 
16084
      double F2 = 0;
 
16085
      double F3 = 0;
 
16086
      double F4 = 0;
 
16087
      double F5 = 0;
 
16088
      double F6 = 0;
 
16089
      double F7 = 0;
 
16090
      double F8 = 0;
 
16091
      
 
16092
      // Total number of operations to compute function values = 24
 
16093
      for (unsigned int r = 0; r < 2; r++)
 
16094
      {
 
16095
        F0 += FE0_C1_D01[ip][r]*w[0][nzc2[r]];
 
16096
        F1 += FE0_C1_D01[ip][r]*w[0][nzc3[r]];
 
16097
        F2 += FE0_C1_D01[ip][r]*w[1][nzc2[r]];
 
16098
        F3 += FE0_C1_D01[ip][r]*w[1][nzc3[r]];
 
16099
        F6 += FE0_C1_D01[ip][r]*w[0][nzc1[r]];
 
16100
        F7 += FE0_C1_D01[ip][r]*w[0][nzc0[r]];
 
16101
      }// end loop over 'r'
 
16102
      
 
16103
      // Total number of operations to compute function values = 18
 
16104
      for (unsigned int r = 0; r < 3; r++)
 
16105
      {
 
16106
        F4 += FE0_C1[ip][r]*w[0][nzc4[r]];
 
16107
        F5 += FE0_C1[ip][r]*w[1][nzc4[r]];
 
16108
        F8 += FE0_C1[ip][r]*w[0][nzc5[r]];
 
16109
      }// end loop over 'r'
 
16110
      
 
16111
      // Number of operations to compute ip constants: 35
 
16112
      // Number of operations: 8
 
16113
      const double Gip0 = W9[ip]*(F4*(G2 + F4*(G0 + F4*G1)) + F8*det);
 
16114
      
 
16115
      // Number of operations: 8
 
16116
      const double Gip1 = W9[ip]*(F0*G5 + F1*G6 + F2*G3 + F3*G4);
 
16117
      
 
16118
      // Number of operations: 3
 
16119
      const double Gip2 = W9[ip]*det*(F4-F5);
 
16120
      
 
16121
      // Number of operations: 4
 
16122
      const double Gip3 = W9[ip]*(F6*G7 + F7*G8);
 
16123
      
 
16124
      // Number of operations: 4
 
16125
      const double Gip4 = W9[ip]*(F6*G8 + F7*G9);
 
16126
      
 
16127
      // Number of operations: 8
 
16128
      const double Gip5 = W9[ip]*(F0*G6 + F1*G11 + F2*G4 + F3*G10);
 
16129
      
 
16130
      
 
16131
      // Number of operations for primary indices = 12
 
16132
      for (unsigned int j = 0; j < 3; j++)
 
16133
      {
 
16134
        // Number of operations to compute entry = 2
 
16135
        A[nzc4[j]] += FE0_C1[ip][j]*Gip0;
 
16136
        // Number of operations to compute entry = 2
 
16137
        A[nzc5[j]] += FE0_C1[ip][j]*Gip2;
 
16138
      }// end loop over 'j'
 
16139
      
 
16140
      // Number of operations for primary indices = 16
 
16141
      for (unsigned int j = 0; j < 2; j++)
 
16142
      {
 
16143
        // Number of operations to compute entry = 2
 
16144
        A[nzc2[j]] += FE0_C1_D01[ip][j]*Gip1;
 
16145
        // Number of operations to compute entry = 2
 
16146
        A[nzc1[j]] += FE0_C1_D01[ip][j]*Gip3;
 
16147
        // Number of operations to compute entry = 2
 
16148
        A[nzc0[j]] += FE0_C1_D01[ip][j]*Gip4;
 
16149
        // Number of operations to compute entry = 2
 
16150
        A[nzc3[j]] += FE0_C1_D01[ip][j]*Gip5;
 
16151
      }// end loop over 'j'
 
16152
    }// end loop over 'ip'
 
16153
}
 
16154
 
 
16155
/// Constructor
 
16156
cahnhilliard2d_1_cell_integral_0::cahnhilliard2d_1_cell_integral_0() : ufc::cell_integral()
 
16157
{
 
16158
    // Do nothing
 
16159
}
 
16160
 
 
16161
/// Destructor
 
16162
cahnhilliard2d_1_cell_integral_0::~cahnhilliard2d_1_cell_integral_0()
 
16163
{
 
16164
    // Do nothing
 
16165
}
 
16166
 
 
16167
/// Tabulate the tensor for the contribution from a local cell
 
16168
void cahnhilliard2d_1_cell_integral_0::tabulate_tensor(double* A,
 
16169
                                    const double * const * w,
 
16170
                                    const ufc::cell& c) const
 
16171
{
 
16172
    // Reset values of the element tensor block
 
16173
    for (unsigned int j = 0; j < 6; j++)
 
16174
      A[j] = 0;
 
16175
    
 
16176
    // Add all contributions to element tensor
 
16177
    integral_0_quadrature.tabulate_tensor(A, w, c);
 
16178
}
 
16179
 
 
16180
/// Constructor
 
16181
cahnhilliard2d_form_1::cahnhilliard2d_form_1() : ufc::form()
 
16182
{
 
16183
    // Do nothing
 
16184
}
 
16185
 
 
16186
/// Destructor
 
16187
cahnhilliard2d_form_1::~cahnhilliard2d_form_1()
15934
16188
{
15935
16189
    // Do nothing
15936
16190
}
15937
16191
 
15938
16192
/// Return a string identifying the form
15939
 
const char* UFC_CahnHilliard2DLinearForm::signature() const
 
16193
const char* cahnhilliard2d_form_1::signature() const
15940
16194
{
15941
 
    return "w0_a0[0, 1, 2, 3, 4, 5] | vi0[0, 1, 2, 3, 4, 5][b0[0, 1]]*va0[0, 1, 2, 3, 4, 5][b0[0, 1]]*dX(0) + -w1_a0[0, 1, 2, 3, 4, 5] | vi0[0, 1, 2, 3, 4, 5][1]*va0[0, 1, 2, 3, 4, 5][1]*dX(0) + -w4_a0[0]w5_a1[0]w1_a2[0, 1, 2, 3, 4, 5](dXa3[0, 1]/dxb0[0, 1])(dXa4[0, 1]/dxb0[0, 1]) | va0[0]*((d/dXa3[0, 1])vi0[0, 1, 2, 3, 4, 5][1])*((d/dXa4[0, 1])va1[0])*va2[0, 1, 2, 3, 4, 5][0]*dX(0) + -w4_a0[0]w5_a1[0]w1_a2[0, 1, 2, 3, 4, 5](dXa3[0, 1]/dxb0[0, 1])(dXa4[0, 1]/dxb0[0, 1]) | va0[0]*((d/dXa3[0, 1])vi0[0, 1, 2, 3, 4, 5][1])*va1[0]*((d/dXa4[0, 1])va2[0, 1, 2, 3, 4, 5][0])*dX(0) + w4_a0[0]w1_a1[0, 1, 2, 3, 4, 5](dXa2[0, 1]/dxb0[0, 1])(dXa3[0, 1]/dxb0[0, 1]) | va0[0]*((d/dXa2[0, 1])vi0[0, 1, 2, 3, 4, 5][1])*((d/dXa3[0, 1])va1[0, 1, 2, 3, 4, 5][0])*dX(0) + w4_a0[0]w5_a1[0]w0_a2[0, 1, 2, 3, 4, 5](dXa3[0, 1]/dxb0[0, 1])(dXa4[0, 1]/dxb0[0, 1]) | va0[0]*((d/dXa3[0, 1])vi0[0, 1, 2, 3, 4, 5][1])*((d/dXa4[0, 1])va1[0])*va2[0, 1, 2, 3, 4, 5][0]*dX(0) + w4_a0[0]w5_a1[0]w0_a2[0, 1, 2, 3, 4, 5](dXa3[0, 1]/dxb0[0, 1])(dXa4[0, 1]/dxb0[0, 1]) | va0[0]*((d/dXa3[0, 1])vi0[0, 1, 2, 3, 4, 5][1])*va1[0]*((d/dXa4[0, 1])va2[0, 1, 2, 3, 4, 5][0])*dX(0) + -4.0w3_a0[0]w0_a1[0, 1, 2, 3, 4, 5]w0_a2[0, 1, 2, 3, 4, 5]w0_a3[0, 1, 2, 3, 4, 5] | vi0[0, 1, 2, 3, 4, 5][0]*va0[0]*va1[0, 1, 2, 3, 4, 5][1]*va2[0, 1, 2, 3, 4, 5][1]*va3[0, 1, 2, 3, 4, 5][1]*dX(0) + 6.0w3_a0[0]w0_a1[0, 1, 2, 3, 4, 5]w0_a2[0, 1, 2, 3, 4, 5] | vi0[0, 1, 2, 3, 4, 5][0]*va0[0]*va1[0, 1, 2, 3, 4, 5][1]*va2[0, 1, 2, 3, 4, 5][1]*dX(0) + -2.0w3_a0[0]w0_a1[0, 1, 2, 3, 4, 5] | vi0[0, 1, 2, 3, 4, 5][0]*va0[0]*va1[0, 1, 2, 3, 4, 5][1]*dX(0) + -w2_a0[0]w0_a1[0, 1, 2, 3, 4, 5](dXa2[0, 1]/dxb0[0, 1])(dXa3[0, 1]/dxb0[0, 1]) | va0[0]*((d/dXa2[0, 1])vi0[0, 1, 2, 3, 4, 5][0])*((d/dXa3[0, 1])va1[0, 1, 2, 3, 4, 5][1])*dX(0)";
 
16195
    return "Form([Integral(Sum(Sum(Product(Constant(Cell('triangle', 1, Space(2)), 4), IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((FixedIndex(0),), {})), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(1),), {Index(1): 2})), Indexed(ComponentTensor(Sum(Product(Constant(Cell('triangle', 1, Space(2)), 5), Indexed(SpatialDerivative(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((FixedIndex(0),), {}))), Product(Indexed(SpatialDerivative(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 1), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((FixedIndex(0),), {})), Sum(IntValue(1, (), (), {}), Product(IntValue(-1, (), (), {}), Constant(Cell('triangle', 1, Space(2)), 5))))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(1),), {Index(1): 2}))), MultiIndex((Index(1),), {Index(1): 2}))), Sum(Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2}))), Product(IntValue(-1, (), (), {}), Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2})), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))))), Sum(Product(IntValue(-1, (), (), {}), Product(Constant(Cell('triangle', 1, Space(2)), 2), IndexSum(Product(Indexed(ComponentTensor(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((Index(3),), {Index(3): 2})), MultiIndex((FixedIndex(1),), {})), MultiIndex((Index(3),), {Index(3): 2})), MultiIndex((Index(4),), {Index(4): 2})), Indexed(ComponentTensor(Indexed(SpatialDerivative(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((FixedIndex(1),), {})), MultiIndex((Index(5),), {Index(5): 2})), MultiIndex((Index(4),), {Index(4): 2}))), MultiIndex((Index(4),), {Index(4): 2})))), Sum(Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(0),), {FixedIndex(0): 2}))), Product(IntValue(-1, (), (), {}), Product(Indexed(BasisFunction(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(Constant(Cell('triangle', 1, Space(2)), 3), Sum(Product(IntValue(-1, (), (), {}), Product(Product(Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})), Product(IntValue(2, (), (), {}), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))), Sum(IntValue(1, (), (), {}), Product(IntValue(-1, (), (), {}), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))))), Product(Product(Product(IntValue(2, (), (), {}), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2}))), Sum(IntValue(1, (), (), {}), Product(IntValue(-1, (), (), {}), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2}))))), Sum(IntValue(1, (), (), {}), Product(IntValue(-1, (), (), {}), Indexed(Function(MixedElement(*[FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1), FiniteElement('Lagrange', Cell('triangle', 1, Space(2)), 1)], **{'value_shape': (2,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 2})))))))))))), Measure('cell', 0, None))])";
15942
16196
}
15943
16197
 
15944
16198
/// Return the rank of the global tensor (r)
15945
 
unsigned int UFC_CahnHilliard2DLinearForm::rank() const
 
16199
unsigned int cahnhilliard2d_form_1::rank() const
15946
16200
{
15947
16201
    return 1;
15948
16202
}
15949
16203
 
15950
16204
/// Return the number of coefficients (n)
15951
 
unsigned int UFC_CahnHilliard2DLinearForm::num_coefficients() const
 
16205
unsigned int cahnhilliard2d_form_1::num_coefficients() const
15952
16206
{
15953
16207
    return 6;
15954
16208
}
15955
16209
 
15956
16210
/// Return the number of cell integrals
15957
 
unsigned int UFC_CahnHilliard2DLinearForm::num_cell_integrals() const
 
16211
unsigned int cahnhilliard2d_form_1::num_cell_integrals() const
15958
16212
{
15959
16213
    return 1;
15960
16214
}
15961
 
  
 
16215
 
15962
16216
/// Return the number of exterior facet integrals
15963
 
unsigned int UFC_CahnHilliard2DLinearForm::num_exterior_facet_integrals() const
 
16217
unsigned int cahnhilliard2d_form_1::num_exterior_facet_integrals() const
15964
16218
{
15965
16219
    return 0;
15966
16220
}
15967
 
  
 
16221
 
15968
16222
/// Return the number of interior facet integrals
15969
 
unsigned int UFC_CahnHilliard2DLinearForm::num_interior_facet_integrals() const
 
16223
unsigned int cahnhilliard2d_form_1::num_interior_facet_integrals() const
15970
16224
{
15971
16225
    return 0;
15972
16226
}
15973
16227
 
15974
16228
/// Create a new finite element for argument function i
15975
 
ufc::finite_element* UFC_CahnHilliard2DLinearForm::create_finite_element(unsigned int i) const
 
16229
ufc::finite_element* cahnhilliard2d_form_1::create_finite_element(unsigned int i) const
15976
16230
{
15977
16231
    switch ( i )
15978
16232
    {
15979
16233
    case 0:
15980
 
      return new UFC_CahnHilliard2DLinearForm_finite_element_0();
 
16234
      return new cahnhilliard2d_1_finite_element_0();
15981
16235
      break;
15982
16236
    case 1:
15983
 
      return new UFC_CahnHilliard2DLinearForm_finite_element_1();
 
16237
      return new cahnhilliard2d_1_finite_element_1();
15984
16238
      break;
15985
16239
    case 2:
15986
 
      return new UFC_CahnHilliard2DLinearForm_finite_element_2();
 
16240
      return new cahnhilliard2d_1_finite_element_2();
15987
16241
      break;
15988
16242
    case 3:
15989
 
      return new UFC_CahnHilliard2DLinearForm_finite_element_3();
 
16243
      return new cahnhilliard2d_1_finite_element_3();
15990
16244
      break;
15991
16245
    case 4:
15992
 
      return new UFC_CahnHilliard2DLinearForm_finite_element_4();
 
16246
      return new cahnhilliard2d_1_finite_element_4();
15993
16247
      break;
15994
16248
    case 5:
15995
 
      return new UFC_CahnHilliard2DLinearForm_finite_element_5();
 
16249
      return new cahnhilliard2d_1_finite_element_5();
15996
16250
      break;
15997
16251
    case 6:
15998
 
      return new UFC_CahnHilliard2DLinearForm_finite_element_6();
 
16252
      return new cahnhilliard2d_1_finite_element_6();
15999
16253
      break;
16000
16254
    }
16001
16255
    return 0;
16002
16256
}
16003
16257
 
16004
16258
/// Create a new dof map for argument function i
16005
 
ufc::dof_map* UFC_CahnHilliard2DLinearForm::create_dof_map(unsigned int i) const
 
16259
ufc::dof_map* cahnhilliard2d_form_1::create_dof_map(unsigned int i) const
16006
16260
{
16007
16261
    switch ( i )
16008
16262
    {
16009
16263
    case 0:
16010
 
      return new UFC_CahnHilliard2DLinearForm_dof_map_0();
 
16264
      return new cahnhilliard2d_1_dof_map_0();
16011
16265
      break;
16012
16266
    case 1:
16013
 
      return new UFC_CahnHilliard2DLinearForm_dof_map_1();
 
16267
      return new cahnhilliard2d_1_dof_map_1();
16014
16268
      break;
16015
16269
    case 2:
16016
 
      return new UFC_CahnHilliard2DLinearForm_dof_map_2();
 
16270
      return new cahnhilliard2d_1_dof_map_2();
16017
16271
      break;
16018
16272
    case 3:
16019
 
      return new UFC_CahnHilliard2DLinearForm_dof_map_3();
 
16273
      return new cahnhilliard2d_1_dof_map_3();
16020
16274
      break;
16021
16275
    case 4:
16022
 
      return new UFC_CahnHilliard2DLinearForm_dof_map_4();
 
16276
      return new cahnhilliard2d_1_dof_map_4();
16023
16277
      break;
16024
16278
    case 5:
16025
 
      return new UFC_CahnHilliard2DLinearForm_dof_map_5();
 
16279
      return new cahnhilliard2d_1_dof_map_5();
16026
16280
      break;
16027
16281
    case 6:
16028
 
      return new UFC_CahnHilliard2DLinearForm_dof_map_6();
 
16282
      return new cahnhilliard2d_1_dof_map_6();
16029
16283
      break;
16030
16284
    }
16031
16285
    return 0;
16032
16286
}
16033
16287
 
16034
16288
/// Create a new cell integral on sub domain i
16035
 
ufc::cell_integral* UFC_CahnHilliard2DLinearForm::create_cell_integral(unsigned int i) const
 
16289
ufc::cell_integral* cahnhilliard2d_form_1::create_cell_integral(unsigned int i) const
16036
16290
{
16037
 
    return new UFC_CahnHilliard2DLinearForm_cell_integral_0();
 
16291
    return new cahnhilliard2d_1_cell_integral_0();
16038
16292
}
16039
16293
 
16040
16294
/// Create a new exterior facet integral on sub domain i
16041
 
ufc::exterior_facet_integral* UFC_CahnHilliard2DLinearForm::create_exterior_facet_integral(unsigned int i) const
 
16295
ufc::exterior_facet_integral* cahnhilliard2d_form_1::create_exterior_facet_integral(unsigned int i) const
16042
16296
{
16043
16297
    return 0;
16044
16298
}
16045
16299
 
16046
16300
/// Create a new interior facet integral on sub domain i
16047
 
ufc::interior_facet_integral* UFC_CahnHilliard2DLinearForm::create_interior_facet_integral(unsigned int i) const
 
16301
ufc::interior_facet_integral* cahnhilliard2d_form_1::create_interior_facet_integral(unsigned int i) const
16048
16302
{
16049
16303
    return 0;
16050
16304
}