~ubuntu-branches/ubuntu/trusty/ffc/trusty

« back to all changes in this revision

Viewing changes to test/regression/reference/tensor/MixedPoisson.h

  • Committer: Bazaar Package Importer
  • Author(s): Johannes Ring
  • Date: 2009-09-25 09:41:39 UTC
  • Revision ID: james.westby@ubuntu.com-20090925094139-nb845p3ffs8j5ike
Tags: upstream-0.7.0
ImportĀ upstreamĀ versionĀ 0.7.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// This code conforms with the UFC specification version 1.0
 
2
// and was automatically generated by FFC version 0.6.2.
 
3
 
 
4
#ifndef __MIXEDPOISSON_H
 
5
#define __MIXEDPOISSON_H
 
6
 
 
7
#include <cmath>
 
8
#include <stdexcept>
 
9
#include <ufc.h>
 
10
 
 
11
/// This class defines the interface for a finite element.
 
12
 
 
13
class mixedpoisson_0_finite_element_0_0: public ufc::finite_element
 
14
{
 
15
public:
 
16
 
 
17
  /// Constructor
 
18
  mixedpoisson_0_finite_element_0_0() : ufc::finite_element()
 
19
  {
 
20
    // Do nothing
 
21
  }
 
22
 
 
23
  /// Destructor
 
24
  virtual ~mixedpoisson_0_finite_element_0_0()
 
25
  {
 
26
    // Do nothing
 
27
  }
 
28
 
 
29
  /// Return a string identifying the finite element
 
30
  virtual const char* signature() const
 
31
  {
 
32
    return "FiniteElement('Brezzi-Douglas-Marini', 'triangle', 1)";
 
33
  }
 
34
 
 
35
  /// Return the cell shape
 
36
  virtual ufc::shape cell_shape() const
 
37
  {
 
38
    return ufc::triangle;
 
39
  }
 
40
 
 
41
  /// Return the dimension of the finite element function space
 
42
  virtual unsigned int space_dimension() const
 
43
  {
 
44
    return 6;
 
45
  }
 
46
 
 
47
  /// Return the rank of the value space
 
48
  virtual unsigned int value_rank() const
 
49
  {
 
50
    return 1;
 
51
  }
 
52
 
 
53
  /// Return the dimension of the value space for axis i
 
54
  virtual unsigned int value_dimension(unsigned int i) const
 
55
  {
 
56
    return 2;
 
57
  }
 
58
 
 
59
  /// Evaluate basis function i at given point in cell
 
60
  virtual void evaluate_basis(unsigned int i,
 
61
                              double* values,
 
62
                              const double* coordinates,
 
63
                              const ufc::cell& c) const
 
64
  {
 
65
    // Extract vertex coordinates
 
66
    const double * const * element_coordinates = c.coordinates;
 
67
    
 
68
    // Compute Jacobian of affine map from reference cell
 
69
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
70
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
71
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
72
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
73
    
 
74
    // Compute determinant of Jacobian
 
75
    const double detJ = J_00*J_11 - J_01*J_10;
 
76
    
 
77
    // Compute inverse of Jacobian
 
78
    
 
79
    // Get coordinates and map to the reference (UFC) element
 
80
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
81
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
82
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
83
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
84
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
85
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
86
    
 
87
    // Map coordinates to the reference square
 
88
    if (std::abs(y - 1.0) < 1e-08)
 
89
      x = -1.0;
 
90
    else
 
91
      x = 2.0 *x/(1.0 - y) - 1.0;
 
92
    y = 2.0*y - 1.0;
 
93
    
 
94
    // Reset values
 
95
    values[0] = 0;
 
96
    values[1] = 0;
 
97
    
 
98
    // Map degree of freedom to element degree of freedom
 
99
    const unsigned int dof = i;
 
100
    
 
101
    // Generate scalings
 
102
    const double scalings_y_0 = 1;
 
103
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
104
    
 
105
    // Compute psitilde_a
 
106
    const double psitilde_a_0 = 1;
 
107
    const double psitilde_a_1 = x;
 
108
    
 
109
    // Compute psitilde_bs
 
110
    const double psitilde_bs_0_0 = 1;
 
111
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
112
    const double psitilde_bs_1_0 = 1;
 
113
    
 
114
    // Compute basisvalues
 
115
    const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
116
    const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
117
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
118
    
 
119
    // Table(s) of coefficients
 
120
    static const double coefficients0[6][3] = \
 
121
    {{0.942809042, 0.577350269, -0.333333333},
 
122
    {-0.471404521, -0.288675135, 0.166666667},
 
123
    {0.471404521, -0.577350269, -0.666666667},
 
124
    {0.471404521, 0.288675135, 0.833333333},
 
125
    {-0.471404521, -0.288675135, 0.166666667},
 
126
    {0.942809042, 0.577350269, -0.333333333}};
 
127
    
 
128
    static const double coefficients1[6][3] = \
 
129
    {{-0.471404521, 0, -0.333333333},
 
130
    {0.942809042, 0, 0.666666667},
 
131
    {0.471404521, 0, 0.333333333},
 
132
    {-0.942809042, 0, -0.666666667},
 
133
    {-0.471404521, 0.866025404, 0.166666667},
 
134
    {-0.471404521, -0.866025404, 0.166666667}};
 
135
    
 
136
    // Extract relevant coefficients
 
137
    const double coeff0_0 = coefficients0[dof][0];
 
138
    const double coeff0_1 = coefficients0[dof][1];
 
139
    const double coeff0_2 = coefficients0[dof][2];
 
140
    const double coeff1_0 = coefficients1[dof][0];
 
141
    const double coeff1_1 = coefficients1[dof][1];
 
142
    const double coeff1_2 = coefficients1[dof][2];
 
143
    
 
144
    // Compute value(s)
 
145
    const double tmp0_0 = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
146
    const double tmp0_1 = coeff1_0*basisvalue0 + coeff1_1*basisvalue1 + coeff1_2*basisvalue2;
 
147
    // Using contravariant Piola transform to map values back to the physical element
 
148
    values[0] = (1.0/detJ)*(J_00*tmp0_0 + J_01*tmp0_1);
 
149
    values[1] = (1.0/detJ)*(J_10*tmp0_0 + J_11*tmp0_1);
 
150
  }
 
151
 
 
152
  /// Evaluate all basis functions at given point in cell
 
153
  virtual void evaluate_basis_all(double* values,
 
154
                                  const double* coordinates,
 
155
                                  const ufc::cell& c) const
 
156
  {
 
157
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
158
  }
 
159
 
 
160
  /// Evaluate order n derivatives of basis function i at given point in cell
 
161
  virtual void evaluate_basis_derivatives(unsigned int i,
 
162
                                          unsigned int n,
 
163
                                          double* values,
 
164
                                          const double* coordinates,
 
165
                                          const ufc::cell& c) const
 
166
  {
 
167
    // Extract vertex coordinates
 
168
    const double * const * element_coordinates = c.coordinates;
 
169
    
 
170
    // Compute Jacobian of affine map from reference cell
 
171
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
172
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
173
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
174
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
175
    
 
176
    // Compute determinant of Jacobian
 
177
    const double detJ = J_00*J_11 - J_01*J_10;
 
178
    
 
179
    // Compute inverse of Jacobian
 
180
    
 
181
    // Get coordinates and map to the reference (UFC) element
 
182
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
183
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
184
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
185
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
186
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
187
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
188
    
 
189
    // Map coordinates to the reference square
 
190
    if (std::abs(y - 1.0) < 1e-08)
 
191
      x = -1.0;
 
192
    else
 
193
      x = 2.0 *x/(1.0 - y) - 1.0;
 
194
    y = 2.0*y - 1.0;
 
195
    
 
196
    // Compute number of derivatives
 
197
    unsigned int num_derivatives = 1;
 
198
    
 
199
    for (unsigned int j = 0; j < n; j++)
 
200
      num_derivatives *= 2;
 
201
    
 
202
    
 
203
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
204
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
205
    
 
206
    for (unsigned int j = 0; j < num_derivatives; j++)
 
207
    {
 
208
      combinations[j] = new unsigned int [n];
 
209
      for (unsigned int k = 0; k < n; k++)
 
210
        combinations[j][k] = 0;
 
211
    }
 
212
    
 
213
    // Generate combinations of derivatives
 
214
    for (unsigned int row = 1; row < num_derivatives; row++)
 
215
    {
 
216
      for (unsigned int num = 0; num < row; num++)
 
217
      {
 
218
        for (unsigned int col = n-1; col+1 > 0; col--)
 
219
        {
 
220
          if (combinations[row][col] + 1 > 1)
 
221
            combinations[row][col] = 0;
 
222
          else
 
223
          {
 
224
            combinations[row][col] += 1;
 
225
            break;
 
226
          }
 
227
        }
 
228
      }
 
229
    }
 
230
    
 
231
    // Compute inverse of Jacobian
 
232
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
233
    
 
234
    // Declare transformation matrix
 
235
    // Declare pointer to two dimensional array and initialise
 
236
    double **transform = new double *[num_derivatives];
 
237
    
 
238
    for (unsigned int j = 0; j < num_derivatives; j++)
 
239
    {
 
240
      transform[j] = new double [num_derivatives];
 
241
      for (unsigned int k = 0; k < num_derivatives; k++)
 
242
        transform[j][k] = 1;
 
243
    }
 
244
    
 
245
    // Construct transformation matrix
 
246
    for (unsigned int row = 0; row < num_derivatives; row++)
 
247
    {
 
248
      for (unsigned int col = 0; col < num_derivatives; col++)
 
249
      {
 
250
        for (unsigned int k = 0; k < n; k++)
 
251
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
252
      }
 
253
    }
 
254
    
 
255
    // Reset values
 
256
    for (unsigned int j = 0; j < 2*num_derivatives; j++)
 
257
      values[j] = 0;
 
258
    
 
259
    // Map degree of freedom to element degree of freedom
 
260
    const unsigned int dof = i;
 
261
    
 
262
    // Generate scalings
 
263
    const double scalings_y_0 = 1;
 
264
    const double scalings_y_1 = scalings_y_0*(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
    
 
270
    // Compute psitilde_bs
 
271
    const double psitilde_bs_0_0 = 1;
 
272
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
273
    const double psitilde_bs_1_0 = 1;
 
274
    
 
275
    // Compute basisvalues
 
276
    const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
277
    const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
278
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
279
    
 
280
    // Table(s) of coefficients
 
281
    static const double coefficients0[6][3] = \
 
282
    {{0.942809042, 0.577350269, -0.333333333},
 
283
    {-0.471404521, -0.288675135, 0.166666667},
 
284
    {0.471404521, -0.577350269, -0.666666667},
 
285
    {0.471404521, 0.288675135, 0.833333333},
 
286
    {-0.471404521, -0.288675135, 0.166666667},
 
287
    {0.942809042, 0.577350269, -0.333333333}};
 
288
    
 
289
    static const double coefficients1[6][3] = \
 
290
    {{-0.471404521, 0, -0.333333333},
 
291
    {0.942809042, 0, 0.666666667},
 
292
    {0.471404521, 0, 0.333333333},
 
293
    {-0.942809042, 0, -0.666666667},
 
294
    {-0.471404521, 0.866025404, 0.166666667},
 
295
    {-0.471404521, -0.866025404, 0.166666667}};
 
296
    
 
297
    // Interesting (new) part
 
298
    // Tables of derivatives of the polynomial base (transpose)
 
299
    static const double dmats0[3][3] = \
 
300
    {{0, 0, 0},
 
301
    {4.89897949, 0, 0},
 
302
    {0, 0, 0}};
 
303
    
 
304
    static const double dmats1[3][3] = \
 
305
    {{0, 0, 0},
 
306
    {2.44948974, 0, 0},
 
307
    {4.24264069, 0, 0}};
 
308
    
 
309
    // Compute reference derivatives
 
310
    // Declare pointer to array of derivatives on FIAT element
 
311
    double *derivatives = new double [2*num_derivatives];
 
312
    
 
313
    // Declare coefficients
 
314
    double coeff0_0 = 0;
 
315
    double coeff0_1 = 0;
 
316
    double coeff0_2 = 0;
 
317
    double coeff1_0 = 0;
 
318
    double coeff1_1 = 0;
 
319
    double coeff1_2 = 0;
 
320
    
 
321
    // Declare new coefficients
 
322
    double new_coeff0_0 = 0;
 
323
    double new_coeff0_1 = 0;
 
324
    double new_coeff0_2 = 0;
 
325
    double new_coeff1_0 = 0;
 
326
    double new_coeff1_1 = 0;
 
327
    double new_coeff1_2 = 0;
 
328
    
 
329
    // Loop possible derivatives
 
330
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
331
    {
 
332
      // Get values from coefficients array
 
333
      new_coeff0_0 = coefficients0[dof][0];
 
334
      new_coeff0_1 = coefficients0[dof][1];
 
335
      new_coeff0_2 = coefficients0[dof][2];
 
336
      new_coeff1_0 = coefficients1[dof][0];
 
337
      new_coeff1_1 = coefficients1[dof][1];
 
338
      new_coeff1_2 = coefficients1[dof][2];
 
339
    
 
340
      // Loop derivative order
 
341
      for (unsigned int j = 0; j < n; j++)
 
342
      {
 
343
        // Update old coefficients
 
344
        coeff0_0 = new_coeff0_0;
 
345
        coeff0_1 = new_coeff0_1;
 
346
        coeff0_2 = new_coeff0_2;
 
347
        coeff1_0 = new_coeff1_0;
 
348
        coeff1_1 = new_coeff1_1;
 
349
        coeff1_2 = new_coeff1_2;
 
350
    
 
351
        if(combinations[deriv_num][j] == 0)
 
352
        {
 
353
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
354
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
355
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
356
          new_coeff1_0 = coeff1_0*dmats0[0][0] + coeff1_1*dmats0[1][0] + coeff1_2*dmats0[2][0];
 
357
          new_coeff1_1 = coeff1_0*dmats0[0][1] + coeff1_1*dmats0[1][1] + coeff1_2*dmats0[2][1];
 
358
          new_coeff1_2 = coeff1_0*dmats0[0][2] + coeff1_1*dmats0[1][2] + coeff1_2*dmats0[2][2];
 
359
        }
 
360
        if(combinations[deriv_num][j] == 1)
 
361
        {
 
362
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
363
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
364
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
365
          new_coeff1_0 = coeff1_0*dmats1[0][0] + coeff1_1*dmats1[1][0] + coeff1_2*dmats1[2][0];
 
366
          new_coeff1_1 = coeff1_0*dmats1[0][1] + coeff1_1*dmats1[1][1] + coeff1_2*dmats1[2][1];
 
367
          new_coeff1_2 = coeff1_0*dmats1[0][2] + coeff1_1*dmats1[1][2] + coeff1_2*dmats1[2][2];
 
368
        }
 
369
    
 
370
      }
 
371
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
372
      // Correct values by the contravariant Piola transform
 
373
      const double tmp0_0 = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
374
      const double tmp0_1 = new_coeff1_0*basisvalue0 + new_coeff1_1*basisvalue1 + new_coeff1_2*basisvalue2;
 
375
      derivatives[deriv_num] = (1.0/detJ)*(J_00*tmp0_0 + J_01*tmp0_1);
 
376
      derivatives[num_derivatives + deriv_num] = (1.0/detJ)*(J_10*tmp0_0 + J_11*tmp0_1);
 
377
    }
 
378
    
 
379
    // Transform derivatives back to physical element
 
380
    for (unsigned int row = 0; row < num_derivatives; row++)
 
381
    {
 
382
      for (unsigned int col = 0; col < num_derivatives; col++)
 
383
      {
 
384
        values[row] += transform[row][col]*derivatives[col];
 
385
        values[num_derivatives + row] += transform[row][col]*derivatives[num_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.666666667, 0.333333333}}, {{0.333333333, 0.666666667}}, {{0, 0.333333333}}, {{0, 0.666666667}}, {{0.333333333, 0}}, {{0.666666667, 0}}};
 
418
    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
 
419
    static const double D[6][1][2] = {{{1, 1}}, {{1, 1}}, {{1, 0}}, {{1, 0}}, {{0, -1}}, {{0, -1}}};
 
420
    
 
421
    // Extract vertex coordinates
 
422
    const double * const * x = c.coordinates;
 
423
    
 
424
    // Compute Jacobian of affine map from reference cell
 
425
    const double J_00 = x[1][0] - x[0][0];
 
426
    const double J_01 = x[2][0] - x[0][0];
 
427
    const double J_10 = x[1][1] - x[0][1];
 
428
    const double J_11 = x[2][1] - x[0][1];
 
429
    
 
430
    // Compute determinant of Jacobian
 
431
    double detJ = J_00*J_11 - J_01*J_10;
 
432
    
 
433
    // Compute inverse of Jacobian
 
434
    const double Jinv_00 =  J_11 / detJ;
 
435
    const double Jinv_01 = -J_01 / detJ;
 
436
    const double Jinv_10 = -J_10 / detJ;
 
437
    const double Jinv_11 =  J_00 / detJ;
 
438
    
 
439
    double copyofvalues[2];
 
440
    double result = 0.0;
 
441
    // Iterate over the points:
 
442
    // Evaluate basis functions for affine mapping
 
443
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
444
    const double w1 = X[i][0][0];
 
445
    const double w2 = X[i][0][1];
 
446
    
 
447
    // Compute affine mapping y = F(X)
 
448
    double y[2];
 
449
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
450
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
451
    
 
452
    // Evaluate function at physical points
 
453
    double values[2];
 
454
    f.evaluate(values, y, c);
 
455
    
 
456
    // Map function values using appropriate mapping
 
457
    // Copy old values:
 
458
    copyofvalues[0] = values[0];
 
459
    copyofvalues[1] = values[1];
 
460
    // Do the inverse of div piola 
 
461
    values[0] = detJ*(Jinv_00*copyofvalues[0]+Jinv_01*copyofvalues[1]);
 
462
    values[1] = detJ*(Jinv_10*copyofvalues[0]+Jinv_11*copyofvalues[1]);
 
463
    
 
464
    // Note that we do not map the weights (yet).
 
465
    
 
466
    // Take directional components
 
467
    for(int k = 0; k < 2; k++)
 
468
      result += values[k]*D[i][0][k];
 
469
    // Multiply by weights
 
470
    result *= W[i][0];
 
471
    
 
472
    return result;
 
473
  }
 
474
 
 
475
  /// Evaluate linear functionals for all dofs on the function f
 
476
  virtual void evaluate_dofs(double* values,
 
477
                             const ufc::function& f,
 
478
                             const ufc::cell& c) const
 
479
  {
 
480
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
481
  }
 
482
 
 
483
  /// Interpolate vertex values from dof values
 
484
  virtual void interpolate_vertex_values(double* vertex_values,
 
485
                                         const double* dof_values,
 
486
                                         const ufc::cell& c) const
 
487
  {
 
488
    // Extract vertex coordinates
 
489
    const double * const * x = c.coordinates;
 
490
    
 
491
    // Compute Jacobian of affine map from reference cell
 
492
    const double J_00 = x[1][0] - x[0][0];
 
493
    const double J_01 = x[2][0] - x[0][0];
 
494
    const double J_10 = x[1][1] - x[0][1];
 
495
    const double J_11 = x[2][1] - x[0][1];
 
496
    
 
497
    // Compute determinant of Jacobian
 
498
    double detJ = J_00*J_11 - J_01*J_10;
 
499
    
 
500
    // Compute inverse of Jacobian
 
501
    // Evaluate at vertices and use Piola mapping
 
502
    vertex_values[0] = (1.0/detJ)*(dof_values[2]*2*J_00 + dof_values[3]*J_00 + dof_values[4]*(-2*J_01) + dof_values[5]*J_01);
 
503
    vertex_values[2] = (1.0/detJ)*(dof_values[0]*2*J_00 + dof_values[1]*J_00 + dof_values[4]*(J_00 + J_01) + dof_values[5]*(2*J_00 - 2*J_01));
 
504
    vertex_values[4] = (1.0/detJ)*(dof_values[0]*J_01 + dof_values[1]*2*J_01 + dof_values[2]*(J_00 + J_01) + dof_values[3]*(2*J_00 - 2*J_01));
 
505
    vertex_values[1] = (1.0/detJ)*(dof_values[2]*2*J_10 + dof_values[3]*J_10 + dof_values[4]*(-2*J_11) + dof_values[5]*J_11);
 
506
    vertex_values[3] = (1.0/detJ)*(dof_values[0]*2*J_10 + dof_values[1]*J_10 + dof_values[4]*(J_10 + J_11) + dof_values[5]*(2*J_10 - 2*J_11));
 
507
    vertex_values[5] = (1.0/detJ)*(dof_values[0]*J_11 + dof_values[1]*2*J_11 + dof_values[2]*(J_10 + J_11) + dof_values[3]*(2*J_10 - 2*J_11));
 
508
  }
 
509
 
 
510
  /// Return the number of sub elements (for a mixed element)
 
511
  virtual unsigned int num_sub_elements() const
 
512
  {
 
513
    return 1;
 
514
  }
 
515
 
 
516
  /// Create a new finite element for sub element i (for a mixed element)
 
517
  virtual ufc::finite_element* create_sub_element(unsigned int i) const
 
518
  {
 
519
    return new mixedpoisson_0_finite_element_0_0();
 
520
  }
 
521
 
 
522
};
 
523
 
 
524
/// This class defines the interface for a finite element.
 
525
 
 
526
class mixedpoisson_0_finite_element_0_1: public ufc::finite_element
 
527
{
 
528
public:
 
529
 
 
530
  /// Constructor
 
531
  mixedpoisson_0_finite_element_0_1() : ufc::finite_element()
 
532
  {
 
533
    // Do nothing
 
534
  }
 
535
 
 
536
  /// Destructor
 
537
  virtual ~mixedpoisson_0_finite_element_0_1()
 
538
  {
 
539
    // Do nothing
 
540
  }
 
541
 
 
542
  /// Return a string identifying the finite element
 
543
  virtual const char* signature() const
 
544
  {
 
545
    return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
 
546
  }
 
547
 
 
548
  /// Return the cell shape
 
549
  virtual ufc::shape cell_shape() const
 
550
  {
 
551
    return ufc::triangle;
 
552
  }
 
553
 
 
554
  /// Return the dimension of the finite element function space
 
555
  virtual unsigned int space_dimension() const
 
556
  {
 
557
    return 1;
 
558
  }
 
559
 
 
560
  /// Return the rank of the value space
 
561
  virtual unsigned int value_rank() const
 
562
  {
 
563
    return 0;
 
564
  }
 
565
 
 
566
  /// Return the dimension of the value space for axis i
 
567
  virtual unsigned int value_dimension(unsigned int i) const
 
568
  {
 
569
    return 1;
 
570
  }
 
571
 
 
572
  /// Evaluate basis function i at given point in cell
 
573
  virtual void evaluate_basis(unsigned int i,
 
574
                              double* values,
 
575
                              const double* coordinates,
 
576
                              const ufc::cell& c) const
 
577
  {
 
578
    // Extract vertex coordinates
 
579
    const double * const * element_coordinates = c.coordinates;
 
580
    
 
581
    // Compute Jacobian of affine map from reference cell
 
582
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
583
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
584
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
585
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
586
    
 
587
    // Compute determinant of Jacobian
 
588
    const double detJ = J_00*J_11 - J_01*J_10;
 
589
    
 
590
    // Compute inverse of Jacobian
 
591
    
 
592
    // Get coordinates and map to the reference (UFC) element
 
593
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
594
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
595
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
596
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
597
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
598
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
599
    
 
600
    // Map coordinates to the reference square
 
601
    if (std::abs(y - 1.0) < 1e-08)
 
602
      x = -1.0;
 
603
    else
 
604
      x = 2.0 *x/(1.0 - y) - 1.0;
 
605
    y = 2.0*y - 1.0;
 
606
    
 
607
    // Reset values
 
608
    *values = 0;
 
609
    
 
610
    // Map degree of freedom to element degree of freedom
 
611
    const unsigned int dof = i;
 
612
    
 
613
    // Generate scalings
 
614
    const double scalings_y_0 = 1;
 
615
    
 
616
    // Compute psitilde_a
 
617
    const double psitilde_a_0 = 1;
 
618
    
 
619
    // Compute psitilde_bs
 
620
    const double psitilde_bs_0_0 = 1;
 
621
    
 
622
    // Compute basisvalues
 
623
    const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
624
    
 
625
    // Table(s) of coefficients
 
626
    static const double coefficients0[1][1] = \
 
627
    {{1.41421356}};
 
628
    
 
629
    // Extract relevant coefficients
 
630
    const double coeff0_0 = coefficients0[dof][0];
 
631
    
 
632
    // Compute value(s)
 
633
    *values = coeff0_0*basisvalue0;
 
634
  }
 
635
 
 
636
  /// Evaluate all basis functions at given point in cell
 
637
  virtual void evaluate_basis_all(double* values,
 
638
                                  const double* coordinates,
 
639
                                  const ufc::cell& c) const
 
640
  {
 
641
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
642
  }
 
643
 
 
644
  /// Evaluate order n derivatives of basis function i at given point in cell
 
645
  virtual void evaluate_basis_derivatives(unsigned int i,
 
646
                                          unsigned int n,
 
647
                                          double* values,
 
648
                                          const double* coordinates,
 
649
                                          const ufc::cell& c) const
 
650
  {
 
651
    // Extract vertex coordinates
 
652
    const double * const * element_coordinates = c.coordinates;
 
653
    
 
654
    // Compute Jacobian of affine map from reference cell
 
655
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
656
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
657
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
658
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
659
    
 
660
    // Compute determinant of Jacobian
 
661
    const double detJ = J_00*J_11 - J_01*J_10;
 
662
    
 
663
    // Compute inverse of Jacobian
 
664
    
 
665
    // Get coordinates and map to the reference (UFC) element
 
666
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
667
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
668
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
669
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
670
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
671
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
672
    
 
673
    // Map coordinates to the reference square
 
674
    if (std::abs(y - 1.0) < 1e-08)
 
675
      x = -1.0;
 
676
    else
 
677
      x = 2.0 *x/(1.0 - y) - 1.0;
 
678
    y = 2.0*y - 1.0;
 
679
    
 
680
    // Compute number of derivatives
 
681
    unsigned int num_derivatives = 1;
 
682
    
 
683
    for (unsigned int j = 0; j < n; j++)
 
684
      num_derivatives *= 2;
 
685
    
 
686
    
 
687
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
688
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
689
    
 
690
    for (unsigned int j = 0; j < num_derivatives; j++)
 
691
    {
 
692
      combinations[j] = new unsigned int [n];
 
693
      for (unsigned int k = 0; k < n; k++)
 
694
        combinations[j][k] = 0;
 
695
    }
 
696
    
 
697
    // Generate combinations of derivatives
 
698
    for (unsigned int row = 1; row < num_derivatives; row++)
 
699
    {
 
700
      for (unsigned int num = 0; num < row; num++)
 
701
      {
 
702
        for (unsigned int col = n-1; col+1 > 0; col--)
 
703
        {
 
704
          if (combinations[row][col] + 1 > 1)
 
705
            combinations[row][col] = 0;
 
706
          else
 
707
          {
 
708
            combinations[row][col] += 1;
 
709
            break;
 
710
          }
 
711
        }
 
712
      }
 
713
    }
 
714
    
 
715
    // Compute inverse of Jacobian
 
716
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
717
    
 
718
    // Declare transformation matrix
 
719
    // Declare pointer to two dimensional array and initialise
 
720
    double **transform = new double *[num_derivatives];
 
721
    
 
722
    for (unsigned int j = 0; j < num_derivatives; j++)
 
723
    {
 
724
      transform[j] = new double [num_derivatives];
 
725
      for (unsigned int k = 0; k < num_derivatives; k++)
 
726
        transform[j][k] = 1;
 
727
    }
 
728
    
 
729
    // Construct transformation matrix
 
730
    for (unsigned int row = 0; row < num_derivatives; row++)
 
731
    {
 
732
      for (unsigned int col = 0; col < num_derivatives; col++)
 
733
      {
 
734
        for (unsigned int k = 0; k < n; k++)
 
735
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
736
      }
 
737
    }
 
738
    
 
739
    // Reset values
 
740
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
 
741
      values[j] = 0;
 
742
    
 
743
    // Map degree of freedom to element degree of freedom
 
744
    const unsigned int dof = i;
 
745
    
 
746
    // Generate scalings
 
747
    const double scalings_y_0 = 1;
 
748
    
 
749
    // Compute psitilde_a
 
750
    const double psitilde_a_0 = 1;
 
751
    
 
752
    // Compute psitilde_bs
 
753
    const double psitilde_bs_0_0 = 1;
 
754
    
 
755
    // Compute basisvalues
 
756
    const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
757
    
 
758
    // Table(s) of coefficients
 
759
    static const double coefficients0[1][1] = \
 
760
    {{1.41421356}};
 
761
    
 
762
    // Interesting (new) part
 
763
    // Tables of derivatives of the polynomial base (transpose)
 
764
    static const double dmats0[1][1] = \
 
765
    {{0}};
 
766
    
 
767
    static const double dmats1[1][1] = \
 
768
    {{0}};
 
769
    
 
770
    // Compute reference derivatives
 
771
    // Declare pointer to array of derivatives on FIAT element
 
772
    double *derivatives = new double [num_derivatives];
 
773
    
 
774
    // Declare coefficients
 
775
    double coeff0_0 = 0;
 
776
    
 
777
    // Declare new coefficients
 
778
    double new_coeff0_0 = 0;
 
779
    
 
780
    // Loop possible derivatives
 
781
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
782
    {
 
783
      // Get values from coefficients array
 
784
      new_coeff0_0 = coefficients0[dof][0];
 
785
    
 
786
      // Loop derivative order
 
787
      for (unsigned int j = 0; j < n; j++)
 
788
      {
 
789
        // Update old coefficients
 
790
        coeff0_0 = new_coeff0_0;
 
791
    
 
792
        if(combinations[deriv_num][j] == 0)
 
793
        {
 
794
          new_coeff0_0 = coeff0_0*dmats0[0][0];
 
795
        }
 
796
        if(combinations[deriv_num][j] == 1)
 
797
        {
 
798
          new_coeff0_0 = coeff0_0*dmats1[0][0];
 
799
        }
 
800
    
 
801
      }
 
802
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
803
      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
 
804
    }
 
805
    
 
806
    // Transform derivatives back to physical element
 
807
    for (unsigned int row = 0; row < num_derivatives; row++)
 
808
    {
 
809
      for (unsigned int col = 0; col < num_derivatives; col++)
 
810
      {
 
811
        values[row] += transform[row][col]*derivatives[col];
 
812
      }
 
813
    }
 
814
    // Delete pointer to array of derivatives on FIAT element
 
815
    delete [] derivatives;
 
816
    
 
817
    // Delete pointer to array of combinations of derivatives and transform
 
818
    for (unsigned int row = 0; row < num_derivatives; row++)
 
819
    {
 
820
      delete [] combinations[row];
 
821
      delete [] transform[row];
 
822
    }
 
823
    
 
824
    delete [] combinations;
 
825
    delete [] transform;
 
826
  }
 
827
 
 
828
  /// Evaluate order n derivatives of all basis functions at given point in cell
 
829
  virtual void evaluate_basis_derivatives_all(unsigned int n,
 
830
                                              double* values,
 
831
                                              const double* coordinates,
 
832
                                              const ufc::cell& c) const
 
833
  {
 
834
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
835
  }
 
836
 
 
837
  /// Evaluate linear functional for dof i on the function f
 
838
  virtual double evaluate_dof(unsigned int i,
 
839
                              const ufc::function& f,
 
840
                              const ufc::cell& c) const
 
841
  {
 
842
    // The reference points, direction and weights:
 
843
    static const double X[1][1][2] = {{{0.333333333, 0.333333333}}};
 
844
    static const double W[1][1] = {{1}};
 
845
    static const double D[1][1][1] = {{{1}}};
 
846
    
 
847
    const double * const * x = c.coordinates;
 
848
    double result = 0.0;
 
849
    // Iterate over the points:
 
850
    // Evaluate basis functions for affine mapping
 
851
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
852
    const double w1 = X[i][0][0];
 
853
    const double w2 = X[i][0][1];
 
854
    
 
855
    // Compute affine mapping y = F(X)
 
856
    double y[2];
 
857
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
858
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
859
    
 
860
    // Evaluate function at physical points
 
861
    double values[1];
 
862
    f.evaluate(values, y, c);
 
863
    
 
864
    // Map function values using appropriate mapping
 
865
    // Affine map: Do nothing
 
866
    
 
867
    // Note that we do not map the weights (yet).
 
868
    
 
869
    // Take directional components
 
870
    for(int k = 0; k < 1; k++)
 
871
      result += values[k]*D[i][0][k];
 
872
    // Multiply by weights
 
873
    result *= W[i][0];
 
874
    
 
875
    return result;
 
876
  }
 
877
 
 
878
  /// Evaluate linear functionals for all dofs on the function f
 
879
  virtual void evaluate_dofs(double* values,
 
880
                             const ufc::function& f,
 
881
                             const ufc::cell& c) const
 
882
  {
 
883
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
884
  }
 
885
 
 
886
  /// Interpolate vertex values from dof values
 
887
  virtual void interpolate_vertex_values(double* vertex_values,
 
888
                                         const double* dof_values,
 
889
                                         const ufc::cell& c) const
 
890
  {
 
891
    // Evaluate at vertices and use affine mapping
 
892
    vertex_values[0] = dof_values[0];
 
893
    vertex_values[1] = dof_values[0];
 
894
    vertex_values[2] = dof_values[0];
 
895
  }
 
896
 
 
897
  /// Return the number of sub elements (for a mixed element)
 
898
  virtual unsigned int num_sub_elements() const
 
899
  {
 
900
    return 1;
 
901
  }
 
902
 
 
903
  /// Create a new finite element for sub element i (for a mixed element)
 
904
  virtual ufc::finite_element* create_sub_element(unsigned int i) const
 
905
  {
 
906
    return new mixedpoisson_0_finite_element_0_1();
 
907
  }
 
908
 
 
909
};
 
910
 
 
911
/// This class defines the interface for a finite element.
 
912
 
 
913
class mixedpoisson_0_finite_element_0: public ufc::finite_element
 
914
{
 
915
public:
 
916
 
 
917
  /// Constructor
 
918
  mixedpoisson_0_finite_element_0() : ufc::finite_element()
 
919
  {
 
920
    // Do nothing
 
921
  }
 
922
 
 
923
  /// Destructor
 
924
  virtual ~mixedpoisson_0_finite_element_0()
 
925
  {
 
926
    // Do nothing
 
927
  }
 
928
 
 
929
  /// Return a string identifying the finite element
 
930
  virtual const char* signature() const
 
931
  {
 
932
    return "MixedElement([FiniteElement('Brezzi-Douglas-Marini', 'triangle', 1), FiniteElement('Discontinuous Lagrange', 'triangle', 0)])";
 
933
  }
 
934
 
 
935
  /// Return the cell shape
 
936
  virtual ufc::shape cell_shape() const
 
937
  {
 
938
    return ufc::triangle;
 
939
  }
 
940
 
 
941
  /// Return the dimension of the finite element function space
 
942
  virtual unsigned int space_dimension() const
 
943
  {
 
944
    return 7;
 
945
  }
 
946
 
 
947
  /// Return the rank of the value space
 
948
  virtual unsigned int value_rank() const
 
949
  {
 
950
    return 1;
 
951
  }
 
952
 
 
953
  /// Return the dimension of the value space for axis i
 
954
  virtual unsigned int value_dimension(unsigned int i) const
 
955
  {
 
956
    return 3;
 
957
  }
 
958
 
 
959
  /// Evaluate basis function i at given point in cell
 
960
  virtual void evaluate_basis(unsigned int i,
 
961
                              double* values,
 
962
                              const double* coordinates,
 
963
                              const ufc::cell& c) const
 
964
  {
 
965
    // Extract vertex coordinates
 
966
    const double * const * element_coordinates = c.coordinates;
 
967
    
 
968
    // Compute Jacobian of affine map from reference cell
 
969
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
970
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
971
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
972
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
973
    
 
974
    // Compute determinant of Jacobian
 
975
    const double detJ = J_00*J_11 - J_01*J_10;
 
976
    
 
977
    // Compute inverse of Jacobian
 
978
    
 
979
    // Get coordinates and map to the reference (UFC) element
 
980
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
981
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
982
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
983
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
984
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
985
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
986
    
 
987
    // Map coordinates to the reference square
 
988
    if (std::abs(y - 1.0) < 1e-08)
 
989
      x = -1.0;
 
990
    else
 
991
      x = 2.0 *x/(1.0 - y) - 1.0;
 
992
    y = 2.0*y - 1.0;
 
993
    
 
994
    // Reset values
 
995
    values[0] = 0;
 
996
    values[1] = 0;
 
997
    values[2] = 0;
 
998
    
 
999
    if (0 <= i && i <= 5)
 
1000
    {
 
1001
      // Map degree of freedom to element degree of freedom
 
1002
      const unsigned int dof = i;
 
1003
    
 
1004
      // Generate scalings
 
1005
      const double scalings_y_0 = 1;
 
1006
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
1007
    
 
1008
      // Compute psitilde_a
 
1009
      const double psitilde_a_0 = 1;
 
1010
      const double psitilde_a_1 = x;
 
1011
    
 
1012
      // Compute psitilde_bs
 
1013
      const double psitilde_bs_0_0 = 1;
 
1014
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
1015
      const double psitilde_bs_1_0 = 1;
 
1016
    
 
1017
      // Compute basisvalues
 
1018
      const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
1019
      const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
1020
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
1021
    
 
1022
      // Table(s) of coefficients
 
1023
      static const double coefficients0[6][3] =   \
 
1024
      {{0.942809042, 0.577350269, -0.333333333},
 
1025
      {-0.471404521, -0.288675135, 0.166666667},
 
1026
      {0.471404521, -0.577350269, -0.666666667},
 
1027
      {0.471404521, 0.288675135, 0.833333333},
 
1028
      {-0.471404521, -0.288675135, 0.166666667},
 
1029
      {0.942809042, 0.577350269, -0.333333333}};
 
1030
    
 
1031
      static const double coefficients1[6][3] =   \
 
1032
      {{-0.471404521, 0, -0.333333333},
 
1033
      {0.942809042, 0, 0.666666667},
 
1034
      {0.471404521, 0, 0.333333333},
 
1035
      {-0.942809042, 0, -0.666666667},
 
1036
      {-0.471404521, 0.866025404, 0.166666667},
 
1037
      {-0.471404521, -0.866025404, 0.166666667}};
 
1038
    
 
1039
      // Extract relevant coefficients
 
1040
      const double coeff0_0 =   coefficients0[dof][0];
 
1041
      const double coeff0_1 =   coefficients0[dof][1];
 
1042
      const double coeff0_2 =   coefficients0[dof][2];
 
1043
      const double coeff1_0 =   coefficients1[dof][0];
 
1044
      const double coeff1_1 =   coefficients1[dof][1];
 
1045
      const double coeff1_2 =   coefficients1[dof][2];
 
1046
    
 
1047
      // Compute value(s)
 
1048
      const double tmp0_0 = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
1049
      const double tmp0_1 = coeff1_0*basisvalue0 + coeff1_1*basisvalue1 + coeff1_2*basisvalue2;
 
1050
      // Using contravariant Piola transform to map values back to the physical element
 
1051
      values[0] = (1.0/detJ)*(J_00*tmp0_0 + J_01*tmp0_1);
 
1052
      values[1] = (1.0/detJ)*(J_10*tmp0_0 + J_11*tmp0_1);
 
1053
    }
 
1054
    
 
1055
    if (6 <= i && i <= 6)
 
1056
    {
 
1057
      // Map degree of freedom to element degree of freedom
 
1058
      const unsigned int dof = i - 6;
 
1059
    
 
1060
      // Generate scalings
 
1061
      const double scalings_y_0 = 1;
 
1062
    
 
1063
      // Compute psitilde_a
 
1064
      const double psitilde_a_0 = 1;
 
1065
    
 
1066
      // Compute psitilde_bs
 
1067
      const double psitilde_bs_0_0 = 1;
 
1068
    
 
1069
      // Compute basisvalues
 
1070
      const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
1071
    
 
1072
      // Table(s) of coefficients
 
1073
      static const double coefficients0[1][1] =   \
 
1074
      {{1.41421356}};
 
1075
    
 
1076
      // Extract relevant coefficients
 
1077
      const double coeff0_0 =   coefficients0[dof][0];
 
1078
    
 
1079
      // Compute value(s)
 
1080
      values[2] = coeff0_0*basisvalue0;
 
1081
    }
 
1082
    
 
1083
  }
 
1084
 
 
1085
  /// Evaluate all basis functions at given point in cell
 
1086
  virtual void evaluate_basis_all(double* values,
 
1087
                                  const double* coordinates,
 
1088
                                  const ufc::cell& c) const
 
1089
  {
 
1090
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
1091
  }
 
1092
 
 
1093
  /// Evaluate order n derivatives of basis function i at given point in cell
 
1094
  virtual void evaluate_basis_derivatives(unsigned int i,
 
1095
                                          unsigned int n,
 
1096
                                          double* values,
 
1097
                                          const double* coordinates,
 
1098
                                          const ufc::cell& c) const
 
1099
  {
 
1100
    // Extract vertex coordinates
 
1101
    const double * const * element_coordinates = c.coordinates;
 
1102
    
 
1103
    // Compute Jacobian of affine map from reference cell
 
1104
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
1105
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
1106
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
1107
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
1108
    
 
1109
    // Compute determinant of Jacobian
 
1110
    const double detJ = J_00*J_11 - J_01*J_10;
 
1111
    
 
1112
    // Compute inverse of Jacobian
 
1113
    
 
1114
    // Get coordinates and map to the reference (UFC) element
 
1115
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
1116
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
1117
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
1118
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
1119
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
1120
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
1121
    
 
1122
    // Map coordinates to the reference square
 
1123
    if (std::abs(y - 1.0) < 1e-08)
 
1124
      x = -1.0;
 
1125
    else
 
1126
      x = 2.0 *x/(1.0 - y) - 1.0;
 
1127
    y = 2.0*y - 1.0;
 
1128
    
 
1129
    // Compute number of derivatives
 
1130
    unsigned int num_derivatives = 1;
 
1131
    
 
1132
    for (unsigned int j = 0; j < n; j++)
 
1133
      num_derivatives *= 2;
 
1134
    
 
1135
    
 
1136
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
1137
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
1138
    
 
1139
    for (unsigned int j = 0; j < num_derivatives; j++)
 
1140
    {
 
1141
      combinations[j] = new unsigned int [n];
 
1142
      for (unsigned int k = 0; k < n; k++)
 
1143
        combinations[j][k] = 0;
 
1144
    }
 
1145
    
 
1146
    // Generate combinations of derivatives
 
1147
    for (unsigned int row = 1; row < num_derivatives; row++)
 
1148
    {
 
1149
      for (unsigned int num = 0; num < row; num++)
 
1150
      {
 
1151
        for (unsigned int col = n-1; col+1 > 0; col--)
 
1152
        {
 
1153
          if (combinations[row][col] + 1 > 1)
 
1154
            combinations[row][col] = 0;
 
1155
          else
 
1156
          {
 
1157
            combinations[row][col] += 1;
 
1158
            break;
 
1159
          }
 
1160
        }
 
1161
      }
 
1162
    }
 
1163
    
 
1164
    // Compute inverse of Jacobian
 
1165
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
1166
    
 
1167
    // Declare transformation matrix
 
1168
    // Declare pointer to two dimensional array and initialise
 
1169
    double **transform = new double *[num_derivatives];
 
1170
    
 
1171
    for (unsigned int j = 0; j < num_derivatives; j++)
 
1172
    {
 
1173
      transform[j] = new double [num_derivatives];
 
1174
      for (unsigned int k = 0; k < num_derivatives; k++)
 
1175
        transform[j][k] = 1;
 
1176
    }
 
1177
    
 
1178
    // Construct transformation matrix
 
1179
    for (unsigned int row = 0; row < num_derivatives; row++)
 
1180
    {
 
1181
      for (unsigned int col = 0; col < num_derivatives; col++)
 
1182
      {
 
1183
        for (unsigned int k = 0; k < n; k++)
 
1184
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
1185
      }
 
1186
    }
 
1187
    
 
1188
    // Reset values
 
1189
    for (unsigned int j = 0; j < 3*num_derivatives; j++)
 
1190
      values[j] = 0;
 
1191
    
 
1192
    if (0 <= i && i <= 5)
 
1193
    {
 
1194
      // Map degree of freedom to element degree of freedom
 
1195
      const unsigned int dof = i;
 
1196
    
 
1197
      // Generate scalings
 
1198
      const double scalings_y_0 = 1;
 
1199
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
1200
    
 
1201
      // Compute psitilde_a
 
1202
      const double psitilde_a_0 = 1;
 
1203
      const double psitilde_a_1 = x;
 
1204
    
 
1205
      // Compute psitilde_bs
 
1206
      const double psitilde_bs_0_0 = 1;
 
1207
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
1208
      const double psitilde_bs_1_0 = 1;
 
1209
    
 
1210
      // Compute basisvalues
 
1211
      const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
1212
      const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
1213
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
1214
    
 
1215
      // Table(s) of coefficients
 
1216
      static const double coefficients0[6][3] =   \
 
1217
      {{0.942809042, 0.577350269, -0.333333333},
 
1218
      {-0.471404521, -0.288675135, 0.166666667},
 
1219
      {0.471404521, -0.577350269, -0.666666667},
 
1220
      {0.471404521, 0.288675135, 0.833333333},
 
1221
      {-0.471404521, -0.288675135, 0.166666667},
 
1222
      {0.942809042, 0.577350269, -0.333333333}};
 
1223
    
 
1224
      static const double coefficients1[6][3] =   \
 
1225
      {{-0.471404521, 0, -0.333333333},
 
1226
      {0.942809042, 0, 0.666666667},
 
1227
      {0.471404521, 0, 0.333333333},
 
1228
      {-0.942809042, 0, -0.666666667},
 
1229
      {-0.471404521, 0.866025404, 0.166666667},
 
1230
      {-0.471404521, -0.866025404, 0.166666667}};
 
1231
    
 
1232
      // Interesting (new) part
 
1233
      // Tables of derivatives of the polynomial base (transpose)
 
1234
      static const double dmats0[3][3] =   \
 
1235
      {{0, 0, 0},
 
1236
      {4.89897949, 0, 0},
 
1237
      {0, 0, 0}};
 
1238
    
 
1239
      static const double dmats1[3][3] =   \
 
1240
      {{0, 0, 0},
 
1241
      {2.44948974, 0, 0},
 
1242
      {4.24264069, 0, 0}};
 
1243
    
 
1244
      // Compute reference derivatives
 
1245
      // Declare pointer to array of derivatives on FIAT element
 
1246
      double *derivatives = new double [2*num_derivatives];
 
1247
    
 
1248
      // Declare coefficients
 
1249
      double coeff0_0 = 0;
 
1250
      double coeff0_1 = 0;
 
1251
      double coeff0_2 = 0;
 
1252
      double coeff1_0 = 0;
 
1253
      double coeff1_1 = 0;
 
1254
      double coeff1_2 = 0;
 
1255
    
 
1256
      // Declare new coefficients
 
1257
      double new_coeff0_0 = 0;
 
1258
      double new_coeff0_1 = 0;
 
1259
      double new_coeff0_2 = 0;
 
1260
      double new_coeff1_0 = 0;
 
1261
      double new_coeff1_1 = 0;
 
1262
      double new_coeff1_2 = 0;
 
1263
    
 
1264
      // Loop possible derivatives
 
1265
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
1266
      {
 
1267
        // Get values from coefficients array
 
1268
        new_coeff0_0 = coefficients0[dof][0];
 
1269
        new_coeff0_1 = coefficients0[dof][1];
 
1270
        new_coeff0_2 = coefficients0[dof][2];
 
1271
        new_coeff1_0 = coefficients1[dof][0];
 
1272
        new_coeff1_1 = coefficients1[dof][1];
 
1273
        new_coeff1_2 = coefficients1[dof][2];
 
1274
    
 
1275
        // Loop derivative order
 
1276
        for (unsigned int j = 0; j < n; j++)
 
1277
        {
 
1278
          // Update old coefficients
 
1279
          coeff0_0 = new_coeff0_0;
 
1280
          coeff0_1 = new_coeff0_1;
 
1281
          coeff0_2 = new_coeff0_2;
 
1282
          coeff1_0 = new_coeff1_0;
 
1283
          coeff1_1 = new_coeff1_1;
 
1284
          coeff1_2 = new_coeff1_2;
 
1285
    
 
1286
          if(combinations[deriv_num][j] == 0)
 
1287
          {
 
1288
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
1289
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
1290
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
1291
            new_coeff1_0 = coeff1_0*dmats0[0][0] + coeff1_1*dmats0[1][0] + coeff1_2*dmats0[2][0];
 
1292
            new_coeff1_1 = coeff1_0*dmats0[0][1] + coeff1_1*dmats0[1][1] + coeff1_2*dmats0[2][1];
 
1293
            new_coeff1_2 = coeff1_0*dmats0[0][2] + coeff1_1*dmats0[1][2] + coeff1_2*dmats0[2][2];
 
1294
          }
 
1295
          if(combinations[deriv_num][j] == 1)
 
1296
          {
 
1297
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
1298
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
1299
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
1300
            new_coeff1_0 = coeff1_0*dmats1[0][0] + coeff1_1*dmats1[1][0] + coeff1_2*dmats1[2][0];
 
1301
            new_coeff1_1 = coeff1_0*dmats1[0][1] + coeff1_1*dmats1[1][1] + coeff1_2*dmats1[2][1];
 
1302
            new_coeff1_2 = coeff1_0*dmats1[0][2] + coeff1_1*dmats1[1][2] + coeff1_2*dmats1[2][2];
 
1303
          }
 
1304
    
 
1305
        }
 
1306
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
1307
        // Correct values by the contravariant Piola transform
 
1308
        const double tmp0_0 = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
1309
        const double tmp0_1 = new_coeff1_0*basisvalue0 + new_coeff1_1*basisvalue1 + new_coeff1_2*basisvalue2;
 
1310
        derivatives[deriv_num] = (1.0/detJ)*(J_00*tmp0_0 + J_01*tmp0_1);
 
1311
        derivatives[num_derivatives + deriv_num] = (1.0/detJ)*(J_10*tmp0_0 + J_11*tmp0_1);
 
1312
      }
 
1313
    
 
1314
      // Transform derivatives back to physical element
 
1315
      for (unsigned int row = 0; row < num_derivatives; row++)
 
1316
      {
 
1317
        for (unsigned int col = 0; col < num_derivatives; col++)
 
1318
        {
 
1319
          values[row] += transform[row][col]*derivatives[col];
 
1320
          values[num_derivatives + row] += transform[row][col]*derivatives[num_derivatives + col];
 
1321
        }
 
1322
      }
 
1323
      // Delete pointer to array of derivatives on FIAT element
 
1324
      delete [] derivatives;
 
1325
    
 
1326
      // Delete pointer to array of combinations of derivatives and transform
 
1327
      for (unsigned int row = 0; row < num_derivatives; row++)
 
1328
      {
 
1329
        delete [] combinations[row];
 
1330
        delete [] transform[row];
 
1331
      }
 
1332
    
 
1333
      delete [] combinations;
 
1334
      delete [] transform;
 
1335
    }
 
1336
    
 
1337
    if (6 <= i && i <= 6)
 
1338
    {
 
1339
      // Map degree of freedom to element degree of freedom
 
1340
      const unsigned int dof = i - 6;
 
1341
    
 
1342
      // Generate scalings
 
1343
      const double scalings_y_0 = 1;
 
1344
    
 
1345
      // Compute psitilde_a
 
1346
      const double psitilde_a_0 = 1;
 
1347
    
 
1348
      // Compute psitilde_bs
 
1349
      const double psitilde_bs_0_0 = 1;
 
1350
    
 
1351
      // Compute basisvalues
 
1352
      const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
1353
    
 
1354
      // Table(s) of coefficients
 
1355
      static const double coefficients0[1][1] =   \
 
1356
      {{1.41421356}};
 
1357
    
 
1358
      // Interesting (new) part
 
1359
      // Tables of derivatives of the polynomial base (transpose)
 
1360
      static const double dmats0[1][1] =   \
 
1361
      {{0}};
 
1362
    
 
1363
      static const double dmats1[1][1] =   \
 
1364
      {{0}};
 
1365
    
 
1366
      // Compute reference derivatives
 
1367
      // Declare pointer to array of derivatives on FIAT element
 
1368
      double *derivatives = new double [num_derivatives];
 
1369
    
 
1370
      // Declare coefficients
 
1371
      double coeff0_0 = 0;
 
1372
    
 
1373
      // Declare new coefficients
 
1374
      double new_coeff0_0 = 0;
 
1375
    
 
1376
      // Loop possible derivatives
 
1377
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
1378
      {
 
1379
        // Get values from coefficients array
 
1380
        new_coeff0_0 = coefficients0[dof][0];
 
1381
    
 
1382
        // Loop derivative order
 
1383
        for (unsigned int j = 0; j < n; j++)
 
1384
        {
 
1385
          // Update old coefficients
 
1386
          coeff0_0 = new_coeff0_0;
 
1387
    
 
1388
          if(combinations[deriv_num][j] == 0)
 
1389
          {
 
1390
            new_coeff0_0 = coeff0_0*dmats0[0][0];
 
1391
          }
 
1392
          if(combinations[deriv_num][j] == 1)
 
1393
          {
 
1394
            new_coeff0_0 = coeff0_0*dmats1[0][0];
 
1395
          }
 
1396
    
 
1397
        }
 
1398
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
1399
        derivatives[deriv_num] = new_coeff0_0*basisvalue0;
 
1400
      }
 
1401
    
 
1402
      // Transform derivatives back to physical element
 
1403
      for (unsigned int row = 0; row < num_derivatives; row++)
 
1404
      {
 
1405
        for (unsigned int col = 0; col < num_derivatives; col++)
 
1406
        {
 
1407
          values[2*num_derivatives + row] += transform[row][col]*derivatives[col];
 
1408
        }
 
1409
      }
 
1410
      // Delete pointer to array of derivatives on FIAT element
 
1411
      delete [] derivatives;
 
1412
    
 
1413
      // Delete pointer to array of combinations of derivatives and transform
 
1414
      for (unsigned int row = 0; row < num_derivatives; row++)
 
1415
      {
 
1416
        delete [] combinations[row];
 
1417
        delete [] transform[row];
 
1418
      }
 
1419
    
 
1420
      delete [] combinations;
 
1421
      delete [] transform;
 
1422
    }
 
1423
    
 
1424
  }
 
1425
 
 
1426
  /// Evaluate order n derivatives of all basis functions at given point in cell
 
1427
  virtual void evaluate_basis_derivatives_all(unsigned int n,
 
1428
                                              double* values,
 
1429
                                              const double* coordinates,
 
1430
                                              const ufc::cell& c) const
 
1431
  {
 
1432
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
1433
  }
 
1434
 
 
1435
  /// Evaluate linear functional for dof i on the function f
 
1436
  virtual double evaluate_dof(unsigned int i,
 
1437
                              const ufc::function& f,
 
1438
                              const ufc::cell& c) const
 
1439
  {
 
1440
    // The reference points, direction and weights:
 
1441
    static const double X[7][1][2] = {{{0.666666667, 0.333333333}}, {{0.333333333, 0.666666667}}, {{0, 0.333333333}}, {{0, 0.666666667}}, {{0.333333333, 0}}, {{0.666666667, 0}}, {{0.333333333, 0.333333333}}};
 
1442
    static const double W[7][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}};
 
1443
    static const double D[7][1][3] = {{{1, 1, 0}}, {{1, 1, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{0, -1, 0}}, {{0, -1, 0}}, {{0, 0, 1}}};
 
1444
    
 
1445
    static const unsigned int mappings[7] = {1, 1, 1, 1, 1, 1, 0};
 
1446
    // Extract vertex coordinates
 
1447
    const double * const * x = c.coordinates;
 
1448
    
 
1449
    // Compute Jacobian of affine map from reference cell
 
1450
    const double J_00 = x[1][0] - x[0][0];
 
1451
    const double J_01 = x[2][0] - x[0][0];
 
1452
    const double J_10 = x[1][1] - x[0][1];
 
1453
    const double J_11 = x[2][1] - x[0][1];
 
1454
    
 
1455
    // Compute determinant of Jacobian
 
1456
    double detJ = J_00*J_11 - J_01*J_10;
 
1457
    
 
1458
    // Compute inverse of Jacobian
 
1459
    const double Jinv_00 =  J_11 / detJ;
 
1460
    const double Jinv_01 = -J_01 / detJ;
 
1461
    const double Jinv_10 = -J_10 / detJ;
 
1462
    const double Jinv_11 =  J_00 / detJ;
 
1463
    
 
1464
    double copyofvalues[3];
 
1465
    double result = 0.0;
 
1466
    // Iterate over the points:
 
1467
    // Evaluate basis functions for affine mapping
 
1468
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
1469
    const double w1 = X[i][0][0];
 
1470
    const double w2 = X[i][0][1];
 
1471
    
 
1472
    // Compute affine mapping y = F(X)
 
1473
    double y[2];
 
1474
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
1475
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
1476
    
 
1477
    // Evaluate function at physical points
 
1478
    double values[3];
 
1479
    f.evaluate(values, y, c);
 
1480
    
 
1481
    // Map function values using appropriate mapping
 
1482
    if (mappings[i] == 0) { 
 
1483
      // Affine map: Do nothing
 
1484
    } else if (mappings[i] == 1) {
 
1485
       // Copy old values:
 
1486
      copyofvalues[0] = values[0];
 
1487
      copyofvalues[1] = values[1];
 
1488
      // Do the inverse of div piola 
 
1489
      values[0] = detJ*(Jinv_00*copyofvalues[0]+Jinv_01*copyofvalues[1]);
 
1490
      values[1] = detJ*(Jinv_10*copyofvalues[0]+Jinv_11*copyofvalues[1]); 
 
1491
    } else { 
 
1492
       // Other mappings not applicable. 
 
1493
    }
 
1494
    
 
1495
    // Note that we do not map the weights (yet).
 
1496
    
 
1497
    // Take directional components
 
1498
    for(int k = 0; k < 3; k++)
 
1499
      result += values[k]*D[i][0][k];
 
1500
    // Multiply by weights
 
1501
    result *= W[i][0];
 
1502
    
 
1503
    return result;
 
1504
  }
 
1505
 
 
1506
  /// Evaluate linear functionals for all dofs on the function f
 
1507
  virtual void evaluate_dofs(double* values,
 
1508
                             const ufc::function& f,
 
1509
                             const ufc::cell& c) const
 
1510
  {
 
1511
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
1512
  }
 
1513
 
 
1514
  /// Interpolate vertex values from dof values
 
1515
  virtual void interpolate_vertex_values(double* vertex_values,
 
1516
                                         const double* dof_values,
 
1517
                                         const ufc::cell& c) const
 
1518
  {
 
1519
    // Extract vertex coordinates
 
1520
    const double * const * x = c.coordinates;
 
1521
    
 
1522
    // Compute Jacobian of affine map from reference cell
 
1523
    const double J_00 = x[1][0] - x[0][0];
 
1524
    const double J_01 = x[2][0] - x[0][0];
 
1525
    const double J_10 = x[1][1] - x[0][1];
 
1526
    const double J_11 = x[2][1] - x[0][1];
 
1527
    
 
1528
    // Compute determinant of Jacobian
 
1529
    double detJ = J_00*J_11 - J_01*J_10;
 
1530
    
 
1531
    // Compute inverse of Jacobian
 
1532
    // Evaluate at vertices and use Piola mapping
 
1533
    vertex_values[0] = (1.0/detJ)*(dof_values[2]*2*J_00 + dof_values[3]*J_00 + dof_values[4]*(-2*J_01) + dof_values[5]*J_01);
 
1534
    vertex_values[3] = (1.0/detJ)*(dof_values[0]*2*J_00 + dof_values[1]*J_00 + dof_values[4]*(J_00 + J_01) + dof_values[5]*(2*J_00 - 2*J_01));
 
1535
    vertex_values[6] = (1.0/detJ)*(dof_values[0]*J_01 + dof_values[1]*2*J_01 + dof_values[2]*(J_00 + J_01) + dof_values[3]*(2*J_00 - 2*J_01));
 
1536
    vertex_values[1] = (1.0/detJ)*(dof_values[2]*2*J_10 + dof_values[3]*J_10 + dof_values[4]*(-2*J_11) + dof_values[5]*J_11);
 
1537
    vertex_values[4] = (1.0/detJ)*(dof_values[0]*2*J_10 + dof_values[1]*J_10 + dof_values[4]*(J_10 + J_11) + dof_values[5]*(2*J_10 - 2*J_11));
 
1538
    vertex_values[7] = (1.0/detJ)*(dof_values[0]*J_11 + dof_values[1]*2*J_11 + dof_values[2]*(J_10 + J_11) + dof_values[3]*(2*J_10 - 2*J_11));
 
1539
    // Evaluate at vertices and use affine mapping
 
1540
    vertex_values[2] = dof_values[6];
 
1541
    vertex_values[5] = dof_values[6];
 
1542
    vertex_values[8] = dof_values[6];
 
1543
  }
 
1544
 
 
1545
  /// Return the number of sub elements (for a mixed element)
 
1546
  virtual unsigned int num_sub_elements() const
 
1547
  {
 
1548
    return 2;
 
1549
  }
 
1550
 
 
1551
  /// Create a new finite element for sub element i (for a mixed element)
 
1552
  virtual ufc::finite_element* create_sub_element(unsigned int i) const
 
1553
  {
 
1554
    switch ( i )
 
1555
    {
 
1556
    case 0:
 
1557
      return new mixedpoisson_0_finite_element_0_0();
 
1558
      break;
 
1559
    case 1:
 
1560
      return new mixedpoisson_0_finite_element_0_1();
 
1561
      break;
 
1562
    }
 
1563
    return 0;
 
1564
  }
 
1565
 
 
1566
};
 
1567
 
 
1568
/// This class defines the interface for a finite element.
 
1569
 
 
1570
class mixedpoisson_0_finite_element_1_0: public ufc::finite_element
 
1571
{
 
1572
public:
 
1573
 
 
1574
  /// Constructor
 
1575
  mixedpoisson_0_finite_element_1_0() : ufc::finite_element()
 
1576
  {
 
1577
    // Do nothing
 
1578
  }
 
1579
 
 
1580
  /// Destructor
 
1581
  virtual ~mixedpoisson_0_finite_element_1_0()
 
1582
  {
 
1583
    // Do nothing
 
1584
  }
 
1585
 
 
1586
  /// Return a string identifying the finite element
 
1587
  virtual const char* signature() const
 
1588
  {
 
1589
    return "FiniteElement('Brezzi-Douglas-Marini', 'triangle', 1)";
 
1590
  }
 
1591
 
 
1592
  /// Return the cell shape
 
1593
  virtual ufc::shape cell_shape() const
 
1594
  {
 
1595
    return ufc::triangle;
 
1596
  }
 
1597
 
 
1598
  /// Return the dimension of the finite element function space
 
1599
  virtual unsigned int space_dimension() const
 
1600
  {
 
1601
    return 6;
 
1602
  }
 
1603
 
 
1604
  /// Return the rank of the value space
 
1605
  virtual unsigned int value_rank() const
 
1606
  {
 
1607
    return 1;
 
1608
  }
 
1609
 
 
1610
  /// Return the dimension of the value space for axis i
 
1611
  virtual unsigned int value_dimension(unsigned int i) const
 
1612
  {
 
1613
    return 2;
 
1614
  }
 
1615
 
 
1616
  /// Evaluate basis function i at given point in cell
 
1617
  virtual void evaluate_basis(unsigned int i,
 
1618
                              double* values,
 
1619
                              const double* coordinates,
 
1620
                              const ufc::cell& c) const
 
1621
  {
 
1622
    // Extract vertex coordinates
 
1623
    const double * const * element_coordinates = c.coordinates;
 
1624
    
 
1625
    // Compute Jacobian of affine map from reference cell
 
1626
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
1627
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
1628
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
1629
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
1630
    
 
1631
    // Compute determinant of Jacobian
 
1632
    const double detJ = J_00*J_11 - J_01*J_10;
 
1633
    
 
1634
    // Compute inverse of Jacobian
 
1635
    
 
1636
    // Get coordinates and map to the reference (UFC) element
 
1637
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
1638
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
1639
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
1640
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
1641
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
1642
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
1643
    
 
1644
    // Map coordinates to the reference square
 
1645
    if (std::abs(y - 1.0) < 1e-08)
 
1646
      x = -1.0;
 
1647
    else
 
1648
      x = 2.0 *x/(1.0 - y) - 1.0;
 
1649
    y = 2.0*y - 1.0;
 
1650
    
 
1651
    // Reset values
 
1652
    values[0] = 0;
 
1653
    values[1] = 0;
 
1654
    
 
1655
    // Map degree of freedom to element degree of freedom
 
1656
    const unsigned int dof = i;
 
1657
    
 
1658
    // Generate scalings
 
1659
    const double scalings_y_0 = 1;
 
1660
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
1661
    
 
1662
    // Compute psitilde_a
 
1663
    const double psitilde_a_0 = 1;
 
1664
    const double psitilde_a_1 = x;
 
1665
    
 
1666
    // Compute psitilde_bs
 
1667
    const double psitilde_bs_0_0 = 1;
 
1668
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
1669
    const double psitilde_bs_1_0 = 1;
 
1670
    
 
1671
    // Compute basisvalues
 
1672
    const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
1673
    const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
1674
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
1675
    
 
1676
    // Table(s) of coefficients
 
1677
    static const double coefficients0[6][3] = \
 
1678
    {{0.942809042, 0.577350269, -0.333333333},
 
1679
    {-0.471404521, -0.288675135, 0.166666667},
 
1680
    {0.471404521, -0.577350269, -0.666666667},
 
1681
    {0.471404521, 0.288675135, 0.833333333},
 
1682
    {-0.471404521, -0.288675135, 0.166666667},
 
1683
    {0.942809042, 0.577350269, -0.333333333}};
 
1684
    
 
1685
    static const double coefficients1[6][3] = \
 
1686
    {{-0.471404521, 0, -0.333333333},
 
1687
    {0.942809042, 0, 0.666666667},
 
1688
    {0.471404521, 0, 0.333333333},
 
1689
    {-0.942809042, 0, -0.666666667},
 
1690
    {-0.471404521, 0.866025404, 0.166666667},
 
1691
    {-0.471404521, -0.866025404, 0.166666667}};
 
1692
    
 
1693
    // Extract relevant coefficients
 
1694
    const double coeff0_0 = coefficients0[dof][0];
 
1695
    const double coeff0_1 = coefficients0[dof][1];
 
1696
    const double coeff0_2 = coefficients0[dof][2];
 
1697
    const double coeff1_0 = coefficients1[dof][0];
 
1698
    const double coeff1_1 = coefficients1[dof][1];
 
1699
    const double coeff1_2 = coefficients1[dof][2];
 
1700
    
 
1701
    // Compute value(s)
 
1702
    const double tmp0_0 = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
1703
    const double tmp0_1 = coeff1_0*basisvalue0 + coeff1_1*basisvalue1 + coeff1_2*basisvalue2;
 
1704
    // Using contravariant Piola transform to map values back to the physical element
 
1705
    values[0] = (1.0/detJ)*(J_00*tmp0_0 + J_01*tmp0_1);
 
1706
    values[1] = (1.0/detJ)*(J_10*tmp0_0 + J_11*tmp0_1);
 
1707
  }
 
1708
 
 
1709
  /// Evaluate all basis functions at given point in cell
 
1710
  virtual void evaluate_basis_all(double* values,
 
1711
                                  const double* coordinates,
 
1712
                                  const ufc::cell& c) const
 
1713
  {
 
1714
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
1715
  }
 
1716
 
 
1717
  /// Evaluate order n derivatives of basis function i at given point in cell
 
1718
  virtual void evaluate_basis_derivatives(unsigned int i,
 
1719
                                          unsigned int n,
 
1720
                                          double* values,
 
1721
                                          const double* coordinates,
 
1722
                                          const ufc::cell& c) const
 
1723
  {
 
1724
    // Extract vertex coordinates
 
1725
    const double * const * element_coordinates = c.coordinates;
 
1726
    
 
1727
    // Compute Jacobian of affine map from reference cell
 
1728
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
1729
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
1730
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
1731
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
1732
    
 
1733
    // Compute determinant of Jacobian
 
1734
    const double detJ = J_00*J_11 - J_01*J_10;
 
1735
    
 
1736
    // Compute inverse of Jacobian
 
1737
    
 
1738
    // Get coordinates and map to the reference (UFC) element
 
1739
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
1740
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
1741
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
1742
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
1743
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
1744
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
1745
    
 
1746
    // Map coordinates to the reference square
 
1747
    if (std::abs(y - 1.0) < 1e-08)
 
1748
      x = -1.0;
 
1749
    else
 
1750
      x = 2.0 *x/(1.0 - y) - 1.0;
 
1751
    y = 2.0*y - 1.0;
 
1752
    
 
1753
    // Compute number of derivatives
 
1754
    unsigned int num_derivatives = 1;
 
1755
    
 
1756
    for (unsigned int j = 0; j < n; j++)
 
1757
      num_derivatives *= 2;
 
1758
    
 
1759
    
 
1760
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
1761
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
1762
    
 
1763
    for (unsigned int j = 0; j < num_derivatives; j++)
 
1764
    {
 
1765
      combinations[j] = new unsigned int [n];
 
1766
      for (unsigned int k = 0; k < n; k++)
 
1767
        combinations[j][k] = 0;
 
1768
    }
 
1769
    
 
1770
    // Generate combinations of derivatives
 
1771
    for (unsigned int row = 1; row < num_derivatives; row++)
 
1772
    {
 
1773
      for (unsigned int num = 0; num < row; num++)
 
1774
      {
 
1775
        for (unsigned int col = n-1; col+1 > 0; col--)
 
1776
        {
 
1777
          if (combinations[row][col] + 1 > 1)
 
1778
            combinations[row][col] = 0;
 
1779
          else
 
1780
          {
 
1781
            combinations[row][col] += 1;
 
1782
            break;
 
1783
          }
 
1784
        }
 
1785
      }
 
1786
    }
 
1787
    
 
1788
    // Compute inverse of Jacobian
 
1789
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
1790
    
 
1791
    // Declare transformation matrix
 
1792
    // Declare pointer to two dimensional array and initialise
 
1793
    double **transform = new double *[num_derivatives];
 
1794
    
 
1795
    for (unsigned int j = 0; j < num_derivatives; j++)
 
1796
    {
 
1797
      transform[j] = new double [num_derivatives];
 
1798
      for (unsigned int k = 0; k < num_derivatives; k++)
 
1799
        transform[j][k] = 1;
 
1800
    }
 
1801
    
 
1802
    // Construct transformation matrix
 
1803
    for (unsigned int row = 0; row < num_derivatives; row++)
 
1804
    {
 
1805
      for (unsigned int col = 0; col < num_derivatives; col++)
 
1806
      {
 
1807
        for (unsigned int k = 0; k < n; k++)
 
1808
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
1809
      }
 
1810
    }
 
1811
    
 
1812
    // Reset values
 
1813
    for (unsigned int j = 0; j < 2*num_derivatives; j++)
 
1814
      values[j] = 0;
 
1815
    
 
1816
    // Map degree of freedom to element degree of freedom
 
1817
    const unsigned int dof = i;
 
1818
    
 
1819
    // Generate scalings
 
1820
    const double scalings_y_0 = 1;
 
1821
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
1822
    
 
1823
    // Compute psitilde_a
 
1824
    const double psitilde_a_0 = 1;
 
1825
    const double psitilde_a_1 = x;
 
1826
    
 
1827
    // Compute psitilde_bs
 
1828
    const double psitilde_bs_0_0 = 1;
 
1829
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
1830
    const double psitilde_bs_1_0 = 1;
 
1831
    
 
1832
    // Compute basisvalues
 
1833
    const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
1834
    const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
1835
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
1836
    
 
1837
    // Table(s) of coefficients
 
1838
    static const double coefficients0[6][3] = \
 
1839
    {{0.942809042, 0.577350269, -0.333333333},
 
1840
    {-0.471404521, -0.288675135, 0.166666667},
 
1841
    {0.471404521, -0.577350269, -0.666666667},
 
1842
    {0.471404521, 0.288675135, 0.833333333},
 
1843
    {-0.471404521, -0.288675135, 0.166666667},
 
1844
    {0.942809042, 0.577350269, -0.333333333}};
 
1845
    
 
1846
    static const double coefficients1[6][3] = \
 
1847
    {{-0.471404521, 0, -0.333333333},
 
1848
    {0.942809042, 0, 0.666666667},
 
1849
    {0.471404521, 0, 0.333333333},
 
1850
    {-0.942809042, 0, -0.666666667},
 
1851
    {-0.471404521, 0.866025404, 0.166666667},
 
1852
    {-0.471404521, -0.866025404, 0.166666667}};
 
1853
    
 
1854
    // Interesting (new) part
 
1855
    // Tables of derivatives of the polynomial base (transpose)
 
1856
    static const double dmats0[3][3] = \
 
1857
    {{0, 0, 0},
 
1858
    {4.89897949, 0, 0},
 
1859
    {0, 0, 0}};
 
1860
    
 
1861
    static const double dmats1[3][3] = \
 
1862
    {{0, 0, 0},
 
1863
    {2.44948974, 0, 0},
 
1864
    {4.24264069, 0, 0}};
 
1865
    
 
1866
    // Compute reference derivatives
 
1867
    // Declare pointer to array of derivatives on FIAT element
 
1868
    double *derivatives = new double [2*num_derivatives];
 
1869
    
 
1870
    // Declare coefficients
 
1871
    double coeff0_0 = 0;
 
1872
    double coeff0_1 = 0;
 
1873
    double coeff0_2 = 0;
 
1874
    double coeff1_0 = 0;
 
1875
    double coeff1_1 = 0;
 
1876
    double coeff1_2 = 0;
 
1877
    
 
1878
    // Declare new coefficients
 
1879
    double new_coeff0_0 = 0;
 
1880
    double new_coeff0_1 = 0;
 
1881
    double new_coeff0_2 = 0;
 
1882
    double new_coeff1_0 = 0;
 
1883
    double new_coeff1_1 = 0;
 
1884
    double new_coeff1_2 = 0;
 
1885
    
 
1886
    // Loop possible derivatives
 
1887
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
1888
    {
 
1889
      // Get values from coefficients array
 
1890
      new_coeff0_0 = coefficients0[dof][0];
 
1891
      new_coeff0_1 = coefficients0[dof][1];
 
1892
      new_coeff0_2 = coefficients0[dof][2];
 
1893
      new_coeff1_0 = coefficients1[dof][0];
 
1894
      new_coeff1_1 = coefficients1[dof][1];
 
1895
      new_coeff1_2 = coefficients1[dof][2];
 
1896
    
 
1897
      // Loop derivative order
 
1898
      for (unsigned int j = 0; j < n; j++)
 
1899
      {
 
1900
        // Update old coefficients
 
1901
        coeff0_0 = new_coeff0_0;
 
1902
        coeff0_1 = new_coeff0_1;
 
1903
        coeff0_2 = new_coeff0_2;
 
1904
        coeff1_0 = new_coeff1_0;
 
1905
        coeff1_1 = new_coeff1_1;
 
1906
        coeff1_2 = new_coeff1_2;
 
1907
    
 
1908
        if(combinations[deriv_num][j] == 0)
 
1909
        {
 
1910
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
1911
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
1912
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
1913
          new_coeff1_0 = coeff1_0*dmats0[0][0] + coeff1_1*dmats0[1][0] + coeff1_2*dmats0[2][0];
 
1914
          new_coeff1_1 = coeff1_0*dmats0[0][1] + coeff1_1*dmats0[1][1] + coeff1_2*dmats0[2][1];
 
1915
          new_coeff1_2 = coeff1_0*dmats0[0][2] + coeff1_1*dmats0[1][2] + coeff1_2*dmats0[2][2];
 
1916
        }
 
1917
        if(combinations[deriv_num][j] == 1)
 
1918
        {
 
1919
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
1920
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
1921
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
1922
          new_coeff1_0 = coeff1_0*dmats1[0][0] + coeff1_1*dmats1[1][0] + coeff1_2*dmats1[2][0];
 
1923
          new_coeff1_1 = coeff1_0*dmats1[0][1] + coeff1_1*dmats1[1][1] + coeff1_2*dmats1[2][1];
 
1924
          new_coeff1_2 = coeff1_0*dmats1[0][2] + coeff1_1*dmats1[1][2] + coeff1_2*dmats1[2][2];
 
1925
        }
 
1926
    
 
1927
      }
 
1928
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
1929
      // Correct values by the contravariant Piola transform
 
1930
      const double tmp0_0 = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
1931
      const double tmp0_1 = new_coeff1_0*basisvalue0 + new_coeff1_1*basisvalue1 + new_coeff1_2*basisvalue2;
 
1932
      derivatives[deriv_num] = (1.0/detJ)*(J_00*tmp0_0 + J_01*tmp0_1);
 
1933
      derivatives[num_derivatives + deriv_num] = (1.0/detJ)*(J_10*tmp0_0 + J_11*tmp0_1);
 
1934
    }
 
1935
    
 
1936
    // Transform derivatives back to physical element
 
1937
    for (unsigned int row = 0; row < num_derivatives; row++)
 
1938
    {
 
1939
      for (unsigned int col = 0; col < num_derivatives; col++)
 
1940
      {
 
1941
        values[row] += transform[row][col]*derivatives[col];
 
1942
        values[num_derivatives + row] += transform[row][col]*derivatives[num_derivatives + col];
 
1943
      }
 
1944
    }
 
1945
    // Delete pointer to array of derivatives on FIAT element
 
1946
    delete [] derivatives;
 
1947
    
 
1948
    // Delete pointer to array of combinations of derivatives and transform
 
1949
    for (unsigned int row = 0; row < num_derivatives; row++)
 
1950
    {
 
1951
      delete [] combinations[row];
 
1952
      delete [] transform[row];
 
1953
    }
 
1954
    
 
1955
    delete [] combinations;
 
1956
    delete [] transform;
 
1957
  }
 
1958
 
 
1959
  /// Evaluate order n derivatives of all basis functions at given point in cell
 
1960
  virtual void evaluate_basis_derivatives_all(unsigned int n,
 
1961
                                              double* values,
 
1962
                                              const double* coordinates,
 
1963
                                              const ufc::cell& c) const
 
1964
  {
 
1965
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
1966
  }
 
1967
 
 
1968
  /// Evaluate linear functional for dof i on the function f
 
1969
  virtual double evaluate_dof(unsigned int i,
 
1970
                              const ufc::function& f,
 
1971
                              const ufc::cell& c) const
 
1972
  {
 
1973
    // The reference points, direction and weights:
 
1974
    static const double X[6][1][2] = {{{0.666666667, 0.333333333}}, {{0.333333333, 0.666666667}}, {{0, 0.333333333}}, {{0, 0.666666667}}, {{0.333333333, 0}}, {{0.666666667, 0}}};
 
1975
    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
 
1976
    static const double D[6][1][2] = {{{1, 1}}, {{1, 1}}, {{1, 0}}, {{1, 0}}, {{0, -1}}, {{0, -1}}};
 
1977
    
 
1978
    // Extract vertex coordinates
 
1979
    const double * const * x = c.coordinates;
 
1980
    
 
1981
    // Compute Jacobian of affine map from reference cell
 
1982
    const double J_00 = x[1][0] - x[0][0];
 
1983
    const double J_01 = x[2][0] - x[0][0];
 
1984
    const double J_10 = x[1][1] - x[0][1];
 
1985
    const double J_11 = x[2][1] - x[0][1];
 
1986
    
 
1987
    // Compute determinant of Jacobian
 
1988
    double detJ = J_00*J_11 - J_01*J_10;
 
1989
    
 
1990
    // Compute inverse of Jacobian
 
1991
    const double Jinv_00 =  J_11 / detJ;
 
1992
    const double Jinv_01 = -J_01 / detJ;
 
1993
    const double Jinv_10 = -J_10 / detJ;
 
1994
    const double Jinv_11 =  J_00 / detJ;
 
1995
    
 
1996
    double copyofvalues[2];
 
1997
    double result = 0.0;
 
1998
    // Iterate over the points:
 
1999
    // Evaluate basis functions for affine mapping
 
2000
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
2001
    const double w1 = X[i][0][0];
 
2002
    const double w2 = X[i][0][1];
 
2003
    
 
2004
    // Compute affine mapping y = F(X)
 
2005
    double y[2];
 
2006
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
2007
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
2008
    
 
2009
    // Evaluate function at physical points
 
2010
    double values[2];
 
2011
    f.evaluate(values, y, c);
 
2012
    
 
2013
    // Map function values using appropriate mapping
 
2014
    // Copy old values:
 
2015
    copyofvalues[0] = values[0];
 
2016
    copyofvalues[1] = values[1];
 
2017
    // Do the inverse of div piola 
 
2018
    values[0] = detJ*(Jinv_00*copyofvalues[0]+Jinv_01*copyofvalues[1]);
 
2019
    values[1] = detJ*(Jinv_10*copyofvalues[0]+Jinv_11*copyofvalues[1]);
 
2020
    
 
2021
    // Note that we do not map the weights (yet).
 
2022
    
 
2023
    // Take directional components
 
2024
    for(int k = 0; k < 2; k++)
 
2025
      result += values[k]*D[i][0][k];
 
2026
    // Multiply by weights
 
2027
    result *= W[i][0];
 
2028
    
 
2029
    return result;
 
2030
  }
 
2031
 
 
2032
  /// Evaluate linear functionals for all dofs on the function f
 
2033
  virtual void evaluate_dofs(double* values,
 
2034
                             const ufc::function& f,
 
2035
                             const ufc::cell& c) const
 
2036
  {
 
2037
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
2038
  }
 
2039
 
 
2040
  /// Interpolate vertex values from dof values
 
2041
  virtual void interpolate_vertex_values(double* vertex_values,
 
2042
                                         const double* dof_values,
 
2043
                                         const ufc::cell& c) const
 
2044
  {
 
2045
    // Extract vertex coordinates
 
2046
    const double * const * x = c.coordinates;
 
2047
    
 
2048
    // Compute Jacobian of affine map from reference cell
 
2049
    const double J_00 = x[1][0] - x[0][0];
 
2050
    const double J_01 = x[2][0] - x[0][0];
 
2051
    const double J_10 = x[1][1] - x[0][1];
 
2052
    const double J_11 = x[2][1] - x[0][1];
 
2053
    
 
2054
    // Compute determinant of Jacobian
 
2055
    double detJ = J_00*J_11 - J_01*J_10;
 
2056
    
 
2057
    // Compute inverse of Jacobian
 
2058
    // Evaluate at vertices and use Piola mapping
 
2059
    vertex_values[0] = (1.0/detJ)*(dof_values[2]*2*J_00 + dof_values[3]*J_00 + dof_values[4]*(-2*J_01) + dof_values[5]*J_01);
 
2060
    vertex_values[2] = (1.0/detJ)*(dof_values[0]*2*J_00 + dof_values[1]*J_00 + dof_values[4]*(J_00 + J_01) + dof_values[5]*(2*J_00 - 2*J_01));
 
2061
    vertex_values[4] = (1.0/detJ)*(dof_values[0]*J_01 + dof_values[1]*2*J_01 + dof_values[2]*(J_00 + J_01) + dof_values[3]*(2*J_00 - 2*J_01));
 
2062
    vertex_values[1] = (1.0/detJ)*(dof_values[2]*2*J_10 + dof_values[3]*J_10 + dof_values[4]*(-2*J_11) + dof_values[5]*J_11);
 
2063
    vertex_values[3] = (1.0/detJ)*(dof_values[0]*2*J_10 + dof_values[1]*J_10 + dof_values[4]*(J_10 + J_11) + dof_values[5]*(2*J_10 - 2*J_11));
 
2064
    vertex_values[5] = (1.0/detJ)*(dof_values[0]*J_11 + dof_values[1]*2*J_11 + dof_values[2]*(J_10 + J_11) + dof_values[3]*(2*J_10 - 2*J_11));
 
2065
  }
 
2066
 
 
2067
  /// Return the number of sub elements (for a mixed element)
 
2068
  virtual unsigned int num_sub_elements() const
 
2069
  {
 
2070
    return 1;
 
2071
  }
 
2072
 
 
2073
  /// Create a new finite element for sub element i (for a mixed element)
 
2074
  virtual ufc::finite_element* create_sub_element(unsigned int i) const
 
2075
  {
 
2076
    return new mixedpoisson_0_finite_element_1_0();
 
2077
  }
 
2078
 
 
2079
};
 
2080
 
 
2081
/// This class defines the interface for a finite element.
 
2082
 
 
2083
class mixedpoisson_0_finite_element_1_1: public ufc::finite_element
 
2084
{
 
2085
public:
 
2086
 
 
2087
  /// Constructor
 
2088
  mixedpoisson_0_finite_element_1_1() : ufc::finite_element()
 
2089
  {
 
2090
    // Do nothing
 
2091
  }
 
2092
 
 
2093
  /// Destructor
 
2094
  virtual ~mixedpoisson_0_finite_element_1_1()
 
2095
  {
 
2096
    // Do nothing
 
2097
  }
 
2098
 
 
2099
  /// Return a string identifying the finite element
 
2100
  virtual const char* signature() const
 
2101
  {
 
2102
    return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
 
2103
  }
 
2104
 
 
2105
  /// Return the cell shape
 
2106
  virtual ufc::shape cell_shape() const
 
2107
  {
 
2108
    return ufc::triangle;
 
2109
  }
 
2110
 
 
2111
  /// Return the dimension of the finite element function space
 
2112
  virtual unsigned int space_dimension() const
 
2113
  {
 
2114
    return 1;
 
2115
  }
 
2116
 
 
2117
  /// Return the rank of the value space
 
2118
  virtual unsigned int value_rank() const
 
2119
  {
 
2120
    return 0;
 
2121
  }
 
2122
 
 
2123
  /// Return the dimension of the value space for axis i
 
2124
  virtual unsigned int value_dimension(unsigned int i) const
 
2125
  {
 
2126
    return 1;
 
2127
  }
 
2128
 
 
2129
  /// Evaluate basis function i at given point in cell
 
2130
  virtual void evaluate_basis(unsigned int i,
 
2131
                              double* values,
 
2132
                              const double* coordinates,
 
2133
                              const ufc::cell& c) const
 
2134
  {
 
2135
    // Extract vertex coordinates
 
2136
    const double * const * element_coordinates = c.coordinates;
 
2137
    
 
2138
    // Compute Jacobian of affine map from reference cell
 
2139
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
2140
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
2141
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
2142
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
2143
    
 
2144
    // Compute determinant of Jacobian
 
2145
    const double detJ = J_00*J_11 - J_01*J_10;
 
2146
    
 
2147
    // Compute inverse of Jacobian
 
2148
    
 
2149
    // Get coordinates and map to the reference (UFC) element
 
2150
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
2151
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
2152
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
2153
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
2154
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
2155
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
2156
    
 
2157
    // Map coordinates to the reference square
 
2158
    if (std::abs(y - 1.0) < 1e-08)
 
2159
      x = -1.0;
 
2160
    else
 
2161
      x = 2.0 *x/(1.0 - y) - 1.0;
 
2162
    y = 2.0*y - 1.0;
 
2163
    
 
2164
    // Reset values
 
2165
    *values = 0;
 
2166
    
 
2167
    // Map degree of freedom to element degree of freedom
 
2168
    const unsigned int dof = i;
 
2169
    
 
2170
    // Generate scalings
 
2171
    const double scalings_y_0 = 1;
 
2172
    
 
2173
    // Compute psitilde_a
 
2174
    const double psitilde_a_0 = 1;
 
2175
    
 
2176
    // Compute psitilde_bs
 
2177
    const double psitilde_bs_0_0 = 1;
 
2178
    
 
2179
    // Compute basisvalues
 
2180
    const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
2181
    
 
2182
    // Table(s) of coefficients
 
2183
    static const double coefficients0[1][1] = \
 
2184
    {{1.41421356}};
 
2185
    
 
2186
    // Extract relevant coefficients
 
2187
    const double coeff0_0 = coefficients0[dof][0];
 
2188
    
 
2189
    // Compute value(s)
 
2190
    *values = coeff0_0*basisvalue0;
 
2191
  }
 
2192
 
 
2193
  /// Evaluate all basis functions at given point in cell
 
2194
  virtual void evaluate_basis_all(double* values,
 
2195
                                  const double* coordinates,
 
2196
                                  const ufc::cell& c) const
 
2197
  {
 
2198
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
2199
  }
 
2200
 
 
2201
  /// Evaluate order n derivatives of basis function i at given point in cell
 
2202
  virtual void evaluate_basis_derivatives(unsigned int i,
 
2203
                                          unsigned int n,
 
2204
                                          double* values,
 
2205
                                          const double* coordinates,
 
2206
                                          const ufc::cell& c) const
 
2207
  {
 
2208
    // Extract vertex coordinates
 
2209
    const double * const * element_coordinates = c.coordinates;
 
2210
    
 
2211
    // Compute Jacobian of affine map from reference cell
 
2212
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
2213
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
2214
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
2215
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
2216
    
 
2217
    // Compute determinant of Jacobian
 
2218
    const double detJ = J_00*J_11 - J_01*J_10;
 
2219
    
 
2220
    // Compute inverse of Jacobian
 
2221
    
 
2222
    // Get coordinates and map to the reference (UFC) element
 
2223
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
2224
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
2225
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
2226
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
2227
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
2228
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
2229
    
 
2230
    // Map coordinates to the reference square
 
2231
    if (std::abs(y - 1.0) < 1e-08)
 
2232
      x = -1.0;
 
2233
    else
 
2234
      x = 2.0 *x/(1.0 - y) - 1.0;
 
2235
    y = 2.0*y - 1.0;
 
2236
    
 
2237
    // Compute number of derivatives
 
2238
    unsigned int num_derivatives = 1;
 
2239
    
 
2240
    for (unsigned int j = 0; j < n; j++)
 
2241
      num_derivatives *= 2;
 
2242
    
 
2243
    
 
2244
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
2245
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
2246
    
 
2247
    for (unsigned int j = 0; j < num_derivatives; j++)
 
2248
    {
 
2249
      combinations[j] = new unsigned int [n];
 
2250
      for (unsigned int k = 0; k < n; k++)
 
2251
        combinations[j][k] = 0;
 
2252
    }
 
2253
    
 
2254
    // Generate combinations of derivatives
 
2255
    for (unsigned int row = 1; row < num_derivatives; row++)
 
2256
    {
 
2257
      for (unsigned int num = 0; num < row; num++)
 
2258
      {
 
2259
        for (unsigned int col = n-1; col+1 > 0; col--)
 
2260
        {
 
2261
          if (combinations[row][col] + 1 > 1)
 
2262
            combinations[row][col] = 0;
 
2263
          else
 
2264
          {
 
2265
            combinations[row][col] += 1;
 
2266
            break;
 
2267
          }
 
2268
        }
 
2269
      }
 
2270
    }
 
2271
    
 
2272
    // Compute inverse of Jacobian
 
2273
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
2274
    
 
2275
    // Declare transformation matrix
 
2276
    // Declare pointer to two dimensional array and initialise
 
2277
    double **transform = new double *[num_derivatives];
 
2278
    
 
2279
    for (unsigned int j = 0; j < num_derivatives; j++)
 
2280
    {
 
2281
      transform[j] = new double [num_derivatives];
 
2282
      for (unsigned int k = 0; k < num_derivatives; k++)
 
2283
        transform[j][k] = 1;
 
2284
    }
 
2285
    
 
2286
    // Construct transformation matrix
 
2287
    for (unsigned int row = 0; row < num_derivatives; row++)
 
2288
    {
 
2289
      for (unsigned int col = 0; col < num_derivatives; col++)
 
2290
      {
 
2291
        for (unsigned int k = 0; k < n; k++)
 
2292
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
2293
      }
 
2294
    }
 
2295
    
 
2296
    // Reset values
 
2297
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
 
2298
      values[j] = 0;
 
2299
    
 
2300
    // Map degree of freedom to element degree of freedom
 
2301
    const unsigned int dof = i;
 
2302
    
 
2303
    // Generate scalings
 
2304
    const double scalings_y_0 = 1;
 
2305
    
 
2306
    // Compute psitilde_a
 
2307
    const double psitilde_a_0 = 1;
 
2308
    
 
2309
    // Compute psitilde_bs
 
2310
    const double psitilde_bs_0_0 = 1;
 
2311
    
 
2312
    // Compute basisvalues
 
2313
    const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
2314
    
 
2315
    // Table(s) of coefficients
 
2316
    static const double coefficients0[1][1] = \
 
2317
    {{1.41421356}};
 
2318
    
 
2319
    // Interesting (new) part
 
2320
    // Tables of derivatives of the polynomial base (transpose)
 
2321
    static const double dmats0[1][1] = \
 
2322
    {{0}};
 
2323
    
 
2324
    static const double dmats1[1][1] = \
 
2325
    {{0}};
 
2326
    
 
2327
    // Compute reference derivatives
 
2328
    // Declare pointer to array of derivatives on FIAT element
 
2329
    double *derivatives = new double [num_derivatives];
 
2330
    
 
2331
    // Declare coefficients
 
2332
    double coeff0_0 = 0;
 
2333
    
 
2334
    // Declare new coefficients
 
2335
    double new_coeff0_0 = 0;
 
2336
    
 
2337
    // Loop possible derivatives
 
2338
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
2339
    {
 
2340
      // Get values from coefficients array
 
2341
      new_coeff0_0 = coefficients0[dof][0];
 
2342
    
 
2343
      // Loop derivative order
 
2344
      for (unsigned int j = 0; j < n; j++)
 
2345
      {
 
2346
        // Update old coefficients
 
2347
        coeff0_0 = new_coeff0_0;
 
2348
    
 
2349
        if(combinations[deriv_num][j] == 0)
 
2350
        {
 
2351
          new_coeff0_0 = coeff0_0*dmats0[0][0];
 
2352
        }
 
2353
        if(combinations[deriv_num][j] == 1)
 
2354
        {
 
2355
          new_coeff0_0 = coeff0_0*dmats1[0][0];
 
2356
        }
 
2357
    
 
2358
      }
 
2359
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
2360
      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
 
2361
    }
 
2362
    
 
2363
    // Transform derivatives back to physical element
 
2364
    for (unsigned int row = 0; row < num_derivatives; row++)
 
2365
    {
 
2366
      for (unsigned int col = 0; col < num_derivatives; col++)
 
2367
      {
 
2368
        values[row] += transform[row][col]*derivatives[col];
 
2369
      }
 
2370
    }
 
2371
    // Delete pointer to array of derivatives on FIAT element
 
2372
    delete [] derivatives;
 
2373
    
 
2374
    // Delete pointer to array of combinations of derivatives and transform
 
2375
    for (unsigned int row = 0; row < num_derivatives; row++)
 
2376
    {
 
2377
      delete [] combinations[row];
 
2378
      delete [] transform[row];
 
2379
    }
 
2380
    
 
2381
    delete [] combinations;
 
2382
    delete [] transform;
 
2383
  }
 
2384
 
 
2385
  /// Evaluate order n derivatives of all basis functions at given point in cell
 
2386
  virtual void evaluate_basis_derivatives_all(unsigned int n,
 
2387
                                              double* values,
 
2388
                                              const double* coordinates,
 
2389
                                              const ufc::cell& c) const
 
2390
  {
 
2391
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
2392
  }
 
2393
 
 
2394
  /// Evaluate linear functional for dof i on the function f
 
2395
  virtual double evaluate_dof(unsigned int i,
 
2396
                              const ufc::function& f,
 
2397
                              const ufc::cell& c) const
 
2398
  {
 
2399
    // The reference points, direction and weights:
 
2400
    static const double X[1][1][2] = {{{0.333333333, 0.333333333}}};
 
2401
    static const double W[1][1] = {{1}};
 
2402
    static const double D[1][1][1] = {{{1}}};
 
2403
    
 
2404
    const double * const * x = c.coordinates;
 
2405
    double result = 0.0;
 
2406
    // Iterate over the points:
 
2407
    // Evaluate basis functions for affine mapping
 
2408
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
2409
    const double w1 = X[i][0][0];
 
2410
    const double w2 = X[i][0][1];
 
2411
    
 
2412
    // Compute affine mapping y = F(X)
 
2413
    double y[2];
 
2414
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
2415
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
2416
    
 
2417
    // Evaluate function at physical points
 
2418
    double values[1];
 
2419
    f.evaluate(values, y, c);
 
2420
    
 
2421
    // Map function values using appropriate mapping
 
2422
    // Affine map: Do nothing
 
2423
    
 
2424
    // Note that we do not map the weights (yet).
 
2425
    
 
2426
    // Take directional components
 
2427
    for(int k = 0; k < 1; k++)
 
2428
      result += values[k]*D[i][0][k];
 
2429
    // Multiply by weights
 
2430
    result *= W[i][0];
 
2431
    
 
2432
    return result;
 
2433
  }
 
2434
 
 
2435
  /// Evaluate linear functionals for all dofs on the function f
 
2436
  virtual void evaluate_dofs(double* values,
 
2437
                             const ufc::function& f,
 
2438
                             const ufc::cell& c) const
 
2439
  {
 
2440
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
2441
  }
 
2442
 
 
2443
  /// Interpolate vertex values from dof values
 
2444
  virtual void interpolate_vertex_values(double* vertex_values,
 
2445
                                         const double* dof_values,
 
2446
                                         const ufc::cell& c) const
 
2447
  {
 
2448
    // Evaluate at vertices and use affine mapping
 
2449
    vertex_values[0] = dof_values[0];
 
2450
    vertex_values[1] = dof_values[0];
 
2451
    vertex_values[2] = dof_values[0];
 
2452
  }
 
2453
 
 
2454
  /// Return the number of sub elements (for a mixed element)
 
2455
  virtual unsigned int num_sub_elements() const
 
2456
  {
 
2457
    return 1;
 
2458
  }
 
2459
 
 
2460
  /// Create a new finite element for sub element i (for a mixed element)
 
2461
  virtual ufc::finite_element* create_sub_element(unsigned int i) const
 
2462
  {
 
2463
    return new mixedpoisson_0_finite_element_1_1();
 
2464
  }
 
2465
 
 
2466
};
 
2467
 
 
2468
/// This class defines the interface for a finite element.
 
2469
 
 
2470
class mixedpoisson_0_finite_element_1: public ufc::finite_element
 
2471
{
 
2472
public:
 
2473
 
 
2474
  /// Constructor
 
2475
  mixedpoisson_0_finite_element_1() : ufc::finite_element()
 
2476
  {
 
2477
    // Do nothing
 
2478
  }
 
2479
 
 
2480
  /// Destructor
 
2481
  virtual ~mixedpoisson_0_finite_element_1()
 
2482
  {
 
2483
    // Do nothing
 
2484
  }
 
2485
 
 
2486
  /// Return a string identifying the finite element
 
2487
  virtual const char* signature() const
 
2488
  {
 
2489
    return "MixedElement([FiniteElement('Brezzi-Douglas-Marini', 'triangle', 1), FiniteElement('Discontinuous Lagrange', 'triangle', 0)])";
 
2490
  }
 
2491
 
 
2492
  /// Return the cell shape
 
2493
  virtual ufc::shape cell_shape() const
 
2494
  {
 
2495
    return ufc::triangle;
 
2496
  }
 
2497
 
 
2498
  /// Return the dimension of the finite element function space
 
2499
  virtual unsigned int space_dimension() const
 
2500
  {
 
2501
    return 7;
 
2502
  }
 
2503
 
 
2504
  /// Return the rank of the value space
 
2505
  virtual unsigned int value_rank() const
 
2506
  {
 
2507
    return 1;
 
2508
  }
 
2509
 
 
2510
  /// Return the dimension of the value space for axis i
 
2511
  virtual unsigned int value_dimension(unsigned int i) const
 
2512
  {
 
2513
    return 3;
 
2514
  }
 
2515
 
 
2516
  /// Evaluate basis function i at given point in cell
 
2517
  virtual void evaluate_basis(unsigned int i,
 
2518
                              double* values,
 
2519
                              const double* coordinates,
 
2520
                              const ufc::cell& c) const
 
2521
  {
 
2522
    // Extract vertex coordinates
 
2523
    const double * const * element_coordinates = c.coordinates;
 
2524
    
 
2525
    // Compute Jacobian of affine map from reference cell
 
2526
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
2527
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
2528
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
2529
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
2530
    
 
2531
    // Compute determinant of Jacobian
 
2532
    const double detJ = J_00*J_11 - J_01*J_10;
 
2533
    
 
2534
    // Compute inverse of Jacobian
 
2535
    
 
2536
    // Get coordinates and map to the reference (UFC) element
 
2537
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
2538
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
2539
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
2540
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
2541
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
2542
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
2543
    
 
2544
    // Map coordinates to the reference square
 
2545
    if (std::abs(y - 1.0) < 1e-08)
 
2546
      x = -1.0;
 
2547
    else
 
2548
      x = 2.0 *x/(1.0 - y) - 1.0;
 
2549
    y = 2.0*y - 1.0;
 
2550
    
 
2551
    // Reset values
 
2552
    values[0] = 0;
 
2553
    values[1] = 0;
 
2554
    values[2] = 0;
 
2555
    
 
2556
    if (0 <= i && i <= 5)
 
2557
    {
 
2558
      // Map degree of freedom to element degree of freedom
 
2559
      const unsigned int dof = i;
 
2560
    
 
2561
      // Generate scalings
 
2562
      const double scalings_y_0 = 1;
 
2563
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
2564
    
 
2565
      // Compute psitilde_a
 
2566
      const double psitilde_a_0 = 1;
 
2567
      const double psitilde_a_1 = x;
 
2568
    
 
2569
      // Compute psitilde_bs
 
2570
      const double psitilde_bs_0_0 = 1;
 
2571
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
2572
      const double psitilde_bs_1_0 = 1;
 
2573
    
 
2574
      // Compute basisvalues
 
2575
      const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
2576
      const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
2577
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
2578
    
 
2579
      // Table(s) of coefficients
 
2580
      static const double coefficients0[6][3] =   \
 
2581
      {{0.942809042, 0.577350269, -0.333333333},
 
2582
      {-0.471404521, -0.288675135, 0.166666667},
 
2583
      {0.471404521, -0.577350269, -0.666666667},
 
2584
      {0.471404521, 0.288675135, 0.833333333},
 
2585
      {-0.471404521, -0.288675135, 0.166666667},
 
2586
      {0.942809042, 0.577350269, -0.333333333}};
 
2587
    
 
2588
      static const double coefficients1[6][3] =   \
 
2589
      {{-0.471404521, 0, -0.333333333},
 
2590
      {0.942809042, 0, 0.666666667},
 
2591
      {0.471404521, 0, 0.333333333},
 
2592
      {-0.942809042, 0, -0.666666667},
 
2593
      {-0.471404521, 0.866025404, 0.166666667},
 
2594
      {-0.471404521, -0.866025404, 0.166666667}};
 
2595
    
 
2596
      // Extract relevant coefficients
 
2597
      const double coeff0_0 =   coefficients0[dof][0];
 
2598
      const double coeff0_1 =   coefficients0[dof][1];
 
2599
      const double coeff0_2 =   coefficients0[dof][2];
 
2600
      const double coeff1_0 =   coefficients1[dof][0];
 
2601
      const double coeff1_1 =   coefficients1[dof][1];
 
2602
      const double coeff1_2 =   coefficients1[dof][2];
 
2603
    
 
2604
      // Compute value(s)
 
2605
      const double tmp0_0 = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
2606
      const double tmp0_1 = coeff1_0*basisvalue0 + coeff1_1*basisvalue1 + coeff1_2*basisvalue2;
 
2607
      // Using contravariant Piola transform to map values back to the physical element
 
2608
      values[0] = (1.0/detJ)*(J_00*tmp0_0 + J_01*tmp0_1);
 
2609
      values[1] = (1.0/detJ)*(J_10*tmp0_0 + J_11*tmp0_1);
 
2610
    }
 
2611
    
 
2612
    if (6 <= i && i <= 6)
 
2613
    {
 
2614
      // Map degree of freedom to element degree of freedom
 
2615
      const unsigned int dof = i - 6;
 
2616
    
 
2617
      // Generate scalings
 
2618
      const double scalings_y_0 = 1;
 
2619
    
 
2620
      // Compute psitilde_a
 
2621
      const double psitilde_a_0 = 1;
 
2622
    
 
2623
      // Compute psitilde_bs
 
2624
      const double psitilde_bs_0_0 = 1;
 
2625
    
 
2626
      // Compute basisvalues
 
2627
      const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
2628
    
 
2629
      // Table(s) of coefficients
 
2630
      static const double coefficients0[1][1] =   \
 
2631
      {{1.41421356}};
 
2632
    
 
2633
      // Extract relevant coefficients
 
2634
      const double coeff0_0 =   coefficients0[dof][0];
 
2635
    
 
2636
      // Compute value(s)
 
2637
      values[2] = coeff0_0*basisvalue0;
 
2638
    }
 
2639
    
 
2640
  }
 
2641
 
 
2642
  /// Evaluate all basis functions at given point in cell
 
2643
  virtual void evaluate_basis_all(double* values,
 
2644
                                  const double* coordinates,
 
2645
                                  const ufc::cell& c) const
 
2646
  {
 
2647
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
2648
  }
 
2649
 
 
2650
  /// Evaluate order n derivatives of basis function i at given point in cell
 
2651
  virtual void evaluate_basis_derivatives(unsigned int i,
 
2652
                                          unsigned int n,
 
2653
                                          double* values,
 
2654
                                          const double* coordinates,
 
2655
                                          const ufc::cell& c) const
 
2656
  {
 
2657
    // Extract vertex coordinates
 
2658
    const double * const * element_coordinates = c.coordinates;
 
2659
    
 
2660
    // Compute Jacobian of affine map from reference cell
 
2661
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
2662
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
2663
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
2664
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
2665
    
 
2666
    // Compute determinant of Jacobian
 
2667
    const double detJ = J_00*J_11 - J_01*J_10;
 
2668
    
 
2669
    // Compute inverse of Jacobian
 
2670
    
 
2671
    // Get coordinates and map to the reference (UFC) element
 
2672
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
2673
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
2674
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
2675
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
2676
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
2677
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
2678
    
 
2679
    // Map coordinates to the reference square
 
2680
    if (std::abs(y - 1.0) < 1e-08)
 
2681
      x = -1.0;
 
2682
    else
 
2683
      x = 2.0 *x/(1.0 - y) - 1.0;
 
2684
    y = 2.0*y - 1.0;
 
2685
    
 
2686
    // Compute number of derivatives
 
2687
    unsigned int num_derivatives = 1;
 
2688
    
 
2689
    for (unsigned int j = 0; j < n; j++)
 
2690
      num_derivatives *= 2;
 
2691
    
 
2692
    
 
2693
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
2694
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
2695
    
 
2696
    for (unsigned int j = 0; j < num_derivatives; j++)
 
2697
    {
 
2698
      combinations[j] = new unsigned int [n];
 
2699
      for (unsigned int k = 0; k < n; k++)
 
2700
        combinations[j][k] = 0;
 
2701
    }
 
2702
    
 
2703
    // Generate combinations of derivatives
 
2704
    for (unsigned int row = 1; row < num_derivatives; row++)
 
2705
    {
 
2706
      for (unsigned int num = 0; num < row; num++)
 
2707
      {
 
2708
        for (unsigned int col = n-1; col+1 > 0; col--)
 
2709
        {
 
2710
          if (combinations[row][col] + 1 > 1)
 
2711
            combinations[row][col] = 0;
 
2712
          else
 
2713
          {
 
2714
            combinations[row][col] += 1;
 
2715
            break;
 
2716
          }
 
2717
        }
 
2718
      }
 
2719
    }
 
2720
    
 
2721
    // Compute inverse of Jacobian
 
2722
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
2723
    
 
2724
    // Declare transformation matrix
 
2725
    // Declare pointer to two dimensional array and initialise
 
2726
    double **transform = new double *[num_derivatives];
 
2727
    
 
2728
    for (unsigned int j = 0; j < num_derivatives; j++)
 
2729
    {
 
2730
      transform[j] = new double [num_derivatives];
 
2731
      for (unsigned int k = 0; k < num_derivatives; k++)
 
2732
        transform[j][k] = 1;
 
2733
    }
 
2734
    
 
2735
    // Construct transformation matrix
 
2736
    for (unsigned int row = 0; row < num_derivatives; row++)
 
2737
    {
 
2738
      for (unsigned int col = 0; col < num_derivatives; col++)
 
2739
      {
 
2740
        for (unsigned int k = 0; k < n; k++)
 
2741
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
2742
      }
 
2743
    }
 
2744
    
 
2745
    // Reset values
 
2746
    for (unsigned int j = 0; j < 3*num_derivatives; j++)
 
2747
      values[j] = 0;
 
2748
    
 
2749
    if (0 <= i && i <= 5)
 
2750
    {
 
2751
      // Map degree of freedom to element degree of freedom
 
2752
      const unsigned int dof = i;
 
2753
    
 
2754
      // Generate scalings
 
2755
      const double scalings_y_0 = 1;
 
2756
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
2757
    
 
2758
      // Compute psitilde_a
 
2759
      const double psitilde_a_0 = 1;
 
2760
      const double psitilde_a_1 = x;
 
2761
    
 
2762
      // Compute psitilde_bs
 
2763
      const double psitilde_bs_0_0 = 1;
 
2764
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
2765
      const double psitilde_bs_1_0 = 1;
 
2766
    
 
2767
      // Compute basisvalues
 
2768
      const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
2769
      const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
2770
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
2771
    
 
2772
      // Table(s) of coefficients
 
2773
      static const double coefficients0[6][3] =   \
 
2774
      {{0.942809042, 0.577350269, -0.333333333},
 
2775
      {-0.471404521, -0.288675135, 0.166666667},
 
2776
      {0.471404521, -0.577350269, -0.666666667},
 
2777
      {0.471404521, 0.288675135, 0.833333333},
 
2778
      {-0.471404521, -0.288675135, 0.166666667},
 
2779
      {0.942809042, 0.577350269, -0.333333333}};
 
2780
    
 
2781
      static const double coefficients1[6][3] =   \
 
2782
      {{-0.471404521, 0, -0.333333333},
 
2783
      {0.942809042, 0, 0.666666667},
 
2784
      {0.471404521, 0, 0.333333333},
 
2785
      {-0.942809042, 0, -0.666666667},
 
2786
      {-0.471404521, 0.866025404, 0.166666667},
 
2787
      {-0.471404521, -0.866025404, 0.166666667}};
 
2788
    
 
2789
      // Interesting (new) part
 
2790
      // Tables of derivatives of the polynomial base (transpose)
 
2791
      static const double dmats0[3][3] =   \
 
2792
      {{0, 0, 0},
 
2793
      {4.89897949, 0, 0},
 
2794
      {0, 0, 0}};
 
2795
    
 
2796
      static const double dmats1[3][3] =   \
 
2797
      {{0, 0, 0},
 
2798
      {2.44948974, 0, 0},
 
2799
      {4.24264069, 0, 0}};
 
2800
    
 
2801
      // Compute reference derivatives
 
2802
      // Declare pointer to array of derivatives on FIAT element
 
2803
      double *derivatives = new double [2*num_derivatives];
 
2804
    
 
2805
      // Declare coefficients
 
2806
      double coeff0_0 = 0;
 
2807
      double coeff0_1 = 0;
 
2808
      double coeff0_2 = 0;
 
2809
      double coeff1_0 = 0;
 
2810
      double coeff1_1 = 0;
 
2811
      double coeff1_2 = 0;
 
2812
    
 
2813
      // Declare new coefficients
 
2814
      double new_coeff0_0 = 0;
 
2815
      double new_coeff0_1 = 0;
 
2816
      double new_coeff0_2 = 0;
 
2817
      double new_coeff1_0 = 0;
 
2818
      double new_coeff1_1 = 0;
 
2819
      double new_coeff1_2 = 0;
 
2820
    
 
2821
      // Loop possible derivatives
 
2822
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
2823
      {
 
2824
        // Get values from coefficients array
 
2825
        new_coeff0_0 = coefficients0[dof][0];
 
2826
        new_coeff0_1 = coefficients0[dof][1];
 
2827
        new_coeff0_2 = coefficients0[dof][2];
 
2828
        new_coeff1_0 = coefficients1[dof][0];
 
2829
        new_coeff1_1 = coefficients1[dof][1];
 
2830
        new_coeff1_2 = coefficients1[dof][2];
 
2831
    
 
2832
        // Loop derivative order
 
2833
        for (unsigned int j = 0; j < n; j++)
 
2834
        {
 
2835
          // Update old coefficients
 
2836
          coeff0_0 = new_coeff0_0;
 
2837
          coeff0_1 = new_coeff0_1;
 
2838
          coeff0_2 = new_coeff0_2;
 
2839
          coeff1_0 = new_coeff1_0;
 
2840
          coeff1_1 = new_coeff1_1;
 
2841
          coeff1_2 = new_coeff1_2;
 
2842
    
 
2843
          if(combinations[deriv_num][j] == 0)
 
2844
          {
 
2845
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
2846
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
2847
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
2848
            new_coeff1_0 = coeff1_0*dmats0[0][0] + coeff1_1*dmats0[1][0] + coeff1_2*dmats0[2][0];
 
2849
            new_coeff1_1 = coeff1_0*dmats0[0][1] + coeff1_1*dmats0[1][1] + coeff1_2*dmats0[2][1];
 
2850
            new_coeff1_2 = coeff1_0*dmats0[0][2] + coeff1_1*dmats0[1][2] + coeff1_2*dmats0[2][2];
 
2851
          }
 
2852
          if(combinations[deriv_num][j] == 1)
 
2853
          {
 
2854
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
2855
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
2856
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
2857
            new_coeff1_0 = coeff1_0*dmats1[0][0] + coeff1_1*dmats1[1][0] + coeff1_2*dmats1[2][0];
 
2858
            new_coeff1_1 = coeff1_0*dmats1[0][1] + coeff1_1*dmats1[1][1] + coeff1_2*dmats1[2][1];
 
2859
            new_coeff1_2 = coeff1_0*dmats1[0][2] + coeff1_1*dmats1[1][2] + coeff1_2*dmats1[2][2];
 
2860
          }
 
2861
    
 
2862
        }
 
2863
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
2864
        // Correct values by the contravariant Piola transform
 
2865
        const double tmp0_0 = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
2866
        const double tmp0_1 = new_coeff1_0*basisvalue0 + new_coeff1_1*basisvalue1 + new_coeff1_2*basisvalue2;
 
2867
        derivatives[deriv_num] = (1.0/detJ)*(J_00*tmp0_0 + J_01*tmp0_1);
 
2868
        derivatives[num_derivatives + deriv_num] = (1.0/detJ)*(J_10*tmp0_0 + J_11*tmp0_1);
 
2869
      }
 
2870
    
 
2871
      // Transform derivatives back to physical element
 
2872
      for (unsigned int row = 0; row < num_derivatives; row++)
 
2873
      {
 
2874
        for (unsigned int col = 0; col < num_derivatives; col++)
 
2875
        {
 
2876
          values[row] += transform[row][col]*derivatives[col];
 
2877
          values[num_derivatives + row] += transform[row][col]*derivatives[num_derivatives + col];
 
2878
        }
 
2879
      }
 
2880
      // Delete pointer to array of derivatives on FIAT element
 
2881
      delete [] derivatives;
 
2882
    
 
2883
      // Delete pointer to array of combinations of derivatives and transform
 
2884
      for (unsigned int row = 0; row < num_derivatives; row++)
 
2885
      {
 
2886
        delete [] combinations[row];
 
2887
        delete [] transform[row];
 
2888
      }
 
2889
    
 
2890
      delete [] combinations;
 
2891
      delete [] transform;
 
2892
    }
 
2893
    
 
2894
    if (6 <= i && i <= 6)
 
2895
    {
 
2896
      // Map degree of freedom to element degree of freedom
 
2897
      const unsigned int dof = i - 6;
 
2898
    
 
2899
      // Generate scalings
 
2900
      const double scalings_y_0 = 1;
 
2901
    
 
2902
      // Compute psitilde_a
 
2903
      const double psitilde_a_0 = 1;
 
2904
    
 
2905
      // Compute psitilde_bs
 
2906
      const double psitilde_bs_0_0 = 1;
 
2907
    
 
2908
      // Compute basisvalues
 
2909
      const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
2910
    
 
2911
      // Table(s) of coefficients
 
2912
      static const double coefficients0[1][1] =   \
 
2913
      {{1.41421356}};
 
2914
    
 
2915
      // Interesting (new) part
 
2916
      // Tables of derivatives of the polynomial base (transpose)
 
2917
      static const double dmats0[1][1] =   \
 
2918
      {{0}};
 
2919
    
 
2920
      static const double dmats1[1][1] =   \
 
2921
      {{0}};
 
2922
    
 
2923
      // Compute reference derivatives
 
2924
      // Declare pointer to array of derivatives on FIAT element
 
2925
      double *derivatives = new double [num_derivatives];
 
2926
    
 
2927
      // Declare coefficients
 
2928
      double coeff0_0 = 0;
 
2929
    
 
2930
      // Declare new coefficients
 
2931
      double new_coeff0_0 = 0;
 
2932
    
 
2933
      // Loop possible derivatives
 
2934
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
2935
      {
 
2936
        // Get values from coefficients array
 
2937
        new_coeff0_0 = coefficients0[dof][0];
 
2938
    
 
2939
        // Loop derivative order
 
2940
        for (unsigned int j = 0; j < n; j++)
 
2941
        {
 
2942
          // Update old coefficients
 
2943
          coeff0_0 = new_coeff0_0;
 
2944
    
 
2945
          if(combinations[deriv_num][j] == 0)
 
2946
          {
 
2947
            new_coeff0_0 = coeff0_0*dmats0[0][0];
 
2948
          }
 
2949
          if(combinations[deriv_num][j] == 1)
 
2950
          {
 
2951
            new_coeff0_0 = coeff0_0*dmats1[0][0];
 
2952
          }
 
2953
    
 
2954
        }
 
2955
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
2956
        derivatives[deriv_num] = new_coeff0_0*basisvalue0;
 
2957
      }
 
2958
    
 
2959
      // Transform derivatives back to physical element
 
2960
      for (unsigned int row = 0; row < num_derivatives; row++)
 
2961
      {
 
2962
        for (unsigned int col = 0; col < num_derivatives; col++)
 
2963
        {
 
2964
          values[2*num_derivatives + row] += transform[row][col]*derivatives[col];
 
2965
        }
 
2966
      }
 
2967
      // Delete pointer to array of derivatives on FIAT element
 
2968
      delete [] derivatives;
 
2969
    
 
2970
      // Delete pointer to array of combinations of derivatives and transform
 
2971
      for (unsigned int row = 0; row < num_derivatives; row++)
 
2972
      {
 
2973
        delete [] combinations[row];
 
2974
        delete [] transform[row];
 
2975
      }
 
2976
    
 
2977
      delete [] combinations;
 
2978
      delete [] transform;
 
2979
    }
 
2980
    
 
2981
  }
 
2982
 
 
2983
  /// Evaluate order n derivatives of all basis functions at given point in cell
 
2984
  virtual void evaluate_basis_derivatives_all(unsigned int n,
 
2985
                                              double* values,
 
2986
                                              const double* coordinates,
 
2987
                                              const ufc::cell& c) const
 
2988
  {
 
2989
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
2990
  }
 
2991
 
 
2992
  /// Evaluate linear functional for dof i on the function f
 
2993
  virtual double evaluate_dof(unsigned int i,
 
2994
                              const ufc::function& f,
 
2995
                              const ufc::cell& c) const
 
2996
  {
 
2997
    // The reference points, direction and weights:
 
2998
    static const double X[7][1][2] = {{{0.666666667, 0.333333333}}, {{0.333333333, 0.666666667}}, {{0, 0.333333333}}, {{0, 0.666666667}}, {{0.333333333, 0}}, {{0.666666667, 0}}, {{0.333333333, 0.333333333}}};
 
2999
    static const double W[7][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}};
 
3000
    static const double D[7][1][3] = {{{1, 1, 0}}, {{1, 1, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{0, -1, 0}}, {{0, -1, 0}}, {{0, 0, 1}}};
 
3001
    
 
3002
    static const unsigned int mappings[7] = {1, 1, 1, 1, 1, 1, 0};
 
3003
    // Extract vertex coordinates
 
3004
    const double * const * x = c.coordinates;
 
3005
    
 
3006
    // Compute Jacobian of affine map from reference cell
 
3007
    const double J_00 = x[1][0] - x[0][0];
 
3008
    const double J_01 = x[2][0] - x[0][0];
 
3009
    const double J_10 = x[1][1] - x[0][1];
 
3010
    const double J_11 = x[2][1] - x[0][1];
 
3011
    
 
3012
    // Compute determinant of Jacobian
 
3013
    double detJ = J_00*J_11 - J_01*J_10;
 
3014
    
 
3015
    // Compute inverse of Jacobian
 
3016
    const double Jinv_00 =  J_11 / detJ;
 
3017
    const double Jinv_01 = -J_01 / detJ;
 
3018
    const double Jinv_10 = -J_10 / detJ;
 
3019
    const double Jinv_11 =  J_00 / detJ;
 
3020
    
 
3021
    double copyofvalues[3];
 
3022
    double result = 0.0;
 
3023
    // Iterate over the points:
 
3024
    // Evaluate basis functions for affine mapping
 
3025
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
3026
    const double w1 = X[i][0][0];
 
3027
    const double w2 = X[i][0][1];
 
3028
    
 
3029
    // Compute affine mapping y = F(X)
 
3030
    double y[2];
 
3031
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
3032
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
3033
    
 
3034
    // Evaluate function at physical points
 
3035
    double values[3];
 
3036
    f.evaluate(values, y, c);
 
3037
    
 
3038
    // Map function values using appropriate mapping
 
3039
    if (mappings[i] == 0) { 
 
3040
      // Affine map: Do nothing
 
3041
    } else if (mappings[i] == 1) {
 
3042
       // Copy old values:
 
3043
      copyofvalues[0] = values[0];
 
3044
      copyofvalues[1] = values[1];
 
3045
      // Do the inverse of div piola 
 
3046
      values[0] = detJ*(Jinv_00*copyofvalues[0]+Jinv_01*copyofvalues[1]);
 
3047
      values[1] = detJ*(Jinv_10*copyofvalues[0]+Jinv_11*copyofvalues[1]); 
 
3048
    } else { 
 
3049
       // Other mappings not applicable. 
 
3050
    }
 
3051
    
 
3052
    // Note that we do not map the weights (yet).
 
3053
    
 
3054
    // Take directional components
 
3055
    for(int k = 0; k < 3; k++)
 
3056
      result += values[k]*D[i][0][k];
 
3057
    // Multiply by weights
 
3058
    result *= W[i][0];
 
3059
    
 
3060
    return result;
 
3061
  }
 
3062
 
 
3063
  /// Evaluate linear functionals for all dofs on the function f
 
3064
  virtual void evaluate_dofs(double* values,
 
3065
                             const ufc::function& f,
 
3066
                             const ufc::cell& c) const
 
3067
  {
 
3068
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
3069
  }
 
3070
 
 
3071
  /// Interpolate vertex values from dof values
 
3072
  virtual void interpolate_vertex_values(double* vertex_values,
 
3073
                                         const double* dof_values,
 
3074
                                         const ufc::cell& c) const
 
3075
  {
 
3076
    // Extract vertex coordinates
 
3077
    const double * const * x = c.coordinates;
 
3078
    
 
3079
    // Compute Jacobian of affine map from reference cell
 
3080
    const double J_00 = x[1][0] - x[0][0];
 
3081
    const double J_01 = x[2][0] - x[0][0];
 
3082
    const double J_10 = x[1][1] - x[0][1];
 
3083
    const double J_11 = x[2][1] - x[0][1];
 
3084
    
 
3085
    // Compute determinant of Jacobian
 
3086
    double detJ = J_00*J_11 - J_01*J_10;
 
3087
    
 
3088
    // Compute inverse of Jacobian
 
3089
    // Evaluate at vertices and use Piola mapping
 
3090
    vertex_values[0] = (1.0/detJ)*(dof_values[2]*2*J_00 + dof_values[3]*J_00 + dof_values[4]*(-2*J_01) + dof_values[5]*J_01);
 
3091
    vertex_values[3] = (1.0/detJ)*(dof_values[0]*2*J_00 + dof_values[1]*J_00 + dof_values[4]*(J_00 + J_01) + dof_values[5]*(2*J_00 - 2*J_01));
 
3092
    vertex_values[6] = (1.0/detJ)*(dof_values[0]*J_01 + dof_values[1]*2*J_01 + dof_values[2]*(J_00 + J_01) + dof_values[3]*(2*J_00 - 2*J_01));
 
3093
    vertex_values[1] = (1.0/detJ)*(dof_values[2]*2*J_10 + dof_values[3]*J_10 + dof_values[4]*(-2*J_11) + dof_values[5]*J_11);
 
3094
    vertex_values[4] = (1.0/detJ)*(dof_values[0]*2*J_10 + dof_values[1]*J_10 + dof_values[4]*(J_10 + J_11) + dof_values[5]*(2*J_10 - 2*J_11));
 
3095
    vertex_values[7] = (1.0/detJ)*(dof_values[0]*J_11 + dof_values[1]*2*J_11 + dof_values[2]*(J_10 + J_11) + dof_values[3]*(2*J_10 - 2*J_11));
 
3096
    // Evaluate at vertices and use affine mapping
 
3097
    vertex_values[2] = dof_values[6];
 
3098
    vertex_values[5] = dof_values[6];
 
3099
    vertex_values[8] = dof_values[6];
 
3100
  }
 
3101
 
 
3102
  /// Return the number of sub elements (for a mixed element)
 
3103
  virtual unsigned int num_sub_elements() const
 
3104
  {
 
3105
    return 2;
 
3106
  }
 
3107
 
 
3108
  /// Create a new finite element for sub element i (for a mixed element)
 
3109
  virtual ufc::finite_element* create_sub_element(unsigned int i) const
 
3110
  {
 
3111
    switch ( i )
 
3112
    {
 
3113
    case 0:
 
3114
      return new mixedpoisson_0_finite_element_1_0();
 
3115
      break;
 
3116
    case 1:
 
3117
      return new mixedpoisson_0_finite_element_1_1();
 
3118
      break;
 
3119
    }
 
3120
    return 0;
 
3121
  }
 
3122
 
 
3123
};
 
3124
 
 
3125
/// This class defines the interface for a local-to-global mapping of
 
3126
/// degrees of freedom (dofs).
 
3127
 
 
3128
class mixedpoisson_0_dof_map_0_0: public ufc::dof_map
 
3129
{
 
3130
private:
 
3131
 
 
3132
  unsigned int __global_dimension;
 
3133
 
 
3134
public:
 
3135
 
 
3136
  /// Constructor
 
3137
  mixedpoisson_0_dof_map_0_0() : ufc::dof_map()
 
3138
  {
 
3139
    __global_dimension = 0;
 
3140
  }
 
3141
 
 
3142
  /// Destructor
 
3143
  virtual ~mixedpoisson_0_dof_map_0_0()
 
3144
  {
 
3145
    // Do nothing
 
3146
  }
 
3147
 
 
3148
  /// Return a string identifying the dof map
 
3149
  virtual const char* signature() const
 
3150
  {
 
3151
    return "FFC dof map for FiniteElement('Brezzi-Douglas-Marini', 'triangle', 1)";
 
3152
  }
 
3153
 
 
3154
  /// Return true iff mesh entities of topological dimension d are needed
 
3155
  virtual bool needs_mesh_entities(unsigned int d) const
 
3156
  {
 
3157
    switch ( d )
 
3158
    {
 
3159
    case 0:
 
3160
      return false;
 
3161
      break;
 
3162
    case 1:
 
3163
      return true;
 
3164
      break;
 
3165
    case 2:
 
3166
      return false;
 
3167
      break;
 
3168
    }
 
3169
    return false;
 
3170
  }
 
3171
 
 
3172
  /// Initialize dof map for mesh (return true iff init_cell() is needed)
 
3173
  virtual bool init_mesh(const ufc::mesh& m)
 
3174
  {
 
3175
    __global_dimension = 2*m.num_entities[1];
 
3176
    return false;
 
3177
  }
 
3178
 
 
3179
  /// Initialize dof map for given cell
 
3180
  virtual void init_cell(const ufc::mesh& m,
 
3181
                         const ufc::cell& c)
 
3182
  {
 
3183
    // Do nothing
 
3184
  }
 
3185
 
 
3186
  /// Finish initialization of dof map for cells
 
3187
  virtual void init_cell_finalize()
 
3188
  {
 
3189
    // Do nothing
 
3190
  }
 
3191
 
 
3192
  /// Return the dimension of the global finite element function space
 
3193
  virtual unsigned int global_dimension() const
 
3194
  {
 
3195
    return __global_dimension;
 
3196
  }
 
3197
 
 
3198
  /// Return the dimension of the local finite element function space for a cell
 
3199
  virtual unsigned int local_dimension(const ufc::cell& c) const
 
3200
  {
 
3201
    return 6;
 
3202
  }
 
3203
 
 
3204
  /// Return the maximum dimension of the local finite element function space
 
3205
  virtual unsigned int max_local_dimension() const
 
3206
  {
 
3207
    return 6;
 
3208
  }
 
3209
 
 
3210
  // Return the geometric dimension of the coordinates this dof map provides
 
3211
  virtual unsigned int geometric_dimension() const
 
3212
  {
 
3213
    return 2;
 
3214
  }
 
3215
 
 
3216
  /// Return the number of dofs on each cell facet
 
3217
  virtual unsigned int num_facet_dofs() const
 
3218
  {
 
3219
    return 2;
 
3220
  }
 
3221
 
 
3222
  /// Return the number of dofs associated with each cell entity of dimension d
 
3223
  virtual unsigned int num_entity_dofs(unsigned int d) const
 
3224
  {
 
3225
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
3226
  }
 
3227
 
 
3228
  /// Tabulate the local-to-global mapping of dofs on a cell
 
3229
  virtual void tabulate_dofs(unsigned int* dofs,
 
3230
                             const ufc::mesh& m,
 
3231
                             const ufc::cell& c) const
 
3232
  {
 
3233
    dofs[0] = 2*c.entity_indices[1][0];
 
3234
    dofs[1] = 2*c.entity_indices[1][0] + 1;
 
3235
    dofs[2] = 2*c.entity_indices[1][1];
 
3236
    dofs[3] = 2*c.entity_indices[1][1] + 1;
 
3237
    dofs[4] = 2*c.entity_indices[1][2];
 
3238
    dofs[5] = 2*c.entity_indices[1][2] + 1;
 
3239
  }
 
3240
 
 
3241
  /// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
3242
  virtual void tabulate_facet_dofs(unsigned int* dofs,
 
3243
                                   unsigned int facet) const
 
3244
  {
 
3245
    switch ( facet )
 
3246
    {
 
3247
    case 0:
 
3248
      dofs[0] = 0;
 
3249
      dofs[1] = 1;
 
3250
      break;
 
3251
    case 1:
 
3252
      dofs[0] = 2;
 
3253
      dofs[1] = 3;
 
3254
      break;
 
3255
    case 2:
 
3256
      dofs[0] = 4;
 
3257
      dofs[1] = 5;
 
3258
      break;
 
3259
    }
 
3260
  }
 
3261
 
 
3262
  /// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
3263
  virtual void tabulate_entity_dofs(unsigned int* dofs,
 
3264
                                    unsigned int d, unsigned int i) const
 
3265
  {
 
3266
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
3267
  }
 
3268
 
 
3269
  /// Tabulate the coordinates of all dofs on a cell
 
3270
  virtual void tabulate_coordinates(double** coordinates,
 
3271
                                    const ufc::cell& c) const
 
3272
  {
 
3273
    const double * const * x = c.coordinates;
 
3274
    coordinates[0][0] = 0.666666667*x[1][0] + 0.333333333*x[2][0];
 
3275
    coordinates[0][1] = 0.666666667*x[1][1] + 0.333333333*x[2][1];
 
3276
    coordinates[1][0] = 0.333333333*x[1][0] + 0.666666667*x[2][0];
 
3277
    coordinates[1][1] = 0.333333333*x[1][1] + 0.666666667*x[2][1];
 
3278
    coordinates[2][0] = 0.666666667*x[0][0] + 0.333333333*x[2][0];
 
3279
    coordinates[2][1] = 0.666666667*x[0][1] + 0.333333333*x[2][1];
 
3280
    coordinates[3][0] = 0.333333333*x[0][0] + 0.666666667*x[2][0];
 
3281
    coordinates[3][1] = 0.333333333*x[0][1] + 0.666666667*x[2][1];
 
3282
    coordinates[4][0] = 0.666666667*x[0][0] + 0.333333333*x[1][0];
 
3283
    coordinates[4][1] = 0.666666667*x[0][1] + 0.333333333*x[1][1];
 
3284
    coordinates[5][0] = 0.333333333*x[0][0] + 0.666666667*x[1][0];
 
3285
    coordinates[5][1] = 0.333333333*x[0][1] + 0.666666667*x[1][1];
 
3286
  }
 
3287
 
 
3288
  /// Return the number of sub dof maps (for a mixed element)
 
3289
  virtual unsigned int num_sub_dof_maps() const
 
3290
  {
 
3291
    return 1;
 
3292
  }
 
3293
 
 
3294
  /// Create a new dof_map for sub dof map i (for a mixed element)
 
3295
  virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
 
3296
  {
 
3297
    return new mixedpoisson_0_dof_map_0_0();
 
3298
  }
 
3299
 
 
3300
};
 
3301
 
 
3302
/// This class defines the interface for a local-to-global mapping of
 
3303
/// degrees of freedom (dofs).
 
3304
 
 
3305
class mixedpoisson_0_dof_map_0_1: public ufc::dof_map
 
3306
{
 
3307
private:
 
3308
 
 
3309
  unsigned int __global_dimension;
 
3310
 
 
3311
public:
 
3312
 
 
3313
  /// Constructor
 
3314
  mixedpoisson_0_dof_map_0_1() : ufc::dof_map()
 
3315
  {
 
3316
    __global_dimension = 0;
 
3317
  }
 
3318
 
 
3319
  /// Destructor
 
3320
  virtual ~mixedpoisson_0_dof_map_0_1()
 
3321
  {
 
3322
    // Do nothing
 
3323
  }
 
3324
 
 
3325
  /// Return a string identifying the dof map
 
3326
  virtual const char* signature() const
 
3327
  {
 
3328
    return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
 
3329
  }
 
3330
 
 
3331
  /// Return true iff mesh entities of topological dimension d are needed
 
3332
  virtual bool needs_mesh_entities(unsigned int d) const
 
3333
  {
 
3334
    switch ( d )
 
3335
    {
 
3336
    case 0:
 
3337
      return false;
 
3338
      break;
 
3339
    case 1:
 
3340
      return false;
 
3341
      break;
 
3342
    case 2:
 
3343
      return true;
 
3344
      break;
 
3345
    }
 
3346
    return false;
 
3347
  }
 
3348
 
 
3349
  /// Initialize dof map for mesh (return true iff init_cell() is needed)
 
3350
  virtual bool init_mesh(const ufc::mesh& m)
 
3351
  {
 
3352
    __global_dimension = m.num_entities[2];
 
3353
    return false;
 
3354
  }
 
3355
 
 
3356
  /// Initialize dof map for given cell
 
3357
  virtual void init_cell(const ufc::mesh& m,
 
3358
                         const ufc::cell& c)
 
3359
  {
 
3360
    // Do nothing
 
3361
  }
 
3362
 
 
3363
  /// Finish initialization of dof map for cells
 
3364
  virtual void init_cell_finalize()
 
3365
  {
 
3366
    // Do nothing
 
3367
  }
 
3368
 
 
3369
  /// Return the dimension of the global finite element function space
 
3370
  virtual unsigned int global_dimension() const
 
3371
  {
 
3372
    return __global_dimension;
 
3373
  }
 
3374
 
 
3375
  /// Return the dimension of the local finite element function space for a cell
 
3376
  virtual unsigned int local_dimension(const ufc::cell& c) const
 
3377
  {
 
3378
    return 1;
 
3379
  }
 
3380
 
 
3381
  /// Return the maximum dimension of the local finite element function space
 
3382
  virtual unsigned int max_local_dimension() const
 
3383
  {
 
3384
    return 1;
 
3385
  }
 
3386
 
 
3387
  // Return the geometric dimension of the coordinates this dof map provides
 
3388
  virtual unsigned int geometric_dimension() const
 
3389
  {
 
3390
    return 2;
 
3391
  }
 
3392
 
 
3393
  /// Return the number of dofs on each cell facet
 
3394
  virtual unsigned int num_facet_dofs() const
 
3395
  {
 
3396
    return 0;
 
3397
  }
 
3398
 
 
3399
  /// Return the number of dofs associated with each cell entity of dimension d
 
3400
  virtual unsigned int num_entity_dofs(unsigned int d) const
 
3401
  {
 
3402
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
3403
  }
 
3404
 
 
3405
  /// Tabulate the local-to-global mapping of dofs on a cell
 
3406
  virtual void tabulate_dofs(unsigned int* dofs,
 
3407
                             const ufc::mesh& m,
 
3408
                             const ufc::cell& c) const
 
3409
  {
 
3410
    dofs[0] = c.entity_indices[2][0];
 
3411
  }
 
3412
 
 
3413
  /// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
3414
  virtual void tabulate_facet_dofs(unsigned int* dofs,
 
3415
                                   unsigned int facet) const
 
3416
  {
 
3417
    switch ( facet )
 
3418
    {
 
3419
    case 0:
 
3420
      
 
3421
      break;
 
3422
    case 1:
 
3423
      
 
3424
      break;
 
3425
    case 2:
 
3426
      
 
3427
      break;
 
3428
    }
 
3429
  }
 
3430
 
 
3431
  /// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
3432
  virtual void tabulate_entity_dofs(unsigned int* dofs,
 
3433
                                    unsigned int d, unsigned int i) const
 
3434
  {
 
3435
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
3436
  }
 
3437
 
 
3438
  /// Tabulate the coordinates of all dofs on a cell
 
3439
  virtual void tabulate_coordinates(double** coordinates,
 
3440
                                    const ufc::cell& c) const
 
3441
  {
 
3442
    const double * const * x = c.coordinates;
 
3443
    coordinates[0][0] = 0.333333333*x[0][0] + 0.333333333*x[1][0] + 0.333333333*x[2][0];
 
3444
    coordinates[0][1] = 0.333333333*x[0][1] + 0.333333333*x[1][1] + 0.333333333*x[2][1];
 
3445
  }
 
3446
 
 
3447
  /// Return the number of sub dof maps (for a mixed element)
 
3448
  virtual unsigned int num_sub_dof_maps() const
 
3449
  {
 
3450
    return 1;
 
3451
  }
 
3452
 
 
3453
  /// Create a new dof_map for sub dof map i (for a mixed element)
 
3454
  virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
 
3455
  {
 
3456
    return new mixedpoisson_0_dof_map_0_1();
 
3457
  }
 
3458
 
 
3459
};
 
3460
 
 
3461
/// This class defines the interface for a local-to-global mapping of
 
3462
/// degrees of freedom (dofs).
 
3463
 
 
3464
class mixedpoisson_0_dof_map_0: public ufc::dof_map
 
3465
{
 
3466
private:
 
3467
 
 
3468
  unsigned int __global_dimension;
 
3469
 
 
3470
public:
 
3471
 
 
3472
  /// Constructor
 
3473
  mixedpoisson_0_dof_map_0() : ufc::dof_map()
 
3474
  {
 
3475
    __global_dimension = 0;
 
3476
  }
 
3477
 
 
3478
  /// Destructor
 
3479
  virtual ~mixedpoisson_0_dof_map_0()
 
3480
  {
 
3481
    // Do nothing
 
3482
  }
 
3483
 
 
3484
  /// Return a string identifying the dof map
 
3485
  virtual const char* signature() const
 
3486
  {
 
3487
    return "FFC dof map for MixedElement([FiniteElement('Brezzi-Douglas-Marini', 'triangle', 1), FiniteElement('Discontinuous Lagrange', 'triangle', 0)])";
 
3488
  }
 
3489
 
 
3490
  /// Return true iff mesh entities of topological dimension d are needed
 
3491
  virtual bool needs_mesh_entities(unsigned int d) const
 
3492
  {
 
3493
    switch ( d )
 
3494
    {
 
3495
    case 0:
 
3496
      return false;
 
3497
      break;
 
3498
    case 1:
 
3499
      return true;
 
3500
      break;
 
3501
    case 2:
 
3502
      return true;
 
3503
      break;
 
3504
    }
 
3505
    return false;
 
3506
  }
 
3507
 
 
3508
  /// Initialize dof map for mesh (return true iff init_cell() is needed)
 
3509
  virtual bool init_mesh(const ufc::mesh& m)
 
3510
  {
 
3511
    __global_dimension = 2*m.num_entities[1] + m.num_entities[2];
 
3512
    return false;
 
3513
  }
 
3514
 
 
3515
  /// Initialize dof map for given cell
 
3516
  virtual void init_cell(const ufc::mesh& m,
 
3517
                         const ufc::cell& c)
 
3518
  {
 
3519
    // Do nothing
 
3520
  }
 
3521
 
 
3522
  /// Finish initialization of dof map for cells
 
3523
  virtual void init_cell_finalize()
 
3524
  {
 
3525
    // Do nothing
 
3526
  }
 
3527
 
 
3528
  /// Return the dimension of the global finite element function space
 
3529
  virtual unsigned int global_dimension() const
 
3530
  {
 
3531
    return __global_dimension;
 
3532
  }
 
3533
 
 
3534
  /// Return the dimension of the local finite element function space for a cell
 
3535
  virtual unsigned int local_dimension(const ufc::cell& c) const
 
3536
  {
 
3537
    return 7;
 
3538
  }
 
3539
 
 
3540
  /// Return the maximum dimension of the local finite element function space
 
3541
  virtual unsigned int max_local_dimension() const
 
3542
  {
 
3543
    return 7;
 
3544
  }
 
3545
 
 
3546
  // Return the geometric dimension of the coordinates this dof map provides
 
3547
  virtual unsigned int geometric_dimension() const
 
3548
  {
 
3549
    return 2;
 
3550
  }
 
3551
 
 
3552
  /// Return the number of dofs on each cell facet
 
3553
  virtual unsigned int num_facet_dofs() const
 
3554
  {
 
3555
    return 2;
 
3556
  }
 
3557
 
 
3558
  /// Return the number of dofs associated with each cell entity of dimension d
 
3559
  virtual unsigned int num_entity_dofs(unsigned int d) const
 
3560
  {
 
3561
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
3562
  }
 
3563
 
 
3564
  /// Tabulate the local-to-global mapping of dofs on a cell
 
3565
  virtual void tabulate_dofs(unsigned int* dofs,
 
3566
                             const ufc::mesh& m,
 
3567
                             const ufc::cell& c) const
 
3568
  {
 
3569
    dofs[0] = 2*c.entity_indices[1][0];
 
3570
    dofs[1] = 2*c.entity_indices[1][0] + 1;
 
3571
    dofs[2] = 2*c.entity_indices[1][1];
 
3572
    dofs[3] = 2*c.entity_indices[1][1] + 1;
 
3573
    dofs[4] = 2*c.entity_indices[1][2];
 
3574
    dofs[5] = 2*c.entity_indices[1][2] + 1;
 
3575
    unsigned int offset = 2*m.num_entities[1];
 
3576
    dofs[6] = offset + c.entity_indices[2][0];
 
3577
  }
 
3578
 
 
3579
  /// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
3580
  virtual void tabulate_facet_dofs(unsigned int* dofs,
 
3581
                                   unsigned int facet) const
 
3582
  {
 
3583
    switch ( facet )
 
3584
    {
 
3585
    case 0:
 
3586
      dofs[0] = 0;
 
3587
      dofs[1] = 1;
 
3588
      break;
 
3589
    case 1:
 
3590
      dofs[0] = 2;
 
3591
      dofs[1] = 3;
 
3592
      break;
 
3593
    case 2:
 
3594
      dofs[0] = 4;
 
3595
      dofs[1] = 5;
 
3596
      break;
 
3597
    }
 
3598
  }
 
3599
 
 
3600
  /// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
3601
  virtual void tabulate_entity_dofs(unsigned int* dofs,
 
3602
                                    unsigned int d, unsigned int i) const
 
3603
  {
 
3604
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
3605
  }
 
3606
 
 
3607
  /// Tabulate the coordinates of all dofs on a cell
 
3608
  virtual void tabulate_coordinates(double** coordinates,
 
3609
                                    const ufc::cell& c) const
 
3610
  {
 
3611
    const double * const * x = c.coordinates;
 
3612
    coordinates[0][0] = 0.666666667*x[1][0] + 0.333333333*x[2][0];
 
3613
    coordinates[0][1] = 0.666666667*x[1][1] + 0.333333333*x[2][1];
 
3614
    coordinates[1][0] = 0.333333333*x[1][0] + 0.666666667*x[2][0];
 
3615
    coordinates[1][1] = 0.333333333*x[1][1] + 0.666666667*x[2][1];
 
3616
    coordinates[2][0] = 0.666666667*x[0][0] + 0.333333333*x[2][0];
 
3617
    coordinates[2][1] = 0.666666667*x[0][1] + 0.333333333*x[2][1];
 
3618
    coordinates[3][0] = 0.333333333*x[0][0] + 0.666666667*x[2][0];
 
3619
    coordinates[3][1] = 0.333333333*x[0][1] + 0.666666667*x[2][1];
 
3620
    coordinates[4][0] = 0.666666667*x[0][0] + 0.333333333*x[1][0];
 
3621
    coordinates[4][1] = 0.666666667*x[0][1] + 0.333333333*x[1][1];
 
3622
    coordinates[5][0] = 0.333333333*x[0][0] + 0.666666667*x[1][0];
 
3623
    coordinates[5][1] = 0.333333333*x[0][1] + 0.666666667*x[1][1];
 
3624
    coordinates[6][0] = 0.333333333*x[0][0] + 0.333333333*x[1][0] + 0.333333333*x[2][0];
 
3625
    coordinates[6][1] = 0.333333333*x[0][1] + 0.333333333*x[1][1] + 0.333333333*x[2][1];
 
3626
  }
 
3627
 
 
3628
  /// Return the number of sub dof maps (for a mixed element)
 
3629
  virtual unsigned int num_sub_dof_maps() const
 
3630
  {
 
3631
    return 2;
 
3632
  }
 
3633
 
 
3634
  /// Create a new dof_map for sub dof map i (for a mixed element)
 
3635
  virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
 
3636
  {
 
3637
    switch ( i )
 
3638
    {
 
3639
    case 0:
 
3640
      return new mixedpoisson_0_dof_map_0_0();
 
3641
      break;
 
3642
    case 1:
 
3643
      return new mixedpoisson_0_dof_map_0_1();
 
3644
      break;
 
3645
    }
 
3646
    return 0;
 
3647
  }
 
3648
 
 
3649
};
 
3650
 
 
3651
/// This class defines the interface for a local-to-global mapping of
 
3652
/// degrees of freedom (dofs).
 
3653
 
 
3654
class mixedpoisson_0_dof_map_1_0: public ufc::dof_map
 
3655
{
 
3656
private:
 
3657
 
 
3658
  unsigned int __global_dimension;
 
3659
 
 
3660
public:
 
3661
 
 
3662
  /// Constructor
 
3663
  mixedpoisson_0_dof_map_1_0() : ufc::dof_map()
 
3664
  {
 
3665
    __global_dimension = 0;
 
3666
  }
 
3667
 
 
3668
  /// Destructor
 
3669
  virtual ~mixedpoisson_0_dof_map_1_0()
 
3670
  {
 
3671
    // Do nothing
 
3672
  }
 
3673
 
 
3674
  /// Return a string identifying the dof map
 
3675
  virtual const char* signature() const
 
3676
  {
 
3677
    return "FFC dof map for FiniteElement('Brezzi-Douglas-Marini', 'triangle', 1)";
 
3678
  }
 
3679
 
 
3680
  /// Return true iff mesh entities of topological dimension d are needed
 
3681
  virtual bool needs_mesh_entities(unsigned int d) const
 
3682
  {
 
3683
    switch ( d )
 
3684
    {
 
3685
    case 0:
 
3686
      return false;
 
3687
      break;
 
3688
    case 1:
 
3689
      return true;
 
3690
      break;
 
3691
    case 2:
 
3692
      return false;
 
3693
      break;
 
3694
    }
 
3695
    return false;
 
3696
  }
 
3697
 
 
3698
  /// Initialize dof map for mesh (return true iff init_cell() is needed)
 
3699
  virtual bool init_mesh(const ufc::mesh& m)
 
3700
  {
 
3701
    __global_dimension = 2*m.num_entities[1];
 
3702
    return false;
 
3703
  }
 
3704
 
 
3705
  /// Initialize dof map for given cell
 
3706
  virtual void init_cell(const ufc::mesh& m,
 
3707
                         const ufc::cell& c)
 
3708
  {
 
3709
    // Do nothing
 
3710
  }
 
3711
 
 
3712
  /// Finish initialization of dof map for cells
 
3713
  virtual void init_cell_finalize()
 
3714
  {
 
3715
    // Do nothing
 
3716
  }
 
3717
 
 
3718
  /// Return the dimension of the global finite element function space
 
3719
  virtual unsigned int global_dimension() const
 
3720
  {
 
3721
    return __global_dimension;
 
3722
  }
 
3723
 
 
3724
  /// Return the dimension of the local finite element function space for a cell
 
3725
  virtual unsigned int local_dimension(const ufc::cell& c) const
 
3726
  {
 
3727
    return 6;
 
3728
  }
 
3729
 
 
3730
  /// Return the maximum dimension of the local finite element function space
 
3731
  virtual unsigned int max_local_dimension() const
 
3732
  {
 
3733
    return 6;
 
3734
  }
 
3735
 
 
3736
  // Return the geometric dimension of the coordinates this dof map provides
 
3737
  virtual unsigned int geometric_dimension() const
 
3738
  {
 
3739
    return 2;
 
3740
  }
 
3741
 
 
3742
  /// Return the number of dofs on each cell facet
 
3743
  virtual unsigned int num_facet_dofs() const
 
3744
  {
 
3745
    return 2;
 
3746
  }
 
3747
 
 
3748
  /// Return the number of dofs associated with each cell entity of dimension d
 
3749
  virtual unsigned int num_entity_dofs(unsigned int d) const
 
3750
  {
 
3751
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
3752
  }
 
3753
 
 
3754
  /// Tabulate the local-to-global mapping of dofs on a cell
 
3755
  virtual void tabulate_dofs(unsigned int* dofs,
 
3756
                             const ufc::mesh& m,
 
3757
                             const ufc::cell& c) const
 
3758
  {
 
3759
    dofs[0] = 2*c.entity_indices[1][0];
 
3760
    dofs[1] = 2*c.entity_indices[1][0] + 1;
 
3761
    dofs[2] = 2*c.entity_indices[1][1];
 
3762
    dofs[3] = 2*c.entity_indices[1][1] + 1;
 
3763
    dofs[4] = 2*c.entity_indices[1][2];
 
3764
    dofs[5] = 2*c.entity_indices[1][2] + 1;
 
3765
  }
 
3766
 
 
3767
  /// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
3768
  virtual void tabulate_facet_dofs(unsigned int* dofs,
 
3769
                                   unsigned int facet) const
 
3770
  {
 
3771
    switch ( facet )
 
3772
    {
 
3773
    case 0:
 
3774
      dofs[0] = 0;
 
3775
      dofs[1] = 1;
 
3776
      break;
 
3777
    case 1:
 
3778
      dofs[0] = 2;
 
3779
      dofs[1] = 3;
 
3780
      break;
 
3781
    case 2:
 
3782
      dofs[0] = 4;
 
3783
      dofs[1] = 5;
 
3784
      break;
 
3785
    }
 
3786
  }
 
3787
 
 
3788
  /// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
3789
  virtual void tabulate_entity_dofs(unsigned int* dofs,
 
3790
                                    unsigned int d, unsigned int i) const
 
3791
  {
 
3792
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
3793
  }
 
3794
 
 
3795
  /// Tabulate the coordinates of all dofs on a cell
 
3796
  virtual void tabulate_coordinates(double** coordinates,
 
3797
                                    const ufc::cell& c) const
 
3798
  {
 
3799
    const double * const * x = c.coordinates;
 
3800
    coordinates[0][0] = 0.666666667*x[1][0] + 0.333333333*x[2][0];
 
3801
    coordinates[0][1] = 0.666666667*x[1][1] + 0.333333333*x[2][1];
 
3802
    coordinates[1][0] = 0.333333333*x[1][0] + 0.666666667*x[2][0];
 
3803
    coordinates[1][1] = 0.333333333*x[1][1] + 0.666666667*x[2][1];
 
3804
    coordinates[2][0] = 0.666666667*x[0][0] + 0.333333333*x[2][0];
 
3805
    coordinates[2][1] = 0.666666667*x[0][1] + 0.333333333*x[2][1];
 
3806
    coordinates[3][0] = 0.333333333*x[0][0] + 0.666666667*x[2][0];
 
3807
    coordinates[3][1] = 0.333333333*x[0][1] + 0.666666667*x[2][1];
 
3808
    coordinates[4][0] = 0.666666667*x[0][0] + 0.333333333*x[1][0];
 
3809
    coordinates[4][1] = 0.666666667*x[0][1] + 0.333333333*x[1][1];
 
3810
    coordinates[5][0] = 0.333333333*x[0][0] + 0.666666667*x[1][0];
 
3811
    coordinates[5][1] = 0.333333333*x[0][1] + 0.666666667*x[1][1];
 
3812
  }
 
3813
 
 
3814
  /// Return the number of sub dof maps (for a mixed element)
 
3815
  virtual unsigned int num_sub_dof_maps() const
 
3816
  {
 
3817
    return 1;
 
3818
  }
 
3819
 
 
3820
  /// Create a new dof_map for sub dof map i (for a mixed element)
 
3821
  virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
 
3822
  {
 
3823
    return new mixedpoisson_0_dof_map_1_0();
 
3824
  }
 
3825
 
 
3826
};
 
3827
 
 
3828
/// This class defines the interface for a local-to-global mapping of
 
3829
/// degrees of freedom (dofs).
 
3830
 
 
3831
class mixedpoisson_0_dof_map_1_1: public ufc::dof_map
 
3832
{
 
3833
private:
 
3834
 
 
3835
  unsigned int __global_dimension;
 
3836
 
 
3837
public:
 
3838
 
 
3839
  /// Constructor
 
3840
  mixedpoisson_0_dof_map_1_1() : ufc::dof_map()
 
3841
  {
 
3842
    __global_dimension = 0;
 
3843
  }
 
3844
 
 
3845
  /// Destructor
 
3846
  virtual ~mixedpoisson_0_dof_map_1_1()
 
3847
  {
 
3848
    // Do nothing
 
3849
  }
 
3850
 
 
3851
  /// Return a string identifying the dof map
 
3852
  virtual const char* signature() const
 
3853
  {
 
3854
    return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
 
3855
  }
 
3856
 
 
3857
  /// Return true iff mesh entities of topological dimension d are needed
 
3858
  virtual bool needs_mesh_entities(unsigned int d) const
 
3859
  {
 
3860
    switch ( d )
 
3861
    {
 
3862
    case 0:
 
3863
      return false;
 
3864
      break;
 
3865
    case 1:
 
3866
      return false;
 
3867
      break;
 
3868
    case 2:
 
3869
      return true;
 
3870
      break;
 
3871
    }
 
3872
    return false;
 
3873
  }
 
3874
 
 
3875
  /// Initialize dof map for mesh (return true iff init_cell() is needed)
 
3876
  virtual bool init_mesh(const ufc::mesh& m)
 
3877
  {
 
3878
    __global_dimension = m.num_entities[2];
 
3879
    return false;
 
3880
  }
 
3881
 
 
3882
  /// Initialize dof map for given cell
 
3883
  virtual void init_cell(const ufc::mesh& m,
 
3884
                         const ufc::cell& c)
 
3885
  {
 
3886
    // Do nothing
 
3887
  }
 
3888
 
 
3889
  /// Finish initialization of dof map for cells
 
3890
  virtual void init_cell_finalize()
 
3891
  {
 
3892
    // Do nothing
 
3893
  }
 
3894
 
 
3895
  /// Return the dimension of the global finite element function space
 
3896
  virtual unsigned int global_dimension() const
 
3897
  {
 
3898
    return __global_dimension;
 
3899
  }
 
3900
 
 
3901
  /// Return the dimension of the local finite element function space for a cell
 
3902
  virtual unsigned int local_dimension(const ufc::cell& c) const
 
3903
  {
 
3904
    return 1;
 
3905
  }
 
3906
 
 
3907
  /// Return the maximum dimension of the local finite element function space
 
3908
  virtual unsigned int max_local_dimension() const
 
3909
  {
 
3910
    return 1;
 
3911
  }
 
3912
 
 
3913
  // Return the geometric dimension of the coordinates this dof map provides
 
3914
  virtual unsigned int geometric_dimension() const
 
3915
  {
 
3916
    return 2;
 
3917
  }
 
3918
 
 
3919
  /// Return the number of dofs on each cell facet
 
3920
  virtual unsigned int num_facet_dofs() const
 
3921
  {
 
3922
    return 0;
 
3923
  }
 
3924
 
 
3925
  /// Return the number of dofs associated with each cell entity of dimension d
 
3926
  virtual unsigned int num_entity_dofs(unsigned int d) const
 
3927
  {
 
3928
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
3929
  }
 
3930
 
 
3931
  /// Tabulate the local-to-global mapping of dofs on a cell
 
3932
  virtual void tabulate_dofs(unsigned int* dofs,
 
3933
                             const ufc::mesh& m,
 
3934
                             const ufc::cell& c) const
 
3935
  {
 
3936
    dofs[0] = c.entity_indices[2][0];
 
3937
  }
 
3938
 
 
3939
  /// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
3940
  virtual void tabulate_facet_dofs(unsigned int* dofs,
 
3941
                                   unsigned int facet) const
 
3942
  {
 
3943
    switch ( facet )
 
3944
    {
 
3945
    case 0:
 
3946
      
 
3947
      break;
 
3948
    case 1:
 
3949
      
 
3950
      break;
 
3951
    case 2:
 
3952
      
 
3953
      break;
 
3954
    }
 
3955
  }
 
3956
 
 
3957
  /// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
3958
  virtual void tabulate_entity_dofs(unsigned int* dofs,
 
3959
                                    unsigned int d, unsigned int i) const
 
3960
  {
 
3961
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
3962
  }
 
3963
 
 
3964
  /// Tabulate the coordinates of all dofs on a cell
 
3965
  virtual void tabulate_coordinates(double** coordinates,
 
3966
                                    const ufc::cell& c) const
 
3967
  {
 
3968
    const double * const * x = c.coordinates;
 
3969
    coordinates[0][0] = 0.333333333*x[0][0] + 0.333333333*x[1][0] + 0.333333333*x[2][0];
 
3970
    coordinates[0][1] = 0.333333333*x[0][1] + 0.333333333*x[1][1] + 0.333333333*x[2][1];
 
3971
  }
 
3972
 
 
3973
  /// Return the number of sub dof maps (for a mixed element)
 
3974
  virtual unsigned int num_sub_dof_maps() const
 
3975
  {
 
3976
    return 1;
 
3977
  }
 
3978
 
 
3979
  /// Create a new dof_map for sub dof map i (for a mixed element)
 
3980
  virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
 
3981
  {
 
3982
    return new mixedpoisson_0_dof_map_1_1();
 
3983
  }
 
3984
 
 
3985
};
 
3986
 
 
3987
/// This class defines the interface for a local-to-global mapping of
 
3988
/// degrees of freedom (dofs).
 
3989
 
 
3990
class mixedpoisson_0_dof_map_1: public ufc::dof_map
 
3991
{
 
3992
private:
 
3993
 
 
3994
  unsigned int __global_dimension;
 
3995
 
 
3996
public:
 
3997
 
 
3998
  /// Constructor
 
3999
  mixedpoisson_0_dof_map_1() : ufc::dof_map()
 
4000
  {
 
4001
    __global_dimension = 0;
 
4002
  }
 
4003
 
 
4004
  /// Destructor
 
4005
  virtual ~mixedpoisson_0_dof_map_1()
 
4006
  {
 
4007
    // Do nothing
 
4008
  }
 
4009
 
 
4010
  /// Return a string identifying the dof map
 
4011
  virtual const char* signature() const
 
4012
  {
 
4013
    return "FFC dof map for MixedElement([FiniteElement('Brezzi-Douglas-Marini', 'triangle', 1), FiniteElement('Discontinuous Lagrange', 'triangle', 0)])";
 
4014
  }
 
4015
 
 
4016
  /// Return true iff mesh entities of topological dimension d are needed
 
4017
  virtual bool needs_mesh_entities(unsigned int d) const
 
4018
  {
 
4019
    switch ( d )
 
4020
    {
 
4021
    case 0:
 
4022
      return false;
 
4023
      break;
 
4024
    case 1:
 
4025
      return true;
 
4026
      break;
 
4027
    case 2:
 
4028
      return true;
 
4029
      break;
 
4030
    }
 
4031
    return false;
 
4032
  }
 
4033
 
 
4034
  /// Initialize dof map for mesh (return true iff init_cell() is needed)
 
4035
  virtual bool init_mesh(const ufc::mesh& m)
 
4036
  {
 
4037
    __global_dimension = 2*m.num_entities[1] + m.num_entities[2];
 
4038
    return false;
 
4039
  }
 
4040
 
 
4041
  /// Initialize dof map for given cell
 
4042
  virtual void init_cell(const ufc::mesh& m,
 
4043
                         const ufc::cell& c)
 
4044
  {
 
4045
    // Do nothing
 
4046
  }
 
4047
 
 
4048
  /// Finish initialization of dof map for cells
 
4049
  virtual void init_cell_finalize()
 
4050
  {
 
4051
    // Do nothing
 
4052
  }
 
4053
 
 
4054
  /// Return the dimension of the global finite element function space
 
4055
  virtual unsigned int global_dimension() const
 
4056
  {
 
4057
    return __global_dimension;
 
4058
  }
 
4059
 
 
4060
  /// Return the dimension of the local finite element function space for a cell
 
4061
  virtual unsigned int local_dimension(const ufc::cell& c) const
 
4062
  {
 
4063
    return 7;
 
4064
  }
 
4065
 
 
4066
  /// Return the maximum dimension of the local finite element function space
 
4067
  virtual unsigned int max_local_dimension() const
 
4068
  {
 
4069
    return 7;
 
4070
  }
 
4071
 
 
4072
  // Return the geometric dimension of the coordinates this dof map provides
 
4073
  virtual unsigned int geometric_dimension() const
 
4074
  {
 
4075
    return 2;
 
4076
  }
 
4077
 
 
4078
  /// Return the number of dofs on each cell facet
 
4079
  virtual unsigned int num_facet_dofs() const
 
4080
  {
 
4081
    return 2;
 
4082
  }
 
4083
 
 
4084
  /// Return the number of dofs associated with each cell entity of dimension d
 
4085
  virtual unsigned int num_entity_dofs(unsigned int d) const
 
4086
  {
 
4087
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
4088
  }
 
4089
 
 
4090
  /// Tabulate the local-to-global mapping of dofs on a cell
 
4091
  virtual void tabulate_dofs(unsigned int* dofs,
 
4092
                             const ufc::mesh& m,
 
4093
                             const ufc::cell& c) const
 
4094
  {
 
4095
    dofs[0] = 2*c.entity_indices[1][0];
 
4096
    dofs[1] = 2*c.entity_indices[1][0] + 1;
 
4097
    dofs[2] = 2*c.entity_indices[1][1];
 
4098
    dofs[3] = 2*c.entity_indices[1][1] + 1;
 
4099
    dofs[4] = 2*c.entity_indices[1][2];
 
4100
    dofs[5] = 2*c.entity_indices[1][2] + 1;
 
4101
    unsigned int offset = 2*m.num_entities[1];
 
4102
    dofs[6] = offset + c.entity_indices[2][0];
 
4103
  }
 
4104
 
 
4105
  /// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
4106
  virtual void tabulate_facet_dofs(unsigned int* dofs,
 
4107
                                   unsigned int facet) const
 
4108
  {
 
4109
    switch ( facet )
 
4110
    {
 
4111
    case 0:
 
4112
      dofs[0] = 0;
 
4113
      dofs[1] = 1;
 
4114
      break;
 
4115
    case 1:
 
4116
      dofs[0] = 2;
 
4117
      dofs[1] = 3;
 
4118
      break;
 
4119
    case 2:
 
4120
      dofs[0] = 4;
 
4121
      dofs[1] = 5;
 
4122
      break;
 
4123
    }
 
4124
  }
 
4125
 
 
4126
  /// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
4127
  virtual void tabulate_entity_dofs(unsigned int* dofs,
 
4128
                                    unsigned int d, unsigned int i) const
 
4129
  {
 
4130
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
4131
  }
 
4132
 
 
4133
  /// Tabulate the coordinates of all dofs on a cell
 
4134
  virtual void tabulate_coordinates(double** coordinates,
 
4135
                                    const ufc::cell& c) const
 
4136
  {
 
4137
    const double * const * x = c.coordinates;
 
4138
    coordinates[0][0] = 0.666666667*x[1][0] + 0.333333333*x[2][0];
 
4139
    coordinates[0][1] = 0.666666667*x[1][1] + 0.333333333*x[2][1];
 
4140
    coordinates[1][0] = 0.333333333*x[1][0] + 0.666666667*x[2][0];
 
4141
    coordinates[1][1] = 0.333333333*x[1][1] + 0.666666667*x[2][1];
 
4142
    coordinates[2][0] = 0.666666667*x[0][0] + 0.333333333*x[2][0];
 
4143
    coordinates[2][1] = 0.666666667*x[0][1] + 0.333333333*x[2][1];
 
4144
    coordinates[3][0] = 0.333333333*x[0][0] + 0.666666667*x[2][0];
 
4145
    coordinates[3][1] = 0.333333333*x[0][1] + 0.666666667*x[2][1];
 
4146
    coordinates[4][0] = 0.666666667*x[0][0] + 0.333333333*x[1][0];
 
4147
    coordinates[4][1] = 0.666666667*x[0][1] + 0.333333333*x[1][1];
 
4148
    coordinates[5][0] = 0.333333333*x[0][0] + 0.666666667*x[1][0];
 
4149
    coordinates[5][1] = 0.333333333*x[0][1] + 0.666666667*x[1][1];
 
4150
    coordinates[6][0] = 0.333333333*x[0][0] + 0.333333333*x[1][0] + 0.333333333*x[2][0];
 
4151
    coordinates[6][1] = 0.333333333*x[0][1] + 0.333333333*x[1][1] + 0.333333333*x[2][1];
 
4152
  }
 
4153
 
 
4154
  /// Return the number of sub dof maps (for a mixed element)
 
4155
  virtual unsigned int num_sub_dof_maps() const
 
4156
  {
 
4157
    return 2;
 
4158
  }
 
4159
 
 
4160
  /// Create a new dof_map for sub dof map i (for a mixed element)
 
4161
  virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
 
4162
  {
 
4163
    switch ( i )
 
4164
    {
 
4165
    case 0:
 
4166
      return new mixedpoisson_0_dof_map_1_0();
 
4167
      break;
 
4168
    case 1:
 
4169
      return new mixedpoisson_0_dof_map_1_1();
 
4170
      break;
 
4171
    }
 
4172
    return 0;
 
4173
  }
 
4174
 
 
4175
};
 
4176
 
 
4177
/// This class defines the interface for the tabulation of the cell
 
4178
/// tensor corresponding to the local contribution to a form from
 
4179
/// the integral over a cell.
 
4180
 
 
4181
class mixedpoisson_0_cell_integral_0_tensor: public ufc::cell_integral
 
4182
{
 
4183
public:
 
4184
 
 
4185
  /// Constructor
 
4186
  mixedpoisson_0_cell_integral_0_tensor() : ufc::cell_integral()
 
4187
  {
 
4188
    // Do nothing
 
4189
  }
 
4190
 
 
4191
  /// Destructor
 
4192
  virtual ~mixedpoisson_0_cell_integral_0_tensor()
 
4193
  {
 
4194
    // Do nothing
 
4195
  }
 
4196
 
 
4197
  /// Tabulate the tensor for the contribution from a local cell
 
4198
  virtual void tabulate_tensor(double* A,
 
4199
                               const double * const * w,
 
4200
                               const ufc::cell& c) const
 
4201
  {
 
4202
    // Number of operations to compute geometry tensor:     48
 
4203
    // Number of operations to compute tensor contraction:  592
 
4204
    // Total number of operations to compute cell tensor:   640
 
4205
    
 
4206
    // Extract vertex coordinates
 
4207
    const double * const * x = c.coordinates;
 
4208
    
 
4209
    // Compute Jacobian of affine map from reference cell
 
4210
    const double J_00 = x[1][0] - x[0][0];
 
4211
    const double J_01 = x[2][0] - x[0][0];
 
4212
    const double J_10 = x[1][1] - x[0][1];
 
4213
    const double J_11 = x[2][1] - x[0][1];
 
4214
    
 
4215
    // Compute determinant of Jacobian
 
4216
    double detJ = J_00*J_11 - J_01*J_10;
 
4217
    
 
4218
    // Compute inverse of Jacobian
 
4219
    const double Jinv_00 =  J_11 / detJ;
 
4220
    const double Jinv_01 = -J_01 / detJ;
 
4221
    const double Jinv_10 = -J_10 / detJ;
 
4222
    const double Jinv_11 =  J_00 / detJ;
 
4223
    
 
4224
    // Set scale factor
 
4225
    const double det = std::abs(detJ);
 
4226
    
 
4227
    // Compute geometry tensor
 
4228
    const double G0_0_0 = 1.0/(detJ)*det*J_00*Jinv_00;
 
4229
    const double G0_0_1 = 1.0/(detJ)*det*J_00*Jinv_10;
 
4230
    const double G0_1_0 = 1.0/(detJ)*det*J_01*Jinv_00;
 
4231
    const double G0_1_1 = 1.0/(detJ)*det*J_01*Jinv_10;
 
4232
    const double G1_0_0 = 1.0/(detJ)*det*J_10*Jinv_01;
 
4233
    const double G1_0_1 = 1.0/(detJ)*det*J_10*Jinv_11;
 
4234
    const double G1_1_0 = 1.0/(detJ)*det*J_11*Jinv_01;
 
4235
    const double G1_1_1 = 1.0/(detJ)*det*J_11*Jinv_11;
 
4236
    const double G2_0_0 = 1.0/(detJ)*det*J_00*Jinv_00;
 
4237
    const double G2_0_1 = 1.0/(detJ)*det*J_00*Jinv_10;
 
4238
    const double G2_1_0 = 1.0/(detJ)*det*J_01*Jinv_00;
 
4239
    const double G2_1_1 = 1.0/(detJ)*det*J_01*Jinv_10;
 
4240
    const double G3_0_0 = 1.0/(detJ)*det*J_10*Jinv_01;
 
4241
    const double G3_0_1 = 1.0/(detJ)*det*J_10*Jinv_11;
 
4242
    const double G3_1_0 = 1.0/(detJ)*det*J_11*Jinv_01;
 
4243
    const double G3_1_1 = 1.0/(detJ)*det*J_11*Jinv_11;
 
4244
    const double G4_0_0 = 1.0/(detJ*detJ)*det*J_00*J_00;
 
4245
    const double G4_0_1 = 1.0/(detJ*detJ)*det*J_00*J_01;
 
4246
    const double G4_1_0 = 1.0/(detJ*detJ)*det*J_01*J_00;
 
4247
    const double G4_1_1 = 1.0/(detJ*detJ)*det*J_01*J_01;
 
4248
    const double G5_0_0 = 1.0/(detJ*detJ)*det*J_10*J_10;
 
4249
    const double G5_0_1 = 1.0/(detJ*detJ)*det*J_10*J_11;
 
4250
    const double G5_1_0 = 1.0/(detJ*detJ)*det*J_11*J_10;
 
4251
    const double G5_1_1 = 1.0/(detJ*detJ)*det*J_11*J_11;
 
4252
    
 
4253
    // Compute element tensor
 
4254
    A[0] += 0.333333333*G4_0_0 - 0.0833333333*G4_0_1 - 0.0833333333*G4_1_0 + 0.0833333333*G4_1_1 + 0.333333333*G5_0_0 - 0.0833333333*G5_0_1 - 0.0833333333*G5_1_0 + 0.0833333333*G5_1_1;
 
4255
    A[1] += -0.166666667*G4_0_0 + 0.166666667*G4_0_1 + 0.0416666667*G4_1_0 - 0.166666667*G4_1_1 - 0.166666667*G5_0_0 + 0.166666667*G5_0_1 + 0.0416666667*G5_1_0 - 0.166666667*G5_1_1;
 
4256
    A[2] += 0.0833333333*G4_0_0 + 0.0833333333*G4_0_1 - 0.0833333333*G4_1_1 + 0.0833333333*G5_0_0 + 0.0833333333*G5_0_1 - 0.0833333333*G5_1_1;
 
4257
    A[3] += 0.0833333333*G4_0_0 - 0.166666667*G4_0_1 - 0.125*G4_1_0 + 0.166666667*G4_1_1 + 0.0833333333*G5_0_0 - 0.166666667*G5_0_1 - 0.125*G5_1_0 + 0.166666667*G5_1_1;
 
4258
    A[4] += -0.166666667*G4_0_0 + 0.0416666667*G4_1_0 + 0.0416666667*G4_1_1 - 0.166666667*G5_0_0 + 0.0416666667*G5_1_0 + 0.0416666667*G5_1_1;
 
4259
    A[5] += 0.333333333*G4_0_0 - 0.25*G4_0_1 - 0.0833333333*G4_1_0 + 0.0416666667*G4_1_1 + 0.333333333*G5_0_0 - 0.25*G5_0_1 - 0.0833333333*G5_1_0 + 0.0416666667*G5_1_1;
 
4260
    A[6] += -1*G2_0_0 + 0.5*G2_1_1 - 1*G3_0_0 + 0.5*G3_1_1;
 
4261
    A[7] += -0.166666667*G4_0_0 + 0.0416666667*G4_0_1 + 0.166666667*G4_1_0 - 0.166666667*G4_1_1 - 0.166666667*G5_0_0 + 0.0416666667*G5_0_1 + 0.166666667*G5_1_0 - 0.166666667*G5_1_1;
 
4262
    A[8] += 0.0833333333*G4_0_0 - 0.0833333333*G4_0_1 - 0.0833333333*G4_1_0 + 0.333333333*G4_1_1 + 0.0833333333*G5_0_0 - 0.0833333333*G5_0_1 - 0.0833333333*G5_1_0 + 0.333333333*G5_1_1;
 
4263
    A[9] += -0.0416666667*G4_0_0 - 0.0416666667*G4_0_1 + 0.166666667*G4_1_1 - 0.0416666667*G5_0_0 - 0.0416666667*G5_0_1 + 0.166666667*G5_1_1;
 
4264
    A[10] += -0.0416666667*G4_0_0 + 0.0833333333*G4_0_1 + 0.25*G4_1_0 - 0.333333333*G4_1_1 - 0.0416666667*G5_0_0 + 0.0833333333*G5_0_1 + 0.25*G5_1_0 - 0.333333333*G5_1_1;
 
4265
    A[11] += 0.0833333333*G4_0_0 - 0.0833333333*G4_1_0 - 0.0833333333*G4_1_1 + 0.0833333333*G5_0_0 - 0.0833333333*G5_1_0 - 0.0833333333*G5_1_1;
 
4266
    A[12] += -0.166666667*G4_0_0 + 0.125*G4_0_1 + 0.166666667*G4_1_0 - 0.0833333333*G4_1_1 - 0.166666667*G5_0_0 + 0.125*G5_0_1 + 0.166666667*G5_1_0 - 0.0833333333*G5_1_1;
 
4267
    A[13] += 0.5*G2_0_0 - 1*G2_1_1 + 0.5*G3_0_0 - 1*G3_1_1;
 
4268
    A[14] += 0.0833333333*G4_0_0 + 0.0833333333*G4_1_0 - 0.0833333333*G4_1_1 + 0.0833333333*G5_0_0 + 0.0833333333*G5_1_0 - 0.0833333333*G5_1_1;
 
4269
    A[15] += -0.0416666667*G4_0_0 - 0.0416666667*G4_1_0 + 0.166666667*G4_1_1 - 0.0416666667*G5_0_0 - 0.0416666667*G5_1_0 + 0.166666667*G5_1_1;
 
4270
    A[16] += 0.25*G4_0_0 + 0.0833333333*G4_1_1 + 0.25*G5_0_0 + 0.0833333333*G5_1_1;
 
4271
    A[17] += -0.125*G4_0_0 + 0.125*G4_1_0 - 0.166666667*G4_1_1 - 0.125*G5_0_0 + 0.125*G5_1_0 - 0.166666667*G5_1_1;
 
4272
    A[18] += -0.0416666667*G4_0_0 - 0.208333333*G4_0_1 - 0.0416666667*G4_1_0 - 0.0416666667*G4_1_1 - 0.0416666667*G5_0_0 - 0.208333333*G5_0_1 - 0.0416666667*G5_1_0 - 0.0416666667*G5_1_1;
 
4273
    A[19] += 0.0833333333*G4_0_0 + 0.0416666667*G4_0_1 + 0.0833333333*G4_1_0 - 0.0416666667*G4_1_1 + 0.0833333333*G5_0_0 + 0.0416666667*G5_0_1 + 0.0833333333*G5_1_0 - 0.0416666667*G5_1_1;
 
4274
    A[20] += 1*G2_0_0 + 1.5*G2_0_1 - 0.5*G2_1_1 + 1*G3_0_0 + 1.5*G3_0_1 - 0.5*G3_1_1;
 
4275
    A[21] += 0.0833333333*G4_0_0 - 0.125*G4_0_1 - 0.166666667*G4_1_0 + 0.166666667*G4_1_1 + 0.0833333333*G5_0_0 - 0.125*G5_0_1 - 0.166666667*G5_1_0 + 0.166666667*G5_1_1;
 
4276
    A[22] += -0.0416666667*G4_0_0 + 0.25*G4_0_1 + 0.0833333333*G4_1_0 - 0.333333333*G4_1_1 - 0.0416666667*G5_0_0 + 0.25*G5_0_1 + 0.0833333333*G5_1_0 - 0.333333333*G5_1_1;
 
4277
    A[23] += -0.125*G4_0_0 + 0.125*G4_0_1 - 0.166666667*G4_1_1 - 0.125*G5_0_0 + 0.125*G5_0_1 - 0.166666667*G5_1_1;
 
4278
    A[24] += 0.25*G4_0_0 - 0.25*G4_0_1 - 0.25*G4_1_0 + 0.333333333*G4_1_1 + 0.25*G5_0_0 - 0.25*G5_0_1 - 0.25*G5_1_0 + 0.333333333*G5_1_1;
 
4279
    A[25] += -0.0416666667*G4_0_0 + 0.0416666667*G4_0_1 + 0.0833333333*G4_1_0 + 0.0833333333*G4_1_1 - 0.0416666667*G5_0_0 + 0.0416666667*G5_0_1 + 0.0833333333*G5_1_0 + 0.0833333333*G5_1_1;
 
4280
    A[26] += 0.0833333333*G4_0_0 - 0.0833333333*G4_0_1 - 0.166666667*G4_1_0 + 0.0833333333*G4_1_1 + 0.0833333333*G5_0_0 - 0.0833333333*G5_0_1 - 0.166666667*G5_1_0 + 0.0833333333*G5_1_1;
 
4281
    A[27] += -0.5*G2_0_0 - 1.5*G2_0_1 + 1*G2_1_1 - 0.5*G3_0_0 - 1.5*G3_0_1 + 1*G3_1_1;
 
4282
    A[28] += -0.166666667*G4_0_0 + 0.0416666667*G4_0_1 + 0.0416666667*G4_1_1 - 0.166666667*G5_0_0 + 0.0416666667*G5_0_1 + 0.0416666667*G5_1_1;
 
4283
    A[29] += 0.0833333333*G4_0_0 - 0.0833333333*G4_0_1 - 0.0833333333*G4_1_1 + 0.0833333333*G5_0_0 - 0.0833333333*G5_0_1 - 0.0833333333*G5_1_1;
 
4284
    A[30] += -0.0416666667*G4_0_0 - 0.0416666667*G4_0_1 - 0.208333333*G4_1_0 - 0.0416666667*G4_1_1 - 0.0416666667*G5_0_0 - 0.0416666667*G5_0_1 - 0.208333333*G5_1_0 - 0.0416666667*G5_1_1;
 
4285
    A[31] += -0.0416666667*G4_0_0 + 0.0833333333*G4_0_1 + 0.0416666667*G4_1_0 + 0.0833333333*G4_1_1 - 0.0416666667*G5_0_0 + 0.0833333333*G5_0_1 + 0.0416666667*G5_1_0 + 0.0833333333*G5_1_1;
 
4286
    A[32] += 0.0833333333*G4_0_0 + 0.25*G4_1_1 + 0.0833333333*G5_0_0 + 0.25*G5_1_1;
 
4287
    A[33] += -0.166666667*G4_0_0 + 0.125*G4_0_1 - 0.125*G4_1_1 - 0.166666667*G5_0_0 + 0.125*G5_0_1 - 0.125*G5_1_1;
 
4288
    A[34] += 0.5*G2_0_0 - 1.5*G2_1_0 - 1*G2_1_1 + 0.5*G3_0_0 - 1.5*G3_1_0 - 1*G3_1_1;
 
4289
    A[35] += 0.333333333*G4_0_0 - 0.0833333333*G4_0_1 - 0.25*G4_1_0 + 0.0416666667*G4_1_1 + 0.333333333*G5_0_0 - 0.0833333333*G5_0_1 - 0.25*G5_1_0 + 0.0416666667*G5_1_1;
 
4290
    A[36] += -0.166666667*G4_0_0 + 0.166666667*G4_0_1 + 0.125*G4_1_0 - 0.0833333333*G4_1_1 - 0.166666667*G5_0_0 + 0.166666667*G5_0_1 + 0.125*G5_1_0 - 0.0833333333*G5_1_1;
 
4291
    A[37] += 0.0833333333*G4_0_0 + 0.0833333333*G4_0_1 + 0.0416666667*G4_1_0 - 0.0416666667*G4_1_1 + 0.0833333333*G5_0_0 + 0.0833333333*G5_0_1 + 0.0416666667*G5_1_0 - 0.0416666667*G5_1_1;
 
4292
    A[38] += 0.0833333333*G4_0_0 - 0.166666667*G4_0_1 - 0.0833333333*G4_1_0 + 0.0833333333*G4_1_1 + 0.0833333333*G5_0_0 - 0.166666667*G5_0_1 - 0.0833333333*G5_1_0 + 0.0833333333*G5_1_1;
 
4293
    A[39] += -0.166666667*G4_0_0 + 0.125*G4_1_0 - 0.125*G4_1_1 - 0.166666667*G5_0_0 + 0.125*G5_1_0 - 0.125*G5_1_1;
 
4294
    A[40] += 0.333333333*G4_0_0 - 0.25*G4_0_1 - 0.25*G4_1_0 + 0.25*G4_1_1 + 0.333333333*G5_0_0 - 0.25*G5_0_1 - 0.25*G5_1_0 + 0.25*G5_1_1;
 
4295
    A[41] += -1*G2_0_0 + 1.5*G2_1_0 + 0.5*G2_1_1 - 1*G3_0_0 + 1.5*G3_1_0 + 0.5*G3_1_1;
 
4296
    A[42] += 1*G0_0_0 - 0.5*G0_1_1 + 1*G1_0_0 - 0.5*G1_1_1;
 
4297
    A[43] += -0.5*G0_0_0 + 1*G0_1_1 - 0.5*G1_0_0 + 1*G1_1_1;
 
4298
    A[44] += -1*G0_0_0 - 1.5*G0_0_1 + 0.5*G0_1_1 - 1*G1_0_0 - 1.5*G1_0_1 + 0.5*G1_1_1;
 
4299
    A[45] += 0.5*G0_0_0 + 1.5*G0_0_1 - 1*G0_1_1 + 0.5*G1_0_0 + 1.5*G1_0_1 - 1*G1_1_1;
 
4300
    A[46] += -0.5*G0_0_0 + 1.5*G0_1_0 + 1*G0_1_1 - 0.5*G1_0_0 + 1.5*G1_1_0 + 1*G1_1_1;
 
4301
    A[47] += 1*G0_0_0 - 1.5*G0_1_0 - 0.5*G0_1_1 + 1*G1_0_0 - 1.5*G1_1_0 - 0.5*G1_1_1;
 
4302
    A[48] += 0;
 
4303
  }
 
4304
 
 
4305
};
 
4306
 
 
4307
/// This class defines the interface for the tabulation of the cell
 
4308
/// tensor corresponding to the local contribution to a form from
 
4309
/// the integral over a cell.
 
4310
 
 
4311
class mixedpoisson_0_cell_integral_0: public ufc::cell_integral
 
4312
{
 
4313
private:
 
4314
 
 
4315
  mixedpoisson_0_cell_integral_0_tensor integral_0_tensor;
 
4316
 
 
4317
public:
 
4318
 
 
4319
  /// Constructor
 
4320
  mixedpoisson_0_cell_integral_0() : ufc::cell_integral()
 
4321
  {
 
4322
    // Do nothing
 
4323
  }
 
4324
 
 
4325
  /// Destructor
 
4326
  virtual ~mixedpoisson_0_cell_integral_0()
 
4327
  {
 
4328
    // Do nothing
 
4329
  }
 
4330
 
 
4331
  /// Tabulate the tensor for the contribution from a local cell
 
4332
  virtual void tabulate_tensor(double* A,
 
4333
                               const double * const * w,
 
4334
                               const ufc::cell& c) const
 
4335
  {
 
4336
    // Reset values of the element tensor block
 
4337
    for (unsigned int j = 0; j < 49; j++)
 
4338
      A[j] = 0;
 
4339
    
 
4340
    // Add all contributions to element tensor
 
4341
    integral_0_tensor.tabulate_tensor(A, w, c);
 
4342
  }
 
4343
 
 
4344
};
 
4345
 
 
4346
/// This class defines the interface for the assembly of the global
 
4347
/// tensor corresponding to a form with r + n arguments, that is, a
 
4348
/// mapping
 
4349
///
 
4350
///     a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
 
4351
///
 
4352
/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
 
4353
/// global tensor A is defined by
 
4354
///
 
4355
///     A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
 
4356
///
 
4357
/// where each argument Vj represents the application to the
 
4358
/// sequence of basis functions of Vj and w1, w2, ..., wn are given
 
4359
/// fixed functions (coefficients).
 
4360
 
 
4361
class mixedpoisson_form_0: public ufc::form
 
4362
{
 
4363
public:
 
4364
 
 
4365
  /// Constructor
 
4366
  mixedpoisson_form_0() : ufc::form()
 
4367
  {
 
4368
    // Do nothing
 
4369
  }
 
4370
 
 
4371
  /// Destructor
 
4372
  virtual ~mixedpoisson_form_0()
 
4373
  {
 
4374
    // Do nothing
 
4375
  }
 
4376
 
 
4377
  /// Return a string identifying the form
 
4378
  virtual const char* signature() const
 
4379
  {
 
4380
    return "Form([Integral(Sum(Product(IndexSum(Indexed(ListTensor(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Brezzi-Douglas-Marini', Cell('triangle', 1, Space(2)), 1), FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)], **{'value_shape': (3,) }), 1), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((FixedIndex(0),), {})), Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Brezzi-Douglas-Marini', Cell('triangle', 1, Space(2)), 1), FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)], **{'value_shape': (3,) }), 1), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((FixedIndex(1),), {}))), MultiIndex((Index(0),), {Index(0): 2})), MultiIndex((Index(0),), {Index(0): 2})), Indexed(BasisFunction(MixedElement(*[FiniteElement('Brezzi-Douglas-Marini', Cell('triangle', 1, Space(2)), 1), FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)], **{'value_shape': (3,) }), 0), MultiIndex((FixedIndex(2),), {FixedIndex(2): 3}))), Sum(IndexSum(Product(Indexed(ListTensor(Indexed(BasisFunction(MixedElement(*[FiniteElement('Brezzi-Douglas-Marini', Cell('triangle', 1, Space(2)), 1), FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)], **{'value_shape': (3,) }), 0), MultiIndex((FixedIndex(0),), {FixedIndex(0): 3})), Indexed(BasisFunction(MixedElement(*[FiniteElement('Brezzi-Douglas-Marini', Cell('triangle', 1, Space(2)), 1), FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)], **{'value_shape': (3,) }), 0), MultiIndex((FixedIndex(1),), {FixedIndex(1): 3}))), MultiIndex((Index(1),), {Index(1): 2})), Indexed(ListTensor(Indexed(BasisFunction(MixedElement(*[FiniteElement('Brezzi-Douglas-Marini', Cell('triangle', 1, Space(2)), 1), FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)], **{'value_shape': (3,) }), 1), MultiIndex((FixedIndex(0),), {FixedIndex(0): 3})), Indexed(BasisFunction(MixedElement(*[FiniteElement('Brezzi-Douglas-Marini', Cell('triangle', 1, Space(2)), 1), FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)], **{'value_shape': (3,) }), 1), MultiIndex((FixedIndex(1),), {FixedIndex(1): 3}))), MultiIndex((Index(1),), {Index(1): 2}))), MultiIndex((Index(1),), {Index(1): 2})), Product(IntValue(-1, (), (), {}), Product(IndexSum(Indexed(ListTensor(Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Brezzi-Douglas-Marini', Cell('triangle', 1, Space(2)), 1), FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)], **{'value_shape': (3,) }), 0), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((FixedIndex(0),), {})), Indexed(SpatialDerivative(BasisFunction(MixedElement(*[FiniteElement('Brezzi-Douglas-Marini', Cell('triangle', 1, Space(2)), 1), FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)], **{'value_shape': (3,) }), 0), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((FixedIndex(1),), {}))), MultiIndex((Index(2),), {Index(2): 2})), MultiIndex((Index(2),), {Index(2): 2})), Indexed(BasisFunction(MixedElement(*[FiniteElement('Brezzi-Douglas-Marini', Cell('triangle', 1, Space(2)), 1), FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)], **{'value_shape': (3,) }), 1), MultiIndex((FixedIndex(2),), {FixedIndex(2): 3})))))), Measure('cell', 0, None))])";
 
4381
  }
 
4382
 
 
4383
  /// Return the rank of the global tensor (r)
 
4384
  virtual unsigned int rank() const
 
4385
  {
 
4386
    return 2;
 
4387
  }
 
4388
 
 
4389
  /// Return the number of coefficients (n)
 
4390
  virtual unsigned int num_coefficients() const
 
4391
  {
 
4392
    return 0;
 
4393
  }
 
4394
 
 
4395
  /// Return the number of cell integrals
 
4396
  virtual unsigned int num_cell_integrals() const
 
4397
  {
 
4398
    return 1;
 
4399
  }
 
4400
 
 
4401
  /// Return the number of exterior facet integrals
 
4402
  virtual unsigned int num_exterior_facet_integrals() const
 
4403
  {
 
4404
    return 0;
 
4405
  }
 
4406
 
 
4407
  /// Return the number of interior facet integrals
 
4408
  virtual unsigned int num_interior_facet_integrals() const
 
4409
  {
 
4410
    return 0;
 
4411
  }
 
4412
 
 
4413
  /// Create a new finite element for argument function i
 
4414
  virtual ufc::finite_element* create_finite_element(unsigned int i) const
 
4415
  {
 
4416
    switch ( i )
 
4417
    {
 
4418
    case 0:
 
4419
      return new mixedpoisson_0_finite_element_0();
 
4420
      break;
 
4421
    case 1:
 
4422
      return new mixedpoisson_0_finite_element_1();
 
4423
      break;
 
4424
    }
 
4425
    return 0;
 
4426
  }
 
4427
 
 
4428
  /// Create a new dof map for argument function i
 
4429
  virtual ufc::dof_map* create_dof_map(unsigned int i) const
 
4430
  {
 
4431
    switch ( i )
 
4432
    {
 
4433
    case 0:
 
4434
      return new mixedpoisson_0_dof_map_0();
 
4435
      break;
 
4436
    case 1:
 
4437
      return new mixedpoisson_0_dof_map_1();
 
4438
      break;
 
4439
    }
 
4440
    return 0;
 
4441
  }
 
4442
 
 
4443
  /// Create a new cell integral on sub domain i
 
4444
  virtual ufc::cell_integral* create_cell_integral(unsigned int i) const
 
4445
  {
 
4446
    return new mixedpoisson_0_cell_integral_0();
 
4447
  }
 
4448
 
 
4449
  /// Create a new exterior facet integral on sub domain i
 
4450
  virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const
 
4451
  {
 
4452
    return 0;
 
4453
  }
 
4454
 
 
4455
  /// Create a new interior facet integral on sub domain i
 
4456
  virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const
 
4457
  {
 
4458
    return 0;
 
4459
  }
 
4460
 
 
4461
};
 
4462
 
 
4463
/// This class defines the interface for a finite element.
 
4464
 
 
4465
class mixedpoisson_1_finite_element_0_0: public ufc::finite_element
 
4466
{
 
4467
public:
 
4468
 
 
4469
  /// Constructor
 
4470
  mixedpoisson_1_finite_element_0_0() : ufc::finite_element()
 
4471
  {
 
4472
    // Do nothing
 
4473
  }
 
4474
 
 
4475
  /// Destructor
 
4476
  virtual ~mixedpoisson_1_finite_element_0_0()
 
4477
  {
 
4478
    // Do nothing
 
4479
  }
 
4480
 
 
4481
  /// Return a string identifying the finite element
 
4482
  virtual const char* signature() const
 
4483
  {
 
4484
    return "FiniteElement('Brezzi-Douglas-Marini', 'triangle', 1)";
 
4485
  }
 
4486
 
 
4487
  /// Return the cell shape
 
4488
  virtual ufc::shape cell_shape() const
 
4489
  {
 
4490
    return ufc::triangle;
 
4491
  }
 
4492
 
 
4493
  /// Return the dimension of the finite element function space
 
4494
  virtual unsigned int space_dimension() const
 
4495
  {
 
4496
    return 6;
 
4497
  }
 
4498
 
 
4499
  /// Return the rank of the value space
 
4500
  virtual unsigned int value_rank() const
 
4501
  {
 
4502
    return 1;
 
4503
  }
 
4504
 
 
4505
  /// Return the dimension of the value space for axis i
 
4506
  virtual unsigned int value_dimension(unsigned int i) const
 
4507
  {
 
4508
    return 2;
 
4509
  }
 
4510
 
 
4511
  /// Evaluate basis function i at given point in cell
 
4512
  virtual void evaluate_basis(unsigned int i,
 
4513
                              double* values,
 
4514
                              const double* coordinates,
 
4515
                              const ufc::cell& c) const
 
4516
  {
 
4517
    // Extract vertex coordinates
 
4518
    const double * const * element_coordinates = c.coordinates;
 
4519
    
 
4520
    // Compute Jacobian of affine map from reference cell
 
4521
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
4522
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
4523
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
4524
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
4525
    
 
4526
    // Compute determinant of Jacobian
 
4527
    const double detJ = J_00*J_11 - J_01*J_10;
 
4528
    
 
4529
    // Compute inverse of Jacobian
 
4530
    
 
4531
    // Get coordinates and map to the reference (UFC) element
 
4532
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
4533
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
4534
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
4535
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
4536
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
4537
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
4538
    
 
4539
    // Map coordinates to the reference square
 
4540
    if (std::abs(y - 1.0) < 1e-08)
 
4541
      x = -1.0;
 
4542
    else
 
4543
      x = 2.0 *x/(1.0 - y) - 1.0;
 
4544
    y = 2.0*y - 1.0;
 
4545
    
 
4546
    // Reset values
 
4547
    values[0] = 0;
 
4548
    values[1] = 0;
 
4549
    
 
4550
    // Map degree of freedom to element degree of freedom
 
4551
    const unsigned int dof = i;
 
4552
    
 
4553
    // Generate scalings
 
4554
    const double scalings_y_0 = 1;
 
4555
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
4556
    
 
4557
    // Compute psitilde_a
 
4558
    const double psitilde_a_0 = 1;
 
4559
    const double psitilde_a_1 = x;
 
4560
    
 
4561
    // Compute psitilde_bs
 
4562
    const double psitilde_bs_0_0 = 1;
 
4563
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
4564
    const double psitilde_bs_1_0 = 1;
 
4565
    
 
4566
    // Compute basisvalues
 
4567
    const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
4568
    const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
4569
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
4570
    
 
4571
    // Table(s) of coefficients
 
4572
    static const double coefficients0[6][3] = \
 
4573
    {{0.942809042, 0.577350269, -0.333333333},
 
4574
    {-0.471404521, -0.288675135, 0.166666667},
 
4575
    {0.471404521, -0.577350269, -0.666666667},
 
4576
    {0.471404521, 0.288675135, 0.833333333},
 
4577
    {-0.471404521, -0.288675135, 0.166666667},
 
4578
    {0.942809042, 0.577350269, -0.333333333}};
 
4579
    
 
4580
    static const double coefficients1[6][3] = \
 
4581
    {{-0.471404521, 0, -0.333333333},
 
4582
    {0.942809042, 0, 0.666666667},
 
4583
    {0.471404521, 0, 0.333333333},
 
4584
    {-0.942809042, 0, -0.666666667},
 
4585
    {-0.471404521, 0.866025404, 0.166666667},
 
4586
    {-0.471404521, -0.866025404, 0.166666667}};
 
4587
    
 
4588
    // Extract relevant coefficients
 
4589
    const double coeff0_0 = coefficients0[dof][0];
 
4590
    const double coeff0_1 = coefficients0[dof][1];
 
4591
    const double coeff0_2 = coefficients0[dof][2];
 
4592
    const double coeff1_0 = coefficients1[dof][0];
 
4593
    const double coeff1_1 = coefficients1[dof][1];
 
4594
    const double coeff1_2 = coefficients1[dof][2];
 
4595
    
 
4596
    // Compute value(s)
 
4597
    const double tmp0_0 = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
4598
    const double tmp0_1 = coeff1_0*basisvalue0 + coeff1_1*basisvalue1 + coeff1_2*basisvalue2;
 
4599
    // Using contravariant Piola transform to map values back to the physical element
 
4600
    values[0] = (1.0/detJ)*(J_00*tmp0_0 + J_01*tmp0_1);
 
4601
    values[1] = (1.0/detJ)*(J_10*tmp0_0 + J_11*tmp0_1);
 
4602
  }
 
4603
 
 
4604
  /// Evaluate all basis functions at given point in cell
 
4605
  virtual void evaluate_basis_all(double* values,
 
4606
                                  const double* coordinates,
 
4607
                                  const ufc::cell& c) const
 
4608
  {
 
4609
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
4610
  }
 
4611
 
 
4612
  /// Evaluate order n derivatives of basis function i at given point in cell
 
4613
  virtual void evaluate_basis_derivatives(unsigned int i,
 
4614
                                          unsigned int n,
 
4615
                                          double* values,
 
4616
                                          const double* coordinates,
 
4617
                                          const ufc::cell& c) const
 
4618
  {
 
4619
    // Extract vertex coordinates
 
4620
    const double * const * element_coordinates = c.coordinates;
 
4621
    
 
4622
    // Compute Jacobian of affine map from reference cell
 
4623
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
4624
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
4625
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
4626
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
4627
    
 
4628
    // Compute determinant of Jacobian
 
4629
    const double detJ = J_00*J_11 - J_01*J_10;
 
4630
    
 
4631
    // Compute inverse of Jacobian
 
4632
    
 
4633
    // Get coordinates and map to the reference (UFC) element
 
4634
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
4635
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
4636
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
4637
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
4638
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
4639
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
4640
    
 
4641
    // Map coordinates to the reference square
 
4642
    if (std::abs(y - 1.0) < 1e-08)
 
4643
      x = -1.0;
 
4644
    else
 
4645
      x = 2.0 *x/(1.0 - y) - 1.0;
 
4646
    y = 2.0*y - 1.0;
 
4647
    
 
4648
    // Compute number of derivatives
 
4649
    unsigned int num_derivatives = 1;
 
4650
    
 
4651
    for (unsigned int j = 0; j < n; j++)
 
4652
      num_derivatives *= 2;
 
4653
    
 
4654
    
 
4655
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
4656
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
4657
    
 
4658
    for (unsigned int j = 0; j < num_derivatives; j++)
 
4659
    {
 
4660
      combinations[j] = new unsigned int [n];
 
4661
      for (unsigned int k = 0; k < n; k++)
 
4662
        combinations[j][k] = 0;
 
4663
    }
 
4664
    
 
4665
    // Generate combinations of derivatives
 
4666
    for (unsigned int row = 1; row < num_derivatives; row++)
 
4667
    {
 
4668
      for (unsigned int num = 0; num < row; num++)
 
4669
      {
 
4670
        for (unsigned int col = n-1; col+1 > 0; col--)
 
4671
        {
 
4672
          if (combinations[row][col] + 1 > 1)
 
4673
            combinations[row][col] = 0;
 
4674
          else
 
4675
          {
 
4676
            combinations[row][col] += 1;
 
4677
            break;
 
4678
          }
 
4679
        }
 
4680
      }
 
4681
    }
 
4682
    
 
4683
    // Compute inverse of Jacobian
 
4684
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
4685
    
 
4686
    // Declare transformation matrix
 
4687
    // Declare pointer to two dimensional array and initialise
 
4688
    double **transform = new double *[num_derivatives];
 
4689
    
 
4690
    for (unsigned int j = 0; j < num_derivatives; j++)
 
4691
    {
 
4692
      transform[j] = new double [num_derivatives];
 
4693
      for (unsigned int k = 0; k < num_derivatives; k++)
 
4694
        transform[j][k] = 1;
 
4695
    }
 
4696
    
 
4697
    // Construct transformation matrix
 
4698
    for (unsigned int row = 0; row < num_derivatives; row++)
 
4699
    {
 
4700
      for (unsigned int col = 0; col < num_derivatives; col++)
 
4701
      {
 
4702
        for (unsigned int k = 0; k < n; k++)
 
4703
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
4704
      }
 
4705
    }
 
4706
    
 
4707
    // Reset values
 
4708
    for (unsigned int j = 0; j < 2*num_derivatives; j++)
 
4709
      values[j] = 0;
 
4710
    
 
4711
    // Map degree of freedom to element degree of freedom
 
4712
    const unsigned int dof = i;
 
4713
    
 
4714
    // Generate scalings
 
4715
    const double scalings_y_0 = 1;
 
4716
    const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
4717
    
 
4718
    // Compute psitilde_a
 
4719
    const double psitilde_a_0 = 1;
 
4720
    const double psitilde_a_1 = x;
 
4721
    
 
4722
    // Compute psitilde_bs
 
4723
    const double psitilde_bs_0_0 = 1;
 
4724
    const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
4725
    const double psitilde_bs_1_0 = 1;
 
4726
    
 
4727
    // Compute basisvalues
 
4728
    const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
4729
    const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
4730
    const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
4731
    
 
4732
    // Table(s) of coefficients
 
4733
    static const double coefficients0[6][3] = \
 
4734
    {{0.942809042, 0.577350269, -0.333333333},
 
4735
    {-0.471404521, -0.288675135, 0.166666667},
 
4736
    {0.471404521, -0.577350269, -0.666666667},
 
4737
    {0.471404521, 0.288675135, 0.833333333},
 
4738
    {-0.471404521, -0.288675135, 0.166666667},
 
4739
    {0.942809042, 0.577350269, -0.333333333}};
 
4740
    
 
4741
    static const double coefficients1[6][3] = \
 
4742
    {{-0.471404521, 0, -0.333333333},
 
4743
    {0.942809042, 0, 0.666666667},
 
4744
    {0.471404521, 0, 0.333333333},
 
4745
    {-0.942809042, 0, -0.666666667},
 
4746
    {-0.471404521, 0.866025404, 0.166666667},
 
4747
    {-0.471404521, -0.866025404, 0.166666667}};
 
4748
    
 
4749
    // Interesting (new) part
 
4750
    // Tables of derivatives of the polynomial base (transpose)
 
4751
    static const double dmats0[3][3] = \
 
4752
    {{0, 0, 0},
 
4753
    {4.89897949, 0, 0},
 
4754
    {0, 0, 0}};
 
4755
    
 
4756
    static const double dmats1[3][3] = \
 
4757
    {{0, 0, 0},
 
4758
    {2.44948974, 0, 0},
 
4759
    {4.24264069, 0, 0}};
 
4760
    
 
4761
    // Compute reference derivatives
 
4762
    // Declare pointer to array of derivatives on FIAT element
 
4763
    double *derivatives = new double [2*num_derivatives];
 
4764
    
 
4765
    // Declare coefficients
 
4766
    double coeff0_0 = 0;
 
4767
    double coeff0_1 = 0;
 
4768
    double coeff0_2 = 0;
 
4769
    double coeff1_0 = 0;
 
4770
    double coeff1_1 = 0;
 
4771
    double coeff1_2 = 0;
 
4772
    
 
4773
    // Declare new coefficients
 
4774
    double new_coeff0_0 = 0;
 
4775
    double new_coeff0_1 = 0;
 
4776
    double new_coeff0_2 = 0;
 
4777
    double new_coeff1_0 = 0;
 
4778
    double new_coeff1_1 = 0;
 
4779
    double new_coeff1_2 = 0;
 
4780
    
 
4781
    // Loop possible derivatives
 
4782
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
4783
    {
 
4784
      // Get values from coefficients array
 
4785
      new_coeff0_0 = coefficients0[dof][0];
 
4786
      new_coeff0_1 = coefficients0[dof][1];
 
4787
      new_coeff0_2 = coefficients0[dof][2];
 
4788
      new_coeff1_0 = coefficients1[dof][0];
 
4789
      new_coeff1_1 = coefficients1[dof][1];
 
4790
      new_coeff1_2 = coefficients1[dof][2];
 
4791
    
 
4792
      // Loop derivative order
 
4793
      for (unsigned int j = 0; j < n; j++)
 
4794
      {
 
4795
        // Update old coefficients
 
4796
        coeff0_0 = new_coeff0_0;
 
4797
        coeff0_1 = new_coeff0_1;
 
4798
        coeff0_2 = new_coeff0_2;
 
4799
        coeff1_0 = new_coeff1_0;
 
4800
        coeff1_1 = new_coeff1_1;
 
4801
        coeff1_2 = new_coeff1_2;
 
4802
    
 
4803
        if(combinations[deriv_num][j] == 0)
 
4804
        {
 
4805
          new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
4806
          new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
4807
          new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
4808
          new_coeff1_0 = coeff1_0*dmats0[0][0] + coeff1_1*dmats0[1][0] + coeff1_2*dmats0[2][0];
 
4809
          new_coeff1_1 = coeff1_0*dmats0[0][1] + coeff1_1*dmats0[1][1] + coeff1_2*dmats0[2][1];
 
4810
          new_coeff1_2 = coeff1_0*dmats0[0][2] + coeff1_1*dmats0[1][2] + coeff1_2*dmats0[2][2];
 
4811
        }
 
4812
        if(combinations[deriv_num][j] == 1)
 
4813
        {
 
4814
          new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
4815
          new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
4816
          new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
4817
          new_coeff1_0 = coeff1_0*dmats1[0][0] + coeff1_1*dmats1[1][0] + coeff1_2*dmats1[2][0];
 
4818
          new_coeff1_1 = coeff1_0*dmats1[0][1] + coeff1_1*dmats1[1][1] + coeff1_2*dmats1[2][1];
 
4819
          new_coeff1_2 = coeff1_0*dmats1[0][2] + coeff1_1*dmats1[1][2] + coeff1_2*dmats1[2][2];
 
4820
        }
 
4821
    
 
4822
      }
 
4823
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
4824
      // Correct values by the contravariant Piola transform
 
4825
      const double tmp0_0 = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
4826
      const double tmp0_1 = new_coeff1_0*basisvalue0 + new_coeff1_1*basisvalue1 + new_coeff1_2*basisvalue2;
 
4827
      derivatives[deriv_num] = (1.0/detJ)*(J_00*tmp0_0 + J_01*tmp0_1);
 
4828
      derivatives[num_derivatives + deriv_num] = (1.0/detJ)*(J_10*tmp0_0 + J_11*tmp0_1);
 
4829
    }
 
4830
    
 
4831
    // Transform derivatives back to physical element
 
4832
    for (unsigned int row = 0; row < num_derivatives; row++)
 
4833
    {
 
4834
      for (unsigned int col = 0; col < num_derivatives; col++)
 
4835
      {
 
4836
        values[row] += transform[row][col]*derivatives[col];
 
4837
        values[num_derivatives + row] += transform[row][col]*derivatives[num_derivatives + col];
 
4838
      }
 
4839
    }
 
4840
    // Delete pointer to array of derivatives on FIAT element
 
4841
    delete [] derivatives;
 
4842
    
 
4843
    // Delete pointer to array of combinations of derivatives and transform
 
4844
    for (unsigned int row = 0; row < num_derivatives; row++)
 
4845
    {
 
4846
      delete [] combinations[row];
 
4847
      delete [] transform[row];
 
4848
    }
 
4849
    
 
4850
    delete [] combinations;
 
4851
    delete [] transform;
 
4852
  }
 
4853
 
 
4854
  /// Evaluate order n derivatives of all basis functions at given point in cell
 
4855
  virtual void evaluate_basis_derivatives_all(unsigned int n,
 
4856
                                              double* values,
 
4857
                                              const double* coordinates,
 
4858
                                              const ufc::cell& c) const
 
4859
  {
 
4860
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
4861
  }
 
4862
 
 
4863
  /// Evaluate linear functional for dof i on the function f
 
4864
  virtual double evaluate_dof(unsigned int i,
 
4865
                              const ufc::function& f,
 
4866
                              const ufc::cell& c) const
 
4867
  {
 
4868
    // The reference points, direction and weights:
 
4869
    static const double X[6][1][2] = {{{0.666666667, 0.333333333}}, {{0.333333333, 0.666666667}}, {{0, 0.333333333}}, {{0, 0.666666667}}, {{0.333333333, 0}}, {{0.666666667, 0}}};
 
4870
    static const double W[6][1] = {{1}, {1}, {1}, {1}, {1}, {1}};
 
4871
    static const double D[6][1][2] = {{{1, 1}}, {{1, 1}}, {{1, 0}}, {{1, 0}}, {{0, -1}}, {{0, -1}}};
 
4872
    
 
4873
    // Extract vertex coordinates
 
4874
    const double * const * x = c.coordinates;
 
4875
    
 
4876
    // Compute Jacobian of affine map from reference cell
 
4877
    const double J_00 = x[1][0] - x[0][0];
 
4878
    const double J_01 = x[2][0] - x[0][0];
 
4879
    const double J_10 = x[1][1] - x[0][1];
 
4880
    const double J_11 = x[2][1] - x[0][1];
 
4881
    
 
4882
    // Compute determinant of Jacobian
 
4883
    double detJ = J_00*J_11 - J_01*J_10;
 
4884
    
 
4885
    // Compute inverse of Jacobian
 
4886
    const double Jinv_00 =  J_11 / detJ;
 
4887
    const double Jinv_01 = -J_01 / detJ;
 
4888
    const double Jinv_10 = -J_10 / detJ;
 
4889
    const double Jinv_11 =  J_00 / detJ;
 
4890
    
 
4891
    double copyofvalues[2];
 
4892
    double result = 0.0;
 
4893
    // Iterate over the points:
 
4894
    // Evaluate basis functions for affine mapping
 
4895
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
4896
    const double w1 = X[i][0][0];
 
4897
    const double w2 = X[i][0][1];
 
4898
    
 
4899
    // Compute affine mapping y = F(X)
 
4900
    double y[2];
 
4901
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
4902
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
4903
    
 
4904
    // Evaluate function at physical points
 
4905
    double values[2];
 
4906
    f.evaluate(values, y, c);
 
4907
    
 
4908
    // Map function values using appropriate mapping
 
4909
    // Copy old values:
 
4910
    copyofvalues[0] = values[0];
 
4911
    copyofvalues[1] = values[1];
 
4912
    // Do the inverse of div piola 
 
4913
    values[0] = detJ*(Jinv_00*copyofvalues[0]+Jinv_01*copyofvalues[1]);
 
4914
    values[1] = detJ*(Jinv_10*copyofvalues[0]+Jinv_11*copyofvalues[1]);
 
4915
    
 
4916
    // Note that we do not map the weights (yet).
 
4917
    
 
4918
    // Take directional components
 
4919
    for(int k = 0; k < 2; k++)
 
4920
      result += values[k]*D[i][0][k];
 
4921
    // Multiply by weights
 
4922
    result *= W[i][0];
 
4923
    
 
4924
    return result;
 
4925
  }
 
4926
 
 
4927
  /// Evaluate linear functionals for all dofs on the function f
 
4928
  virtual void evaluate_dofs(double* values,
 
4929
                             const ufc::function& f,
 
4930
                             const ufc::cell& c) const
 
4931
  {
 
4932
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
4933
  }
 
4934
 
 
4935
  /// Interpolate vertex values from dof values
 
4936
  virtual void interpolate_vertex_values(double* vertex_values,
 
4937
                                         const double* dof_values,
 
4938
                                         const ufc::cell& c) const
 
4939
  {
 
4940
    // Extract vertex coordinates
 
4941
    const double * const * x = c.coordinates;
 
4942
    
 
4943
    // Compute Jacobian of affine map from reference cell
 
4944
    const double J_00 = x[1][0] - x[0][0];
 
4945
    const double J_01 = x[2][0] - x[0][0];
 
4946
    const double J_10 = x[1][1] - x[0][1];
 
4947
    const double J_11 = x[2][1] - x[0][1];
 
4948
    
 
4949
    // Compute determinant of Jacobian
 
4950
    double detJ = J_00*J_11 - J_01*J_10;
 
4951
    
 
4952
    // Compute inverse of Jacobian
 
4953
    // Evaluate at vertices and use Piola mapping
 
4954
    vertex_values[0] = (1.0/detJ)*(dof_values[2]*2*J_00 + dof_values[3]*J_00 + dof_values[4]*(-2*J_01) + dof_values[5]*J_01);
 
4955
    vertex_values[2] = (1.0/detJ)*(dof_values[0]*2*J_00 + dof_values[1]*J_00 + dof_values[4]*(J_00 + J_01) + dof_values[5]*(2*J_00 - 2*J_01));
 
4956
    vertex_values[4] = (1.0/detJ)*(dof_values[0]*J_01 + dof_values[1]*2*J_01 + dof_values[2]*(J_00 + J_01) + dof_values[3]*(2*J_00 - 2*J_01));
 
4957
    vertex_values[1] = (1.0/detJ)*(dof_values[2]*2*J_10 + dof_values[3]*J_10 + dof_values[4]*(-2*J_11) + dof_values[5]*J_11);
 
4958
    vertex_values[3] = (1.0/detJ)*(dof_values[0]*2*J_10 + dof_values[1]*J_10 + dof_values[4]*(J_10 + J_11) + dof_values[5]*(2*J_10 - 2*J_11));
 
4959
    vertex_values[5] = (1.0/detJ)*(dof_values[0]*J_11 + dof_values[1]*2*J_11 + dof_values[2]*(J_10 + J_11) + dof_values[3]*(2*J_10 - 2*J_11));
 
4960
  }
 
4961
 
 
4962
  /// Return the number of sub elements (for a mixed element)
 
4963
  virtual unsigned int num_sub_elements() const
 
4964
  {
 
4965
    return 1;
 
4966
  }
 
4967
 
 
4968
  /// Create a new finite element for sub element i (for a mixed element)
 
4969
  virtual ufc::finite_element* create_sub_element(unsigned int i) const
 
4970
  {
 
4971
    return new mixedpoisson_1_finite_element_0_0();
 
4972
  }
 
4973
 
 
4974
};
 
4975
 
 
4976
/// This class defines the interface for a finite element.
 
4977
 
 
4978
class mixedpoisson_1_finite_element_0_1: public ufc::finite_element
 
4979
{
 
4980
public:
 
4981
 
 
4982
  /// Constructor
 
4983
  mixedpoisson_1_finite_element_0_1() : ufc::finite_element()
 
4984
  {
 
4985
    // Do nothing
 
4986
  }
 
4987
 
 
4988
  /// Destructor
 
4989
  virtual ~mixedpoisson_1_finite_element_0_1()
 
4990
  {
 
4991
    // Do nothing
 
4992
  }
 
4993
 
 
4994
  /// Return a string identifying the finite element
 
4995
  virtual const char* signature() const
 
4996
  {
 
4997
    return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
 
4998
  }
 
4999
 
 
5000
  /// Return the cell shape
 
5001
  virtual ufc::shape cell_shape() const
 
5002
  {
 
5003
    return ufc::triangle;
 
5004
  }
 
5005
 
 
5006
  /// Return the dimension of the finite element function space
 
5007
  virtual unsigned int space_dimension() const
 
5008
  {
 
5009
    return 1;
 
5010
  }
 
5011
 
 
5012
  /// Return the rank of the value space
 
5013
  virtual unsigned int value_rank() const
 
5014
  {
 
5015
    return 0;
 
5016
  }
 
5017
 
 
5018
  /// Return the dimension of the value space for axis i
 
5019
  virtual unsigned int value_dimension(unsigned int i) const
 
5020
  {
 
5021
    return 1;
 
5022
  }
 
5023
 
 
5024
  /// Evaluate basis function i at given point in cell
 
5025
  virtual void evaluate_basis(unsigned int i,
 
5026
                              double* values,
 
5027
                              const double* coordinates,
 
5028
                              const ufc::cell& c) const
 
5029
  {
 
5030
    // Extract vertex coordinates
 
5031
    const double * const * element_coordinates = c.coordinates;
 
5032
    
 
5033
    // Compute Jacobian of affine map from reference cell
 
5034
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
5035
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
5036
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
5037
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
5038
    
 
5039
    // Compute determinant of Jacobian
 
5040
    const double detJ = J_00*J_11 - J_01*J_10;
 
5041
    
 
5042
    // Compute inverse of Jacobian
 
5043
    
 
5044
    // Get coordinates and map to the reference (UFC) element
 
5045
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
5046
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
5047
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
5048
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
5049
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
5050
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
5051
    
 
5052
    // Map coordinates to the reference square
 
5053
    if (std::abs(y - 1.0) < 1e-08)
 
5054
      x = -1.0;
 
5055
    else
 
5056
      x = 2.0 *x/(1.0 - y) - 1.0;
 
5057
    y = 2.0*y - 1.0;
 
5058
    
 
5059
    // Reset values
 
5060
    *values = 0;
 
5061
    
 
5062
    // Map degree of freedom to element degree of freedom
 
5063
    const unsigned int dof = i;
 
5064
    
 
5065
    // Generate scalings
 
5066
    const double scalings_y_0 = 1;
 
5067
    
 
5068
    // Compute psitilde_a
 
5069
    const double psitilde_a_0 = 1;
 
5070
    
 
5071
    // Compute psitilde_bs
 
5072
    const double psitilde_bs_0_0 = 1;
 
5073
    
 
5074
    // Compute basisvalues
 
5075
    const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
5076
    
 
5077
    // Table(s) of coefficients
 
5078
    static const double coefficients0[1][1] = \
 
5079
    {{1.41421356}};
 
5080
    
 
5081
    // Extract relevant coefficients
 
5082
    const double coeff0_0 = coefficients0[dof][0];
 
5083
    
 
5084
    // Compute value(s)
 
5085
    *values = coeff0_0*basisvalue0;
 
5086
  }
 
5087
 
 
5088
  /// Evaluate all basis functions at given point in cell
 
5089
  virtual void evaluate_basis_all(double* values,
 
5090
                                  const double* coordinates,
 
5091
                                  const ufc::cell& c) const
 
5092
  {
 
5093
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
5094
  }
 
5095
 
 
5096
  /// Evaluate order n derivatives of basis function i at given point in cell
 
5097
  virtual void evaluate_basis_derivatives(unsigned int i,
 
5098
                                          unsigned int n,
 
5099
                                          double* values,
 
5100
                                          const double* coordinates,
 
5101
                                          const ufc::cell& c) const
 
5102
  {
 
5103
    // Extract vertex coordinates
 
5104
    const double * const * element_coordinates = c.coordinates;
 
5105
    
 
5106
    // Compute Jacobian of affine map from reference cell
 
5107
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
5108
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
5109
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
5110
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
5111
    
 
5112
    // Compute determinant of Jacobian
 
5113
    const double detJ = J_00*J_11 - J_01*J_10;
 
5114
    
 
5115
    // Compute inverse of Jacobian
 
5116
    
 
5117
    // Get coordinates and map to the reference (UFC) element
 
5118
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
5119
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
5120
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
5121
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
5122
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
5123
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
5124
    
 
5125
    // Map coordinates to the reference square
 
5126
    if (std::abs(y - 1.0) < 1e-08)
 
5127
      x = -1.0;
 
5128
    else
 
5129
      x = 2.0 *x/(1.0 - y) - 1.0;
 
5130
    y = 2.0*y - 1.0;
 
5131
    
 
5132
    // Compute number of derivatives
 
5133
    unsigned int num_derivatives = 1;
 
5134
    
 
5135
    for (unsigned int j = 0; j < n; j++)
 
5136
      num_derivatives *= 2;
 
5137
    
 
5138
    
 
5139
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
5140
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
5141
    
 
5142
    for (unsigned int j = 0; j < num_derivatives; j++)
 
5143
    {
 
5144
      combinations[j] = new unsigned int [n];
 
5145
      for (unsigned int k = 0; k < n; k++)
 
5146
        combinations[j][k] = 0;
 
5147
    }
 
5148
    
 
5149
    // Generate combinations of derivatives
 
5150
    for (unsigned int row = 1; row < num_derivatives; row++)
 
5151
    {
 
5152
      for (unsigned int num = 0; num < row; num++)
 
5153
      {
 
5154
        for (unsigned int col = n-1; col+1 > 0; col--)
 
5155
        {
 
5156
          if (combinations[row][col] + 1 > 1)
 
5157
            combinations[row][col] = 0;
 
5158
          else
 
5159
          {
 
5160
            combinations[row][col] += 1;
 
5161
            break;
 
5162
          }
 
5163
        }
 
5164
      }
 
5165
    }
 
5166
    
 
5167
    // Compute inverse of Jacobian
 
5168
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
5169
    
 
5170
    // Declare transformation matrix
 
5171
    // Declare pointer to two dimensional array and initialise
 
5172
    double **transform = new double *[num_derivatives];
 
5173
    
 
5174
    for (unsigned int j = 0; j < num_derivatives; j++)
 
5175
    {
 
5176
      transform[j] = new double [num_derivatives];
 
5177
      for (unsigned int k = 0; k < num_derivatives; k++)
 
5178
        transform[j][k] = 1;
 
5179
    }
 
5180
    
 
5181
    // Construct transformation matrix
 
5182
    for (unsigned int row = 0; row < num_derivatives; row++)
 
5183
    {
 
5184
      for (unsigned int col = 0; col < num_derivatives; col++)
 
5185
      {
 
5186
        for (unsigned int k = 0; k < n; k++)
 
5187
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
5188
      }
 
5189
    }
 
5190
    
 
5191
    // Reset values
 
5192
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
 
5193
      values[j] = 0;
 
5194
    
 
5195
    // Map degree of freedom to element degree of freedom
 
5196
    const unsigned int dof = i;
 
5197
    
 
5198
    // Generate scalings
 
5199
    const double scalings_y_0 = 1;
 
5200
    
 
5201
    // Compute psitilde_a
 
5202
    const double psitilde_a_0 = 1;
 
5203
    
 
5204
    // Compute psitilde_bs
 
5205
    const double psitilde_bs_0_0 = 1;
 
5206
    
 
5207
    // Compute basisvalues
 
5208
    const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
5209
    
 
5210
    // Table(s) of coefficients
 
5211
    static const double coefficients0[1][1] = \
 
5212
    {{1.41421356}};
 
5213
    
 
5214
    // Interesting (new) part
 
5215
    // Tables of derivatives of the polynomial base (transpose)
 
5216
    static const double dmats0[1][1] = \
 
5217
    {{0}};
 
5218
    
 
5219
    static const double dmats1[1][1] = \
 
5220
    {{0}};
 
5221
    
 
5222
    // Compute reference derivatives
 
5223
    // Declare pointer to array of derivatives on FIAT element
 
5224
    double *derivatives = new double [num_derivatives];
 
5225
    
 
5226
    // Declare coefficients
 
5227
    double coeff0_0 = 0;
 
5228
    
 
5229
    // Declare new coefficients
 
5230
    double new_coeff0_0 = 0;
 
5231
    
 
5232
    // Loop possible derivatives
 
5233
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
5234
    {
 
5235
      // Get values from coefficients array
 
5236
      new_coeff0_0 = coefficients0[dof][0];
 
5237
    
 
5238
      // Loop derivative order
 
5239
      for (unsigned int j = 0; j < n; j++)
 
5240
      {
 
5241
        // Update old coefficients
 
5242
        coeff0_0 = new_coeff0_0;
 
5243
    
 
5244
        if(combinations[deriv_num][j] == 0)
 
5245
        {
 
5246
          new_coeff0_0 = coeff0_0*dmats0[0][0];
 
5247
        }
 
5248
        if(combinations[deriv_num][j] == 1)
 
5249
        {
 
5250
          new_coeff0_0 = coeff0_0*dmats1[0][0];
 
5251
        }
 
5252
    
 
5253
      }
 
5254
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
5255
      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
 
5256
    }
 
5257
    
 
5258
    // Transform derivatives back to physical element
 
5259
    for (unsigned int row = 0; row < num_derivatives; row++)
 
5260
    {
 
5261
      for (unsigned int col = 0; col < num_derivatives; col++)
 
5262
      {
 
5263
        values[row] += transform[row][col]*derivatives[col];
 
5264
      }
 
5265
    }
 
5266
    // Delete pointer to array of derivatives on FIAT element
 
5267
    delete [] derivatives;
 
5268
    
 
5269
    // Delete pointer to array of combinations of derivatives and transform
 
5270
    for (unsigned int row = 0; row < num_derivatives; row++)
 
5271
    {
 
5272
      delete [] combinations[row];
 
5273
      delete [] transform[row];
 
5274
    }
 
5275
    
 
5276
    delete [] combinations;
 
5277
    delete [] transform;
 
5278
  }
 
5279
 
 
5280
  /// Evaluate order n derivatives of all basis functions at given point in cell
 
5281
  virtual void evaluate_basis_derivatives_all(unsigned int n,
 
5282
                                              double* values,
 
5283
                                              const double* coordinates,
 
5284
                                              const ufc::cell& c) const
 
5285
  {
 
5286
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
5287
  }
 
5288
 
 
5289
  /// Evaluate linear functional for dof i on the function f
 
5290
  virtual double evaluate_dof(unsigned int i,
 
5291
                              const ufc::function& f,
 
5292
                              const ufc::cell& c) const
 
5293
  {
 
5294
    // The reference points, direction and weights:
 
5295
    static const double X[1][1][2] = {{{0.333333333, 0.333333333}}};
 
5296
    static const double W[1][1] = {{1}};
 
5297
    static const double D[1][1][1] = {{{1}}};
 
5298
    
 
5299
    const double * const * x = c.coordinates;
 
5300
    double result = 0.0;
 
5301
    // Iterate over the points:
 
5302
    // Evaluate basis functions for affine mapping
 
5303
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
5304
    const double w1 = X[i][0][0];
 
5305
    const double w2 = X[i][0][1];
 
5306
    
 
5307
    // Compute affine mapping y = F(X)
 
5308
    double y[2];
 
5309
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
5310
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
5311
    
 
5312
    // Evaluate function at physical points
 
5313
    double values[1];
 
5314
    f.evaluate(values, y, c);
 
5315
    
 
5316
    // Map function values using appropriate mapping
 
5317
    // Affine map: Do nothing
 
5318
    
 
5319
    // Note that we do not map the weights (yet).
 
5320
    
 
5321
    // Take directional components
 
5322
    for(int k = 0; k < 1; k++)
 
5323
      result += values[k]*D[i][0][k];
 
5324
    // Multiply by weights
 
5325
    result *= W[i][0];
 
5326
    
 
5327
    return result;
 
5328
  }
 
5329
 
 
5330
  /// Evaluate linear functionals for all dofs on the function f
 
5331
  virtual void evaluate_dofs(double* values,
 
5332
                             const ufc::function& f,
 
5333
                             const ufc::cell& c) const
 
5334
  {
 
5335
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
5336
  }
 
5337
 
 
5338
  /// Interpolate vertex values from dof values
 
5339
  virtual void interpolate_vertex_values(double* vertex_values,
 
5340
                                         const double* dof_values,
 
5341
                                         const ufc::cell& c) const
 
5342
  {
 
5343
    // Evaluate at vertices and use affine mapping
 
5344
    vertex_values[0] = dof_values[0];
 
5345
    vertex_values[1] = dof_values[0];
 
5346
    vertex_values[2] = dof_values[0];
 
5347
  }
 
5348
 
 
5349
  /// Return the number of sub elements (for a mixed element)
 
5350
  virtual unsigned int num_sub_elements() const
 
5351
  {
 
5352
    return 1;
 
5353
  }
 
5354
 
 
5355
  /// Create a new finite element for sub element i (for a mixed element)
 
5356
  virtual ufc::finite_element* create_sub_element(unsigned int i) const
 
5357
  {
 
5358
    return new mixedpoisson_1_finite_element_0_1();
 
5359
  }
 
5360
 
 
5361
};
 
5362
 
 
5363
/// This class defines the interface for a finite element.
 
5364
 
 
5365
class mixedpoisson_1_finite_element_0: public ufc::finite_element
 
5366
{
 
5367
public:
 
5368
 
 
5369
  /// Constructor
 
5370
  mixedpoisson_1_finite_element_0() : ufc::finite_element()
 
5371
  {
 
5372
    // Do nothing
 
5373
  }
 
5374
 
 
5375
  /// Destructor
 
5376
  virtual ~mixedpoisson_1_finite_element_0()
 
5377
  {
 
5378
    // Do nothing
 
5379
  }
 
5380
 
 
5381
  /// Return a string identifying the finite element
 
5382
  virtual const char* signature() const
 
5383
  {
 
5384
    return "MixedElement([FiniteElement('Brezzi-Douglas-Marini', 'triangle', 1), FiniteElement('Discontinuous Lagrange', 'triangle', 0)])";
 
5385
  }
 
5386
 
 
5387
  /// Return the cell shape
 
5388
  virtual ufc::shape cell_shape() const
 
5389
  {
 
5390
    return ufc::triangle;
 
5391
  }
 
5392
 
 
5393
  /// Return the dimension of the finite element function space
 
5394
  virtual unsigned int space_dimension() const
 
5395
  {
 
5396
    return 7;
 
5397
  }
 
5398
 
 
5399
  /// Return the rank of the value space
 
5400
  virtual unsigned int value_rank() const
 
5401
  {
 
5402
    return 1;
 
5403
  }
 
5404
 
 
5405
  /// Return the dimension of the value space for axis i
 
5406
  virtual unsigned int value_dimension(unsigned int i) const
 
5407
  {
 
5408
    return 3;
 
5409
  }
 
5410
 
 
5411
  /// Evaluate basis function i at given point in cell
 
5412
  virtual void evaluate_basis(unsigned int i,
 
5413
                              double* values,
 
5414
                              const double* coordinates,
 
5415
                              const ufc::cell& c) const
 
5416
  {
 
5417
    // Extract vertex coordinates
 
5418
    const double * const * element_coordinates = c.coordinates;
 
5419
    
 
5420
    // Compute Jacobian of affine map from reference cell
 
5421
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
5422
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
5423
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
5424
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
5425
    
 
5426
    // Compute determinant of Jacobian
 
5427
    const double detJ = J_00*J_11 - J_01*J_10;
 
5428
    
 
5429
    // Compute inverse of Jacobian
 
5430
    
 
5431
    // Get coordinates and map to the reference (UFC) element
 
5432
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
5433
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
5434
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
5435
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
5436
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
5437
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
5438
    
 
5439
    // Map coordinates to the reference square
 
5440
    if (std::abs(y - 1.0) < 1e-08)
 
5441
      x = -1.0;
 
5442
    else
 
5443
      x = 2.0 *x/(1.0 - y) - 1.0;
 
5444
    y = 2.0*y - 1.0;
 
5445
    
 
5446
    // Reset values
 
5447
    values[0] = 0;
 
5448
    values[1] = 0;
 
5449
    values[2] = 0;
 
5450
    
 
5451
    if (0 <= i && i <= 5)
 
5452
    {
 
5453
      // Map degree of freedom to element degree of freedom
 
5454
      const unsigned int dof = i;
 
5455
    
 
5456
      // Generate scalings
 
5457
      const double scalings_y_0 = 1;
 
5458
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
5459
    
 
5460
      // Compute psitilde_a
 
5461
      const double psitilde_a_0 = 1;
 
5462
      const double psitilde_a_1 = x;
 
5463
    
 
5464
      // Compute psitilde_bs
 
5465
      const double psitilde_bs_0_0 = 1;
 
5466
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
5467
      const double psitilde_bs_1_0 = 1;
 
5468
    
 
5469
      // Compute basisvalues
 
5470
      const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
5471
      const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
5472
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
5473
    
 
5474
      // Table(s) of coefficients
 
5475
      static const double coefficients0[6][3] =   \
 
5476
      {{0.942809042, 0.577350269, -0.333333333},
 
5477
      {-0.471404521, -0.288675135, 0.166666667},
 
5478
      {0.471404521, -0.577350269, -0.666666667},
 
5479
      {0.471404521, 0.288675135, 0.833333333},
 
5480
      {-0.471404521, -0.288675135, 0.166666667},
 
5481
      {0.942809042, 0.577350269, -0.333333333}};
 
5482
    
 
5483
      static const double coefficients1[6][3] =   \
 
5484
      {{-0.471404521, 0, -0.333333333},
 
5485
      {0.942809042, 0, 0.666666667},
 
5486
      {0.471404521, 0, 0.333333333},
 
5487
      {-0.942809042, 0, -0.666666667},
 
5488
      {-0.471404521, 0.866025404, 0.166666667},
 
5489
      {-0.471404521, -0.866025404, 0.166666667}};
 
5490
    
 
5491
      // Extract relevant coefficients
 
5492
      const double coeff0_0 =   coefficients0[dof][0];
 
5493
      const double coeff0_1 =   coefficients0[dof][1];
 
5494
      const double coeff0_2 =   coefficients0[dof][2];
 
5495
      const double coeff1_0 =   coefficients1[dof][0];
 
5496
      const double coeff1_1 =   coefficients1[dof][1];
 
5497
      const double coeff1_2 =   coefficients1[dof][2];
 
5498
    
 
5499
      // Compute value(s)
 
5500
      const double tmp0_0 = coeff0_0*basisvalue0 + coeff0_1*basisvalue1 + coeff0_2*basisvalue2;
 
5501
      const double tmp0_1 = coeff1_0*basisvalue0 + coeff1_1*basisvalue1 + coeff1_2*basisvalue2;
 
5502
      // Using contravariant Piola transform to map values back to the physical element
 
5503
      values[0] = (1.0/detJ)*(J_00*tmp0_0 + J_01*tmp0_1);
 
5504
      values[1] = (1.0/detJ)*(J_10*tmp0_0 + J_11*tmp0_1);
 
5505
    }
 
5506
    
 
5507
    if (6 <= i && i <= 6)
 
5508
    {
 
5509
      // Map degree of freedom to element degree of freedom
 
5510
      const unsigned int dof = i - 6;
 
5511
    
 
5512
      // Generate scalings
 
5513
      const double scalings_y_0 = 1;
 
5514
    
 
5515
      // Compute psitilde_a
 
5516
      const double psitilde_a_0 = 1;
 
5517
    
 
5518
      // Compute psitilde_bs
 
5519
      const double psitilde_bs_0_0 = 1;
 
5520
    
 
5521
      // Compute basisvalues
 
5522
      const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
5523
    
 
5524
      // Table(s) of coefficients
 
5525
      static const double coefficients0[1][1] =   \
 
5526
      {{1.41421356}};
 
5527
    
 
5528
      // Extract relevant coefficients
 
5529
      const double coeff0_0 =   coefficients0[dof][0];
 
5530
    
 
5531
      // Compute value(s)
 
5532
      values[2] = coeff0_0*basisvalue0;
 
5533
    }
 
5534
    
 
5535
  }
 
5536
 
 
5537
  /// Evaluate all basis functions at given point in cell
 
5538
  virtual void evaluate_basis_all(double* values,
 
5539
                                  const double* coordinates,
 
5540
                                  const ufc::cell& c) const
 
5541
  {
 
5542
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
5543
  }
 
5544
 
 
5545
  /// Evaluate order n derivatives of basis function i at given point in cell
 
5546
  virtual void evaluate_basis_derivatives(unsigned int i,
 
5547
                                          unsigned int n,
 
5548
                                          double* values,
 
5549
                                          const double* coordinates,
 
5550
                                          const ufc::cell& c) const
 
5551
  {
 
5552
    // Extract vertex coordinates
 
5553
    const double * const * element_coordinates = c.coordinates;
 
5554
    
 
5555
    // Compute Jacobian of affine map from reference cell
 
5556
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
5557
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
5558
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
5559
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
5560
    
 
5561
    // Compute determinant of Jacobian
 
5562
    const double detJ = J_00*J_11 - J_01*J_10;
 
5563
    
 
5564
    // Compute inverse of Jacobian
 
5565
    
 
5566
    // Get coordinates and map to the reference (UFC) element
 
5567
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
5568
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
5569
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
5570
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
5571
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
5572
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
5573
    
 
5574
    // Map coordinates to the reference square
 
5575
    if (std::abs(y - 1.0) < 1e-08)
 
5576
      x = -1.0;
 
5577
    else
 
5578
      x = 2.0 *x/(1.0 - y) - 1.0;
 
5579
    y = 2.0*y - 1.0;
 
5580
    
 
5581
    // Compute number of derivatives
 
5582
    unsigned int num_derivatives = 1;
 
5583
    
 
5584
    for (unsigned int j = 0; j < n; j++)
 
5585
      num_derivatives *= 2;
 
5586
    
 
5587
    
 
5588
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
5589
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
5590
    
 
5591
    for (unsigned int j = 0; j < num_derivatives; j++)
 
5592
    {
 
5593
      combinations[j] = new unsigned int [n];
 
5594
      for (unsigned int k = 0; k < n; k++)
 
5595
        combinations[j][k] = 0;
 
5596
    }
 
5597
    
 
5598
    // Generate combinations of derivatives
 
5599
    for (unsigned int row = 1; row < num_derivatives; row++)
 
5600
    {
 
5601
      for (unsigned int num = 0; num < row; num++)
 
5602
      {
 
5603
        for (unsigned int col = n-1; col+1 > 0; col--)
 
5604
        {
 
5605
          if (combinations[row][col] + 1 > 1)
 
5606
            combinations[row][col] = 0;
 
5607
          else
 
5608
          {
 
5609
            combinations[row][col] += 1;
 
5610
            break;
 
5611
          }
 
5612
        }
 
5613
      }
 
5614
    }
 
5615
    
 
5616
    // Compute inverse of Jacobian
 
5617
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
5618
    
 
5619
    // Declare transformation matrix
 
5620
    // Declare pointer to two dimensional array and initialise
 
5621
    double **transform = new double *[num_derivatives];
 
5622
    
 
5623
    for (unsigned int j = 0; j < num_derivatives; j++)
 
5624
    {
 
5625
      transform[j] = new double [num_derivatives];
 
5626
      for (unsigned int k = 0; k < num_derivatives; k++)
 
5627
        transform[j][k] = 1;
 
5628
    }
 
5629
    
 
5630
    // Construct transformation matrix
 
5631
    for (unsigned int row = 0; row < num_derivatives; row++)
 
5632
    {
 
5633
      for (unsigned int col = 0; col < num_derivatives; col++)
 
5634
      {
 
5635
        for (unsigned int k = 0; k < n; k++)
 
5636
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
5637
      }
 
5638
    }
 
5639
    
 
5640
    // Reset values
 
5641
    for (unsigned int j = 0; j < 3*num_derivatives; j++)
 
5642
      values[j] = 0;
 
5643
    
 
5644
    if (0 <= i && i <= 5)
 
5645
    {
 
5646
      // Map degree of freedom to element degree of freedom
 
5647
      const unsigned int dof = i;
 
5648
    
 
5649
      // Generate scalings
 
5650
      const double scalings_y_0 = 1;
 
5651
      const double scalings_y_1 = scalings_y_0*(0.5 - 0.5*y);
 
5652
    
 
5653
      // Compute psitilde_a
 
5654
      const double psitilde_a_0 = 1;
 
5655
      const double psitilde_a_1 = x;
 
5656
    
 
5657
      // Compute psitilde_bs
 
5658
      const double psitilde_bs_0_0 = 1;
 
5659
      const double psitilde_bs_0_1 = 1.5*y + 0.5;
 
5660
      const double psitilde_bs_1_0 = 1;
 
5661
    
 
5662
      // Compute basisvalues
 
5663
      const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
5664
      const double basisvalue1 = 1.73205081*psitilde_a_1*scalings_y_1*psitilde_bs_1_0;
 
5665
      const double basisvalue2 = psitilde_a_0*scalings_y_0*psitilde_bs_0_1;
 
5666
    
 
5667
      // Table(s) of coefficients
 
5668
      static const double coefficients0[6][3] =   \
 
5669
      {{0.942809042, 0.577350269, -0.333333333},
 
5670
      {-0.471404521, -0.288675135, 0.166666667},
 
5671
      {0.471404521, -0.577350269, -0.666666667},
 
5672
      {0.471404521, 0.288675135, 0.833333333},
 
5673
      {-0.471404521, -0.288675135, 0.166666667},
 
5674
      {0.942809042, 0.577350269, -0.333333333}};
 
5675
    
 
5676
      static const double coefficients1[6][3] =   \
 
5677
      {{-0.471404521, 0, -0.333333333},
 
5678
      {0.942809042, 0, 0.666666667},
 
5679
      {0.471404521, 0, 0.333333333},
 
5680
      {-0.942809042, 0, -0.666666667},
 
5681
      {-0.471404521, 0.866025404, 0.166666667},
 
5682
      {-0.471404521, -0.866025404, 0.166666667}};
 
5683
    
 
5684
      // Interesting (new) part
 
5685
      // Tables of derivatives of the polynomial base (transpose)
 
5686
      static const double dmats0[3][3] =   \
 
5687
      {{0, 0, 0},
 
5688
      {4.89897949, 0, 0},
 
5689
      {0, 0, 0}};
 
5690
    
 
5691
      static const double dmats1[3][3] =   \
 
5692
      {{0, 0, 0},
 
5693
      {2.44948974, 0, 0},
 
5694
      {4.24264069, 0, 0}};
 
5695
    
 
5696
      // Compute reference derivatives
 
5697
      // Declare pointer to array of derivatives on FIAT element
 
5698
      double *derivatives = new double [2*num_derivatives];
 
5699
    
 
5700
      // Declare coefficients
 
5701
      double coeff0_0 = 0;
 
5702
      double coeff0_1 = 0;
 
5703
      double coeff0_2 = 0;
 
5704
      double coeff1_0 = 0;
 
5705
      double coeff1_1 = 0;
 
5706
      double coeff1_2 = 0;
 
5707
    
 
5708
      // Declare new coefficients
 
5709
      double new_coeff0_0 = 0;
 
5710
      double new_coeff0_1 = 0;
 
5711
      double new_coeff0_2 = 0;
 
5712
      double new_coeff1_0 = 0;
 
5713
      double new_coeff1_1 = 0;
 
5714
      double new_coeff1_2 = 0;
 
5715
    
 
5716
      // Loop possible derivatives
 
5717
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
5718
      {
 
5719
        // Get values from coefficients array
 
5720
        new_coeff0_0 = coefficients0[dof][0];
 
5721
        new_coeff0_1 = coefficients0[dof][1];
 
5722
        new_coeff0_2 = coefficients0[dof][2];
 
5723
        new_coeff1_0 = coefficients1[dof][0];
 
5724
        new_coeff1_1 = coefficients1[dof][1];
 
5725
        new_coeff1_2 = coefficients1[dof][2];
 
5726
    
 
5727
        // Loop derivative order
 
5728
        for (unsigned int j = 0; j < n; j++)
 
5729
        {
 
5730
          // Update old coefficients
 
5731
          coeff0_0 = new_coeff0_0;
 
5732
          coeff0_1 = new_coeff0_1;
 
5733
          coeff0_2 = new_coeff0_2;
 
5734
          coeff1_0 = new_coeff1_0;
 
5735
          coeff1_1 = new_coeff1_1;
 
5736
          coeff1_2 = new_coeff1_2;
 
5737
    
 
5738
          if(combinations[deriv_num][j] == 0)
 
5739
          {
 
5740
            new_coeff0_0 = coeff0_0*dmats0[0][0] + coeff0_1*dmats0[1][0] + coeff0_2*dmats0[2][0];
 
5741
            new_coeff0_1 = coeff0_0*dmats0[0][1] + coeff0_1*dmats0[1][1] + coeff0_2*dmats0[2][1];
 
5742
            new_coeff0_2 = coeff0_0*dmats0[0][2] + coeff0_1*dmats0[1][2] + coeff0_2*dmats0[2][2];
 
5743
            new_coeff1_0 = coeff1_0*dmats0[0][0] + coeff1_1*dmats0[1][0] + coeff1_2*dmats0[2][0];
 
5744
            new_coeff1_1 = coeff1_0*dmats0[0][1] + coeff1_1*dmats0[1][1] + coeff1_2*dmats0[2][1];
 
5745
            new_coeff1_2 = coeff1_0*dmats0[0][2] + coeff1_1*dmats0[1][2] + coeff1_2*dmats0[2][2];
 
5746
          }
 
5747
          if(combinations[deriv_num][j] == 1)
 
5748
          {
 
5749
            new_coeff0_0 = coeff0_0*dmats1[0][0] + coeff0_1*dmats1[1][0] + coeff0_2*dmats1[2][0];
 
5750
            new_coeff0_1 = coeff0_0*dmats1[0][1] + coeff0_1*dmats1[1][1] + coeff0_2*dmats1[2][1];
 
5751
            new_coeff0_2 = coeff0_0*dmats1[0][2] + coeff0_1*dmats1[1][2] + coeff0_2*dmats1[2][2];
 
5752
            new_coeff1_0 = coeff1_0*dmats1[0][0] + coeff1_1*dmats1[1][0] + coeff1_2*dmats1[2][0];
 
5753
            new_coeff1_1 = coeff1_0*dmats1[0][1] + coeff1_1*dmats1[1][1] + coeff1_2*dmats1[2][1];
 
5754
            new_coeff1_2 = coeff1_0*dmats1[0][2] + coeff1_1*dmats1[1][2] + coeff1_2*dmats1[2][2];
 
5755
          }
 
5756
    
 
5757
        }
 
5758
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
5759
        // Correct values by the contravariant Piola transform
 
5760
        const double tmp0_0 = new_coeff0_0*basisvalue0 + new_coeff0_1*basisvalue1 + new_coeff0_2*basisvalue2;
 
5761
        const double tmp0_1 = new_coeff1_0*basisvalue0 + new_coeff1_1*basisvalue1 + new_coeff1_2*basisvalue2;
 
5762
        derivatives[deriv_num] = (1.0/detJ)*(J_00*tmp0_0 + J_01*tmp0_1);
 
5763
        derivatives[num_derivatives + deriv_num] = (1.0/detJ)*(J_10*tmp0_0 + J_11*tmp0_1);
 
5764
      }
 
5765
    
 
5766
      // Transform derivatives back to physical element
 
5767
      for (unsigned int row = 0; row < num_derivatives; row++)
 
5768
      {
 
5769
        for (unsigned int col = 0; col < num_derivatives; col++)
 
5770
        {
 
5771
          values[row] += transform[row][col]*derivatives[col];
 
5772
          values[num_derivatives + row] += transform[row][col]*derivatives[num_derivatives + col];
 
5773
        }
 
5774
      }
 
5775
      // Delete pointer to array of derivatives on FIAT element
 
5776
      delete [] derivatives;
 
5777
    
 
5778
      // Delete pointer to array of combinations of derivatives and transform
 
5779
      for (unsigned int row = 0; row < num_derivatives; row++)
 
5780
      {
 
5781
        delete [] combinations[row];
 
5782
        delete [] transform[row];
 
5783
      }
 
5784
    
 
5785
      delete [] combinations;
 
5786
      delete [] transform;
 
5787
    }
 
5788
    
 
5789
    if (6 <= i && i <= 6)
 
5790
    {
 
5791
      // Map degree of freedom to element degree of freedom
 
5792
      const unsigned int dof = i - 6;
 
5793
    
 
5794
      // Generate scalings
 
5795
      const double scalings_y_0 = 1;
 
5796
    
 
5797
      // Compute psitilde_a
 
5798
      const double psitilde_a_0 = 1;
 
5799
    
 
5800
      // Compute psitilde_bs
 
5801
      const double psitilde_bs_0_0 = 1;
 
5802
    
 
5803
      // Compute basisvalues
 
5804
      const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
5805
    
 
5806
      // Table(s) of coefficients
 
5807
      static const double coefficients0[1][1] =   \
 
5808
      {{1.41421356}};
 
5809
    
 
5810
      // Interesting (new) part
 
5811
      // Tables of derivatives of the polynomial base (transpose)
 
5812
      static const double dmats0[1][1] =   \
 
5813
      {{0}};
 
5814
    
 
5815
      static const double dmats1[1][1] =   \
 
5816
      {{0}};
 
5817
    
 
5818
      // Compute reference derivatives
 
5819
      // Declare pointer to array of derivatives on FIAT element
 
5820
      double *derivatives = new double [num_derivatives];
 
5821
    
 
5822
      // Declare coefficients
 
5823
      double coeff0_0 = 0;
 
5824
    
 
5825
      // Declare new coefficients
 
5826
      double new_coeff0_0 = 0;
 
5827
    
 
5828
      // Loop possible derivatives
 
5829
      for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
5830
      {
 
5831
        // Get values from coefficients array
 
5832
        new_coeff0_0 = coefficients0[dof][0];
 
5833
    
 
5834
        // Loop derivative order
 
5835
        for (unsigned int j = 0; j < n; j++)
 
5836
        {
 
5837
          // Update old coefficients
 
5838
          coeff0_0 = new_coeff0_0;
 
5839
    
 
5840
          if(combinations[deriv_num][j] == 0)
 
5841
          {
 
5842
            new_coeff0_0 = coeff0_0*dmats0[0][0];
 
5843
          }
 
5844
          if(combinations[deriv_num][j] == 1)
 
5845
          {
 
5846
            new_coeff0_0 = coeff0_0*dmats1[0][0];
 
5847
          }
 
5848
    
 
5849
        }
 
5850
        // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
5851
        derivatives[deriv_num] = new_coeff0_0*basisvalue0;
 
5852
      }
 
5853
    
 
5854
      // Transform derivatives back to physical element
 
5855
      for (unsigned int row = 0; row < num_derivatives; row++)
 
5856
      {
 
5857
        for (unsigned int col = 0; col < num_derivatives; col++)
 
5858
        {
 
5859
          values[2*num_derivatives + row] += transform[row][col]*derivatives[col];
 
5860
        }
 
5861
      }
 
5862
      // Delete pointer to array of derivatives on FIAT element
 
5863
      delete [] derivatives;
 
5864
    
 
5865
      // Delete pointer to array of combinations of derivatives and transform
 
5866
      for (unsigned int row = 0; row < num_derivatives; row++)
 
5867
      {
 
5868
        delete [] combinations[row];
 
5869
        delete [] transform[row];
 
5870
      }
 
5871
    
 
5872
      delete [] combinations;
 
5873
      delete [] transform;
 
5874
    }
 
5875
    
 
5876
  }
 
5877
 
 
5878
  /// Evaluate order n derivatives of all basis functions at given point in cell
 
5879
  virtual void evaluate_basis_derivatives_all(unsigned int n,
 
5880
                                              double* values,
 
5881
                                              const double* coordinates,
 
5882
                                              const ufc::cell& c) const
 
5883
  {
 
5884
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
5885
  }
 
5886
 
 
5887
  /// Evaluate linear functional for dof i on the function f
 
5888
  virtual double evaluate_dof(unsigned int i,
 
5889
                              const ufc::function& f,
 
5890
                              const ufc::cell& c) const
 
5891
  {
 
5892
    // The reference points, direction and weights:
 
5893
    static const double X[7][1][2] = {{{0.666666667, 0.333333333}}, {{0.333333333, 0.666666667}}, {{0, 0.333333333}}, {{0, 0.666666667}}, {{0.333333333, 0}}, {{0.666666667, 0}}, {{0.333333333, 0.333333333}}};
 
5894
    static const double W[7][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}};
 
5895
    static const double D[7][1][3] = {{{1, 1, 0}}, {{1, 1, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{0, -1, 0}}, {{0, -1, 0}}, {{0, 0, 1}}};
 
5896
    
 
5897
    static const unsigned int mappings[7] = {1, 1, 1, 1, 1, 1, 0};
 
5898
    // Extract vertex coordinates
 
5899
    const double * const * x = c.coordinates;
 
5900
    
 
5901
    // Compute Jacobian of affine map from reference cell
 
5902
    const double J_00 = x[1][0] - x[0][0];
 
5903
    const double J_01 = x[2][0] - x[0][0];
 
5904
    const double J_10 = x[1][1] - x[0][1];
 
5905
    const double J_11 = x[2][1] - x[0][1];
 
5906
    
 
5907
    // Compute determinant of Jacobian
 
5908
    double detJ = J_00*J_11 - J_01*J_10;
 
5909
    
 
5910
    // Compute inverse of Jacobian
 
5911
    const double Jinv_00 =  J_11 / detJ;
 
5912
    const double Jinv_01 = -J_01 / detJ;
 
5913
    const double Jinv_10 = -J_10 / detJ;
 
5914
    const double Jinv_11 =  J_00 / detJ;
 
5915
    
 
5916
    double copyofvalues[3];
 
5917
    double result = 0.0;
 
5918
    // Iterate over the points:
 
5919
    // Evaluate basis functions for affine mapping
 
5920
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
5921
    const double w1 = X[i][0][0];
 
5922
    const double w2 = X[i][0][1];
 
5923
    
 
5924
    // Compute affine mapping y = F(X)
 
5925
    double y[2];
 
5926
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
5927
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
5928
    
 
5929
    // Evaluate function at physical points
 
5930
    double values[3];
 
5931
    f.evaluate(values, y, c);
 
5932
    
 
5933
    // Map function values using appropriate mapping
 
5934
    if (mappings[i] == 0) { 
 
5935
      // Affine map: Do nothing
 
5936
    } else if (mappings[i] == 1) {
 
5937
       // Copy old values:
 
5938
      copyofvalues[0] = values[0];
 
5939
      copyofvalues[1] = values[1];
 
5940
      // Do the inverse of div piola 
 
5941
      values[0] = detJ*(Jinv_00*copyofvalues[0]+Jinv_01*copyofvalues[1]);
 
5942
      values[1] = detJ*(Jinv_10*copyofvalues[0]+Jinv_11*copyofvalues[1]); 
 
5943
    } else { 
 
5944
       // Other mappings not applicable. 
 
5945
    }
 
5946
    
 
5947
    // Note that we do not map the weights (yet).
 
5948
    
 
5949
    // Take directional components
 
5950
    for(int k = 0; k < 3; k++)
 
5951
      result += values[k]*D[i][0][k];
 
5952
    // Multiply by weights
 
5953
    result *= W[i][0];
 
5954
    
 
5955
    return result;
 
5956
  }
 
5957
 
 
5958
  /// Evaluate linear functionals for all dofs on the function f
 
5959
  virtual void evaluate_dofs(double* values,
 
5960
                             const ufc::function& f,
 
5961
                             const ufc::cell& c) const
 
5962
  {
 
5963
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
5964
  }
 
5965
 
 
5966
  /// Interpolate vertex values from dof values
 
5967
  virtual void interpolate_vertex_values(double* vertex_values,
 
5968
                                         const double* dof_values,
 
5969
                                         const ufc::cell& c) const
 
5970
  {
 
5971
    // Extract vertex coordinates
 
5972
    const double * const * x = c.coordinates;
 
5973
    
 
5974
    // Compute Jacobian of affine map from reference cell
 
5975
    const double J_00 = x[1][0] - x[0][0];
 
5976
    const double J_01 = x[2][0] - x[0][0];
 
5977
    const double J_10 = x[1][1] - x[0][1];
 
5978
    const double J_11 = x[2][1] - x[0][1];
 
5979
    
 
5980
    // Compute determinant of Jacobian
 
5981
    double detJ = J_00*J_11 - J_01*J_10;
 
5982
    
 
5983
    // Compute inverse of Jacobian
 
5984
    // Evaluate at vertices and use Piola mapping
 
5985
    vertex_values[0] = (1.0/detJ)*(dof_values[2]*2*J_00 + dof_values[3]*J_00 + dof_values[4]*(-2*J_01) + dof_values[5]*J_01);
 
5986
    vertex_values[3] = (1.0/detJ)*(dof_values[0]*2*J_00 + dof_values[1]*J_00 + dof_values[4]*(J_00 + J_01) + dof_values[5]*(2*J_00 - 2*J_01));
 
5987
    vertex_values[6] = (1.0/detJ)*(dof_values[0]*J_01 + dof_values[1]*2*J_01 + dof_values[2]*(J_00 + J_01) + dof_values[3]*(2*J_00 - 2*J_01));
 
5988
    vertex_values[1] = (1.0/detJ)*(dof_values[2]*2*J_10 + dof_values[3]*J_10 + dof_values[4]*(-2*J_11) + dof_values[5]*J_11);
 
5989
    vertex_values[4] = (1.0/detJ)*(dof_values[0]*2*J_10 + dof_values[1]*J_10 + dof_values[4]*(J_10 + J_11) + dof_values[5]*(2*J_10 - 2*J_11));
 
5990
    vertex_values[7] = (1.0/detJ)*(dof_values[0]*J_11 + dof_values[1]*2*J_11 + dof_values[2]*(J_10 + J_11) + dof_values[3]*(2*J_10 - 2*J_11));
 
5991
    // Evaluate at vertices and use affine mapping
 
5992
    vertex_values[2] = dof_values[6];
 
5993
    vertex_values[5] = dof_values[6];
 
5994
    vertex_values[8] = dof_values[6];
 
5995
  }
 
5996
 
 
5997
  /// Return the number of sub elements (for a mixed element)
 
5998
  virtual unsigned int num_sub_elements() const
 
5999
  {
 
6000
    return 2;
 
6001
  }
 
6002
 
 
6003
  /// Create a new finite element for sub element i (for a mixed element)
 
6004
  virtual ufc::finite_element* create_sub_element(unsigned int i) const
 
6005
  {
 
6006
    switch ( i )
 
6007
    {
 
6008
    case 0:
 
6009
      return new mixedpoisson_1_finite_element_0_0();
 
6010
      break;
 
6011
    case 1:
 
6012
      return new mixedpoisson_1_finite_element_0_1();
 
6013
      break;
 
6014
    }
 
6015
    return 0;
 
6016
  }
 
6017
 
 
6018
};
 
6019
 
 
6020
/// This class defines the interface for a finite element.
 
6021
 
 
6022
class mixedpoisson_1_finite_element_1: public ufc::finite_element
 
6023
{
 
6024
public:
 
6025
 
 
6026
  /// Constructor
 
6027
  mixedpoisson_1_finite_element_1() : ufc::finite_element()
 
6028
  {
 
6029
    // Do nothing
 
6030
  }
 
6031
 
 
6032
  /// Destructor
 
6033
  virtual ~mixedpoisson_1_finite_element_1()
 
6034
  {
 
6035
    // Do nothing
 
6036
  }
 
6037
 
 
6038
  /// Return a string identifying the finite element
 
6039
  virtual const char* signature() const
 
6040
  {
 
6041
    return "FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
 
6042
  }
 
6043
 
 
6044
  /// Return the cell shape
 
6045
  virtual ufc::shape cell_shape() const
 
6046
  {
 
6047
    return ufc::triangle;
 
6048
  }
 
6049
 
 
6050
  /// Return the dimension of the finite element function space
 
6051
  virtual unsigned int space_dimension() const
 
6052
  {
 
6053
    return 1;
 
6054
  }
 
6055
 
 
6056
  /// Return the rank of the value space
 
6057
  virtual unsigned int value_rank() const
 
6058
  {
 
6059
    return 0;
 
6060
  }
 
6061
 
 
6062
  /// Return the dimension of the value space for axis i
 
6063
  virtual unsigned int value_dimension(unsigned int i) const
 
6064
  {
 
6065
    return 1;
 
6066
  }
 
6067
 
 
6068
  /// Evaluate basis function i at given point in cell
 
6069
  virtual void evaluate_basis(unsigned int i,
 
6070
                              double* values,
 
6071
                              const double* coordinates,
 
6072
                              const ufc::cell& c) const
 
6073
  {
 
6074
    // Extract vertex coordinates
 
6075
    const double * const * element_coordinates = c.coordinates;
 
6076
    
 
6077
    // Compute Jacobian of affine map from reference cell
 
6078
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
6079
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
6080
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
6081
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
6082
    
 
6083
    // Compute determinant of Jacobian
 
6084
    const double detJ = J_00*J_11 - J_01*J_10;
 
6085
    
 
6086
    // Compute inverse of Jacobian
 
6087
    
 
6088
    // Get coordinates and map to the reference (UFC) element
 
6089
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
6090
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
6091
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
6092
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
6093
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
6094
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
6095
    
 
6096
    // Map coordinates to the reference square
 
6097
    if (std::abs(y - 1.0) < 1e-08)
 
6098
      x = -1.0;
 
6099
    else
 
6100
      x = 2.0 *x/(1.0 - y) - 1.0;
 
6101
    y = 2.0*y - 1.0;
 
6102
    
 
6103
    // Reset values
 
6104
    *values = 0;
 
6105
    
 
6106
    // Map degree of freedom to element degree of freedom
 
6107
    const unsigned int dof = i;
 
6108
    
 
6109
    // Generate scalings
 
6110
    const double scalings_y_0 = 1;
 
6111
    
 
6112
    // Compute psitilde_a
 
6113
    const double psitilde_a_0 = 1;
 
6114
    
 
6115
    // Compute psitilde_bs
 
6116
    const double psitilde_bs_0_0 = 1;
 
6117
    
 
6118
    // Compute basisvalues
 
6119
    const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
6120
    
 
6121
    // Table(s) of coefficients
 
6122
    static const double coefficients0[1][1] = \
 
6123
    {{1.41421356}};
 
6124
    
 
6125
    // Extract relevant coefficients
 
6126
    const double coeff0_0 = coefficients0[dof][0];
 
6127
    
 
6128
    // Compute value(s)
 
6129
    *values = coeff0_0*basisvalue0;
 
6130
  }
 
6131
 
 
6132
  /// Evaluate all basis functions at given point in cell
 
6133
  virtual void evaluate_basis_all(double* values,
 
6134
                                  const double* coordinates,
 
6135
                                  const ufc::cell& c) const
 
6136
  {
 
6137
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
6138
  }
 
6139
 
 
6140
  /// Evaluate order n derivatives of basis function i at given point in cell
 
6141
  virtual void evaluate_basis_derivatives(unsigned int i,
 
6142
                                          unsigned int n,
 
6143
                                          double* values,
 
6144
                                          const double* coordinates,
 
6145
                                          const ufc::cell& c) const
 
6146
  {
 
6147
    // Extract vertex coordinates
 
6148
    const double * const * element_coordinates = c.coordinates;
 
6149
    
 
6150
    // Compute Jacobian of affine map from reference cell
 
6151
    const double J_00 = element_coordinates[1][0] - element_coordinates[0][0];
 
6152
    const double J_01 = element_coordinates[2][0] - element_coordinates[0][0];
 
6153
    const double J_10 = element_coordinates[1][1] - element_coordinates[0][1];
 
6154
    const double J_11 = element_coordinates[2][1] - element_coordinates[0][1];
 
6155
    
 
6156
    // Compute determinant of Jacobian
 
6157
    const double detJ = J_00*J_11 - J_01*J_10;
 
6158
    
 
6159
    // Compute inverse of Jacobian
 
6160
    
 
6161
    // Get coordinates and map to the reference (UFC) element
 
6162
    double x = (element_coordinates[0][1]*element_coordinates[2][0] -\
 
6163
                element_coordinates[0][0]*element_coordinates[2][1] +\
 
6164
                J_11*coordinates[0] - J_01*coordinates[1]) / detJ;
 
6165
    double y = (element_coordinates[1][1]*element_coordinates[0][0] -\
 
6166
                element_coordinates[1][0]*element_coordinates[0][1] -\
 
6167
                J_10*coordinates[0] + J_00*coordinates[1]) / detJ;
 
6168
    
 
6169
    // Map coordinates to the reference square
 
6170
    if (std::abs(y - 1.0) < 1e-08)
 
6171
      x = -1.0;
 
6172
    else
 
6173
      x = 2.0 *x/(1.0 - y) - 1.0;
 
6174
    y = 2.0*y - 1.0;
 
6175
    
 
6176
    // Compute number of derivatives
 
6177
    unsigned int num_derivatives = 1;
 
6178
    
 
6179
    for (unsigned int j = 0; j < n; j++)
 
6180
      num_derivatives *= 2;
 
6181
    
 
6182
    
 
6183
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
6184
    unsigned int **combinations = new unsigned int *[num_derivatives];
 
6185
    
 
6186
    for (unsigned int j = 0; j < num_derivatives; j++)
 
6187
    {
 
6188
      combinations[j] = new unsigned int [n];
 
6189
      for (unsigned int k = 0; k < n; k++)
 
6190
        combinations[j][k] = 0;
 
6191
    }
 
6192
    
 
6193
    // Generate combinations of derivatives
 
6194
    for (unsigned int row = 1; row < num_derivatives; row++)
 
6195
    {
 
6196
      for (unsigned int num = 0; num < row; num++)
 
6197
      {
 
6198
        for (unsigned int col = n-1; col+1 > 0; col--)
 
6199
        {
 
6200
          if (combinations[row][col] + 1 > 1)
 
6201
            combinations[row][col] = 0;
 
6202
          else
 
6203
          {
 
6204
            combinations[row][col] += 1;
 
6205
            break;
 
6206
          }
 
6207
        }
 
6208
      }
 
6209
    }
 
6210
    
 
6211
    // Compute inverse of Jacobian
 
6212
    const double Jinv[2][2] =  {{J_11 / detJ, -J_01 / detJ}, {-J_10 / detJ, J_00 / detJ}};
 
6213
    
 
6214
    // Declare transformation matrix
 
6215
    // Declare pointer to two dimensional array and initialise
 
6216
    double **transform = new double *[num_derivatives];
 
6217
    
 
6218
    for (unsigned int j = 0; j < num_derivatives; j++)
 
6219
    {
 
6220
      transform[j] = new double [num_derivatives];
 
6221
      for (unsigned int k = 0; k < num_derivatives; k++)
 
6222
        transform[j][k] = 1;
 
6223
    }
 
6224
    
 
6225
    // Construct transformation matrix
 
6226
    for (unsigned int row = 0; row < num_derivatives; row++)
 
6227
    {
 
6228
      for (unsigned int col = 0; col < num_derivatives; col++)
 
6229
      {
 
6230
        for (unsigned int k = 0; k < n; k++)
 
6231
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
 
6232
      }
 
6233
    }
 
6234
    
 
6235
    // Reset values
 
6236
    for (unsigned int j = 0; j < 1*num_derivatives; j++)
 
6237
      values[j] = 0;
 
6238
    
 
6239
    // Map degree of freedom to element degree of freedom
 
6240
    const unsigned int dof = i;
 
6241
    
 
6242
    // Generate scalings
 
6243
    const double scalings_y_0 = 1;
 
6244
    
 
6245
    // Compute psitilde_a
 
6246
    const double psitilde_a_0 = 1;
 
6247
    
 
6248
    // Compute psitilde_bs
 
6249
    const double psitilde_bs_0_0 = 1;
 
6250
    
 
6251
    // Compute basisvalues
 
6252
    const double basisvalue0 = 0.707106781*psitilde_a_0*scalings_y_0*psitilde_bs_0_0;
 
6253
    
 
6254
    // Table(s) of coefficients
 
6255
    static const double coefficients0[1][1] = \
 
6256
    {{1.41421356}};
 
6257
    
 
6258
    // Interesting (new) part
 
6259
    // Tables of derivatives of the polynomial base (transpose)
 
6260
    static const double dmats0[1][1] = \
 
6261
    {{0}};
 
6262
    
 
6263
    static const double dmats1[1][1] = \
 
6264
    {{0}};
 
6265
    
 
6266
    // Compute reference derivatives
 
6267
    // Declare pointer to array of derivatives on FIAT element
 
6268
    double *derivatives = new double [num_derivatives];
 
6269
    
 
6270
    // Declare coefficients
 
6271
    double coeff0_0 = 0;
 
6272
    
 
6273
    // Declare new coefficients
 
6274
    double new_coeff0_0 = 0;
 
6275
    
 
6276
    // Loop possible derivatives
 
6277
    for (unsigned int deriv_num = 0; deriv_num < num_derivatives; deriv_num++)
 
6278
    {
 
6279
      // Get values from coefficients array
 
6280
      new_coeff0_0 = coefficients0[dof][0];
 
6281
    
 
6282
      // Loop derivative order
 
6283
      for (unsigned int j = 0; j < n; j++)
 
6284
      {
 
6285
        // Update old coefficients
 
6286
        coeff0_0 = new_coeff0_0;
 
6287
    
 
6288
        if(combinations[deriv_num][j] == 0)
 
6289
        {
 
6290
          new_coeff0_0 = coeff0_0*dmats0[0][0];
 
6291
        }
 
6292
        if(combinations[deriv_num][j] == 1)
 
6293
        {
 
6294
          new_coeff0_0 = coeff0_0*dmats1[0][0];
 
6295
        }
 
6296
    
 
6297
      }
 
6298
      // Compute derivatives on reference element as dot product of coefficients and basisvalues
 
6299
      derivatives[deriv_num] = new_coeff0_0*basisvalue0;
 
6300
    }
 
6301
    
 
6302
    // Transform derivatives back to physical element
 
6303
    for (unsigned int row = 0; row < num_derivatives; row++)
 
6304
    {
 
6305
      for (unsigned int col = 0; col < num_derivatives; col++)
 
6306
      {
 
6307
        values[row] += transform[row][col]*derivatives[col];
 
6308
      }
 
6309
    }
 
6310
    // Delete pointer to array of derivatives on FIAT element
 
6311
    delete [] derivatives;
 
6312
    
 
6313
    // Delete pointer to array of combinations of derivatives and transform
 
6314
    for (unsigned int row = 0; row < num_derivatives; row++)
 
6315
    {
 
6316
      delete [] combinations[row];
 
6317
      delete [] transform[row];
 
6318
    }
 
6319
    
 
6320
    delete [] combinations;
 
6321
    delete [] transform;
 
6322
  }
 
6323
 
 
6324
  /// Evaluate order n derivatives of all basis functions at given point in cell
 
6325
  virtual void evaluate_basis_derivatives_all(unsigned int n,
 
6326
                                              double* values,
 
6327
                                              const double* coordinates,
 
6328
                                              const ufc::cell& c) const
 
6329
  {
 
6330
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
6331
  }
 
6332
 
 
6333
  /// Evaluate linear functional for dof i on the function f
 
6334
  virtual double evaluate_dof(unsigned int i,
 
6335
                              const ufc::function& f,
 
6336
                              const ufc::cell& c) const
 
6337
  {
 
6338
    // The reference points, direction and weights:
 
6339
    static const double X[1][1][2] = {{{0.333333333, 0.333333333}}};
 
6340
    static const double W[1][1] = {{1}};
 
6341
    static const double D[1][1][1] = {{{1}}};
 
6342
    
 
6343
    const double * const * x = c.coordinates;
 
6344
    double result = 0.0;
 
6345
    // Iterate over the points:
 
6346
    // Evaluate basis functions for affine mapping
 
6347
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1];
 
6348
    const double w1 = X[i][0][0];
 
6349
    const double w2 = X[i][0][1];
 
6350
    
 
6351
    // Compute affine mapping y = F(X)
 
6352
    double y[2];
 
6353
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0];
 
6354
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1];
 
6355
    
 
6356
    // Evaluate function at physical points
 
6357
    double values[1];
 
6358
    f.evaluate(values, y, c);
 
6359
    
 
6360
    // Map function values using appropriate mapping
 
6361
    // Affine map: Do nothing
 
6362
    
 
6363
    // Note that we do not map the weights (yet).
 
6364
    
 
6365
    // Take directional components
 
6366
    for(int k = 0; k < 1; k++)
 
6367
      result += values[k]*D[i][0][k];
 
6368
    // Multiply by weights
 
6369
    result *= W[i][0];
 
6370
    
 
6371
    return result;
 
6372
  }
 
6373
 
 
6374
  /// Evaluate linear functionals for all dofs on the function f
 
6375
  virtual void evaluate_dofs(double* values,
 
6376
                             const ufc::function& f,
 
6377
                             const ufc::cell& c) const
 
6378
  {
 
6379
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
6380
  }
 
6381
 
 
6382
  /// Interpolate vertex values from dof values
 
6383
  virtual void interpolate_vertex_values(double* vertex_values,
 
6384
                                         const double* dof_values,
 
6385
                                         const ufc::cell& c) const
 
6386
  {
 
6387
    // Evaluate at vertices and use affine mapping
 
6388
    vertex_values[0] = dof_values[0];
 
6389
    vertex_values[1] = dof_values[0];
 
6390
    vertex_values[2] = dof_values[0];
 
6391
  }
 
6392
 
 
6393
  /// Return the number of sub elements (for a mixed element)
 
6394
  virtual unsigned int num_sub_elements() const
 
6395
  {
 
6396
    return 1;
 
6397
  }
 
6398
 
 
6399
  /// Create a new finite element for sub element i (for a mixed element)
 
6400
  virtual ufc::finite_element* create_sub_element(unsigned int i) const
 
6401
  {
 
6402
    return new mixedpoisson_1_finite_element_1();
 
6403
  }
 
6404
 
 
6405
};
 
6406
 
 
6407
/// This class defines the interface for a local-to-global mapping of
 
6408
/// degrees of freedom (dofs).
 
6409
 
 
6410
class mixedpoisson_1_dof_map_0_0: public ufc::dof_map
 
6411
{
 
6412
private:
 
6413
 
 
6414
  unsigned int __global_dimension;
 
6415
 
 
6416
public:
 
6417
 
 
6418
  /// Constructor
 
6419
  mixedpoisson_1_dof_map_0_0() : ufc::dof_map()
 
6420
  {
 
6421
    __global_dimension = 0;
 
6422
  }
 
6423
 
 
6424
  /// Destructor
 
6425
  virtual ~mixedpoisson_1_dof_map_0_0()
 
6426
  {
 
6427
    // Do nothing
 
6428
  }
 
6429
 
 
6430
  /// Return a string identifying the dof map
 
6431
  virtual const char* signature() const
 
6432
  {
 
6433
    return "FFC dof map for FiniteElement('Brezzi-Douglas-Marini', 'triangle', 1)";
 
6434
  }
 
6435
 
 
6436
  /// Return true iff mesh entities of topological dimension d are needed
 
6437
  virtual bool needs_mesh_entities(unsigned int d) const
 
6438
  {
 
6439
    switch ( d )
 
6440
    {
 
6441
    case 0:
 
6442
      return false;
 
6443
      break;
 
6444
    case 1:
 
6445
      return true;
 
6446
      break;
 
6447
    case 2:
 
6448
      return false;
 
6449
      break;
 
6450
    }
 
6451
    return false;
 
6452
  }
 
6453
 
 
6454
  /// Initialize dof map for mesh (return true iff init_cell() is needed)
 
6455
  virtual bool init_mesh(const ufc::mesh& m)
 
6456
  {
 
6457
    __global_dimension = 2*m.num_entities[1];
 
6458
    return false;
 
6459
  }
 
6460
 
 
6461
  /// Initialize dof map for given cell
 
6462
  virtual void init_cell(const ufc::mesh& m,
 
6463
                         const ufc::cell& c)
 
6464
  {
 
6465
    // Do nothing
 
6466
  }
 
6467
 
 
6468
  /// Finish initialization of dof map for cells
 
6469
  virtual void init_cell_finalize()
 
6470
  {
 
6471
    // Do nothing
 
6472
  }
 
6473
 
 
6474
  /// Return the dimension of the global finite element function space
 
6475
  virtual unsigned int global_dimension() const
 
6476
  {
 
6477
    return __global_dimension;
 
6478
  }
 
6479
 
 
6480
  /// Return the dimension of the local finite element function space for a cell
 
6481
  virtual unsigned int local_dimension(const ufc::cell& c) const
 
6482
  {
 
6483
    return 6;
 
6484
  }
 
6485
 
 
6486
  /// Return the maximum dimension of the local finite element function space
 
6487
  virtual unsigned int max_local_dimension() const
 
6488
  {
 
6489
    return 6;
 
6490
  }
 
6491
 
 
6492
  // Return the geometric dimension of the coordinates this dof map provides
 
6493
  virtual unsigned int geometric_dimension() const
 
6494
  {
 
6495
    return 2;
 
6496
  }
 
6497
 
 
6498
  /// Return the number of dofs on each cell facet
 
6499
  virtual unsigned int num_facet_dofs() const
 
6500
  {
 
6501
    return 2;
 
6502
  }
 
6503
 
 
6504
  /// Return the number of dofs associated with each cell entity of dimension d
 
6505
  virtual unsigned int num_entity_dofs(unsigned int d) const
 
6506
  {
 
6507
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
6508
  }
 
6509
 
 
6510
  /// Tabulate the local-to-global mapping of dofs on a cell
 
6511
  virtual void tabulate_dofs(unsigned int* dofs,
 
6512
                             const ufc::mesh& m,
 
6513
                             const ufc::cell& c) const
 
6514
  {
 
6515
    dofs[0] = 2*c.entity_indices[1][0];
 
6516
    dofs[1] = 2*c.entity_indices[1][0] + 1;
 
6517
    dofs[2] = 2*c.entity_indices[1][1];
 
6518
    dofs[3] = 2*c.entity_indices[1][1] + 1;
 
6519
    dofs[4] = 2*c.entity_indices[1][2];
 
6520
    dofs[5] = 2*c.entity_indices[1][2] + 1;
 
6521
  }
 
6522
 
 
6523
  /// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
6524
  virtual void tabulate_facet_dofs(unsigned int* dofs,
 
6525
                                   unsigned int facet) const
 
6526
  {
 
6527
    switch ( facet )
 
6528
    {
 
6529
    case 0:
 
6530
      dofs[0] = 0;
 
6531
      dofs[1] = 1;
 
6532
      break;
 
6533
    case 1:
 
6534
      dofs[0] = 2;
 
6535
      dofs[1] = 3;
 
6536
      break;
 
6537
    case 2:
 
6538
      dofs[0] = 4;
 
6539
      dofs[1] = 5;
 
6540
      break;
 
6541
    }
 
6542
  }
 
6543
 
 
6544
  /// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
6545
  virtual void tabulate_entity_dofs(unsigned int* dofs,
 
6546
                                    unsigned int d, unsigned int i) const
 
6547
  {
 
6548
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
6549
  }
 
6550
 
 
6551
  /// Tabulate the coordinates of all dofs on a cell
 
6552
  virtual void tabulate_coordinates(double** coordinates,
 
6553
                                    const ufc::cell& c) const
 
6554
  {
 
6555
    const double * const * x = c.coordinates;
 
6556
    coordinates[0][0] = 0.666666667*x[1][0] + 0.333333333*x[2][0];
 
6557
    coordinates[0][1] = 0.666666667*x[1][1] + 0.333333333*x[2][1];
 
6558
    coordinates[1][0] = 0.333333333*x[1][0] + 0.666666667*x[2][0];
 
6559
    coordinates[1][1] = 0.333333333*x[1][1] + 0.666666667*x[2][1];
 
6560
    coordinates[2][0] = 0.666666667*x[0][0] + 0.333333333*x[2][0];
 
6561
    coordinates[2][1] = 0.666666667*x[0][1] + 0.333333333*x[2][1];
 
6562
    coordinates[3][0] = 0.333333333*x[0][0] + 0.666666667*x[2][0];
 
6563
    coordinates[3][1] = 0.333333333*x[0][1] + 0.666666667*x[2][1];
 
6564
    coordinates[4][0] = 0.666666667*x[0][0] + 0.333333333*x[1][0];
 
6565
    coordinates[4][1] = 0.666666667*x[0][1] + 0.333333333*x[1][1];
 
6566
    coordinates[5][0] = 0.333333333*x[0][0] + 0.666666667*x[1][0];
 
6567
    coordinates[5][1] = 0.333333333*x[0][1] + 0.666666667*x[1][1];
 
6568
  }
 
6569
 
 
6570
  /// Return the number of sub dof maps (for a mixed element)
 
6571
  virtual unsigned int num_sub_dof_maps() const
 
6572
  {
 
6573
    return 1;
 
6574
  }
 
6575
 
 
6576
  /// Create a new dof_map for sub dof map i (for a mixed element)
 
6577
  virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
 
6578
  {
 
6579
    return new mixedpoisson_1_dof_map_0_0();
 
6580
  }
 
6581
 
 
6582
};
 
6583
 
 
6584
/// This class defines the interface for a local-to-global mapping of
 
6585
/// degrees of freedom (dofs).
 
6586
 
 
6587
class mixedpoisson_1_dof_map_0_1: public ufc::dof_map
 
6588
{
 
6589
private:
 
6590
 
 
6591
  unsigned int __global_dimension;
 
6592
 
 
6593
public:
 
6594
 
 
6595
  /// Constructor
 
6596
  mixedpoisson_1_dof_map_0_1() : ufc::dof_map()
 
6597
  {
 
6598
    __global_dimension = 0;
 
6599
  }
 
6600
 
 
6601
  /// Destructor
 
6602
  virtual ~mixedpoisson_1_dof_map_0_1()
 
6603
  {
 
6604
    // Do nothing
 
6605
  }
 
6606
 
 
6607
  /// Return a string identifying the dof map
 
6608
  virtual const char* signature() const
 
6609
  {
 
6610
    return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
 
6611
  }
 
6612
 
 
6613
  /// Return true iff mesh entities of topological dimension d are needed
 
6614
  virtual bool needs_mesh_entities(unsigned int d) const
 
6615
  {
 
6616
    switch ( d )
 
6617
    {
 
6618
    case 0:
 
6619
      return false;
 
6620
      break;
 
6621
    case 1:
 
6622
      return false;
 
6623
      break;
 
6624
    case 2:
 
6625
      return true;
 
6626
      break;
 
6627
    }
 
6628
    return false;
 
6629
  }
 
6630
 
 
6631
  /// Initialize dof map for mesh (return true iff init_cell() is needed)
 
6632
  virtual bool init_mesh(const ufc::mesh& m)
 
6633
  {
 
6634
    __global_dimension = m.num_entities[2];
 
6635
    return false;
 
6636
  }
 
6637
 
 
6638
  /// Initialize dof map for given cell
 
6639
  virtual void init_cell(const ufc::mesh& m,
 
6640
                         const ufc::cell& c)
 
6641
  {
 
6642
    // Do nothing
 
6643
  }
 
6644
 
 
6645
  /// Finish initialization of dof map for cells
 
6646
  virtual void init_cell_finalize()
 
6647
  {
 
6648
    // Do nothing
 
6649
  }
 
6650
 
 
6651
  /// Return the dimension of the global finite element function space
 
6652
  virtual unsigned int global_dimension() const
 
6653
  {
 
6654
    return __global_dimension;
 
6655
  }
 
6656
 
 
6657
  /// Return the dimension of the local finite element function space for a cell
 
6658
  virtual unsigned int local_dimension(const ufc::cell& c) const
 
6659
  {
 
6660
    return 1;
 
6661
  }
 
6662
 
 
6663
  /// Return the maximum dimension of the local finite element function space
 
6664
  virtual unsigned int max_local_dimension() const
 
6665
  {
 
6666
    return 1;
 
6667
  }
 
6668
 
 
6669
  // Return the geometric dimension of the coordinates this dof map provides
 
6670
  virtual unsigned int geometric_dimension() const
 
6671
  {
 
6672
    return 2;
 
6673
  }
 
6674
 
 
6675
  /// Return the number of dofs on each cell facet
 
6676
  virtual unsigned int num_facet_dofs() const
 
6677
  {
 
6678
    return 0;
 
6679
  }
 
6680
 
 
6681
  /// Return the number of dofs associated with each cell entity of dimension d
 
6682
  virtual unsigned int num_entity_dofs(unsigned int d) const
 
6683
  {
 
6684
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
6685
  }
 
6686
 
 
6687
  /// Tabulate the local-to-global mapping of dofs on a cell
 
6688
  virtual void tabulate_dofs(unsigned int* dofs,
 
6689
                             const ufc::mesh& m,
 
6690
                             const ufc::cell& c) const
 
6691
  {
 
6692
    dofs[0] = c.entity_indices[2][0];
 
6693
  }
 
6694
 
 
6695
  /// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
6696
  virtual void tabulate_facet_dofs(unsigned int* dofs,
 
6697
                                   unsigned int facet) const
 
6698
  {
 
6699
    switch ( facet )
 
6700
    {
 
6701
    case 0:
 
6702
      
 
6703
      break;
 
6704
    case 1:
 
6705
      
 
6706
      break;
 
6707
    case 2:
 
6708
      
 
6709
      break;
 
6710
    }
 
6711
  }
 
6712
 
 
6713
  /// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
6714
  virtual void tabulate_entity_dofs(unsigned int* dofs,
 
6715
                                    unsigned int d, unsigned int i) const
 
6716
  {
 
6717
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
6718
  }
 
6719
 
 
6720
  /// Tabulate the coordinates of all dofs on a cell
 
6721
  virtual void tabulate_coordinates(double** coordinates,
 
6722
                                    const ufc::cell& c) const
 
6723
  {
 
6724
    const double * const * x = c.coordinates;
 
6725
    coordinates[0][0] = 0.333333333*x[0][0] + 0.333333333*x[1][0] + 0.333333333*x[2][0];
 
6726
    coordinates[0][1] = 0.333333333*x[0][1] + 0.333333333*x[1][1] + 0.333333333*x[2][1];
 
6727
  }
 
6728
 
 
6729
  /// Return the number of sub dof maps (for a mixed element)
 
6730
  virtual unsigned int num_sub_dof_maps() const
 
6731
  {
 
6732
    return 1;
 
6733
  }
 
6734
 
 
6735
  /// Create a new dof_map for sub dof map i (for a mixed element)
 
6736
  virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
 
6737
  {
 
6738
    return new mixedpoisson_1_dof_map_0_1();
 
6739
  }
 
6740
 
 
6741
};
 
6742
 
 
6743
/// This class defines the interface for a local-to-global mapping of
 
6744
/// degrees of freedom (dofs).
 
6745
 
 
6746
class mixedpoisson_1_dof_map_0: public ufc::dof_map
 
6747
{
 
6748
private:
 
6749
 
 
6750
  unsigned int __global_dimension;
 
6751
 
 
6752
public:
 
6753
 
 
6754
  /// Constructor
 
6755
  mixedpoisson_1_dof_map_0() : ufc::dof_map()
 
6756
  {
 
6757
    __global_dimension = 0;
 
6758
  }
 
6759
 
 
6760
  /// Destructor
 
6761
  virtual ~mixedpoisson_1_dof_map_0()
 
6762
  {
 
6763
    // Do nothing
 
6764
  }
 
6765
 
 
6766
  /// Return a string identifying the dof map
 
6767
  virtual const char* signature() const
 
6768
  {
 
6769
    return "FFC dof map for MixedElement([FiniteElement('Brezzi-Douglas-Marini', 'triangle', 1), FiniteElement('Discontinuous Lagrange', 'triangle', 0)])";
 
6770
  }
 
6771
 
 
6772
  /// Return true iff mesh entities of topological dimension d are needed
 
6773
  virtual bool needs_mesh_entities(unsigned int d) const
 
6774
  {
 
6775
    switch ( d )
 
6776
    {
 
6777
    case 0:
 
6778
      return false;
 
6779
      break;
 
6780
    case 1:
 
6781
      return true;
 
6782
      break;
 
6783
    case 2:
 
6784
      return true;
 
6785
      break;
 
6786
    }
 
6787
    return false;
 
6788
  }
 
6789
 
 
6790
  /// Initialize dof map for mesh (return true iff init_cell() is needed)
 
6791
  virtual bool init_mesh(const ufc::mesh& m)
 
6792
  {
 
6793
    __global_dimension = 2*m.num_entities[1] + m.num_entities[2];
 
6794
    return false;
 
6795
  }
 
6796
 
 
6797
  /// Initialize dof map for given cell
 
6798
  virtual void init_cell(const ufc::mesh& m,
 
6799
                         const ufc::cell& c)
 
6800
  {
 
6801
    // Do nothing
 
6802
  }
 
6803
 
 
6804
  /// Finish initialization of dof map for cells
 
6805
  virtual void init_cell_finalize()
 
6806
  {
 
6807
    // Do nothing
 
6808
  }
 
6809
 
 
6810
  /// Return the dimension of the global finite element function space
 
6811
  virtual unsigned int global_dimension() const
 
6812
  {
 
6813
    return __global_dimension;
 
6814
  }
 
6815
 
 
6816
  /// Return the dimension of the local finite element function space for a cell
 
6817
  virtual unsigned int local_dimension(const ufc::cell& c) const
 
6818
  {
 
6819
    return 7;
 
6820
  }
 
6821
 
 
6822
  /// Return the maximum dimension of the local finite element function space
 
6823
  virtual unsigned int max_local_dimension() const
 
6824
  {
 
6825
    return 7;
 
6826
  }
 
6827
 
 
6828
  // Return the geometric dimension of the coordinates this dof map provides
 
6829
  virtual unsigned int geometric_dimension() const
 
6830
  {
 
6831
    return 2;
 
6832
  }
 
6833
 
 
6834
  /// Return the number of dofs on each cell facet
 
6835
  virtual unsigned int num_facet_dofs() const
 
6836
  {
 
6837
    return 2;
 
6838
  }
 
6839
 
 
6840
  /// Return the number of dofs associated with each cell entity of dimension d
 
6841
  virtual unsigned int num_entity_dofs(unsigned int d) const
 
6842
  {
 
6843
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
6844
  }
 
6845
 
 
6846
  /// Tabulate the local-to-global mapping of dofs on a cell
 
6847
  virtual void tabulate_dofs(unsigned int* dofs,
 
6848
                             const ufc::mesh& m,
 
6849
                             const ufc::cell& c) const
 
6850
  {
 
6851
    dofs[0] = 2*c.entity_indices[1][0];
 
6852
    dofs[1] = 2*c.entity_indices[1][0] + 1;
 
6853
    dofs[2] = 2*c.entity_indices[1][1];
 
6854
    dofs[3] = 2*c.entity_indices[1][1] + 1;
 
6855
    dofs[4] = 2*c.entity_indices[1][2];
 
6856
    dofs[5] = 2*c.entity_indices[1][2] + 1;
 
6857
    unsigned int offset = 2*m.num_entities[1];
 
6858
    dofs[6] = offset + c.entity_indices[2][0];
 
6859
  }
 
6860
 
 
6861
  /// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
6862
  virtual void tabulate_facet_dofs(unsigned int* dofs,
 
6863
                                   unsigned int facet) const
 
6864
  {
 
6865
    switch ( facet )
 
6866
    {
 
6867
    case 0:
 
6868
      dofs[0] = 0;
 
6869
      dofs[1] = 1;
 
6870
      break;
 
6871
    case 1:
 
6872
      dofs[0] = 2;
 
6873
      dofs[1] = 3;
 
6874
      break;
 
6875
    case 2:
 
6876
      dofs[0] = 4;
 
6877
      dofs[1] = 5;
 
6878
      break;
 
6879
    }
 
6880
  }
 
6881
 
 
6882
  /// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
6883
  virtual void tabulate_entity_dofs(unsigned int* dofs,
 
6884
                                    unsigned int d, unsigned int i) const
 
6885
  {
 
6886
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
6887
  }
 
6888
 
 
6889
  /// Tabulate the coordinates of all dofs on a cell
 
6890
  virtual void tabulate_coordinates(double** coordinates,
 
6891
                                    const ufc::cell& c) const
 
6892
  {
 
6893
    const double * const * x = c.coordinates;
 
6894
    coordinates[0][0] = 0.666666667*x[1][0] + 0.333333333*x[2][0];
 
6895
    coordinates[0][1] = 0.666666667*x[1][1] + 0.333333333*x[2][1];
 
6896
    coordinates[1][0] = 0.333333333*x[1][0] + 0.666666667*x[2][0];
 
6897
    coordinates[1][1] = 0.333333333*x[1][1] + 0.666666667*x[2][1];
 
6898
    coordinates[2][0] = 0.666666667*x[0][0] + 0.333333333*x[2][0];
 
6899
    coordinates[2][1] = 0.666666667*x[0][1] + 0.333333333*x[2][1];
 
6900
    coordinates[3][0] = 0.333333333*x[0][0] + 0.666666667*x[2][0];
 
6901
    coordinates[3][1] = 0.333333333*x[0][1] + 0.666666667*x[2][1];
 
6902
    coordinates[4][0] = 0.666666667*x[0][0] + 0.333333333*x[1][0];
 
6903
    coordinates[4][1] = 0.666666667*x[0][1] + 0.333333333*x[1][1];
 
6904
    coordinates[5][0] = 0.333333333*x[0][0] + 0.666666667*x[1][0];
 
6905
    coordinates[5][1] = 0.333333333*x[0][1] + 0.666666667*x[1][1];
 
6906
    coordinates[6][0] = 0.333333333*x[0][0] + 0.333333333*x[1][0] + 0.333333333*x[2][0];
 
6907
    coordinates[6][1] = 0.333333333*x[0][1] + 0.333333333*x[1][1] + 0.333333333*x[2][1];
 
6908
  }
 
6909
 
 
6910
  /// Return the number of sub dof maps (for a mixed element)
 
6911
  virtual unsigned int num_sub_dof_maps() const
 
6912
  {
 
6913
    return 2;
 
6914
  }
 
6915
 
 
6916
  /// Create a new dof_map for sub dof map i (for a mixed element)
 
6917
  virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
 
6918
  {
 
6919
    switch ( i )
 
6920
    {
 
6921
    case 0:
 
6922
      return new mixedpoisson_1_dof_map_0_0();
 
6923
      break;
 
6924
    case 1:
 
6925
      return new mixedpoisson_1_dof_map_0_1();
 
6926
      break;
 
6927
    }
 
6928
    return 0;
 
6929
  }
 
6930
 
 
6931
};
 
6932
 
 
6933
/// This class defines the interface for a local-to-global mapping of
 
6934
/// degrees of freedom (dofs).
 
6935
 
 
6936
class mixedpoisson_1_dof_map_1: public ufc::dof_map
 
6937
{
 
6938
private:
 
6939
 
 
6940
  unsigned int __global_dimension;
 
6941
 
 
6942
public:
 
6943
 
 
6944
  /// Constructor
 
6945
  mixedpoisson_1_dof_map_1() : ufc::dof_map()
 
6946
  {
 
6947
    __global_dimension = 0;
 
6948
  }
 
6949
 
 
6950
  /// Destructor
 
6951
  virtual ~mixedpoisson_1_dof_map_1()
 
6952
  {
 
6953
    // Do nothing
 
6954
  }
 
6955
 
 
6956
  /// Return a string identifying the dof map
 
6957
  virtual const char* signature() const
 
6958
  {
 
6959
    return "FFC dof map for FiniteElement('Discontinuous Lagrange', 'triangle', 0)";
 
6960
  }
 
6961
 
 
6962
  /// Return true iff mesh entities of topological dimension d are needed
 
6963
  virtual bool needs_mesh_entities(unsigned int d) const
 
6964
  {
 
6965
    switch ( d )
 
6966
    {
 
6967
    case 0:
 
6968
      return false;
 
6969
      break;
 
6970
    case 1:
 
6971
      return false;
 
6972
      break;
 
6973
    case 2:
 
6974
      return true;
 
6975
      break;
 
6976
    }
 
6977
    return false;
 
6978
  }
 
6979
 
 
6980
  /// Initialize dof map for mesh (return true iff init_cell() is needed)
 
6981
  virtual bool init_mesh(const ufc::mesh& m)
 
6982
  {
 
6983
    __global_dimension = m.num_entities[2];
 
6984
    return false;
 
6985
  }
 
6986
 
 
6987
  /// Initialize dof map for given cell
 
6988
  virtual void init_cell(const ufc::mesh& m,
 
6989
                         const ufc::cell& c)
 
6990
  {
 
6991
    // Do nothing
 
6992
  }
 
6993
 
 
6994
  /// Finish initialization of dof map for cells
 
6995
  virtual void init_cell_finalize()
 
6996
  {
 
6997
    // Do nothing
 
6998
  }
 
6999
 
 
7000
  /// Return the dimension of the global finite element function space
 
7001
  virtual unsigned int global_dimension() const
 
7002
  {
 
7003
    return __global_dimension;
 
7004
  }
 
7005
 
 
7006
  /// Return the dimension of the local finite element function space for a cell
 
7007
  virtual unsigned int local_dimension(const ufc::cell& c) const
 
7008
  {
 
7009
    return 1;
 
7010
  }
 
7011
 
 
7012
  /// Return the maximum dimension of the local finite element function space
 
7013
  virtual unsigned int max_local_dimension() const
 
7014
  {
 
7015
    return 1;
 
7016
  }
 
7017
 
 
7018
  // Return the geometric dimension of the coordinates this dof map provides
 
7019
  virtual unsigned int geometric_dimension() const
 
7020
  {
 
7021
    return 2;
 
7022
  }
 
7023
 
 
7024
  /// Return the number of dofs on each cell facet
 
7025
  virtual unsigned int num_facet_dofs() const
 
7026
  {
 
7027
    return 0;
 
7028
  }
 
7029
 
 
7030
  /// Return the number of dofs associated with each cell entity of dimension d
 
7031
  virtual unsigned int num_entity_dofs(unsigned int d) const
 
7032
  {
 
7033
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
7034
  }
 
7035
 
 
7036
  /// Tabulate the local-to-global mapping of dofs on a cell
 
7037
  virtual void tabulate_dofs(unsigned int* dofs,
 
7038
                             const ufc::mesh& m,
 
7039
                             const ufc::cell& c) const
 
7040
  {
 
7041
    dofs[0] = c.entity_indices[2][0];
 
7042
  }
 
7043
 
 
7044
  /// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
7045
  virtual void tabulate_facet_dofs(unsigned int* dofs,
 
7046
                                   unsigned int facet) const
 
7047
  {
 
7048
    switch ( facet )
 
7049
    {
 
7050
    case 0:
 
7051
      
 
7052
      break;
 
7053
    case 1:
 
7054
      
 
7055
      break;
 
7056
    case 2:
 
7057
      
 
7058
      break;
 
7059
    }
 
7060
  }
 
7061
 
 
7062
  /// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
7063
  virtual void tabulate_entity_dofs(unsigned int* dofs,
 
7064
                                    unsigned int d, unsigned int i) const
 
7065
  {
 
7066
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
7067
  }
 
7068
 
 
7069
  /// Tabulate the coordinates of all dofs on a cell
 
7070
  virtual void tabulate_coordinates(double** coordinates,
 
7071
                                    const ufc::cell& c) const
 
7072
  {
 
7073
    const double * const * x = c.coordinates;
 
7074
    coordinates[0][0] = 0.333333333*x[0][0] + 0.333333333*x[1][0] + 0.333333333*x[2][0];
 
7075
    coordinates[0][1] = 0.333333333*x[0][1] + 0.333333333*x[1][1] + 0.333333333*x[2][1];
 
7076
  }
 
7077
 
 
7078
  /// Return the number of sub dof maps (for a mixed element)
 
7079
  virtual unsigned int num_sub_dof_maps() const
 
7080
  {
 
7081
    return 1;
 
7082
  }
 
7083
 
 
7084
  /// Create a new dof_map for sub dof map i (for a mixed element)
 
7085
  virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
 
7086
  {
 
7087
    return new mixedpoisson_1_dof_map_1();
 
7088
  }
 
7089
 
 
7090
};
 
7091
 
 
7092
/// This class defines the interface for the tabulation of the cell
 
7093
/// tensor corresponding to the local contribution to a form from
 
7094
/// the integral over a cell.
 
7095
 
 
7096
class mixedpoisson_1_cell_integral_0_tensor: public ufc::cell_integral
 
7097
{
 
7098
public:
 
7099
 
 
7100
  /// Constructor
 
7101
  mixedpoisson_1_cell_integral_0_tensor() : ufc::cell_integral()
 
7102
  {
 
7103
    // Do nothing
 
7104
  }
 
7105
 
 
7106
  /// Destructor
 
7107
  virtual ~mixedpoisson_1_cell_integral_0_tensor()
 
7108
  {
 
7109
    // Do nothing
 
7110
  }
 
7111
 
 
7112
  /// Tabulate the tensor for the contribution from a local cell
 
7113
  virtual void tabulate_tensor(double* A,
 
7114
                               const double * const * w,
 
7115
                               const ufc::cell& c) const
 
7116
  {
 
7117
    // Number of operations to compute geometry tensor:     1
 
7118
    // Number of operations to compute tensor contraction:  1
 
7119
    // Total number of operations to compute cell tensor:   2
 
7120
    
 
7121
    // Extract vertex coordinates
 
7122
    const double * const * x = c.coordinates;
 
7123
    
 
7124
    // Compute Jacobian of affine map from reference cell
 
7125
    const double J_00 = x[1][0] - x[0][0];
 
7126
    const double J_01 = x[2][0] - x[0][0];
 
7127
    const double J_10 = x[1][1] - x[0][1];
 
7128
    const double J_11 = x[2][1] - x[0][1];
 
7129
    
 
7130
    // Compute determinant of Jacobian
 
7131
    double detJ = J_00*J_11 - J_01*J_10;
 
7132
    
 
7133
    // Compute inverse of Jacobian
 
7134
    
 
7135
    // Set scale factor
 
7136
    const double det = std::abs(detJ);
 
7137
    
 
7138
    // Compute geometry tensor
 
7139
    const double G0_0 = det*w[0][0];
 
7140
    
 
7141
    // Compute element tensor
 
7142
    A[0] += 0;
 
7143
    A[1] += 0;
 
7144
    A[2] += 0;
 
7145
    A[3] += 0;
 
7146
    A[4] += 0;
 
7147
    A[5] += 0;
 
7148
    A[6] += 0.5*G0_0;
 
7149
  }
 
7150
 
 
7151
};
 
7152
 
 
7153
/// This class defines the interface for the tabulation of the cell
 
7154
/// tensor corresponding to the local contribution to a form from
 
7155
/// the integral over a cell.
 
7156
 
 
7157
class mixedpoisson_1_cell_integral_0: public ufc::cell_integral
 
7158
{
 
7159
private:
 
7160
 
 
7161
  mixedpoisson_1_cell_integral_0_tensor integral_0_tensor;
 
7162
 
 
7163
public:
 
7164
 
 
7165
  /// Constructor
 
7166
  mixedpoisson_1_cell_integral_0() : ufc::cell_integral()
 
7167
  {
 
7168
    // Do nothing
 
7169
  }
 
7170
 
 
7171
  /// Destructor
 
7172
  virtual ~mixedpoisson_1_cell_integral_0()
 
7173
  {
 
7174
    // Do nothing
 
7175
  }
 
7176
 
 
7177
  /// Tabulate the tensor for the contribution from a local cell
 
7178
  virtual void tabulate_tensor(double* A,
 
7179
                               const double * const * w,
 
7180
                               const ufc::cell& c) const
 
7181
  {
 
7182
    // Reset values of the element tensor block
 
7183
    for (unsigned int j = 0; j < 7; j++)
 
7184
      A[j] = 0;
 
7185
    
 
7186
    // Add all contributions to element tensor
 
7187
    integral_0_tensor.tabulate_tensor(A, w, c);
 
7188
  }
 
7189
 
 
7190
};
 
7191
 
 
7192
/// This class defines the interface for the assembly of the global
 
7193
/// tensor corresponding to a form with r + n arguments, that is, a
 
7194
/// mapping
 
7195
///
 
7196
///     a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
 
7197
///
 
7198
/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
 
7199
/// global tensor A is defined by
 
7200
///
 
7201
///     A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
 
7202
///
 
7203
/// where each argument Vj represents the application to the
 
7204
/// sequence of basis functions of Vj and w1, w2, ..., wn are given
 
7205
/// fixed functions (coefficients).
 
7206
 
 
7207
class mixedpoisson_form_1: public ufc::form
 
7208
{
 
7209
public:
 
7210
 
 
7211
  /// Constructor
 
7212
  mixedpoisson_form_1() : ufc::form()
 
7213
  {
 
7214
    // Do nothing
 
7215
  }
 
7216
 
 
7217
  /// Destructor
 
7218
  virtual ~mixedpoisson_form_1()
 
7219
  {
 
7220
    // Do nothing
 
7221
  }
 
7222
 
 
7223
  /// Return a string identifying the form
 
7224
  virtual const char* signature() const
 
7225
  {
 
7226
    return "Form([Integral(Product(Function(FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0), 0), Indexed(BasisFunction(MixedElement(*[FiniteElement('Brezzi-Douglas-Marini', Cell('triangle', 1, Space(2)), 1), FiniteElement('Discontinuous Lagrange', Cell('triangle', 1, Space(2)), 0)], **{'value_shape': (3,) }), 0), MultiIndex((FixedIndex(2),), {FixedIndex(2): 3}))), Measure('cell', 0, None))])";
 
7227
  }
 
7228
 
 
7229
  /// Return the rank of the global tensor (r)
 
7230
  virtual unsigned int rank() const
 
7231
  {
 
7232
    return 1;
 
7233
  }
 
7234
 
 
7235
  /// Return the number of coefficients (n)
 
7236
  virtual unsigned int num_coefficients() const
 
7237
  {
 
7238
    return 1;
 
7239
  }
 
7240
 
 
7241
  /// Return the number of cell integrals
 
7242
  virtual unsigned int num_cell_integrals() const
 
7243
  {
 
7244
    return 1;
 
7245
  }
 
7246
 
 
7247
  /// Return the number of exterior facet integrals
 
7248
  virtual unsigned int num_exterior_facet_integrals() const
 
7249
  {
 
7250
    return 0;
 
7251
  }
 
7252
 
 
7253
  /// Return the number of interior facet integrals
 
7254
  virtual unsigned int num_interior_facet_integrals() const
 
7255
  {
 
7256
    return 0;
 
7257
  }
 
7258
 
 
7259
  /// Create a new finite element for argument function i
 
7260
  virtual ufc::finite_element* create_finite_element(unsigned int i) const
 
7261
  {
 
7262
    switch ( i )
 
7263
    {
 
7264
    case 0:
 
7265
      return new mixedpoisson_1_finite_element_0();
 
7266
      break;
 
7267
    case 1:
 
7268
      return new mixedpoisson_1_finite_element_1();
 
7269
      break;
 
7270
    }
 
7271
    return 0;
 
7272
  }
 
7273
 
 
7274
  /// Create a new dof map for argument function i
 
7275
  virtual ufc::dof_map* create_dof_map(unsigned int i) const
 
7276
  {
 
7277
    switch ( i )
 
7278
    {
 
7279
    case 0:
 
7280
      return new mixedpoisson_1_dof_map_0();
 
7281
      break;
 
7282
    case 1:
 
7283
      return new mixedpoisson_1_dof_map_1();
 
7284
      break;
 
7285
    }
 
7286
    return 0;
 
7287
  }
 
7288
 
 
7289
  /// Create a new cell integral on sub domain i
 
7290
  virtual ufc::cell_integral* create_cell_integral(unsigned int i) const
 
7291
  {
 
7292
    return new mixedpoisson_1_cell_integral_0();
 
7293
  }
 
7294
 
 
7295
  /// Create a new exterior facet integral on sub domain i
 
7296
  virtual ufc::exterior_facet_integral* create_exterior_facet_integral(unsigned int i) const
 
7297
  {
 
7298
    return 0;
 
7299
  }
 
7300
 
 
7301
  /// Create a new interior facet integral on sub domain i
 
7302
  virtual ufc::interior_facet_integral* create_interior_facet_integral(unsigned int i) const
 
7303
  {
 
7304
    return 0;
 
7305
  }
 
7306
 
 
7307
};
 
7308
 
 
7309
#endif