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

« back to all changes in this revision

Viewing changes to demo/pde/dg/advection-diffusion/cpp/Velocity.h

  • 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
// This code conforms with the UFC specification version 1.0
2
 
// and was automatically generated by FFC version 0.6.1.
 
2
// and was automatically generated by FFC version 0.7.0.
3
3
//
4
4
// Warning: This code was generated with the option '-l dolfin'
5
5
// and contains DOLFIN-specific wrappers that depend on DOLFIN.
11
11
#include <stdexcept>
12
12
#include <fstream>
13
13
#include <ufc.h>
14
 
 
15
 
/// This class defines the interface for a finite element.
16
 
 
17
 
class UFC_Velocity_finite_element_0_0: public ufc::finite_element
18
 
{
19
 
public:
20
 
 
21
 
  /// Constructor
22
 
  UFC_Velocity_finite_element_0_0() : ufc::finite_element()
23
 
  {
24
 
    // Do nothing
25
 
  }
26
 
 
27
 
  /// Destructor
28
 
  virtual ~UFC_Velocity_finite_element_0_0()
29
 
  {
30
 
    // Do nothing
31
 
  }
32
 
 
33
 
  /// Return a string identifying the finite element
34
 
  virtual const char* signature() const
35
 
  {
36
 
    return "FiniteElement('Lagrange', 'triangle', 2)";
37
 
  }
38
 
 
39
 
  /// Return the cell shape
40
 
  virtual ufc::shape cell_shape() const
41
 
  {
42
 
    return ufc::triangle;
43
 
  }
44
 
 
45
 
  /// Return the dimension of the finite element function space
46
 
  virtual unsigned int space_dimension() const
47
 
  {
48
 
    return 6;
49
 
  }
50
 
 
51
 
  /// Return the rank of the value space
52
 
  virtual unsigned int value_rank() const
53
 
  {
54
 
    return 0;
55
 
  }
56
 
 
57
 
  /// Return the dimension of the value space for axis i
58
 
  virtual unsigned int value_dimension(unsigned int i) const
59
 
  {
60
 
    return 1;
61
 
  }
62
 
 
63
 
  /// Evaluate basis function i at given point in cell
64
 
  virtual void evaluate_basis(unsigned int i,
65
 
                              double* values,
66
 
                              const double* coordinates,
67
 
                              const ufc::cell& c) const
68
 
  {
69
 
    // Extract vertex coordinates
70
 
    const double * const * element_coordinates = c.coordinates;
71
 
    
72
 
    // Compute Jacobian of affine map from reference cell
73
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
74
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
75
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
76
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
77
 
      
78
 
    // Compute determinant of Jacobian
79
 
    const double detJ = J_00*J_11 - J_01*J_10;
80
 
    
81
 
    // Compute inverse of Jacobian
82
 
    
83
 
    // Get coordinates and map to the reference (UFC) element
84
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
85
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
86
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
87
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
88
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
89
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
90
 
    
91
 
    // Map coordinates to the reference square
92
 
    if (std::abs(y - 1.0) < 1e-14)
93
 
      x = -1.0;
94
 
    else
95
 
      x = 2.0 *x/(1.0 - y) - 1.0;
96
 
    y = 2.0*y - 1.0;
97
 
    
98
 
    // Reset values
99
 
    *values = 0;
100
 
    
101
 
    // Map degree of freedom to element degree of freedom
102
 
    const unsigned int dof = i;
103
 
    
104
 
    // Generate scalings
105
 
    const double scalings_y_0 = 1;
106
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
107
 
    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
108
 
    
109
 
    // Compute psitilde_a
110
 
    const double psitilde_a_0 = 1;
111
 
    const double psitilde_a_1 = x;
112
 
    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
113
 
    
114
 
    // Compute psitilde_bs
115
 
    const double psitilde_bs_0_0 = 1;
116
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
117
 
    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
118
 
    const double psitilde_bs_1_0 = 1;
119
 
    const double psitilde_bs_1_1 = 2.5*y + 1.5;
120
 
    const double psitilde_bs_2_0 = 1;
121
 
    
122
 
    // Compute basisvalues
123
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
124
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
125
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
126
 
    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
127
 
    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
128
 
    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
129
 
    
130
 
    // Table(s) of coefficients
131
 
    const static double coefficients0[6][6] = \
132
 
    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
133
 
    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
134
 
    {0, 0, 0.2, 0, 0, 0.163299316185545},
135
 
    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
136
 
    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
137
 
    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
138
 
    
139
 
    // Extract relevant coefficients
140
 
    const double coeff0_0 = coefficients0[dof][0];
141
 
    const double coeff0_1 = coefficients0[dof][1];
142
 
    const double coeff0_2 = coefficients0[dof][2];
143
 
    const double coeff0_3 = coefficients0[dof][3];
144
 
    const double coeff0_4 = coefficients0[dof][4];
145
 
    const double coeff0_5 = coefficients0[dof][5];
146
 
    
147
 
    // Compute value(s)
148
 
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
149
 
  }
150
 
 
151
 
  /// Evaluate all basis functions at given point in cell
152
 
  virtual void evaluate_basis_all(double* values,
153
 
                                  const double* coordinates,
154
 
                                  const ufc::cell& c) const
155
 
  {
156
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
157
 
  }
158
 
 
159
 
  /// Evaluate order n derivatives of basis function i at given point in cell
160
 
  virtual void evaluate_basis_derivatives(unsigned int i,
161
 
                                          unsigned int n,
162
 
                                          double* values,
163
 
                                          const double* coordinates,
164
 
                                          const ufc::cell& c) const
165
 
  {
166
 
    // Extract vertex coordinates
167
 
    const double * const * element_coordinates = c.coordinates;
168
 
    
169
 
    // Compute Jacobian of affine map from reference cell
170
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
171
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
172
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
173
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
174
 
      
175
 
    // Compute determinant of Jacobian
176
 
    const double detJ = J_00*J_11 - J_01*J_10;
177
 
    
178
 
    // Compute inverse of Jacobian
179
 
    
180
 
    // Get coordinates and map to the reference (UFC) element
181
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
182
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
183
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
184
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
185
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
186
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
187
 
    
188
 
    // Map coordinates to the reference square
189
 
    if (std::abs(y - 1.0) < 1e-14)
190
 
      x = -1.0;
191
 
    else
192
 
      x = 2.0 *x/(1.0 - y) - 1.0;
193
 
    y = 2.0*y - 1.0;
194
 
    
195
 
    // Compute number of derivatives
196
 
    unsigned int num_derivatives = 1;
197
 
    
198
 
    for (unsigned int j = 0; j < n; j++)
199
 
      num_derivatives *= 2;
200
 
    
201
 
    
202
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
203
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
204
 
        
205
 
    for (unsigned int j = 0; j < num_derivatives; j++)
206
 
    {
207
 
      combinations[j] = new unsigned int [n];
208
 
      for (unsigned int k = 0; k < n; k++)
209
 
        combinations[j][k] = 0;
210
 
    }
211
 
        
212
 
    // Generate combinations of derivatives
213
 
    for (unsigned int row = 1; row < num_derivatives; row++)
214
 
    {
215
 
      for (unsigned int num = 0; num < row; num++)
216
 
      {
217
 
        for (unsigned int col = n-1; col+1 > 0; col--)
218
 
        {
219
 
          if (combinations[row][col] + 1 > 1)
220
 
            combinations[row][col] = 0;
221
 
          else
222
 
          {
223
 
            combinations[row][col] += 1;
224
 
            break;
225
 
          }
226
 
        }
227
 
      }
228
 
    }
229
 
    
230
 
    // Compute inverse of Jacobian
231
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
232
 
    
233
 
    // Declare transformation matrix
234
 
    // Declare pointer to two dimensional array and initialise
235
 
    double **transform = new double *[num_derivatives];
236
 
        
237
 
    for (unsigned int j = 0; j < num_derivatives; j++)
238
 
    {
239
 
      transform[j] = new double [num_derivatives];
240
 
      for (unsigned int k = 0; k < num_derivatives; k++)
241
 
        transform[j][k] = 1;
242
 
    }
243
 
    
244
 
    // Construct transformation matrix
245
 
    for (unsigned int row = 0; row < num_derivatives; row++)
246
 
    {
247
 
      for (unsigned int col = 0; col < num_derivatives; col++)
248
 
      {
249
 
        for (unsigned int k = 0; k < n; k++)
250
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
251
 
      }
252
 
    }
253
 
    
254
 
    // Reset values
255
 
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
256
 
      values[j] = 0;
257
 
    
258
 
    // Map degree of freedom to element degree of freedom
259
 
    const unsigned int dof = i;
260
 
    
261
 
    // Generate scalings
262
 
    const double scalings_y_0 = 1;
263
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
264
 
    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
265
 
    
266
 
    // Compute psitilde_a
267
 
    const double psitilde_a_0 = 1;
268
 
    const double psitilde_a_1 = x;
269
 
    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
270
 
    
271
 
    // Compute psitilde_bs
272
 
    const double psitilde_bs_0_0 = 1;
273
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
274
 
    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
275
 
    const double psitilde_bs_1_0 = 1;
276
 
    const double psitilde_bs_1_1 = 2.5*y + 1.5;
277
 
    const double psitilde_bs_2_0 = 1;
278
 
    
279
 
    // Compute basisvalues
280
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
281
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
282
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
283
 
    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
284
 
    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
285
 
    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
286
 
    
287
 
    // Table(s) of coefficients
288
 
    const static double coefficients0[6][6] = \
289
 
    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
290
 
    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
291
 
    {0, 0, 0.2, 0, 0, 0.163299316185545},
292
 
    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
293
 
    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
294
 
    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
295
 
    
296
 
    // Interesting (new) part
297
 
    // Tables of derivatives of the polynomial base (transpose)
298
 
    const static double dmats0[6][6] = \
299
 
    {{0, 0, 0, 0, 0, 0},
300
 
    {4.89897948556635, 0, 0, 0, 0, 0},
301
 
    {0, 0, 0, 0, 0, 0},
302
 
    {0, 9.48683298050514, 0, 0, 0, 0},
303
 
    {4, 0, 7.07106781186548, 0, 0, 0},
304
 
    {0, 0, 0, 0, 0, 0}};
305
 
    
306
 
    const static double dmats1[6][6] = \
307
 
    {{0, 0, 0, 0, 0, 0},
308
 
    {2.44948974278318, 0, 0, 0, 0, 0},
309
 
    {4.24264068711928, 0, 0, 0, 0, 0},
310
 
    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
311
 
    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
312
 
    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
313
 
    
314
 
    // Compute reference derivatives
315
 
    // Declare pointer to array of derivatives on FIAT element
316
 
    double *derivatives = new double [num_derivatives];
317
 
    
318
 
    // Declare coefficients
319
 
    double coeff0_0 = 0;
320
 
    double coeff0_1 = 0;
321
 
    double coeff0_2 = 0;
322
 
    double coeff0_3 = 0;
323
 
    double coeff0_4 = 0;
324
 
    double coeff0_5 = 0;
325
 
    
326
 
    // Declare new coefficients
327
 
    double new_coeff0_0 = 0;
328
 
    double new_coeff0_1 = 0;
329
 
    double new_coeff0_2 = 0;
330
 
    double new_coeff0_3 = 0;
331
 
    double new_coeff0_4 = 0;
332
 
    double new_coeff0_5 = 0;
333
 
    
334
 
    // Loop possible derivatives
335
 
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
336
 
    {
337
 
      // Get values from coefficients array
338
 
      new_coeff0_0 = coefficients0[dof][0];
339
 
      new_coeff0_1 = coefficients0[dof][1];
340
 
      new_coeff0_2 = coefficients0[dof][2];
341
 
      new_coeff0_3 = coefficients0[dof][3];
342
 
      new_coeff0_4 = coefficients0[dof][4];
343
 
      new_coeff0_5 = coefficients0[dof][5];
344
 
    
345
 
      // Loop derivative order
346
 
      for (unsigned int j = 0; j < n; j++)
347
 
      {
348
 
        // Update old coefficients
349
 
        coeff0_0 = new_coeff0_0;
350
 
        coeff0_1 = new_coeff0_1;
351
 
        coeff0_2 = new_coeff0_2;
352
 
        coeff0_3 = new_coeff0_3;
353
 
        coeff0_4 = new_coeff0_4;
354
 
        coeff0_5 = new_coeff0_5;
355
 
    
356
 
        if(combinations[deriv_num][j] == 0)
357
 
        {
358
 
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
359
 
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
360
 
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
361
 
          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
362
 
          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
363
 
          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
364
 
        }
365
 
        if(combinations[deriv_num][j] == 1)
366
 
        {
367
 
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
368
 
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
369
 
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
370
 
          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
371
 
          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
372
 
          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
373
 
        }
374
 
    
375
 
      }
376
 
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
377
 
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
378
 
    }
379
 
    
380
 
    // Transform derivatives back to physical element
381
 
    for (unsigned int row = 0; row < num_derivatives; row++)
382
 
    {
383
 
      for (unsigned int col = 0; col < num_derivatives; col++)
384
 
      {
385
 
        values[row] += transform[row][col]*derivatives[col];
386
 
      }
387
 
    }
388
 
    // Delete pointer to array of derivatives on FIAT element
389
 
    delete [] derivatives;
390
 
    
391
 
    // Delete pointer to array of combinations of derivatives and transform
392
 
    for (unsigned int row = 0; row < num_derivatives; row++)
393
 
    {
394
 
      delete [] combinations[row];
395
 
      delete [] transform[row];
396
 
    }
397
 
    
398
 
    delete [] combinations;
399
 
    delete [] transform;
400
 
  }
401
 
 
402
 
  /// Evaluate order n derivatives of all basis functions at given point in cell
403
 
  virtual void evaluate_basis_derivatives_all(unsigned int n,
404
 
                                              double* values,
405
 
                                              const double* coordinates,
406
 
                                              const ufc::cell& c) const
407
 
  {
408
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
409
 
  }
410
 
 
411
 
  /// Evaluate linear functional for dof i on the function f
412
 
  virtual double evaluate_dof(unsigned int i,
413
 
                              const ufc::function& f,
414
 
                              const ufc::cell& c) const
415
 
  {
416
 
    // The reference points, direction and weights:
417
 
    const static double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
418
 
    const static double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
419
 
    const static double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
420
 
    
421
 
    const double * const * x = c.coordinates;
422
 
    double result = 0.0;
423
 
    // Iterate over the points:
424
 
    // Evaluate basis functions for affine mapping
425
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
426
 
    const double w1 = X[i][0][0];
427
 
    const double w2 = X[i][0][1];
428
 
    
429
 
    // Compute affine mapping y = F(X)
430
 
    double y[2];
431
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
432
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
433
 
    
434
 
    // Evaluate function at physical points
435
 
    double values[1];
436
 
    f.evaluate(values, y, c);
437
 
    
438
 
    // Map function values using appropriate mapping
439
 
    // Affine map: Do nothing
440
 
    
441
 
    // Note that we do not map the weights (yet).
442
 
    
443
 
    // Take directional components
444
 
    for(int k = 0; k < 1; k++)
445
 
      result += values[k]*D[i][0][k];
446
 
    // Multiply by weights 
447
 
    result *= W[i][0];
448
 
    
449
 
    return result;
450
 
  }
451
 
 
452
 
  /// Evaluate linear functionals for all dofs on the function f
453
 
  virtual void evaluate_dofs(double* values,
454
 
                             const ufc::function& f,
455
 
                             const ufc::cell& c) const
456
 
  {
457
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
458
 
  }
459
 
 
460
 
  /// Interpolate vertex values from dof values
461
 
  virtual void interpolate_vertex_values(double* vertex_values,
462
 
                                         const double* dof_values,
463
 
                                         const ufc::cell& c) const
464
 
  {
465
 
    // Evaluate at vertices and use affine mapping
466
 
    vertex_values[0] = dof_values[0];
467
 
    vertex_values[1] = dof_values[1];
468
 
    vertex_values[2] = dof_values[2];
469
 
  }
470
 
 
471
 
  /// Return the number of sub elements (for a mixed element)
472
 
  virtual unsigned int num_sub_elements() const
473
 
  {
474
 
    return 1;
475
 
  }
476
 
 
477
 
  /// Create a new finite element for sub element i (for a mixed element)
478
 
  virtual ufc::finite_element* create_sub_element(unsigned int i) const
479
 
  {
480
 
    return new UFC_Velocity_finite_element_0_0();
481
 
  }
482
 
 
483
 
};
484
 
 
485
 
/// This class defines the interface for a finite element.
486
 
 
487
 
class UFC_Velocity_finite_element_0_1: public ufc::finite_element
488
 
{
489
 
public:
490
 
 
491
 
  /// Constructor
492
 
  UFC_Velocity_finite_element_0_1() : ufc::finite_element()
493
 
  {
494
 
    // Do nothing
495
 
  }
496
 
 
497
 
  /// Destructor
498
 
  virtual ~UFC_Velocity_finite_element_0_1()
499
 
  {
500
 
    // Do nothing
501
 
  }
502
 
 
503
 
  /// Return a string identifying the finite element
504
 
  virtual const char* signature() const
505
 
  {
506
 
    return "FiniteElement('Lagrange', 'triangle', 2)";
507
 
  }
508
 
 
509
 
  /// Return the cell shape
510
 
  virtual ufc::shape cell_shape() const
511
 
  {
512
 
    return ufc::triangle;
513
 
  }
514
 
 
515
 
  /// Return the dimension of the finite element function space
516
 
  virtual unsigned int space_dimension() const
517
 
  {
518
 
    return 6;
519
 
  }
520
 
 
521
 
  /// Return the rank of the value space
522
 
  virtual unsigned int value_rank() const
523
 
  {
524
 
    return 0;
525
 
  }
526
 
 
527
 
  /// Return the dimension of the value space for axis i
528
 
  virtual unsigned int value_dimension(unsigned int i) const
529
 
  {
530
 
    return 1;
531
 
  }
532
 
 
533
 
  /// Evaluate basis function i at given point in cell
534
 
  virtual void evaluate_basis(unsigned int i,
535
 
                              double* values,
536
 
                              const double* coordinates,
537
 
                              const ufc::cell& c) const
538
 
  {
539
 
    // Extract vertex coordinates
540
 
    const double * const * element_coordinates = c.coordinates;
541
 
    
542
 
    // Compute Jacobian of affine map from reference cell
543
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
544
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
545
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
546
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
547
 
      
548
 
    // Compute determinant of Jacobian
549
 
    const double detJ = J_00*J_11 - J_01*J_10;
550
 
    
551
 
    // Compute inverse of Jacobian
552
 
    
553
 
    // Get coordinates and map to the reference (UFC) element
554
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
555
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
556
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
557
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
558
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
559
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
560
 
    
561
 
    // Map coordinates to the reference square
562
 
    if (std::abs(y - 1.0) < 1e-14)
563
 
      x = -1.0;
564
 
    else
565
 
      x = 2.0 *x/(1.0 - y) - 1.0;
566
 
    y = 2.0*y - 1.0;
567
 
    
568
 
    // Reset values
569
 
    *values = 0;
570
 
    
571
 
    // Map degree of freedom to element degree of freedom
572
 
    const unsigned int dof = i;
573
 
    
574
 
    // Generate scalings
575
 
    const double scalings_y_0 = 1;
576
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
577
 
    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
578
 
    
579
 
    // Compute psitilde_a
580
 
    const double psitilde_a_0 = 1;
581
 
    const double psitilde_a_1 = x;
582
 
    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
583
 
    
584
 
    // Compute psitilde_bs
585
 
    const double psitilde_bs_0_0 = 1;
586
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
587
 
    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
588
 
    const double psitilde_bs_1_0 = 1;
589
 
    const double psitilde_bs_1_1 = 2.5*y + 1.5;
590
 
    const double psitilde_bs_2_0 = 1;
591
 
    
592
 
    // Compute basisvalues
593
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
594
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
595
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
596
 
    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
597
 
    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
598
 
    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
599
 
    
600
 
    // Table(s) of coefficients
601
 
    const static double coefficients0[6][6] = \
602
 
    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
603
 
    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
604
 
    {0, 0, 0.2, 0, 0, 0.163299316185545},
605
 
    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
606
 
    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
607
 
    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
608
 
    
609
 
    // Extract relevant coefficients
610
 
    const double coeff0_0 = coefficients0[dof][0];
611
 
    const double coeff0_1 = coefficients0[dof][1];
612
 
    const double coeff0_2 = coefficients0[dof][2];
613
 
    const double coeff0_3 = coefficients0[dof][3];
614
 
    const double coeff0_4 = coefficients0[dof][4];
615
 
    const double coeff0_5 = coefficients0[dof][5];
616
 
    
617
 
    // Compute value(s)
618
 
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
619
 
  }
620
 
 
621
 
  /// Evaluate all basis functions at given point in cell
622
 
  virtual void evaluate_basis_all(double* values,
623
 
                                  const double* coordinates,
624
 
                                  const ufc::cell& c) const
625
 
  {
626
 
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
627
 
  }
628
 
 
629
 
  /// Evaluate order n derivatives of basis function i at given point in cell
630
 
  virtual void evaluate_basis_derivatives(unsigned int i,
631
 
                                          unsigned int n,
632
 
                                          double* values,
633
 
                                          const double* coordinates,
634
 
                                          const ufc::cell& c) const
635
 
  {
636
 
    // Extract vertex coordinates
637
 
    const double * const * element_coordinates = c.coordinates;
638
 
    
639
 
    // Compute Jacobian of affine map from reference cell
640
 
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
641
 
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
642
 
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
643
 
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
644
 
      
645
 
    // Compute determinant of Jacobian
646
 
    const double detJ = J_00*J_11 - J_01*J_10;
647
 
    
648
 
    // Compute inverse of Jacobian
649
 
    
650
 
    // Get coordinates and map to the reference (UFC) element
651
 
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
652
 
                element_coordinates[0][0]*element_coordinates[2][1] +\
653
 
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
654
 
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
655
 
                element_coordinates[1][0]*element_coordinates[0][1] -\
656
 
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
657
 
    
658
 
    // Map coordinates to the reference square
659
 
    if (std::abs(y - 1.0) < 1e-14)
660
 
      x = -1.0;
661
 
    else
662
 
      x = 2.0 *x/(1.0 - y) - 1.0;
663
 
    y = 2.0*y - 1.0;
664
 
    
665
 
    // Compute number of derivatives
666
 
    unsigned int num_derivatives = 1;
667
 
    
668
 
    for (unsigned int j = 0; j < n; j++)
669
 
      num_derivatives *= 2;
670
 
    
671
 
    
672
 
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
673
 
    unsigned int **combinations = new unsigned int *[num_derivatives];
674
 
        
675
 
    for (unsigned int j = 0; j < num_derivatives; j++)
676
 
    {
677
 
      combinations[j] = new unsigned int [n];
678
 
      for (unsigned int k = 0; k < n; k++)
679
 
        combinations[j][k] = 0;
680
 
    }
681
 
        
682
 
    // Generate combinations of derivatives
683
 
    for (unsigned int row = 1; row < num_derivatives; row++)
684
 
    {
685
 
      for (unsigned int num = 0; num < row; num++)
686
 
      {
687
 
        for (unsigned int col = n-1; col+1 > 0; col--)
688
 
        {
689
 
          if (combinations[row][col] + 1 > 1)
690
 
            combinations[row][col] = 0;
691
 
          else
692
 
          {
693
 
            combinations[row][col] += 1;
694
 
            break;
695
 
          }
696
 
        }
697
 
      }
698
 
    }
699
 
    
700
 
    // Compute inverse of Jacobian
701
 
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
702
 
    
703
 
    // Declare transformation matrix
704
 
    // Declare pointer to two dimensional array and initialise
705
 
    double **transform = new double *[num_derivatives];
706
 
        
707
 
    for (unsigned int j = 0; j < num_derivatives; j++)
708
 
    {
709
 
      transform[j] = new double [num_derivatives];
710
 
      for (unsigned int k = 0; k < num_derivatives; k++)
711
 
        transform[j][k] = 1;
712
 
    }
713
 
    
714
 
    // Construct transformation matrix
715
 
    for (unsigned int row = 0; row < num_derivatives; row++)
716
 
    {
717
 
      for (unsigned int col = 0; col < num_derivatives; col++)
718
 
      {
719
 
        for (unsigned int k = 0; k < n; k++)
720
 
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
721
 
      }
722
 
    }
723
 
    
724
 
    // Reset values
725
 
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
726
 
      values[j] = 0;
727
 
    
728
 
    // Map degree of freedom to element degree of freedom
729
 
    const unsigned int dof = i;
730
 
    
731
 
    // Generate scalings
732
 
    const double scalings_y_0 = 1;
733
 
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
734
 
    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
735
 
    
736
 
    // Compute psitilde_a
737
 
    const double psitilde_a_0 = 1;
738
 
    const double psitilde_a_1 = x;
739
 
    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
740
 
    
741
 
    // Compute psitilde_bs
742
 
    const double psitilde_bs_0_0 = 1;
743
 
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
744
 
    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
745
 
    const double psitilde_bs_1_0 = 1;
746
 
    const double psitilde_bs_1_1 = 2.5*y + 1.5;
747
 
    const double psitilde_bs_2_0 = 1;
748
 
    
749
 
    // Compute basisvalues
750
 
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
751
 
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
752
 
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
753
 
    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
754
 
    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
755
 
    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
756
 
    
757
 
    // Table(s) of coefficients
758
 
    const static double coefficients0[6][6] = \
759
 
    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
760
 
    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
761
 
    {0, 0, 0.2, 0, 0, 0.163299316185545},
762
 
    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
763
 
    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
764
 
    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
765
 
    
766
 
    // Interesting (new) part
767
 
    // Tables of derivatives of the polynomial base (transpose)
768
 
    const static double dmats0[6][6] = \
769
 
    {{0, 0, 0, 0, 0, 0},
770
 
    {4.89897948556635, 0, 0, 0, 0, 0},
771
 
    {0, 0, 0, 0, 0, 0},
772
 
    {0, 9.48683298050514, 0, 0, 0, 0},
773
 
    {4, 0, 7.07106781186548, 0, 0, 0},
774
 
    {0, 0, 0, 0, 0, 0}};
775
 
    
776
 
    const static double dmats1[6][6] = \
777
 
    {{0, 0, 0, 0, 0, 0},
778
 
    {2.44948974278318, 0, 0, 0, 0, 0},
779
 
    {4.24264068711928, 0, 0, 0, 0, 0},
780
 
    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
781
 
    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
782
 
    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
783
 
    
784
 
    // Compute reference derivatives
785
 
    // Declare pointer to array of derivatives on FIAT element
786
 
    double *derivatives = new double [num_derivatives];
787
 
    
788
 
    // Declare coefficients
789
 
    double coeff0_0 = 0;
790
 
    double coeff0_1 = 0;
791
 
    double coeff0_2 = 0;
792
 
    double coeff0_3 = 0;
793
 
    double coeff0_4 = 0;
794
 
    double coeff0_5 = 0;
795
 
    
796
 
    // Declare new coefficients
797
 
    double new_coeff0_0 = 0;
798
 
    double new_coeff0_1 = 0;
799
 
    double new_coeff0_2 = 0;
800
 
    double new_coeff0_3 = 0;
801
 
    double new_coeff0_4 = 0;
802
 
    double new_coeff0_5 = 0;
803
 
    
804
 
    // Loop possible derivatives
805
 
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
806
 
    {
807
 
      // Get values from coefficients array
808
 
      new_coeff0_0 = coefficients0[dof][0];
809
 
      new_coeff0_1 = coefficients0[dof][1];
810
 
      new_coeff0_2 = coefficients0[dof][2];
811
 
      new_coeff0_3 = coefficients0[dof][3];
812
 
      new_coeff0_4 = coefficients0[dof][4];
813
 
      new_coeff0_5 = coefficients0[dof][5];
814
 
    
815
 
      // Loop derivative order
816
 
      for (unsigned int j = 0; j < n; j++)
817
 
      {
818
 
        // Update old coefficients
819
 
        coeff0_0 = new_coeff0_0;
820
 
        coeff0_1 = new_coeff0_1;
821
 
        coeff0_2 = new_coeff0_2;
822
 
        coeff0_3 = new_coeff0_3;
823
 
        coeff0_4 = new_coeff0_4;
824
 
        coeff0_5 = new_coeff0_5;
825
 
    
826
 
        if(combinations[deriv_num][j] == 0)
827
 
        {
828
 
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
829
 
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
830
 
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
831
 
          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
832
 
          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
833
 
          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
834
 
        }
835
 
        if(combinations[deriv_num][j] == 1)
836
 
        {
837
 
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
838
 
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
839
 
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
840
 
          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
841
 
          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
842
 
          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
843
 
        }
844
 
    
845
 
      }
846
 
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
847
 
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
848
 
    }
849
 
    
850
 
    // Transform derivatives back to physical element
851
 
    for (unsigned int row = 0; row < num_derivatives; row++)
852
 
    {
853
 
      for (unsigned int col = 0; col < num_derivatives; col++)
854
 
      {
855
 
        values[row] += transform[row][col]*derivatives[col];
856
 
      }
857
 
    }
858
 
    // Delete pointer to array of derivatives on FIAT element
859
 
    delete [] derivatives;
860
 
    
861
 
    // Delete pointer to array of combinations of derivatives and transform
862
 
    for (unsigned int row = 0; row < num_derivatives; row++)
863
 
    {
864
 
      delete [] combinations[row];
865
 
      delete [] transform[row];
866
 
    }
867
 
    
868
 
    delete [] combinations;
869
 
    delete [] transform;
870
 
  }
871
 
 
872
 
  /// Evaluate order n derivatives of all basis functions at given point in cell
873
 
  virtual void evaluate_basis_derivatives_all(unsigned int n,
874
 
                                              double* values,
875
 
                                              const double* coordinates,
876
 
                                              const ufc::cell& c) const
877
 
  {
878
 
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
879
 
  }
880
 
 
881
 
  /// Evaluate linear functional for dof i on the function f
882
 
  virtual double evaluate_dof(unsigned int i,
883
 
                              const ufc::function& f,
884
 
                              const ufc::cell& c) const
885
 
  {
886
 
    // The reference points, direction and weights:
887
 
    const static double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
888
 
    const static double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
889
 
    const static double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
890
 
    
891
 
    const double * const * x = c.coordinates;
892
 
    double result = 0.0;
893
 
    // Iterate over the points:
894
 
    // Evaluate basis functions for affine mapping
895
 
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
896
 
    const double w1 = X[i][0][0];
897
 
    const double w2 = X[i][0][1];
898
 
    
899
 
    // Compute affine mapping y = F(X)
900
 
    double y[2];
901
 
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
902
 
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
903
 
    
904
 
    // Evaluate function at physical points
905
 
    double values[1];
906
 
    f.evaluate(values, y, c);
907
 
    
908
 
    // Map function values using appropriate mapping
909
 
    // Affine map: Do nothing
910
 
    
911
 
    // Note that we do not map the weights (yet).
912
 
    
913
 
    // Take directional components
914
 
    for(int k = 0; k < 1; k++)
915
 
      result += values[k]*D[i][0][k];
916
 
    // Multiply by weights 
917
 
    result *= W[i][0];
918
 
    
919
 
    return result;
920
 
  }
921
 
 
922
 
  /// Evaluate linear functionals for all dofs on the function f
923
 
  virtual void evaluate_dofs(double* values,
924
 
                             const ufc::function& f,
925
 
                             const ufc::cell& c) const
926
 
  {
927
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
928
 
  }
929
 
 
930
 
  /// Interpolate vertex values from dof values
931
 
  virtual void interpolate_vertex_values(double* vertex_values,
932
 
                                         const double* dof_values,
933
 
                                         const ufc::cell& c) const
934
 
  {
935
 
    // Evaluate at vertices and use affine mapping
936
 
    vertex_values[0] = dof_values[0];
937
 
    vertex_values[1] = dof_values[1];
938
 
    vertex_values[2] = dof_values[2];
939
 
  }
940
 
 
941
 
  /// Return the number of sub elements (for a mixed element)
942
 
  virtual unsigned int num_sub_elements() const
943
 
  {
944
 
    return 1;
945
 
  }
946
 
 
947
 
  /// Create a new finite element for sub element i (for a mixed element)
948
 
  virtual ufc::finite_element* create_sub_element(unsigned int i) const
949
 
  {
950
 
    return new UFC_Velocity_finite_element_0_1();
951
 
  }
952
 
 
953
 
};
954
 
 
955
 
/// This class defines the interface for a finite element.
956
 
 
957
 
class UFC_Velocity_finite_element_0: public ufc::finite_element
958
 
{
959
 
public:
960
 
 
961
 
  /// Constructor
962
 
  UFC_Velocity_finite_element_0() : ufc::finite_element()
963
 
  {
964
 
    // Do nothing
965
 
  }
966
 
 
967
 
  /// Destructor
968
 
  virtual ~UFC_Velocity_finite_element_0()
 
14
    
 
15
/// This class defines the interface for a finite element.
 
16
 
 
17
class velocity_0_finite_element_0_0: public ufc::finite_element
 
18
{
 
19
public:
 
20
 
 
21
  /// Constructor
 
22
  velocity_0_finite_element_0_0() : ufc::finite_element()
 
23
  {
 
24
    // Do nothing
 
25
  }
 
26
 
 
27
  /// Destructor
 
28
  virtual ~velocity_0_finite_element_0_0()
 
29
  {
 
30
    // Do nothing
 
31
  }
 
32
 
 
33
  /// Return a string identifying the finite element
 
34
  virtual const char* signature() const
 
35
  {
 
36
    return "FiniteElement('Lagrange', 'triangle', 2)";
 
37
  }
 
38
 
 
39
  /// Return the cell shape
 
40
  virtual ufc::shape cell_shape() const
 
41
  {
 
42
    return ufc::triangle;
 
43
  }
 
44
 
 
45
  /// Return the dimension of the finite element function space
 
46
  virtual unsigned int space_dimension() const
 
47
  {
 
48
    return 6;
 
49
  }
 
50
 
 
51
  /// Return the rank of the value space
 
52
  virtual unsigned int value_rank() const
 
53
  {
 
54
    return 0;
 
55
  }
 
56
 
 
57
  /// Return the dimension of the value space for axis i
 
58
  virtual unsigned int value_dimension(unsigned int i) const
 
59
  {
 
60
    return 1;
 
61
  }
 
62
 
 
63
  /// Evaluate basis function i at given point in cell
 
64
  virtual void evaluate_basis(unsigned int i,
 
65
                              double* values,
 
66
                              const double* coordinates,
 
67
                              const ufc::cell& c) const
 
68
  {
 
69
    // Extract vertex coordinates
 
70
    const double * const * element_coordinates = c.coordinates;
 
71
    
 
72
    // Compute Jacobian of affine map from reference cell
 
73
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
74
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
75
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
76
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
77
    
 
78
    // Compute determinant of Jacobian
 
79
    const double detJ = J_00*J_11 - J_01*J_10;
 
80
    
 
81
    // Compute inverse of Jacobian
 
82
    
 
83
    // Get coordinates and map to the reference (UFC) element
 
84
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
85
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
86
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
87
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
88
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
89
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
90
    
 
91
    // Map coordinates to the reference square
 
92
    if (std::abs(y - 1.0) < 1e-14)
 
93
      x = -1.0;
 
94
    else
 
95
      x = 2.0 *x/(1.0 - y) - 1.0;
 
96
    y = 2.0*y - 1.0;
 
97
    
 
98
    // Reset values
 
99
    *values = 0;
 
100
    
 
101
    // Map degree of freedom to element degree of freedom
 
102
    const unsigned int dof = i;
 
103
    
 
104
    // Generate scalings
 
105
    const double scalings_y_0 = 1;
 
106
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
107
    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
 
108
    
 
109
    // Compute psitilde_a
 
110
    const double psitilde_a_0 = 1;
 
111
    const double psitilde_a_1 = x;
 
112
    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
 
113
    
 
114
    // Compute psitilde_bs
 
115
    const double psitilde_bs_0_0 = 1;
 
116
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
117
    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
 
118
    const double psitilde_bs_1_0 = 1;
 
119
    const double psitilde_bs_1_1 = 2.5*y + 1.5;
 
120
    const double psitilde_bs_2_0 = 1;
 
121
    
 
122
    // Compute basisvalues
 
123
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
124
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
125
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
126
    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
 
127
    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
 
128
    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
 
129
    
 
130
    // Table(s) of coefficients
 
131
    static const double coefficients0[6][6] = \
 
132
    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
 
133
    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
 
134
    {0, 0, 0.2, 0, 0, 0.163299316185545},
 
135
    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
 
136
    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
 
137
    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
 
138
    
 
139
    // Extract relevant coefficients
 
140
    const double coeff0_0 = coefficients0[dof][0];
 
141
    const double coeff0_1 = coefficients0[dof][1];
 
142
    const double coeff0_2 = coefficients0[dof][2];
 
143
    const double coeff0_3 = coefficients0[dof][3];
 
144
    const double coeff0_4 = coefficients0[dof][4];
 
145
    const double coeff0_5 = coefficients0[dof][5];
 
146
    
 
147
    // Compute value(s)
 
148
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
 
149
  }
 
150
 
 
151
  /// Evaluate all basis functions at given point in cell
 
152
  virtual void evaluate_basis_all(double* values,
 
153
                                  const double* coordinates,
 
154
                                  const ufc::cell& c) const
 
155
  {
 
156
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
157
  }
 
158
 
 
159
  /// Evaluate order n derivatives of basis function i at given point in cell
 
160
  virtual void evaluate_basis_derivatives(unsigned int i,
 
161
                                          unsigned int n,
 
162
                                          double* values,
 
163
                                          const double* coordinates,
 
164
                                          const ufc::cell& c) const
 
165
  {
 
166
    // Extract vertex coordinates
 
167
    const double * const * element_coordinates = c.coordinates;
 
168
    
 
169
    // Compute Jacobian of affine map from reference cell
 
170
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
171
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
172
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
173
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
174
    
 
175
    // Compute determinant of Jacobian
 
176
    const double detJ = J_00*J_11 - J_01*J_10;
 
177
    
 
178
    // Compute inverse of Jacobian
 
179
    
 
180
    // Get coordinates and map to the reference (UFC) element
 
181
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
182
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
183
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
184
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
185
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
186
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
187
    
 
188
    // Map coordinates to the reference square
 
189
    if (std::abs(y - 1.0) < 1e-14)
 
190
      x = -1.0;
 
191
    else
 
192
      x = 2.0 *x/(1.0 - y) - 1.0;
 
193
    y = 2.0*y - 1.0;
 
194
    
 
195
    // Compute number of derivatives
 
196
    unsigned int num_derivatives = 1;
 
197
    
 
198
    for (unsigned int j = 0; j < n; j++)
 
199
      num_derivatives *= 2;
 
200
    
 
201
    
 
202
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
203
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
204
    
 
205
    for (unsigned int j = 0; j < num_derivatives; j++)
 
206
    {
 
207
      combinations[j] = new unsigned int [n];
 
208
      for (unsigned int k = 0; k < n; k++)
 
209
        combinations[j][k] = 0;
 
210
    }
 
211
    
 
212
    // Generate combinations of derivatives
 
213
    for (unsigned int row = 1; row < num_derivatives; row++)
 
214
    {
 
215
      for (unsigned int num = 0; num < row; num++)
 
216
      {
 
217
        for (unsigned int col = n-1; col+1 > 0; col--)
 
218
        {
 
219
          if (combinations[row][col] + 1 > 1)
 
220
            combinations[row][col] = 0;
 
221
          else
 
222
          {
 
223
            combinations[row][col] += 1;
 
224
            break;
 
225
          }
 
226
        }
 
227
      }
 
228
    }
 
229
    
 
230
    // Compute inverse of Jacobian
 
231
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
232
    
 
233
    // Declare transformation matrix
 
234
    // Declare pointer to two dimensional array and initialise
 
235
    double **transform = new double *[num_derivatives];
 
236
    
 
237
    for (unsigned int j = 0; j < num_derivatives; j++)
 
238
    {
 
239
      transform[j] = new double [num_derivatives];
 
240
      for (unsigned int k = 0; k < num_derivatives; k++)
 
241
        transform[j][k] = 1;
 
242
    }
 
243
    
 
244
    // Construct transformation matrix
 
245
    for (unsigned int row = 0; row < num_derivatives; row++)
 
246
    {
 
247
      for (unsigned int col = 0; col < num_derivatives; col++)
 
248
      {
 
249
        for (unsigned int k = 0; k < n; k++)
 
250
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
251
      }
 
252
    }
 
253
    
 
254
    // Reset values
 
255
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
 
256
      values[j] = 0;
 
257
    
 
258
    // Map degree of freedom to element degree of freedom
 
259
    const unsigned int dof = i;
 
260
    
 
261
    // Generate scalings
 
262
    const double scalings_y_0 = 1;
 
263
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
264
    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
 
265
    
 
266
    // Compute psitilde_a
 
267
    const double psitilde_a_0 = 1;
 
268
    const double psitilde_a_1 = x;
 
269
    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
 
270
    
 
271
    // Compute psitilde_bs
 
272
    const double psitilde_bs_0_0 = 1;
 
273
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
274
    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
 
275
    const double psitilde_bs_1_0 = 1;
 
276
    const double psitilde_bs_1_1 = 2.5*y + 1.5;
 
277
    const double psitilde_bs_2_0 = 1;
 
278
    
 
279
    // Compute basisvalues
 
280
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
281
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
282
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
283
    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
 
284
    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
 
285
    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
 
286
    
 
287
    // Table(s) of coefficients
 
288
    static const double coefficients0[6][6] = \
 
289
    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
 
290
    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
 
291
    {0, 0, 0.2, 0, 0, 0.163299316185545},
 
292
    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
 
293
    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
 
294
    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
 
295
    
 
296
    // Interesting (new) part
 
297
    // Tables of derivatives of the polynomial base (transpose)
 
298
    static const double dmats0[6][6] = \
 
299
    {{0, 0, 0, 0, 0, 0},
 
300
    {4.89897948556635, 0, 0, 0, 0, 0},
 
301
    {0, 0, 0, 0, 0, 0},
 
302
    {0, 9.48683298050514, 0, 0, 0, 0},
 
303
    {4, 0, 7.07106781186548, 0, 0, 0},
 
304
    {0, 0, 0, 0, 0, 0}};
 
305
    
 
306
    static const double dmats1[6][6] = \
 
307
    {{0, 0, 0, 0, 0, 0},
 
308
    {2.44948974278318, 0, 0, 0, 0, 0},
 
309
    {4.24264068711928, 0, 0, 0, 0, 0},
 
310
    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
 
311
    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
 
312
    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
 
313
    
 
314
    // Compute reference derivatives
 
315
    // Declare pointer to array of derivatives on FIAT element
 
316
    double *derivatives = new double [num_derivatives];
 
317
    
 
318
    // Declare coefficients
 
319
    double coeff0_0 = 0;
 
320
    double coeff0_1 = 0;
 
321
    double coeff0_2 = 0;
 
322
    double coeff0_3 = 0;
 
323
    double coeff0_4 = 0;
 
324
    double coeff0_5 = 0;
 
325
    
 
326
    // Declare new coefficients
 
327
    double new_coeff0_0 = 0;
 
328
    double new_coeff0_1 = 0;
 
329
    double new_coeff0_2 = 0;
 
330
    double new_coeff0_3 = 0;
 
331
    double new_coeff0_4 = 0;
 
332
    double new_coeff0_5 = 0;
 
333
    
 
334
    // Loop possible derivatives
 
335
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
336
    {
 
337
      // Get values from coefficients array
 
338
      new_coeff0_0 = coefficients0[dof][0];
 
339
      new_coeff0_1 = coefficients0[dof][1];
 
340
      new_coeff0_2 = coefficients0[dof][2];
 
341
      new_coeff0_3 = coefficients0[dof][3];
 
342
      new_coeff0_4 = coefficients0[dof][4];
 
343
      new_coeff0_5 = coefficients0[dof][5];
 
344
    
 
345
      // Loop derivative order
 
346
      for (unsigned int j = 0; j < n; j++)
 
347
      {
 
348
        // Update old coefficients
 
349
        coeff0_0 = new_coeff0_0;
 
350
        coeff0_1 = new_coeff0_1;
 
351
        coeff0_2 = new_coeff0_2;
 
352
        coeff0_3 = new_coeff0_3;
 
353
        coeff0_4 = new_coeff0_4;
 
354
        coeff0_5 = new_coeff0_5;
 
355
    
 
356
        if(combinations[deriv_num][j] == 0)
 
357
        {
 
358
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
 
359
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
 
360
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
 
361
          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
 
362
          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
 
363
          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
 
364
        }
 
365
        if(combinations[deriv_num][j] == 1)
 
366
        {
 
367
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
 
368
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
 
369
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
 
370
          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
 
371
          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
 
372
          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
 
373
        }
 
374
    
 
375
      }
 
376
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
377
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
 
378
    }
 
379
    
 
380
    // Transform derivatives back to physical element
 
381
    for (unsigned int row = 0; row < num_derivatives; row++)
 
382
    {
 
383
      for (unsigned int col = 0; col < num_derivatives; col++)
 
384
      {
 
385
        values[row] += transform[row][col]*derivatives[col];
 
386
      }
 
387
    }
 
388
    // Delete pointer to array of derivatives on FIAT element
 
389
    delete [] derivatives;
 
390
    
 
391
    // Delete pointer to array of combinations of derivatives and transform
 
392
    for (unsigned int row = 0; row < num_derivatives; row++)
 
393
    {
 
394
      delete [] combinations[row];
 
395
      delete [] transform[row];
 
396
    }
 
397
    
 
398
    delete [] combinations;
 
399
    delete [] transform;
 
400
  }
 
401
 
 
402
  /// Evaluate order n derivatives of all basis functions at given point in cell
 
403
  virtual void evaluate_basis_derivatives_all(unsigned int n,
 
404
                                              double* values,
 
405
                                              const double* coordinates,
 
406
                                              const ufc::cell& c) const
 
407
  {
 
408
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
409
  }
 
410
 
 
411
  /// Evaluate linear functional for dof i on the function f
 
412
  virtual double evaluate_dof(unsigned int i,
 
413
                              const ufc::function& f,
 
414
                              const ufc::cell& c) const
 
415
  {
 
416
    // The reference points, direction and weights:
 
417
    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
 
418
    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
 
419
    static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
 
420
    
 
421
    const double * const * x = c.coordinates;
 
422
    double result = 0.0;
 
423
    // Iterate over the points:
 
424
    // Evaluate basis functions for affine mapping
 
425
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
426
    const double w1 = X[i][0][0];
 
427
    const double w2 = X[i][0][1];
 
428
    
 
429
    // Compute affine mapping y = F(X)
 
430
    double y[2];
 
431
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
432
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
433
    
 
434
    // Evaluate function at physical points
 
435
    double values[1];
 
436
    f.evaluate(values, y, c);
 
437
    
 
438
    // Map function values using appropriate mapping
 
439
    // Affine map: Do nothing
 
440
    
 
441
    // Note that we do not map the weights (yet).
 
442
    
 
443
    // Take directional components
 
444
    for(int k = 0; k < 1; k++)
 
445
      result += values[k]*D[i][0][k];
 
446
    // Multiply by weights
 
447
    result *= W[i][0];
 
448
    
 
449
    return result;
 
450
  }
 
451
 
 
452
  /// Evaluate linear functionals for all dofs on the function f
 
453
  virtual void evaluate_dofs(double* values,
 
454
                             const ufc::function& f,
 
455
                             const ufc::cell& c) const
 
456
  {
 
457
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
458
  }
 
459
 
 
460
  /// Interpolate vertex values from dof values
 
461
  virtual void interpolate_vertex_values(double* vertex_values,
 
462
                                         const double* dof_values,
 
463
                                         const ufc::cell& c) const
 
464
  {
 
465
    // Evaluate at vertices and use affine mapping
 
466
    vertex_values[0] = dof_values[0];
 
467
    vertex_values[1] = dof_values[1];
 
468
    vertex_values[2] = dof_values[2];
 
469
  }
 
470
 
 
471
  /// Return the number of sub elements (for a mixed element)
 
472
  virtual unsigned int num_sub_elements() const
 
473
  {
 
474
    return 1;
 
475
  }
 
476
 
 
477
  /// Create a new finite element for sub element i (for a mixed element)
 
478
  virtual ufc::finite_element* create_sub_element(unsigned int i) const
 
479
  {
 
480
    return new velocity_0_finite_element_0_0();
 
481
  }
 
482
 
 
483
};
 
484
 
 
485
/// This class defines the interface for a finite element.
 
486
 
 
487
class velocity_0_finite_element_0_1: public ufc::finite_element
 
488
{
 
489
public:
 
490
 
 
491
  /// Constructor
 
492
  velocity_0_finite_element_0_1() : ufc::finite_element()
 
493
  {
 
494
    // Do nothing
 
495
  }
 
496
 
 
497
  /// Destructor
 
498
  virtual ~velocity_0_finite_element_0_1()
 
499
  {
 
500
    // Do nothing
 
501
  }
 
502
 
 
503
  /// Return a string identifying the finite element
 
504
  virtual const char* signature() const
 
505
  {
 
506
    return "FiniteElement('Lagrange', 'triangle', 2)";
 
507
  }
 
508
 
 
509
  /// Return the cell shape
 
510
  virtual ufc::shape cell_shape() const
 
511
  {
 
512
    return ufc::triangle;
 
513
  }
 
514
 
 
515
  /// Return the dimension of the finite element function space
 
516
  virtual unsigned int space_dimension() const
 
517
  {
 
518
    return 6;
 
519
  }
 
520
 
 
521
  /// Return the rank of the value space
 
522
  virtual unsigned int value_rank() const
 
523
  {
 
524
    return 0;
 
525
  }
 
526
 
 
527
  /// Return the dimension of the value space for axis i
 
528
  virtual unsigned int value_dimension(unsigned int i) const
 
529
  {
 
530
    return 1;
 
531
  }
 
532
 
 
533
  /// Evaluate basis function i at given point in cell
 
534
  virtual void evaluate_basis(unsigned int i,
 
535
                              double* values,
 
536
                              const double* coordinates,
 
537
                              const ufc::cell& c) const
 
538
  {
 
539
    // Extract vertex coordinates
 
540
    const double * const * element_coordinates = c.coordinates;
 
541
    
 
542
    // Compute Jacobian of affine map from reference cell
 
543
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
544
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
545
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
546
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
547
    
 
548
    // Compute determinant of Jacobian
 
549
    const double detJ = J_00*J_11 - J_01*J_10;
 
550
    
 
551
    // Compute inverse of Jacobian
 
552
    
 
553
    // Get coordinates and map to the reference (UFC) element
 
554
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
555
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
556
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
557
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
558
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
559
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
560
    
 
561
    // Map coordinates to the reference square
 
562
    if (std::abs(y - 1.0) < 1e-14)
 
563
      x = -1.0;
 
564
    else
 
565
      x = 2.0 *x/(1.0 - y) - 1.0;
 
566
    y = 2.0*y - 1.0;
 
567
    
 
568
    // Reset values
 
569
    *values = 0;
 
570
    
 
571
    // Map degree of freedom to element degree of freedom
 
572
    const unsigned int dof = i;
 
573
    
 
574
    // Generate scalings
 
575
    const double scalings_y_0 = 1;
 
576
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
577
    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
 
578
    
 
579
    // Compute psitilde_a
 
580
    const double psitilde_a_0 = 1;
 
581
    const double psitilde_a_1 = x;
 
582
    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
 
583
    
 
584
    // Compute psitilde_bs
 
585
    const double psitilde_bs_0_0 = 1;
 
586
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
587
    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
 
588
    const double psitilde_bs_1_0 = 1;
 
589
    const double psitilde_bs_1_1 = 2.5*y + 1.5;
 
590
    const double psitilde_bs_2_0 = 1;
 
591
    
 
592
    // Compute basisvalues
 
593
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
594
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
595
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
596
    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
 
597
    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
 
598
    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
 
599
    
 
600
    // Table(s) of coefficients
 
601
    static const double coefficients0[6][6] = \
 
602
    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
 
603
    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
 
604
    {0, 0, 0.2, 0, 0, 0.163299316185545},
 
605
    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
 
606
    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
 
607
    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
 
608
    
 
609
    // Extract relevant coefficients
 
610
    const double coeff0_0 = coefficients0[dof][0];
 
611
    const double coeff0_1 = coefficients0[dof][1];
 
612
    const double coeff0_2 = coefficients0[dof][2];
 
613
    const double coeff0_3 = coefficients0[dof][3];
 
614
    const double coeff0_4 = coefficients0[dof][4];
 
615
    const double coeff0_5 = coefficients0[dof][5];
 
616
    
 
617
    // Compute value(s)
 
618
    *values = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2 + coeff0_3*basisvalue3 + coeff0_4*basisvalue4 + coeff0_5*basisvalue5;
 
619
  }
 
620
 
 
621
  /// Evaluate all basis functions at given point in cell
 
622
  virtual void evaluate_basis_all(double* values,
 
623
                                  const double* coordinates,
 
624
                                  const ufc::cell& c) const
 
625
  {
 
626
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
627
  }
 
628
 
 
629
  /// Evaluate order n derivatives of basis function i at given point in cell
 
630
  virtual void evaluate_basis_derivatives(unsigned int i,
 
631
                                          unsigned int n,
 
632
                                          double* values,
 
633
                                          const double* coordinates,
 
634
                                          const ufc::cell& c) const
 
635
  {
 
636
    // Extract vertex coordinates
 
637
    const double * const * element_coordinates = c.coordinates;
 
638
    
 
639
    // Compute Jacobian of affine map from reference cell
 
640
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
641
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
642
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
643
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
644
    
 
645
    // Compute determinant of Jacobian
 
646
    const double detJ = J_00*J_11 - J_01*J_10;
 
647
    
 
648
    // Compute inverse of Jacobian
 
649
    
 
650
    // Get coordinates and map to the reference (UFC) element
 
651
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
652
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
653
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
654
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
655
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
656
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
657
    
 
658
    // Map coordinates to the reference square
 
659
    if (std::abs(y - 1.0) < 1e-14)
 
660
      x = -1.0;
 
661
    else
 
662
      x = 2.0 *x/(1.0 - y) - 1.0;
 
663
    y = 2.0*y - 1.0;
 
664
    
 
665
    // Compute number of derivatives
 
666
    unsigned int num_derivatives = 1;
 
667
    
 
668
    for (unsigned int j = 0; j < n; j++)
 
669
      num_derivatives *= 2;
 
670
    
 
671
    
 
672
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
673
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
674
    
 
675
    for (unsigned int j = 0; j < num_derivatives; j++)
 
676
    {
 
677
      combinations[j] = new unsigned int [n];
 
678
      for (unsigned int k = 0; k < n; k++)
 
679
        combinations[j][k] = 0;
 
680
    }
 
681
    
 
682
    // Generate combinations of derivatives
 
683
    for (unsigned int row = 1; row < num_derivatives; row++)
 
684
    {
 
685
      for (unsigned int num = 0; num < row; num++)
 
686
      {
 
687
        for (unsigned int col = n-1; col+1 > 0; col--)
 
688
        {
 
689
          if (combinations[row][col] + 1 > 1)
 
690
            combinations[row][col] = 0;
 
691
          else
 
692
          {
 
693
            combinations[row][col] += 1;
 
694
            break;
 
695
          }
 
696
        }
 
697
      }
 
698
    }
 
699
    
 
700
    // Compute inverse of Jacobian
 
701
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
702
    
 
703
    // Declare transformation matrix
 
704
    // Declare pointer to two dimensional array and initialise
 
705
    double **transform = new double *[num_derivatives];
 
706
    
 
707
    for (unsigned int j = 0; j < num_derivatives; j++)
 
708
    {
 
709
      transform[j] = new double [num_derivatives];
 
710
      for (unsigned int k = 0; k < num_derivatives; k++)
 
711
        transform[j][k] = 1;
 
712
    }
 
713
    
 
714
    // Construct transformation matrix
 
715
    for (unsigned int row = 0; row < num_derivatives; row++)
 
716
    {
 
717
      for (unsigned int col = 0; col < num_derivatives; col++)
 
718
      {
 
719
        for (unsigned int k = 0; k < n; k++)
 
720
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
721
      }
 
722
    }
 
723
    
 
724
    // Reset values
 
725
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
 
726
      values[j] = 0;
 
727
    
 
728
    // Map degree of freedom to element degree of freedom
 
729
    const unsigned int dof = i;
 
730
    
 
731
    // Generate scalings
 
732
    const double scalings_y_0 = 1;
 
733
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
734
    const double scalings_y_2 = scalings_y_1*(0.5 - 0.5*y);
 
735
    
 
736
    // Compute psitilde_a
 
737
    const double psitilde_a_0 = 1;
 
738
    const double psitilde_a_1 = x;
 
739
    const double psitilde_a_2 = 1.5*x*psitilde_a_1 - 0.5*psitilde_a_0;
 
740
    
 
741
    // Compute psitilde_bs
 
742
    const double psitilde_bs_0_0 = 1;
 
743
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
744
    const double psitilde_bs_0_2 = 0.111111111111111*psitilde_bs_0_1 + 1.66666666666667*y*psitilde_bs_0_1 - 0.555555555555556*psitilde_bs_0_0;
 
745
    const double psitilde_bs_1_0 = 1;
 
746
    const double psitilde_bs_1_1 = 2.5*y + 1.5;
 
747
    const double psitilde_bs_2_0 = 1;
 
748
    
 
749
    // Compute basisvalues
 
750
    const double basisvalue0 = 0.707106781186548*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
751
    const double basisvalue1 = 1.73205080756888*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
752
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
753
    const double basisvalue3 = 2.73861278752583*psitilde_a_2*scalings_y_2*psitilde_bs_2_0;
 
754
    const double basisvalue4 = 2.12132034355964*psitilde_a_1*scalings_y_1*psitilde_bs_1_1;
 
755
    const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
 
756
    
 
757
    // Table(s) of coefficients
 
758
    static const double coefficients0[6][6] = \
 
759
    {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
 
760
    {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
 
761
    {0, 0, 0.2, 0, 0, 0.163299316185545},
 
762
    {0.471404520791032, 0.23094010767585, 0.133333333333333, 0, 0.188561808316413, -0.163299316185545},
 
763
    {0.471404520791032, -0.23094010767585, 0.133333333333333, 0, -0.188561808316413, -0.163299316185545},
 
764
    {0.471404520791032, 0, -0.266666666666667, -0.243432247780074, 0, 0.0544331053951817}};
 
765
    
 
766
    // Interesting (new) part
 
767
    // Tables of derivatives of the polynomial base (transpose)
 
768
    static const double dmats0[6][6] = \
 
769
    {{0, 0, 0, 0, 0, 0},
 
770
    {4.89897948556635, 0, 0, 0, 0, 0},
 
771
    {0, 0, 0, 0, 0, 0},
 
772
    {0, 9.48683298050514, 0, 0, 0, 0},
 
773
    {4, 0, 7.07106781186548, 0, 0, 0},
 
774
    {0, 0, 0, 0, 0, 0}};
 
775
    
 
776
    static const double dmats1[6][6] = \
 
777
    {{0, 0, 0, 0, 0, 0},
 
778
    {2.44948974278318, 0, 0, 0, 0, 0},
 
779
    {4.24264068711928, 0, 0, 0, 0, 0},
 
780
    {2.58198889747161, 4.74341649025257, -0.912870929175277, 0, 0, 0},
 
781
    {2, 6.12372435695795, 3.53553390593274, 0, 0, 0},
 
782
    {-2.3094010767585, 0, 8.16496580927726, 0, 0, 0}};
 
783
    
 
784
    // Compute reference derivatives
 
785
    // Declare pointer to array of derivatives on FIAT element
 
786
    double *derivatives = new double [num_derivatives];
 
787
    
 
788
    // Declare coefficients
 
789
    double coeff0_0 = 0;
 
790
    double coeff0_1 = 0;
 
791
    double coeff0_2 = 0;
 
792
    double coeff0_3 = 0;
 
793
    double coeff0_4 = 0;
 
794
    double coeff0_5 = 0;
 
795
    
 
796
    // Declare new coefficients
 
797
    double new_coeff0_0 = 0;
 
798
    double new_coeff0_1 = 0;
 
799
    double new_coeff0_2 = 0;
 
800
    double new_coeff0_3 = 0;
 
801
    double new_coeff0_4 = 0;
 
802
    double new_coeff0_5 = 0;
 
803
    
 
804
    // Loop possible derivatives
 
805
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
806
    {
 
807
      // Get values from coefficients array
 
808
      new_coeff0_0 = coefficients0[dof][0];
 
809
      new_coeff0_1 = coefficients0[dof][1];
 
810
      new_coeff0_2 = coefficients0[dof][2];
 
811
      new_coeff0_3 = coefficients0[dof][3];
 
812
      new_coeff0_4 = coefficients0[dof][4];
 
813
      new_coeff0_5 = coefficients0[dof][5];
 
814
    
 
815
      // Loop derivative order
 
816
      for (unsigned int j = 0; j < n; j++)
 
817
      {
 
818
        // Update old coefficients
 
819
        coeff0_0 = new_coeff0_0;
 
820
        coeff0_1 = new_coeff0_1;
 
821
        coeff0_2 = new_coeff0_2;
 
822
        coeff0_3 = new_coeff0_3;
 
823
        coeff0_4 = new_coeff0_4;
 
824
        coeff0_5 = new_coeff0_5;
 
825
    
 
826
        if(combinations[deriv_num][j] == 0)
 
827
        {
 
828
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0] + coeff0_3*dmats0[3][0] + coeff0_4*dmats0[4][0] + coeff0_5*dmats0[5][0];
 
829
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1] + coeff0_3*dmats0[3][1] + coeff0_4*dmats0[4][1] + coeff0_5*dmats0[5][1];
 
830
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2] + coeff0_3*dmats0[3][2] + coeff0_4*dmats0[4][2] + coeff0_5*dmats0[5][2];
 
831
          new_coeff0_3 = coeff0_0*dmats0[0][3] + coeff0_1*dmats0[1][3] + coeff0_2*dmats0[2][3] + coeff0_3*dmats0[3][3] + coeff0_4*dmats0[4][3] + coeff0_5*dmats0[5][3];
 
832
          new_coeff0_4 = coeff0_0*dmats0[0][4] + coeff0_1*dmats0[1][4] + coeff0_2*dmats0[2][4] + coeff0_3*dmats0[3][4] + coeff0_4*dmats0[4][4] + coeff0_5*dmats0[5][4];
 
833
          new_coeff0_5 = coeff0_0*dmats0[0][5] + coeff0_1*dmats0[1][5] + coeff0_2*dmats0[2][5] + coeff0_3*dmats0[3][5] + coeff0_4*dmats0[4][5] + coeff0_5*dmats0[5][5];
 
834
        }
 
835
        if(combinations[deriv_num][j] == 1)
 
836
        {
 
837
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0] + coeff0_3*dmats1[3][0] + coeff0_4*dmats1[4][0] + coeff0_5*dmats1[5][0];
 
838
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1] + coeff0_3*dmats1[3][1] + coeff0_4*dmats1[4][1] + coeff0_5*dmats1[5][1];
 
839
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2] + coeff0_3*dmats1[3][2] + coeff0_4*dmats1[4][2] + coeff0_5*dmats1[5][2];
 
840
          new_coeff0_3 = coeff0_0*dmats1[0][3] + coeff0_1*dmats1[1][3] + coeff0_2*dmats1[2][3] + coeff0_3*dmats1[3][3] + coeff0_4*dmats1[4][3] + coeff0_5*dmats1[5][3];
 
841
          new_coeff0_4 = coeff0_0*dmats1[0][4] + coeff0_1*dmats1[1][4] + coeff0_2*dmats1[2][4] + coeff0_3*dmats1[3][4] + coeff0_4*dmats1[4][4] + coeff0_5*dmats1[5][4];
 
842
          new_coeff0_5 = coeff0_0*dmats1[0][5] + coeff0_1*dmats1[1][5] + coeff0_2*dmats1[2][5] + coeff0_3*dmats1[3][5] + coeff0_4*dmats1[4][5] + coeff0_5*dmats1[5][5];
 
843
        }
 
844
    
 
845
      }
 
846
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
847
      derivatives[deriv_num] = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2 + new_coeff0_3*basisvalue3 + new_coeff0_4*basisvalue4 + new_coeff0_5*basisvalue5;
 
848
    }
 
849
    
 
850
    // Transform derivatives back to physical element
 
851
    for (unsigned int row = 0; row < num_derivatives; row++)
 
852
    {
 
853
      for (unsigned int col = 0; col < num_derivatives; col++)
 
854
      {
 
855
        values[row] += transform[row][col]*derivatives[col];
 
856
      }
 
857
    }
 
858
    // Delete pointer to array of derivatives on FIAT element
 
859
    delete [] derivatives;
 
860
    
 
861
    // Delete pointer to array of combinations of derivatives and transform
 
862
    for (unsigned int row = 0; row < num_derivatives; row++)
 
863
    {
 
864
      delete [] combinations[row];
 
865
      delete [] transform[row];
 
866
    }
 
867
    
 
868
    delete [] combinations;
 
869
    delete [] transform;
 
870
  }
 
871
 
 
872
  /// Evaluate order n derivatives of all basis functions at given point in cell
 
873
  virtual void evaluate_basis_derivatives_all(unsigned int n,
 
874
                                              double* values,
 
875
                                              const double* coordinates,
 
876
                                              const ufc::cell& c) const
 
877
  {
 
878
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
879
  }
 
880
 
 
881
  /// Evaluate linear functional for dof i on the function f
 
882
  virtual double evaluate_dof(unsigned int i,
 
883
                              const ufc::function& f,
 
884
                              const ufc::cell& c) const
 
885
  {
 
886
    // The reference points, direction and weights:
 
887
    static const double X[6][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
 
888
    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
 
889
    static const double D[6][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
 
890
    
 
891
    const double * const * x = c.coordinates;
 
892
    double result = 0.0;
 
893
    // Iterate over the points:
 
894
    // Evaluate basis functions for affine mapping
 
895
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
896
    const double w1 = X[i][0][0];
 
897
    const double w2 = X[i][0][1];
 
898
    
 
899
    // Compute affine mapping y = F(X)
 
900
    double y[2];
 
901
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
902
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
903
    
 
904
    // Evaluate function at physical points
 
905
    double values[1];
 
906
    f.evaluate(values, y, c);
 
907
    
 
908
    // Map function values using appropriate mapping
 
909
    // Affine map: Do nothing
 
910
    
 
911
    // Note that we do not map the weights (yet).
 
912
    
 
913
    // Take directional components
 
914
    for(int k = 0; k < 1; k++)
 
915
      result += values[k]*D[i][0][k];
 
916
    // Multiply by weights
 
917
    result *= W[i][0];
 
918
    
 
919
    return result;
 
920
  }
 
921
 
 
922
  /// Evaluate linear functionals for all dofs on the function f
 
923
  virtual void evaluate_dofs(double* values,
 
924
                             const ufc::function& f,
 
925
                             const ufc::cell& c) const
 
926
  {
 
927
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
928
  }
 
929
 
 
930
  /// Interpolate vertex values from dof values
 
931
  virtual void interpolate_vertex_values(double* vertex_values,
 
932
                                         const double* dof_values,
 
933
                                         const ufc::cell& c) const
 
934
  {
 
935
    // Evaluate at vertices and use affine mapping
 
936
    vertex_values[0] = dof_values[0];
 
937
    vertex_values[1] = dof_values[1];
 
938
    vertex_values[2] = dof_values[2];
 
939
  }
 
940
 
 
941
  /// Return the number of sub elements (for a mixed element)
 
942
  virtual unsigned int num_sub_elements() const
 
943
  {
 
944
    return 1;
 
945
  }
 
946
 
 
947
  /// Create a new finite element for sub element i (for a mixed element)
 
948
  virtual ufc::finite_element* create_sub_element(unsigned int i) const
 
949
  {
 
950
    return new velocity_0_finite_element_0_1();
 
951
  }
 
952
 
 
953
};
 
954
 
 
955
/// This class defines the interface for a finite element.
 
956
 
 
957
class velocity_0_finite_element_0: public ufc::finite_element
 
958
{
 
959
public:
 
960
 
 
961
  /// Constructor
 
962
  velocity_0_finite_element_0() : ufc::finite_element()
 
963
  {
 
964
    // Do nothing
 
965
  }
 
966
 
 
967
  /// Destructor
 
968
  virtual ~velocity_0_finite_element_0()
969
969
  {
970
970
    // Do nothing
971
971
  }
1014
1014
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1015
1015
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1016
1016
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1017
 
      
 
1017
    
1018
1018
    // Compute determinant of Jacobian
1019
1019
    const double detJ = J_00*J_11 - J_01*J_10;
1020
1020
    
1071
1071
      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
1072
1072
    
1073
1073
      // Table(s) of coefficients
1074
 
      const static double coefficients0[6][6] =   \
 
1074
      static const double coefficients0[6][6] =   \
1075
1075
      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
1076
1076
      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
1077
1077
      {0, 0, 0.2, 0, 0, 0.163299316185545},
1123
1123
      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
1124
1124
    
1125
1125
      // Table(s) of coefficients
1126
 
      const static double coefficients0[6][6] =   \
 
1126
      static const double coefficients0[6][6] =   \
1127
1127
      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
1128
1128
      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
1129
1129
      {0, 0, 0.2, 0, 0, 0.163299316185545},
1168
1168
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
1169
1169
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
1170
1170
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
1171
 
      
 
1171
    
1172
1172
    // Compute determinant of Jacobian
1173
1173
    const double detJ = J_00*J_11 - J_01*J_10;
1174
1174
    
1198
1198
    
1199
1199
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
1200
1200
    unsigned int **combinations = new unsigned int *[num_derivatives];
1201
 
        
 
1201
    
1202
1202
    for (unsigned int j = 0; j < num_derivatives; j++)
1203
1203
    {
1204
1204
      combinations[j] = new unsigned int [n];
1205
1205
      for (unsigned int k = 0; k < n; k++)
1206
1206
        combinations[j][k] = 0;
1207
1207
    }
1208
 
        
 
1208
    
1209
1209
    // Generate combinations of derivatives
1210
1210
    for (unsigned int row = 1; row < num_derivatives; row++)
1211
1211
    {
1230
1230
    // Declare transformation matrix
1231
1231
    // Declare pointer to two dimensional array and initialise
1232
1232
    double **transform = new double *[num_derivatives];
1233
 
        
 
1233
    
1234
1234
    for (unsigned int j = 0; j < num_derivatives; j++)
1235
1235
    {
1236
1236
      transform[j] = new double [num_derivatives];
1284
1284
      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
1285
1285
    
1286
1286
      // Table(s) of coefficients
1287
 
      const static double coefficients0[6][6] =   \
 
1287
      static const double coefficients0[6][6] =   \
1288
1288
      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
1289
1289
      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
1290
1290
      {0, 0, 0.2, 0, 0, 0.163299316185545},
1294
1294
    
1295
1295
      // Interesting (new) part
1296
1296
      // Tables of derivatives of the polynomial base (transpose)
1297
 
      const static double dmats0[6][6] =   \
 
1297
      static const double dmats0[6][6] =   \
1298
1298
      {{0, 0, 0, 0, 0, 0},
1299
1299
      {4.89897948556635, 0, 0, 0, 0, 0},
1300
1300
      {0, 0, 0, 0, 0, 0},
1302
1302
      {4, 0, 7.07106781186548, 0, 0, 0},
1303
1303
      {0, 0, 0, 0, 0, 0}};
1304
1304
    
1305
 
      const static double dmats1[6][6] =   \
 
1305
      static const double dmats1[6][6] =   \
1306
1306
      {{0, 0, 0, 0, 0, 0},
1307
1307
      {2.44948974278318, 0, 0, 0, 0, 0},
1308
1308
      {4.24264068711928, 0, 0, 0, 0, 0},
1430
1430
      const double basisvalue5 = 1.22474487139159*psitilde_a_0*scalings_y_0*psitilde_bs_0_2;
1431
1431
    
1432
1432
      // Table(s) of coefficients
1433
 
      const static double coefficients0[6][6] =   \
 
1433
      static const double coefficients0[6][6] =   \
1434
1434
      {{0, -0.173205080756888, -0.1, 0.121716123890037, 0.0942809041582064, 0.0544331053951817},
1435
1435
      {0, 0.173205080756888, -0.1, 0.121716123890037, -0.0942809041582063, 0.0544331053951818},
1436
1436
      {0, 0, 0.2, 0, 0, 0.163299316185545},
1440
1440
    
1441
1441
      // Interesting (new) part
1442
1442
      // Tables of derivatives of the polynomial base (transpose)
1443
 
      const static double dmats0[6][6] =   \
 
1443
      static const double dmats0[6][6] =   \
1444
1444
      {{0, 0, 0, 0, 0, 0},
1445
1445
      {4.89897948556635, 0, 0, 0, 0, 0},
1446
1446
      {0, 0, 0, 0, 0, 0},
1448
1448
      {4, 0, 7.07106781186548, 0, 0, 0},
1449
1449
      {0, 0, 0, 0, 0, 0}};
1450
1450
    
1451
 
      const static double dmats1[6][6] =   \
 
1451
      static const double dmats1[6][6] =   \
1452
1452
      {{0, 0, 0, 0, 0, 0},
1453
1453
      {2.44948974278318, 0, 0, 0, 0, 0},
1454
1454
      {4.24264068711928, 0, 0, 0, 0, 0},
1561
1561
                              const ufc::cell& c) const
1562
1562
  {
1563
1563
    // The reference points, direction and weights:
1564
 
    const static double X[12][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}, {{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
1565
 
    const static double W[12][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
1566
 
    const static double D[12][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
 
1564
    static const double X[12][1][2] = {{{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}, {{0, 0}}, {{1, 0}}, {{0, 1}}, {{0.5, 0.5}}, {{0, 0.5}}, {{0.5, 0}}};
 
1565
    static const double W[12][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
 
1566
    static const double D[12][1][2] = {{{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{1, 0}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}, {{0, 1}}};
1567
1567
    
1568
1568
    const double * const * x = c.coordinates;
1569
1569
    double result = 0.0;
1590
1590
    // Take directional components
1591
1591
    for(int k = 0; k < 2; k++)
1592
1592
      result += values[k]*D[i][0][k];
1593
 
    // Multiply by weights 
 
1593
    // Multiply by weights
1594
1594
    result *= W[i][0];
1595
1595
    
1596
1596
    return result;
1631
1631
    switch ( i )
1632
1632
    {
1633
1633
    case 0:
1634
 
      return new UFC_Velocity_finite_element_0_0();
 
1634
      return new velocity_0_finite_element_0_0();
1635
1635
      break;
1636
1636
    case 1:
1637
 
      return new UFC_Velocity_finite_element_0_1();
 
1637
      return new velocity_0_finite_element_0_1();
1638
1638
      break;
1639
1639
    }
1640
1640
    return 0;
1645
1645
/// This class defines the interface for a local-to-global mapping of
1646
1646
/// degrees of freedom (dofs).
1647
1647
 
1648
 
class UFC_Velocity_dof_map_0_0: public ufc::dof_map
1649
 
{
1650
 
private:
1651
 
 
1652
 
  unsigned int __global_dimension;
1653
 
 
1654
 
public:
1655
 
 
1656
 
  /// Constructor
1657
 
  UFC_Velocity_dof_map_0_0() : ufc::dof_map()
1658
 
  {
1659
 
    __global_dimension = 0;
1660
 
  }
1661
 
 
1662
 
  /// Destructor
1663
 
  virtual ~UFC_Velocity_dof_map_0_0()
1664
 
  {
1665
 
    // Do nothing
1666
 
  }
1667
 
 
1668
 
  /// Return a string identifying the dof map
1669
 
  virtual const char* signature() const
1670
 
  {
1671
 
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 2)";
1672
 
  }
1673
 
 
1674
 
  /// Return true iff mesh entities of topological dimension d are needed
1675
 
  virtual bool needs_mesh_entities(unsigned int d) const
1676
 
  {
1677
 
    switch ( d )
1678
 
    {
1679
 
    case 0:
1680
 
      return true;
1681
 
      break;
1682
 
    case 1:
1683
 
      return true;
1684
 
      break;
1685
 
    case 2:
1686
 
      return false;
1687
 
      break;
1688
 
    }
1689
 
    return false;
1690
 
  }
1691
 
 
1692
 
  /// Initialize dof map for mesh (return true iff init_cell() is needed)
1693
 
  virtual bool init_mesh(const ufc::mesh& m)
1694
 
  {
1695
 
    __global_dimension = m.num_entities[0] + m.num_entities[1];
1696
 
    return false;
1697
 
  }
1698
 
 
1699
 
  /// Initialize dof map for given cell
1700
 
  virtual void init_cell(const ufc::mesh& m,
1701
 
                         const ufc::cell& c)
1702
 
  {
1703
 
    // Do nothing
1704
 
  }
1705
 
 
1706
 
  /// Finish initialization of dof map for cells
1707
 
  virtual void init_cell_finalize()
1708
 
  {
1709
 
    // Do nothing
1710
 
  }
1711
 
 
1712
 
  /// Return the dimension of the global finite element function space
1713
 
  virtual unsigned int global_dimension() const
1714
 
  {
1715
 
    return __global_dimension;
1716
 
  }
1717
 
 
1718
 
  /// Return the dimension of the local finite element function space
1719
 
  virtual unsigned int local_dimension() const
1720
 
  {
1721
 
    return 6;
1722
 
  }
1723
 
 
1724
 
  // Return the geometric dimension of the coordinates this dof map provides
1725
 
  virtual unsigned int geometric_dimension() const
1726
 
  {
1727
 
    return 2;
1728
 
  }
1729
 
 
1730
 
  /// Return the number of dofs on each cell facet
1731
 
  virtual unsigned int num_facet_dofs() const
1732
 
  {
1733
 
    return 3;
1734
 
  }
1735
 
 
1736
 
  /// Return the number of dofs associated with each cell entity of dimension d
1737
 
  virtual unsigned int num_entity_dofs(unsigned int d) const
1738
 
  {
1739
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1740
 
  }
1741
 
 
1742
 
  /// Tabulate the local-to-global mapping of dofs on a cell
1743
 
  virtual void tabulate_dofs(unsigned int* dofs,
1744
 
                             const ufc::mesh& m,
1745
 
                             const ufc::cell& c) const
1746
 
  {
1747
 
    dofs[0] = c.entity_indices[0][0];
1748
 
    dofs[1] = c.entity_indices[0][1];
1749
 
    dofs[2] = c.entity_indices[0][2];
1750
 
    unsigned int offset = m.num_entities[0];
1751
 
    dofs[3] = offset + c.entity_indices[1][0];
1752
 
    dofs[4] = offset + c.entity_indices[1][1];
1753
 
    dofs[5] = offset + c.entity_indices[1][2];
1754
 
  }
1755
 
 
1756
 
  /// Tabulate the local-to-local mapping from facet dofs to cell dofs
1757
 
  virtual void tabulate_facet_dofs(unsigned int* dofs,
1758
 
                                   unsigned int facet) const
1759
 
  {
1760
 
    switch ( facet )
1761
 
    {
1762
 
    case 0:
1763
 
      dofs[0] = 1;
1764
 
      dofs[1] = 2;
1765
 
      dofs[2] = 3;
1766
 
      break;
1767
 
    case 1:
1768
 
      dofs[0] = 0;
1769
 
      dofs[1] = 2;
1770
 
      dofs[2] = 4;
1771
 
      break;
1772
 
    case 2:
1773
 
      dofs[0] = 0;
1774
 
      dofs[1] = 1;
1775
 
      dofs[2] = 5;
1776
 
      break;
1777
 
    }
1778
 
  }
1779
 
 
1780
 
  /// Tabulate the local-to-local mapping of dofs on entity (d, i)
1781
 
  virtual void tabulate_entity_dofs(unsigned int* dofs,
1782
 
                                    unsigned int d, unsigned int i) const
1783
 
  {
1784
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1785
 
  }
1786
 
 
1787
 
  /// Tabulate the coordinates of all dofs on a cell
1788
 
  virtual void tabulate_coordinates(double** coordinates,
1789
 
                                    const ufc::cell& c) const
1790
 
  {
1791
 
    const double * const * x = c.coordinates;
1792
 
    coordinates[0][0] = x[0][0];
1793
 
    coordinates[0][1] = x[0][1];
1794
 
    coordinates[1][0] = x[1][0];
1795
 
    coordinates[1][1] = x[1][1];
1796
 
    coordinates[2][0] = x[2][0];
1797
 
    coordinates[2][1] = x[2][1];
1798
 
    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
1799
 
    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
1800
 
    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
1801
 
    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
1802
 
    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
1803
 
    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
1804
 
  }
1805
 
 
1806
 
  /// Return the number of sub dof maps (for a mixed element)
1807
 
  virtual unsigned int num_sub_dof_maps() const
1808
 
  {
1809
 
    return 1;
1810
 
  }
1811
 
 
1812
 
  /// Create a new dof_map for sub dof map i (for a mixed element)
1813
 
  virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
1814
 
  {
1815
 
    return new UFC_Velocity_dof_map_0_0();
1816
 
  }
1817
 
 
1818
 
};
1819
 
 
1820
 
/// This class defines the interface for a local-to-global mapping of
1821
 
/// degrees of freedom (dofs).
1822
 
 
1823
 
class UFC_Velocity_dof_map_0_1: public ufc::dof_map
1824
 
{
1825
 
private:
1826
 
 
1827
 
  unsigned int __global_dimension;
1828
 
 
1829
 
public:
1830
 
 
1831
 
  /// Constructor
1832
 
  UFC_Velocity_dof_map_0_1() : ufc::dof_map()
1833
 
  {
1834
 
    __global_dimension = 0;
1835
 
  }
1836
 
 
1837
 
  /// Destructor
1838
 
  virtual ~UFC_Velocity_dof_map_0_1()
1839
 
  {
1840
 
    // Do nothing
1841
 
  }
1842
 
 
1843
 
  /// Return a string identifying the dof map
1844
 
  virtual const char* signature() const
1845
 
  {
1846
 
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 2)";
1847
 
  }
1848
 
 
1849
 
  /// Return true iff mesh entities of topological dimension d are needed
1850
 
  virtual bool needs_mesh_entities(unsigned int d) const
1851
 
  {
1852
 
    switch ( d )
1853
 
    {
1854
 
    case 0:
1855
 
      return true;
1856
 
      break;
1857
 
    case 1:
1858
 
      return true;
1859
 
      break;
1860
 
    case 2:
1861
 
      return false;
1862
 
      break;
1863
 
    }
1864
 
    return false;
1865
 
  }
1866
 
 
1867
 
  /// Initialize dof map for mesh (return true iff init_cell() is needed)
1868
 
  virtual bool init_mesh(const ufc::mesh& m)
1869
 
  {
1870
 
    __global_dimension = m.num_entities[0] + m.num_entities[1];
1871
 
    return false;
1872
 
  }
1873
 
 
1874
 
  /// Initialize dof map for given cell
1875
 
  virtual void init_cell(const ufc::mesh& m,
1876
 
                         const ufc::cell& c)
1877
 
  {
1878
 
    // Do nothing
1879
 
  }
1880
 
 
1881
 
  /// Finish initialization of dof map for cells
1882
 
  virtual void init_cell_finalize()
1883
 
  {
1884
 
    // Do nothing
1885
 
  }
1886
 
 
1887
 
  /// Return the dimension of the global finite element function space
1888
 
  virtual unsigned int global_dimension() const
1889
 
  {
1890
 
    return __global_dimension;
1891
 
  }
1892
 
 
1893
 
  /// Return the dimension of the local finite element function space
1894
 
  virtual unsigned int local_dimension() const
1895
 
  {
1896
 
    return 6;
1897
 
  }
1898
 
 
1899
 
  // Return the geometric dimension of the coordinates this dof map provides
1900
 
  virtual unsigned int geometric_dimension() const
1901
 
  {
1902
 
    return 2;
1903
 
  }
1904
 
 
1905
 
  /// Return the number of dofs on each cell facet
1906
 
  virtual unsigned int num_facet_dofs() const
1907
 
  {
1908
 
    return 3;
1909
 
  }
1910
 
 
1911
 
  /// Return the number of dofs associated with each cell entity of dimension d
1912
 
  virtual unsigned int num_entity_dofs(unsigned int d) const
1913
 
  {
1914
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1915
 
  }
1916
 
 
1917
 
  /// Tabulate the local-to-global mapping of dofs on a cell
1918
 
  virtual void tabulate_dofs(unsigned int* dofs,
1919
 
                             const ufc::mesh& m,
1920
 
                             const ufc::cell& c) const
1921
 
  {
1922
 
    dofs[0] = c.entity_indices[0][0];
1923
 
    dofs[1] = c.entity_indices[0][1];
1924
 
    dofs[2] = c.entity_indices[0][2];
1925
 
    unsigned int offset = m.num_entities[0];
1926
 
    dofs[3] = offset + c.entity_indices[1][0];
1927
 
    dofs[4] = offset + c.entity_indices[1][1];
1928
 
    dofs[5] = offset + c.entity_indices[1][2];
1929
 
  }
1930
 
 
1931
 
  /// Tabulate the local-to-local mapping from facet dofs to cell dofs
1932
 
  virtual void tabulate_facet_dofs(unsigned int* dofs,
1933
 
                                   unsigned int facet) const
1934
 
  {
1935
 
    switch ( facet )
1936
 
    {
1937
 
    case 0:
1938
 
      dofs[0] = 1;
1939
 
      dofs[1] = 2;
1940
 
      dofs[2] = 3;
1941
 
      break;
1942
 
    case 1:
1943
 
      dofs[0] = 0;
1944
 
      dofs[1] = 2;
1945
 
      dofs[2] = 4;
1946
 
      break;
1947
 
    case 2:
1948
 
      dofs[0] = 0;
1949
 
      dofs[1] = 1;
1950
 
      dofs[2] = 5;
1951
 
      break;
1952
 
    }
1953
 
  }
1954
 
 
1955
 
  /// Tabulate the local-to-local mapping of dofs on entity (d, i)
1956
 
  virtual void tabulate_entity_dofs(unsigned int* dofs,
1957
 
                                    unsigned int d, unsigned int i) const
1958
 
  {
1959
 
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
1960
 
  }
1961
 
 
1962
 
  /// Tabulate the coordinates of all dofs on a cell
1963
 
  virtual void tabulate_coordinates(double** coordinates,
1964
 
                                    const ufc::cell& c) const
1965
 
  {
1966
 
    const double * const * x = c.coordinates;
1967
 
    coordinates[0][0] = x[0][0];
1968
 
    coordinates[0][1] = x[0][1];
1969
 
    coordinates[1][0] = x[1][0];
1970
 
    coordinates[1][1] = x[1][1];
1971
 
    coordinates[2][0] = x[2][0];
1972
 
    coordinates[2][1] = x[2][1];
1973
 
    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
1974
 
    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
1975
 
    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
1976
 
    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
1977
 
    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
1978
 
    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
1979
 
  }
1980
 
 
1981
 
  /// Return the number of sub dof maps (for a mixed element)
1982
 
  virtual unsigned int num_sub_dof_maps() const
1983
 
  {
1984
 
    return 1;
1985
 
  }
1986
 
 
1987
 
  /// Create a new dof_map for sub dof map i (for a mixed element)
1988
 
  virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
1989
 
  {
1990
 
    return new UFC_Velocity_dof_map_0_1();
1991
 
  }
1992
 
 
1993
 
};
1994
 
 
1995
 
/// This class defines the interface for a local-to-global mapping of
1996
 
/// degrees of freedom (dofs).
1997
 
 
1998
 
class UFC_Velocity_dof_map_0: public ufc::dof_map
1999
 
{
2000
 
private:
2001
 
 
2002
 
  unsigned int __global_dimension;
2003
 
 
2004
 
public:
2005
 
 
2006
 
  /// Constructor
2007
 
  UFC_Velocity_dof_map_0() : ufc::dof_map()
2008
 
  {
2009
 
    __global_dimension = 0;
2010
 
  }
2011
 
 
2012
 
  /// Destructor
2013
 
  virtual ~UFC_Velocity_dof_map_0()
 
1648
class velocity_0_dof_map_0_0: public ufc::dof_map
 
1649
{
 
1650
private:
 
1651
 
 
1652
  unsigned int __global_dimension;
 
1653
 
 
1654
public:
 
1655
 
 
1656
  /// Constructor
 
1657
  velocity_0_dof_map_0_0() : ufc::dof_map()
 
1658
  {
 
1659
    __global_dimension = 0;
 
1660
  }
 
1661
 
 
1662
  /// Destructor
 
1663
  virtual ~velocity_0_dof_map_0_0()
 
1664
  {
 
1665
    // Do nothing
 
1666
  }
 
1667
 
 
1668
  /// Return a string identifying the dof map
 
1669
  virtual const char* signature() const
 
1670
  {
 
1671
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 2)";
 
1672
  }
 
1673
 
 
1674
  /// Return true iff mesh entities of topological dimension d are needed
 
1675
  virtual bool needs_mesh_entities(unsigned int d) const
 
1676
  {
 
1677
    switch ( d )
 
1678
    {
 
1679
    case 0:
 
1680
      return true;
 
1681
      break;
 
1682
    case 1:
 
1683
      return true;
 
1684
      break;
 
1685
    case 2:
 
1686
      return false;
 
1687
      break;
 
1688
    }
 
1689
    return false;
 
1690
  }
 
1691
 
 
1692
  /// Initialize dof map for mesh (return true iff init_cell() is needed)
 
1693
  virtual bool init_mesh(const ufc::mesh& m)
 
1694
  {
 
1695
    __global_dimension = m.num_entities[0] + m.num_entities[1];
 
1696
    return false;
 
1697
  }
 
1698
 
 
1699
  /// Initialize dof map for given cell
 
1700
  virtual void init_cell(const ufc::mesh& m,
 
1701
                         const ufc::cell& c)
 
1702
  {
 
1703
    // Do nothing
 
1704
  }
 
1705
 
 
1706
  /// Finish initialization of dof map for cells
 
1707
  virtual void init_cell_finalize()
 
1708
  {
 
1709
    // Do nothing
 
1710
  }
 
1711
 
 
1712
  /// Return the dimension of the global finite element function space
 
1713
  virtual unsigned int global_dimension() const
 
1714
  {
 
1715
    return __global_dimension;
 
1716
  }
 
1717
 
 
1718
  /// Return the dimension of the local finite element function space for a cell
 
1719
  virtual unsigned int local_dimension(const ufc::cell& c) const
 
1720
  {
 
1721
    return 6;
 
1722
  }
 
1723
 
 
1724
  /// Return the maximum dimension of the local finite element function space
 
1725
  virtual unsigned int max_local_dimension() const
 
1726
  {
 
1727
    return 6;
 
1728
  }
 
1729
 
 
1730
  // Return the geometric dimension of the coordinates this dof map provides
 
1731
  virtual unsigned int geometric_dimension() const
 
1732
  {
 
1733
    return 2;
 
1734
  }
 
1735
 
 
1736
  /// Return the number of dofs on each cell facet
 
1737
  virtual unsigned int num_facet_dofs() const
 
1738
  {
 
1739
    return 3;
 
1740
  }
 
1741
 
 
1742
  /// Return the number of dofs associated with each cell entity of dimension d
 
1743
  virtual unsigned int num_entity_dofs(unsigned int d) const
 
1744
  {
 
1745
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
1746
  }
 
1747
 
 
1748
  /// Tabulate the local-to-global mapping of dofs on a cell
 
1749
  virtual void tabulate_dofs(unsigned int* dofs,
 
1750
                             const ufc::mesh& m,
 
1751
                             const ufc::cell& c) const
 
1752
  {
 
1753
    dofs[0] = c.entity_indices[0][0];
 
1754
    dofs[1] = c.entity_indices[0][1];
 
1755
    dofs[2] = c.entity_indices[0][2];
 
1756
    unsigned int offset = m.num_entities[0];
 
1757
    dofs[3] = offset + c.entity_indices[1][0];
 
1758
    dofs[4] = offset + c.entity_indices[1][1];
 
1759
    dofs[5] = offset + c.entity_indices[1][2];
 
1760
  }
 
1761
 
 
1762
  /// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
1763
  virtual void tabulate_facet_dofs(unsigned int* dofs,
 
1764
                                   unsigned int facet) const
 
1765
  {
 
1766
    switch ( facet )
 
1767
    {
 
1768
    case 0:
 
1769
      dofs[0] = 1;
 
1770
      dofs[1] = 2;
 
1771
      dofs[2] = 3;
 
1772
      break;
 
1773
    case 1:
 
1774
      dofs[0] = 0;
 
1775
      dofs[1] = 2;
 
1776
      dofs[2] = 4;
 
1777
      break;
 
1778
    case 2:
 
1779
      dofs[0] = 0;
 
1780
      dofs[1] = 1;
 
1781
      dofs[2] = 5;
 
1782
      break;
 
1783
    }
 
1784
  }
 
1785
 
 
1786
  /// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
1787
  virtual void tabulate_entity_dofs(unsigned int* dofs,
 
1788
                                    unsigned int d, unsigned int i) const
 
1789
  {
 
1790
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
1791
  }
 
1792
 
 
1793
  /// Tabulate the coordinates of all dofs on a cell
 
1794
  virtual void tabulate_coordinates(double** coordinates,
 
1795
                                    const ufc::cell& c) const
 
1796
  {
 
1797
    const double * const * x = c.coordinates;
 
1798
    coordinates[0][0] = x[0][0];
 
1799
    coordinates[0][1] = x[0][1];
 
1800
    coordinates[1][0] = x[1][0];
 
1801
    coordinates[1][1] = x[1][1];
 
1802
    coordinates[2][0] = x[2][0];
 
1803
    coordinates[2][1] = x[2][1];
 
1804
    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
 
1805
    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
 
1806
    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
 
1807
    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
 
1808
    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
 
1809
    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
 
1810
  }
 
1811
 
 
1812
  /// Return the number of sub dof maps (for a mixed element)
 
1813
  virtual unsigned int num_sub_dof_maps() const
 
1814
  {
 
1815
    return 1;
 
1816
  }
 
1817
 
 
1818
  /// Create a new dof_map for sub dof map i (for a mixed element)
 
1819
  virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
 
1820
  {
 
1821
    return new velocity_0_dof_map_0_0();
 
1822
  }
 
1823
 
 
1824
};
 
1825
 
 
1826
/// This class defines the interface for a local-to-global mapping of
 
1827
/// degrees of freedom (dofs).
 
1828
 
 
1829
class velocity_0_dof_map_0_1: public ufc::dof_map
 
1830
{
 
1831
private:
 
1832
 
 
1833
  unsigned int __global_dimension;
 
1834
 
 
1835
public:
 
1836
 
 
1837
  /// Constructor
 
1838
  velocity_0_dof_map_0_1() : ufc::dof_map()
 
1839
  {
 
1840
    __global_dimension = 0;
 
1841
  }
 
1842
 
 
1843
  /// Destructor
 
1844
  virtual ~velocity_0_dof_map_0_1()
 
1845
  {
 
1846
    // Do nothing
 
1847
  }
 
1848
 
 
1849
  /// Return a string identifying the dof map
 
1850
  virtual const char* signature() const
 
1851
  {
 
1852
    return "FFC dof map for FiniteElement('Lagrange', 'triangle', 2)";
 
1853
  }
 
1854
 
 
1855
  /// Return true iff mesh entities of topological dimension d are needed
 
1856
  virtual bool needs_mesh_entities(unsigned int d) const
 
1857
  {
 
1858
    switch ( d )
 
1859
    {
 
1860
    case 0:
 
1861
      return true;
 
1862
      break;
 
1863
    case 1:
 
1864
      return true;
 
1865
      break;
 
1866
    case 2:
 
1867
      return false;
 
1868
      break;
 
1869
    }
 
1870
    return false;
 
1871
  }
 
1872
 
 
1873
  /// Initialize dof map for mesh (return true iff init_cell() is needed)
 
1874
  virtual bool init_mesh(const ufc::mesh& m)
 
1875
  {
 
1876
    __global_dimension = m.num_entities[0] + m.num_entities[1];
 
1877
    return false;
 
1878
  }
 
1879
 
 
1880
  /// Initialize dof map for given cell
 
1881
  virtual void init_cell(const ufc::mesh& m,
 
1882
                         const ufc::cell& c)
 
1883
  {
 
1884
    // Do nothing
 
1885
  }
 
1886
 
 
1887
  /// Finish initialization of dof map for cells
 
1888
  virtual void init_cell_finalize()
 
1889
  {
 
1890
    // Do nothing
 
1891
  }
 
1892
 
 
1893
  /// Return the dimension of the global finite element function space
 
1894
  virtual unsigned int global_dimension() const
 
1895
  {
 
1896
    return __global_dimension;
 
1897
  }
 
1898
 
 
1899
  /// Return the dimension of the local finite element function space for a cell
 
1900
  virtual unsigned int local_dimension(const ufc::cell& c) const
 
1901
  {
 
1902
    return 6;
 
1903
  }
 
1904
 
 
1905
  /// Return the maximum dimension of the local finite element function space
 
1906
  virtual unsigned int max_local_dimension() const
 
1907
  {
 
1908
    return 6;
 
1909
  }
 
1910
 
 
1911
  // Return the geometric dimension of the coordinates this dof map provides
 
1912
  virtual unsigned int geometric_dimension() const
 
1913
  {
 
1914
    return 2;
 
1915
  }
 
1916
 
 
1917
  /// Return the number of dofs on each cell facet
 
1918
  virtual unsigned int num_facet_dofs() const
 
1919
  {
 
1920
    return 3;
 
1921
  }
 
1922
 
 
1923
  /// Return the number of dofs associated with each cell entity of dimension d
 
1924
  virtual unsigned int num_entity_dofs(unsigned int d) const
 
1925
  {
 
1926
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
1927
  }
 
1928
 
 
1929
  /// Tabulate the local-to-global mapping of dofs on a cell
 
1930
  virtual void tabulate_dofs(unsigned int* dofs,
 
1931
                             const ufc::mesh& m,
 
1932
                             const ufc::cell& c) const
 
1933
  {
 
1934
    dofs[0] = c.entity_indices[0][0];
 
1935
    dofs[1] = c.entity_indices[0][1];
 
1936
    dofs[2] = c.entity_indices[0][2];
 
1937
    unsigned int offset = m.num_entities[0];
 
1938
    dofs[3] = offset + c.entity_indices[1][0];
 
1939
    dofs[4] = offset + c.entity_indices[1][1];
 
1940
    dofs[5] = offset + c.entity_indices[1][2];
 
1941
  }
 
1942
 
 
1943
  /// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
1944
  virtual void tabulate_facet_dofs(unsigned int* dofs,
 
1945
                                   unsigned int facet) const
 
1946
  {
 
1947
    switch ( facet )
 
1948
    {
 
1949
    case 0:
 
1950
      dofs[0] = 1;
 
1951
      dofs[1] = 2;
 
1952
      dofs[2] = 3;
 
1953
      break;
 
1954
    case 1:
 
1955
      dofs[0] = 0;
 
1956
      dofs[1] = 2;
 
1957
      dofs[2] = 4;
 
1958
      break;
 
1959
    case 2:
 
1960
      dofs[0] = 0;
 
1961
      dofs[1] = 1;
 
1962
      dofs[2] = 5;
 
1963
      break;
 
1964
    }
 
1965
  }
 
1966
 
 
1967
  /// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
1968
  virtual void tabulate_entity_dofs(unsigned int* dofs,
 
1969
                                    unsigned int d, unsigned int i) const
 
1970
  {
 
1971
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
1972
  }
 
1973
 
 
1974
  /// Tabulate the coordinates of all dofs on a cell
 
1975
  virtual void tabulate_coordinates(double** coordinates,
 
1976
                                    const ufc::cell& c) const
 
1977
  {
 
1978
    const double * const * x = c.coordinates;
 
1979
    coordinates[0][0] = x[0][0];
 
1980
    coordinates[0][1] = x[0][1];
 
1981
    coordinates[1][0] = x[1][0];
 
1982
    coordinates[1][1] = x[1][1];
 
1983
    coordinates[2][0] = x[2][0];
 
1984
    coordinates[2][1] = x[2][1];
 
1985
    coordinates[3][0] = 0.5*x[1][0] + 0.5*x[2][0];
 
1986
    coordinates[3][1] = 0.5*x[1][1] + 0.5*x[2][1];
 
1987
    coordinates[4][0] = 0.5*x[0][0] + 0.5*x[2][0];
 
1988
    coordinates[4][1] = 0.5*x[0][1] + 0.5*x[2][1];
 
1989
    coordinates[5][0] = 0.5*x[0][0] + 0.5*x[1][0];
 
1990
    coordinates[5][1] = 0.5*x[0][1] + 0.5*x[1][1];
 
1991
  }
 
1992
 
 
1993
  /// Return the number of sub dof maps (for a mixed element)
 
1994
  virtual unsigned int num_sub_dof_maps() const
 
1995
  {
 
1996
    return 1;
 
1997
  }
 
1998
 
 
1999
  /// Create a new dof_map for sub dof map i (for a mixed element)
 
2000
  virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
 
2001
  {
 
2002
    return new velocity_0_dof_map_0_1();
 
2003
  }
 
2004
 
 
2005
};
 
2006
 
 
2007
/// This class defines the interface for a local-to-global mapping of
 
2008
/// degrees of freedom (dofs).
 
2009
 
 
2010
class velocity_0_dof_map_0: public ufc::dof_map
 
2011
{
 
2012
private:
 
2013
 
 
2014
  unsigned int __global_dimension;
 
2015
 
 
2016
public:
 
2017
 
 
2018
  /// Constructor
 
2019
  velocity_0_dof_map_0() : ufc::dof_map()
 
2020
  {
 
2021
    __global_dimension = 0;
 
2022
  }
 
2023
 
 
2024
  /// Destructor
 
2025
  virtual ~velocity_0_dof_map_0()
2014
2026
  {
2015
2027
    // Do nothing
2016
2028
  }
2065
2077
    return __global_dimension;
2066
2078
  }
2067
2079
 
2068
 
  /// Return the dimension of the local finite element function space
2069
 
  virtual unsigned int local_dimension() const
 
2080
  /// Return the dimension of the local finite element function space for a cell
 
2081
  virtual unsigned int local_dimension(const ufc::cell& c) const
 
2082
  {
 
2083
    return 12;
 
2084
  }
 
2085
 
 
2086
  /// Return the maximum dimension of the local finite element function space
 
2087
  virtual unsigned int max_local_dimension() const
2070
2088
  {
2071
2089
    return 12;
2072
2090
  }
2194
2212
    switch ( i )
2195
2213
    {
2196
2214
    case 0:
2197
 
      return new UFC_Velocity_dof_map_0_0();
 
2215
      return new velocity_0_dof_map_0_0();
2198
2216
      break;
2199
2217
    case 1:
2200
 
      return new UFC_Velocity_dof_map_0_1();
 
2218
      return new velocity_0_dof_map_0_1();
2201
2219
      break;
2202
2220
    }
2203
2221
    return 0;
2205
2223
 
2206
2224
};
2207
2225
 
 
2226
/// This class defines the interface for the assembly of the global
 
2227
/// tensor corresponding to a form with r + n arguments, that is, a
 
2228
/// mapping
 
2229
///
 
2230
///     a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
 
2231
///
 
2232
/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
 
2233
/// global tensor A is defined by
 
2234
///
 
2235
///     A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
 
2236
///
 
2237
/// where each argument Vj represents the application to the
 
2238
/// sequence of basis functions of Vj and w1, w2, ..., wn are given
 
2239
/// fixed functions (coefficients).
 
2240
 
 
2241
class velocity_form_0: public ufc::form
 
2242
{
 
2243
public:
 
2244
 
 
2245
  /// Constructor
 
2246
  velocity_form_0() : ufc::form()
 
2247
  {
 
2248
    // Do nothing
 
2249
  }
 
2250
 
 
2251
  /// Destructor
 
2252
  virtual ~velocity_form_0()
 
2253
  {
 
2254
    // Do nothing
 
2255
  }
 
2256
 
 
2257
  /// Return a string identifying the form
 
2258
  virtual const char* signature() const
 
2259
  {
 
2260
    return "None";
 
2261
  }
 
2262
 
 
2263
  /// Return the rank of the global tensor (r)
 
2264
  virtual unsigned int rank() const
 
2265
  {
 
2266
    return -1;
 
2267
  }
 
2268
 
 
2269
  /// Return the number of coefficients (n)
 
2270
  virtual unsigned int num_coefficients() const
 
2271
  {
 
2272
    return 0;
 
2273
  }
 
2274
 
 
2275
  /// Return the number of cell integrals
 
2276
  virtual unsigned int num_cell_integrals() const
 
2277
  {
 
2278
    return 0;
 
2279
  }
 
2280
 
 
2281
  /// Return the number of exterior facet integrals
 
2282
  virtual unsigned int num_exterior_facet_integrals() const
 
2283
  {
 
2284
    return 0;
 
2285
  }
 
2286
 
 
2287
  /// Return the number of interior facet integrals
 
2288
  virtual unsigned int num_interior_facet_integrals() const
 
2289
  {
 
2290
    return 0;
 
2291
  }
 
2292
 
 
2293
  /// Create a new finite element for argument function i
 
2294
  virtual ufc::finite_element* create_finite_element(unsigned int i) const
 
2295
  {
 
2296
    return 0;
 
2297
  }
 
2298
 
 
2299
  /// Create a new dof map for argument function i
 
2300
  virtual ufc::dof_map* create_dof_map(unsigned int i) const
 
2301
  {
 
2302
    return 0;
 
2303
  }
 
2304
 
 
2305
  /// Create a new cell integral on sub domain i
 
2306
  virtual ufc::cell_integral* create_cell_integral(unsigned int i) const
 
2307
  {
 
2308
    return 0;
 
2309
  }
 
2310
 
 
2311
  /// Create a new exterior facet integral on sub domain i
 
2312
  virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const
 
2313
  {
 
2314
    return 0;
 
2315
  }
 
2316
 
 
2317
  /// Create a new interior facet integral on sub domain i
 
2318
  virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const
 
2319
  {
 
2320
    return 0;
 
2321
  }
 
2322
 
 
2323
};
 
2324
 
2208
2325
// DOLFIN wrappers
2209
2326
 
2210
 
#include <dolfin/fem/Form.h>
 
2327
// Standard library includes
 
2328
#include <string>
 
2329
 
 
2330
// DOLFIN includes
 
2331
#include <dolfin/common/NoDeleter.h>
2211
2332
#include <dolfin/fem/FiniteElement.h>
2212
2333
#include <dolfin/fem/DofMap.h>
2213
 
#include <dolfin/function/Coefficient.h>
2214
 
#include <dolfin/function/Function.h>
 
2334
#include <dolfin/fem/Form.h>
2215
2335
#include <dolfin/function/FunctionSpace.h>
2216
 
 
2217
 
class VelocityFunctionSpace : public dolfin::FunctionSpace
2218
 
{
2219
 
public:
2220
 
 
2221
 
  VelocityFunctionSpace(const dolfin::Mesh& mesh)
2222
 
    : dolfin::FunctionSpace(boost::shared_ptr<const dolfin::Mesh>(&mesh, dolfin::NoDeleter<const dolfin::Mesh>()),
2223
 
                            boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new UFC_Velocity_finite_element_0()))),
2224
 
                            boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new UFC_Velocity_dof_map_0()), mesh)))
2225
 
  {
2226
 
    // Do nothing
2227
 
  }
2228
 
 
2229
 
};
 
2336
#include <dolfin/function/GenericFunction.h>
 
2337
#include <dolfin/function/CoefficientAssigner.h>
 
2338
 
 
2339
namespace Velocity
 
2340
{
 
2341
 
 
2342
class Form_0_FunctionSpace_0: public dolfin::FunctionSpace
 
2343
{
 
2344
public:
 
2345
 
 
2346
  Form_0_FunctionSpace_0(const dolfin::Mesh& mesh):
 
2347
      dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
 
2348
                            boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new velocity_0_finite_element_0()))),
 
2349
                            boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new velocity_0_dof_map_0()), dolfin::reference_to_no_delete_pointer(mesh))))
 
2350
  {
 
2351
    // Do nothing
 
2352
  }
 
2353
 
 
2354
  Form_0_FunctionSpace_0(dolfin::Mesh& mesh):
 
2355
    dolfin::FunctionSpace(dolfin::reference_to_no_delete_pointer(mesh),
 
2356
                          boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new velocity_0_finite_element_0()))),
 
2357
                          boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new velocity_0_dof_map_0()), dolfin::reference_to_no_delete_pointer(mesh))))
 
2358
  {
 
2359
    // Do nothing
 
2360
  }
 
2361
 
 
2362
  Form_0_FunctionSpace_0(boost::shared_ptr<dolfin::Mesh> mesh):
 
2363
      dolfin::FunctionSpace(mesh,
 
2364
                            boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new velocity_0_finite_element_0()))),
 
2365
                            boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new velocity_0_dof_map_0()), mesh)))
 
2366
  {
 
2367
      // Do nothing
 
2368
  }
 
2369
 
 
2370
  Form_0_FunctionSpace_0(boost::shared_ptr<const dolfin::Mesh> mesh):
 
2371
      dolfin::FunctionSpace(mesh,
 
2372
                            boost::shared_ptr<const dolfin::FiniteElement>(new dolfin::FiniteElement(boost::shared_ptr<ufc::finite_element>(new velocity_0_finite_element_0()))),
 
2373
                            boost::shared_ptr<const dolfin::DofMap>(new dolfin::DofMap(boost::shared_ptr<ufc::dof_map>(new velocity_0_dof_map_0()), mesh)))
 
2374
  {
 
2375
      // Do nothing
 
2376
  }
 
2377
 
 
2378
 
 
2379
  ~Form_0_FunctionSpace_0()
 
2380
  {
 
2381
  }
 
2382
 
 
2383
};
 
2384
 
 
2385
class Form_0: public dolfin::Form
 
2386
{
 
2387
public:
 
2388
 
 
2389
  // Constructor
 
2390
  Form_0(const dolfin::FunctionSpace& V0):
 
2391
    dolfin::Form(1, 0)
 
2392
  {
 
2393
    _function_spaces[0] = reference_to_no_delete_pointer(V0);
 
2394
 
 
2395
    _ufc_form = boost::shared_ptr<const ufc::form>(new velocity_form_0());
 
2396
  }
 
2397
 
 
2398
  // Constructor
 
2399
  Form_0(boost::shared_ptr<const dolfin::FunctionSpace> V0):
 
2400
    dolfin::Form(1, 0)
 
2401
  {
 
2402
    _function_spaces[0] = V0;
 
2403
 
 
2404
    _ufc_form = boost::shared_ptr<const ufc::form>(new velocity_form_0());
 
2405
  }
 
2406
 
 
2407
  // Destructor
 
2408
  ~Form_0()
 
2409
  {}
 
2410
 
 
2411
  /// Return the number of the coefficient with this name
 
2412
  virtual dolfin::uint coefficient_number(const std::string& name) const
 
2413
  {
 
2414
 
 
2415
    dolfin::error("No coefficients.");
 
2416
    return 0;
 
2417
  }
 
2418
 
 
2419
  /// Return the name of the coefficient with this number
 
2420
  virtual std::string coefficient_name(dolfin::uint i) const
 
2421
  {
 
2422
 
 
2423
    dolfin::error("No coefficients.");
 
2424
    return "unnamed";
 
2425
  }
 
2426
 
 
2427
  // Typedefs
 
2428
  typedef Form_0_FunctionSpace_0 TestSpace;
 
2429
 
 
2430
  // Coefficients
 
2431
};
 
2432
 
 
2433
// Class typedefs
 
2434
typedef Form_0 LinearForm;
 
2435
typedef Form_0::TestSpace FunctionSpace;
 
2436
 
 
2437
} // namespace Velocity
2230
2438
 
2231
2439
#endif