~ubuntu-branches/ubuntu/utopic/ffc/utopic

« back to all changes in this revision

Viewing changes to test/regression/references/r_auto/X_Element9.h

  • Committer: Package Import Robot
  • Author(s): Johannes Ring
  • Date: 2013-06-26 14:48:32 UTC
  • mfrom: (1.1.13)
  • Revision ID: package-import@ubuntu.com-20130626144832-1xd8htax4s3utybz
Tags: 1.2.0-1
* New upstream release.
* debian/control:
  - Bump required version for python-ufc, python-fiat, python-instant
    and python-ufl in Depends field.
  - Bump Standards-Version to 3.9.4.
  - Remove DM-Upload-Allowed field.
  - Bump required debhelper version in Build-Depends.
  - Remove cdbs from Build-Depends.
  - Use canonical URIs for Vcs-* fields.
* debian/compat: Bump to compatibility level 9.
* debian/rules: Rewrite for debhelper (drop cdbs).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// This code conforms with the UFC specification version 2.2.0
 
2
// and was automatically generated by FFC version 1.2.0.
 
3
// 
 
4
// This code was generated with the following parameters:
 
5
// 
 
6
//   cache_dir:                      ''
 
7
//   convert_exceptions_to_warnings: True
 
8
//   cpp_optimize:                   False
 
9
//   cpp_optimize_flags:             '-O2'
 
10
//   epsilon:                        1e-14
 
11
//   error_control:                  False
 
12
//   form_postfix:                   True
 
13
//   format:                         'ufc'
 
14
//   log_level:                      20
 
15
//   log_prefix:                     ''
 
16
//   optimize:                       False
 
17
//   output_dir:                     '.'
 
18
//   precision:                      '8'
 
19
//   quadrature_degree:              'auto'
 
20
//   quadrature_rule:                'auto'
 
21
//   representation:                 'auto'
 
22
//   split:                          False
 
23
//   swig_binary:                    'swig'
 
24
//   swig_path:                      ''
 
25
 
 
26
#ifndef __X_ELEMENT9_H
 
27
#define __X_ELEMENT9_H
 
28
 
 
29
#include <cmath>
 
30
#include <stdexcept>
 
31
#include <fstream>
 
32
#include <ufc.h>
 
33
 
 
34
/// This class defines the interface for a finite element.
 
35
 
 
36
class x_element9_finite_element_0: public ufc::finite_element
 
37
{
 
38
public:
 
39
 
 
40
  /// Constructor
 
41
  x_element9_finite_element_0() : ufc::finite_element()
 
42
  {
 
43
    // Do nothing
 
44
  }
 
45
 
 
46
  /// Destructor
 
47
  virtual ~x_element9_finite_element_0()
 
48
  {
 
49
    // Do nothing
 
50
  }
 
51
 
 
52
  /// Return a string identifying the finite element
 
53
  virtual const char* signature() const
 
54
  {
 
55
    return "FiniteElement('Raviart-Thomas', Domain(Cell('triangle', 3), 'triangle_multiverse', 3, 2), 2, None)";
 
56
  }
 
57
 
 
58
  /// Return the cell shape
 
59
  virtual ufc::shape cell_shape() const
 
60
  {
 
61
    return ufc::triangle;
 
62
  }
 
63
 
 
64
  /// Return the topological dimension of the cell shape
 
65
  virtual std::size_t topological_dimension() const
 
66
  {
 
67
    return 2;
 
68
  }
 
69
 
 
70
  /// Return the geometric dimension of the cell shape
 
71
  virtual std::size_t geometric_dimension() const
 
72
  {
 
73
    return 3;
 
74
  }
 
75
 
 
76
  /// Return the dimension of the finite element function space
 
77
  virtual std::size_t space_dimension() const
 
78
  {
 
79
    return 8;
 
80
  }
 
81
 
 
82
  /// Return the rank of the value space
 
83
  virtual std::size_t value_rank() const
 
84
  {
 
85
    return 1;
 
86
  }
 
87
 
 
88
  /// Return the dimension of the value space for axis i
 
89
  virtual std::size_t value_dimension(std::size_t i) const
 
90
  {
 
91
    switch (i)
 
92
    {
 
93
    case 0:
 
94
      {
 
95
        return 3;
 
96
        break;
 
97
      }
 
98
    }
 
99
    
 
100
    return 0;
 
101
  }
 
102
 
 
103
  /// Evaluate basis function i at given point x in cell
 
104
  virtual void evaluate_basis(std::size_t i,
 
105
                              double* values,
 
106
                              const double* x,
 
107
                              const double* vertex_coordinates,
 
108
                              int cell_orientation) const
 
109
  {
 
110
    // Compute Jacobian
 
111
    double J[6];
 
112
    compute_jacobian_triangle_3d(J, vertex_coordinates);
 
113
    
 
114
    // Compute Jacobian inverse and determinant
 
115
    double K[6];
 
116
    double detJ;
 
117
    compute_jacobian_inverse_triangle_3d(K, detJ, J);
 
118
    
 
119
    
 
120
    // Check orientation
 
121
    if (cell_orientation == -1)
 
122
      throw std::runtime_error("cell orientation must be defined (not -1)");
 
123
    // (If cell_orientation == 1 = down, multiply det(J) by -1)
 
124
    else if (cell_orientation == 1)
 
125
      detJ *= -1;
 
126
    
 
127
    
 
128
    const double b0 = vertex_coordinates[0];
 
129
    const double b1 = vertex_coordinates[1];
 
130
    const double b2 = vertex_coordinates[2];
 
131
    
 
132
    // P_FFC = J^dag (p - b), P_FIAT = 2*P_FFC - (1, 1)
 
133
    double X = 2*(K[0]*(x[0] - b0) + K[1]*(x[1] - b1) + K[2]*(x[2] - b2)) - 1.0;
 
134
    double Y = 2*(K[3]*(x[0] - b0) + K[4]*(x[1] - b1) + K[5]*(x[2] - b2)) - 1.0;
 
135
    
 
136
    
 
137
    // Reset values
 
138
    values[0] = 0.0;
 
139
    values[1] = 0.0;
 
140
    switch (i)
 
141
    {
 
142
    case 0:
 
143
      {
 
144
        
 
145
      // Array of basisvalues
 
146
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
147
      
 
148
      // Declare helper variables
 
149
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
150
      double tmp1 = (1.0 - Y)/2.0;
 
151
      double tmp2 = tmp1*tmp1;
 
152
      
 
153
      // Compute basisvalues
 
154
      basisvalues[0] = 1.0;
 
155
      basisvalues[1] = tmp0;
 
156
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
157
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
158
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
159
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
160
      basisvalues[0] *= std::sqrt(0.5);
 
161
      basisvalues[2] *= std::sqrt(1.0);
 
162
      basisvalues[5] *= std::sqrt(1.5);
 
163
      basisvalues[1] *= std::sqrt(3.0);
 
164
      basisvalues[4] *= std::sqrt(4.5);
 
165
      basisvalues[3] *= std::sqrt(7.5);
 
166
      
 
167
      // Table(s) of coefficients
 
168
      static const double coefficients0[6] = \
 
169
      {0.23570226, 0.40414519, -0.23333333, 0.18257419, -0.14142136, 0.081649658};
 
170
      
 
171
      static const double coefficients1[6] = \
 
172
      {-0.11785113, 0.17320508, -0.23333333, 0.0, 0.14142136, -0.12247449};
 
173
      
 
174
      // Compute value(s)
 
175
      for (unsigned int r = 0; r < 6; r++)
 
176
      {
 
177
        values[0] += coefficients0[r]*basisvalues[r];
 
178
        values[1] += coefficients1[r]*basisvalues[r];
 
179
      }// end loop over 'r'
 
180
      
 
181
      // Using contravariant Piola transform to map values back to the physical element
 
182
      const double tmp_ref0 = values[0];
 
183
      const double tmp_ref1 = values[1];
 
184
      values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
185
      values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
186
      values[2] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
187
        break;
 
188
      }
 
189
    case 1:
 
190
      {
 
191
        
 
192
      // Array of basisvalues
 
193
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
194
      
 
195
      // Declare helper variables
 
196
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
197
      double tmp1 = (1.0 - Y)/2.0;
 
198
      double tmp2 = tmp1*tmp1;
 
199
      
 
200
      // Compute basisvalues
 
201
      basisvalues[0] = 1.0;
 
202
      basisvalues[1] = tmp0;
 
203
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
204
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
205
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
206
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
207
      basisvalues[0] *= std::sqrt(0.5);
 
208
      basisvalues[2] *= std::sqrt(1.0);
 
209
      basisvalues[5] *= std::sqrt(1.5);
 
210
      basisvalues[1] *= std::sqrt(3.0);
 
211
      basisvalues[4] *= std::sqrt(4.5);
 
212
      basisvalues[3] *= std::sqrt(7.5);
 
213
      
 
214
      // Table(s) of coefficients
 
215
      static const double coefficients0[6] = \
 
216
      {-0.11785113, -0.11547005, 0.26666667, 0.0, 0.14142136, -0.12247449};
 
217
      
 
218
      static const double coefficients1[6] = \
 
219
      {0.23570226, 0.0, 0.46666667, 0.0, 0.0, 0.24494897};
 
220
      
 
221
      // Compute value(s)
 
222
      for (unsigned int r = 0; r < 6; r++)
 
223
      {
 
224
        values[0] += coefficients0[r]*basisvalues[r];
 
225
        values[1] += coefficients1[r]*basisvalues[r];
 
226
      }// end loop over 'r'
 
227
      
 
228
      // Using contravariant Piola transform to map values back to the physical element
 
229
      const double tmp_ref0 = values[0];
 
230
      const double tmp_ref1 = values[1];
 
231
      values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
232
      values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
233
      values[2] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
234
        break;
 
235
      }
 
236
    case 2:
 
237
      {
 
238
        
 
239
      // Array of basisvalues
 
240
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
241
      
 
242
      // Declare helper variables
 
243
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
244
      double tmp1 = (1.0 - Y)/2.0;
 
245
      double tmp2 = tmp1*tmp1;
 
246
      
 
247
      // Compute basisvalues
 
248
      basisvalues[0] = 1.0;
 
249
      basisvalues[1] = tmp0;
 
250
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
251
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
252
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
253
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
254
      basisvalues[0] *= std::sqrt(0.5);
 
255
      basisvalues[2] *= std::sqrt(1.0);
 
256
      basisvalues[5] *= std::sqrt(1.5);
 
257
      basisvalues[1] *= std::sqrt(3.0);
 
258
      basisvalues[4] *= std::sqrt(4.5);
 
259
      basisvalues[3] *= std::sqrt(7.5);
 
260
      
 
261
      // Table(s) of coefficients
 
262
      static const double coefficients0[6] = \
 
263
      {0.11785113, -0.57735027, -0.46666667, 0.18257419, 0.0, -0.040824829};
 
264
      
 
265
      static const double coefficients1[6] = \
 
266
      {0.11785113, 0.17320508, 0.23333333, 0.0, 0.14142136, 0.12247449};
 
267
      
 
268
      // Compute value(s)
 
269
      for (unsigned int r = 0; r < 6; r++)
 
270
      {
 
271
        values[0] += coefficients0[r]*basisvalues[r];
 
272
        values[1] += coefficients1[r]*basisvalues[r];
 
273
      }// end loop over 'r'
 
274
      
 
275
      // Using contravariant Piola transform to map values back to the physical element
 
276
      const double tmp_ref0 = values[0];
 
277
      const double tmp_ref1 = values[1];
 
278
      values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
279
      values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
280
      values[2] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
281
        break;
 
282
      }
 
283
    case 3:
 
284
      {
 
285
        
 
286
      // Array of basisvalues
 
287
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
288
      
 
289
      // Declare helper variables
 
290
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
291
      double tmp1 = (1.0 - Y)/2.0;
 
292
      double tmp2 = tmp1*tmp1;
 
293
      
 
294
      // Compute basisvalues
 
295
      basisvalues[0] = 1.0;
 
296
      basisvalues[1] = tmp0;
 
297
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
298
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
299
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
300
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
301
      basisvalues[0] *= std::sqrt(0.5);
 
302
      basisvalues[2] *= std::sqrt(1.0);
 
303
      basisvalues[5] *= std::sqrt(1.5);
 
304
      basisvalues[1] *= std::sqrt(3.0);
 
305
      basisvalues[4] *= std::sqrt(4.5);
 
306
      basisvalues[3] *= std::sqrt(7.5);
 
307
      
 
308
      // Table(s) of coefficients
 
309
      static const double coefficients0[6] = \
 
310
      {0.11785113, 0.11547005, 0.73333333, 0.0, -0.14142136, 0.12247449};
 
311
      
 
312
      static const double coefficients1[6] = \
 
313
      {-0.23570226, 0.0, -0.46666667, 0.0, 0.0, -0.24494897};
 
314
      
 
315
      // Compute value(s)
 
316
      for (unsigned int r = 0; r < 6; r++)
 
317
      {
 
318
        values[0] += coefficients0[r]*basisvalues[r];
 
319
        values[1] += coefficients1[r]*basisvalues[r];
 
320
      }// end loop over 'r'
 
321
      
 
322
      // Using contravariant Piola transform to map values back to the physical element
 
323
      const double tmp_ref0 = values[0];
 
324
      const double tmp_ref1 = values[1];
 
325
      values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
326
      values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
327
      values[2] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
328
        break;
 
329
      }
 
330
    case 4:
 
331
      {
 
332
        
 
333
      // Array of basisvalues
 
334
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
335
      
 
336
      // Declare helper variables
 
337
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
338
      double tmp1 = (1.0 - Y)/2.0;
 
339
      double tmp2 = tmp1*tmp1;
 
340
      
 
341
      // Compute basisvalues
 
342
      basisvalues[0] = 1.0;
 
343
      basisvalues[1] = tmp0;
 
344
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
345
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
346
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
347
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
348
      basisvalues[0] *= std::sqrt(0.5);
 
349
      basisvalues[2] *= std::sqrt(1.0);
 
350
      basisvalues[5] *= std::sqrt(1.5);
 
351
      basisvalues[1] *= std::sqrt(3.0);
 
352
      basisvalues[4] *= std::sqrt(4.5);
 
353
      basisvalues[3] *= std::sqrt(7.5);
 
354
      
 
355
      // Table(s) of coefficients
 
356
      static const double coefficients0[6] = \
 
357
      {-0.11785113, -0.28867513, -0.033333333, -0.18257419, 0.0, 0.040824829};
 
358
      
 
359
      static const double coefficients1[6] = \
 
360
      {-0.11785113, 0.69282032, 0.26666667, 0.0, -0.14142136, -0.12247449};
 
361
      
 
362
      // Compute value(s)
 
363
      for (unsigned int r = 0; r < 6; r++)
 
364
      {
 
365
        values[0] += coefficients0[r]*basisvalues[r];
 
366
        values[1] += coefficients1[r]*basisvalues[r];
 
367
      }// end loop over 'r'
 
368
      
 
369
      // Using contravariant Piola transform to map values back to the physical element
 
370
      const double tmp_ref0 = values[0];
 
371
      const double tmp_ref1 = values[1];
 
372
      values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
373
      values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
374
      values[2] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
375
        break;
 
376
      }
 
377
    case 5:
 
378
      {
 
379
        
 
380
      // Array of basisvalues
 
381
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
382
      
 
383
      // Declare helper variables
 
384
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
385
      double tmp1 = (1.0 - Y)/2.0;
 
386
      double tmp2 = tmp1*tmp1;
 
387
      
 
388
      // Compute basisvalues
 
389
      basisvalues[0] = 1.0;
 
390
      basisvalues[1] = tmp0;
 
391
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
392
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
393
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
394
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
395
      basisvalues[0] *= std::sqrt(0.5);
 
396
      basisvalues[2] *= std::sqrt(1.0);
 
397
      basisvalues[5] *= std::sqrt(1.5);
 
398
      basisvalues[1] *= std::sqrt(3.0);
 
399
      basisvalues[4] *= std::sqrt(4.5);
 
400
      basisvalues[3] *= std::sqrt(7.5);
 
401
      
 
402
      // Table(s) of coefficients
 
403
      static const double coefficients0[6] = \
 
404
      {0.23570226, 0.40414519, -0.23333333, 0.18257419, -0.14142136, 0.081649658};
 
405
      
 
406
      static const double coefficients1[6] = \
 
407
      {-0.11785113, -0.69282032, 0.26666667, 0.0, 0.14142136, -0.12247449};
 
408
      
 
409
      // Compute value(s)
 
410
      for (unsigned int r = 0; r < 6; r++)
 
411
      {
 
412
        values[0] += coefficients0[r]*basisvalues[r];
 
413
        values[1] += coefficients1[r]*basisvalues[r];
 
414
      }// end loop over 'r'
 
415
      
 
416
      // Using contravariant Piola transform to map values back to the physical element
 
417
      const double tmp_ref0 = values[0];
 
418
      const double tmp_ref1 = values[1];
 
419
      values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
420
      values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
421
      values[2] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
422
        break;
 
423
      }
 
424
    case 6:
 
425
      {
 
426
        
 
427
      // Array of basisvalues
 
428
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
429
      
 
430
      // Declare helper variables
 
431
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
432
      double tmp1 = (1.0 - Y)/2.0;
 
433
      double tmp2 = tmp1*tmp1;
 
434
      
 
435
      // Compute basisvalues
 
436
      basisvalues[0] = 1.0;
 
437
      basisvalues[1] = tmp0;
 
438
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
439
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
440
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
441
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
442
      basisvalues[0] *= std::sqrt(0.5);
 
443
      basisvalues[2] *= std::sqrt(1.0);
 
444
      basisvalues[5] *= std::sqrt(1.5);
 
445
      basisvalues[1] *= std::sqrt(3.0);
 
446
      basisvalues[4] *= std::sqrt(4.5);
 
447
      basisvalues[3] *= std::sqrt(7.5);
 
448
      
 
449
      // Table(s) of coefficients
 
450
      static const double coefficients0[6] = \
 
451
      {1.0606602, 0.17320508, -0.3, -0.36514837, 0.14142136, -0.040824829};
 
452
      
 
453
      static const double coefficients1[6] = \
 
454
      {0.0, -0.34641016, 0.0, 0.0, -0.28284271, 0.0};
 
455
      
 
456
      // Compute value(s)
 
457
      for (unsigned int r = 0; r < 6; r++)
 
458
      {
 
459
        values[0] += coefficients0[r]*basisvalues[r];
 
460
        values[1] += coefficients1[r]*basisvalues[r];
 
461
      }// end loop over 'r'
 
462
      
 
463
      // Using contravariant Piola transform to map values back to the physical element
 
464
      const double tmp_ref0 = values[0];
 
465
      const double tmp_ref1 = values[1];
 
466
      values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
467
      values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
468
      values[2] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
469
        break;
 
470
      }
 
471
    case 7:
 
472
      {
 
473
        
 
474
      // Array of basisvalues
 
475
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
476
      
 
477
      // Declare helper variables
 
478
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
479
      double tmp1 = (1.0 - Y)/2.0;
 
480
      double tmp2 = tmp1*tmp1;
 
481
      
 
482
      // Compute basisvalues
 
483
      basisvalues[0] = 1.0;
 
484
      basisvalues[1] = tmp0;
 
485
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
486
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
487
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
488
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
489
      basisvalues[0] *= std::sqrt(0.5);
 
490
      basisvalues[2] *= std::sqrt(1.0);
 
491
      basisvalues[5] *= std::sqrt(1.5);
 
492
      basisvalues[1] *= std::sqrt(3.0);
 
493
      basisvalues[4] *= std::sqrt(4.5);
 
494
      basisvalues[3] *= std::sqrt(7.5);
 
495
      
 
496
      // Table(s) of coefficients
 
497
      static const double coefficients0[6] = \
 
498
      {0.0, -0.17320508, -0.3, -0.18257419, -0.14142136, 0.16329932};
 
499
      
 
500
      static const double coefficients1[6] = \
 
501
      {1.0606602, -0.17320508, 0.3, 0.0, -0.14142136, -0.36742346};
 
502
      
 
503
      // Compute value(s)
 
504
      for (unsigned int r = 0; r < 6; r++)
 
505
      {
 
506
        values[0] += coefficients0[r]*basisvalues[r];
 
507
        values[1] += coefficients1[r]*basisvalues[r];
 
508
      }// end loop over 'r'
 
509
      
 
510
      // Using contravariant Piola transform to map values back to the physical element
 
511
      const double tmp_ref0 = values[0];
 
512
      const double tmp_ref1 = values[1];
 
513
      values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
514
      values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
515
      values[2] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
516
        break;
 
517
      }
 
518
    }
 
519
    
 
520
  }
 
521
 
 
522
  /// Evaluate all basis functions at given point x in cell
 
523
  virtual void evaluate_basis_all(double* values,
 
524
                                  const double* x,
 
525
                                  const double* vertex_coordinates,
 
526
                                  int cell_orientation) const
 
527
  {
 
528
    // Helper variable to hold values of a single dof.
 
529
    double dof_values[3] = {0.0, 0.0, 0.0};
 
530
    
 
531
    // Loop dofs and call evaluate_basis
 
532
    for (unsigned int r = 0; r < 8; r++)
 
533
    {
 
534
      evaluate_basis(r, dof_values, x, vertex_coordinates, cell_orientation);
 
535
      for (unsigned int s = 0; s < 3; s++)
 
536
      {
 
537
        values[r*3 + s] = dof_values[s];
 
538
      }// end loop over 's'
 
539
    }// end loop over 'r'
 
540
  }
 
541
 
 
542
  /// Evaluate order n derivatives of basis function i at given point x in cell
 
543
  virtual void evaluate_basis_derivatives(std::size_t i,
 
544
                                          std::size_t n,
 
545
                                          double* values,
 
546
                                          const double* x,
 
547
                                          const double* vertex_coordinates,
 
548
                                          int cell_orientation) const
 
549
  {
 
550
    // Compute Jacobian
 
551
    double J[6];
 
552
    compute_jacobian_triangle_3d(J, vertex_coordinates);
 
553
    
 
554
    // Compute Jacobian inverse and determinant
 
555
    double K[6];
 
556
    double detJ;
 
557
    compute_jacobian_inverse_triangle_3d(K, detJ, J);
 
558
    
 
559
    
 
560
    // Check orientation
 
561
    if (cell_orientation == -1)
 
562
      throw std::runtime_error("cell orientation must be defined (not -1)");
 
563
    // (If cell_orientation == 1 = down, multiply det(J) by -1)
 
564
    else if (cell_orientation == 1)
 
565
      detJ *= -1;
 
566
    
 
567
    
 
568
    const double b0 = vertex_coordinates[0];
 
569
    const double b1 = vertex_coordinates[1];
 
570
    const double b2 = vertex_coordinates[2];
 
571
    
 
572
    // P_FFC = J^dag (p - b), P_FIAT = 2*P_FFC - (1, 1)
 
573
    double X = 2*(K[0]*(x[0] - b0) + K[1]*(x[1] - b1) + K[2]*(x[2] - b2)) - 1.0;
 
574
    double Y = 2*(K[3]*(x[0] - b0) + K[4]*(x[1] - b1) + K[5]*(x[2] - b2)) - 1.0;
 
575
    
 
576
    
 
577
    // Compute number of derivatives.
 
578
    unsigned int num_derivatives_t = 1;
 
579
    for (unsigned int r = 0; r < n; r++)
 
580
    {
 
581
      num_derivatives_t *= 2;
 
582
    }// end loop over 'r'
 
583
    
 
584
    // Compute number of derivatives.
 
585
    unsigned int num_derivatives_g = 1;
 
586
    for (unsigned int r = 0; r < n; r++)
 
587
    {
 
588
      num_derivatives_g *= 3;
 
589
    }// end loop over 'r'
 
590
    
 
591
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
592
    unsigned int **combinations_t = new unsigned int *[num_derivatives_t];
 
593
    for (unsigned int row = 0; row < num_derivatives_t; row++)
 
594
    {
 
595
      combinations_t[row] = new unsigned int [n];
 
596
      for (unsigned int col = 0; col < n; col++)
 
597
        combinations_t[row][col] = 0;
 
598
    }
 
599
    
 
600
    // Generate combinations of derivatives
 
601
    for (unsigned int row = 1; row < num_derivatives_t; row++)
 
602
    {
 
603
      for (unsigned int num = 0; num < row; num++)
 
604
      {
 
605
        for (unsigned int col = n-1; col+1 > 0; col--)
 
606
        {
 
607
          if (combinations_t[row][col] + 1 > 1)
 
608
            combinations_t[row][col] = 0;
 
609
          else
 
610
          {
 
611
            combinations_t[row][col] += 1;
 
612
            break;
 
613
          }
 
614
        }
 
615
      }
 
616
    }
 
617
    
 
618
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
619
    unsigned int **combinations_g = new unsigned int *[num_derivatives_g];
 
620
    for (unsigned int row = 0; row < num_derivatives_g; row++)
 
621
    {
 
622
      combinations_g[row] = new unsigned int [n];
 
623
      for (unsigned int col = 0; col < n; col++)
 
624
        combinations_g[row][col] = 0;
 
625
    }
 
626
    
 
627
    // Generate combinations of derivatives
 
628
    for (unsigned int row = 1; row < num_derivatives_g; row++)
 
629
    {
 
630
      for (unsigned int num = 0; num < row; num++)
 
631
      {
 
632
        for (unsigned int col = n-1; col+1 > 0; col--)
 
633
        {
 
634
          if (combinations_g[row][col] + 1 > 2)
 
635
            combinations_g[row][col] = 0;
 
636
          else
 
637
          {
 
638
            combinations_g[row][col] += 1;
 
639
            break;
 
640
          }
 
641
        }
 
642
      }
 
643
    }
 
644
    
 
645
    // Compute inverse of Jacobian
 
646
    const double Jinv[2][3] = {{K[0], K[1], K[2]}, {K[3], K[4], K[5]}};
 
647
    
 
648
    // Declare transformation matrix
 
649
    // Declare pointer to two dimensional array and initialise
 
650
    double **transform = new double *[num_derivatives_g];
 
651
    
 
652
    for (unsigned int j = 0; j < num_derivatives_g; j++)
 
653
    {
 
654
      transform[j] = new double [num_derivatives_t];
 
655
      for (unsigned int k = 0; k < num_derivatives_t; k++)
 
656
        transform[j][k] = 1;
 
657
    }
 
658
    
 
659
    // Construct transformation matrix
 
660
    for (unsigned int row = 0; row < num_derivatives_g; row++)
 
661
    {
 
662
      for (unsigned int col = 0; col < num_derivatives_t; col++)
 
663
      {
 
664
        for (unsigned int k = 0; k < n; k++)
 
665
          transform[row][col] *= Jinv[combinations_t[col][k]][combinations_g[row][k]];
 
666
      }
 
667
    }
 
668
    
 
669
    // Reset values. Assuming that values is always an array.
 
670
    for (unsigned int r = 0; r < 3*num_derivatives_g; r++)
 
671
    {
 
672
      values[r] = 0.0;
 
673
    }// end loop over 'r'
 
674
    
 
675
    switch (i)
 
676
    {
 
677
    case 0:
 
678
      {
 
679
        
 
680
      // Array of basisvalues
 
681
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
682
      
 
683
      // Declare helper variables
 
684
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
685
      double tmp1 = (1.0 - Y)/2.0;
 
686
      double tmp2 = tmp1*tmp1;
 
687
      
 
688
      // Compute basisvalues
 
689
      basisvalues[0] = 1.0;
 
690
      basisvalues[1] = tmp0;
 
691
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
692
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
693
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
694
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
695
      basisvalues[0] *= std::sqrt(0.5);
 
696
      basisvalues[2] *= std::sqrt(1.0);
 
697
      basisvalues[5] *= std::sqrt(1.5);
 
698
      basisvalues[1] *= std::sqrt(3.0);
 
699
      basisvalues[4] *= std::sqrt(4.5);
 
700
      basisvalues[3] *= std::sqrt(7.5);
 
701
      
 
702
      // Table(s) of coefficients
 
703
      static const double coefficients0[6] = \
 
704
      {0.23570226, 0.40414519, -0.23333333, 0.18257419, -0.14142136, 0.081649658};
 
705
      
 
706
      static const double coefficients1[6] = \
 
707
      {-0.11785113, 0.17320508, -0.23333333, 0.0, 0.14142136, -0.12247449};
 
708
      
 
709
      // Tables of derivatives of the polynomial base (transpose).
 
710
      static const double dmats0[6][6] = \
 
711
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
712
      {4.8989795, 0.0, 0.0, 0.0, 0.0, 0.0},
 
713
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
714
      {0.0, 9.486833, 0.0, 0.0, 0.0, 0.0},
 
715
      {4.0, 0.0, 7.0710678, 0.0, 0.0, 0.0},
 
716
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}};
 
717
      
 
718
      static const double dmats1[6][6] = \
 
719
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
720
      {2.4494897, 0.0, 0.0, 0.0, 0.0, 0.0},
 
721
      {4.2426407, 0.0, 0.0, 0.0, 0.0, 0.0},
 
722
      {2.5819889, 4.7434165, -0.91287093, 0.0, 0.0, 0.0},
 
723
      {2.0, 6.1237244, 3.5355339, 0.0, 0.0, 0.0},
 
724
      {-2.3094011, 0.0, 8.1649658, 0.0, 0.0, 0.0}};
 
725
      
 
726
      // Compute reference derivatives.
 
727
      // Declare pointer to array of derivatives on FIAT element.
 
728
      double *derivatives = new double[2*num_derivatives_t];
 
729
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
730
      {
 
731
        derivatives[r] = 0.0;
 
732
      }// end loop over 'r'
 
733
      
 
734
      // Declare pointer to array of reference derivatives on physical element.
 
735
      double *derivatives_p = new double[3*num_derivatives_t];
 
736
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
737
      {
 
738
        derivatives_p[r] = 0.0;
 
739
      }// end loop over 'r'
 
740
      
 
741
      // Declare derivative matrix (of polynomial basis).
 
742
      double dmats[6][6] = \
 
743
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
744
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
745
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
746
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
747
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
748
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
749
      
 
750
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
751
      double dmats_old[6][6] = \
 
752
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
753
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
754
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
755
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
756
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
757
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
758
      
 
759
      // Loop possible derivatives.
 
760
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
761
      {
 
762
        // Resetting dmats values to compute next derivative.
 
763
        for (unsigned int t = 0; t < 6; t++)
 
764
        {
 
765
          for (unsigned int u = 0; u < 6; u++)
 
766
          {
 
767
            dmats[t][u] = 0.0;
 
768
            if (t == u)
 
769
            {
 
770
            dmats[t][u] = 1.0;
 
771
            }
 
772
            
 
773
          }// end loop over 'u'
 
774
        }// end loop over 't'
 
775
        
 
776
        // Looping derivative order to generate dmats.
 
777
        for (unsigned int s = 0; s < n; s++)
 
778
        {
 
779
          // Updating dmats_old with new values and resetting dmats.
 
780
          for (unsigned int t = 0; t < 6; t++)
 
781
          {
 
782
            for (unsigned int u = 0; u < 6; u++)
 
783
            {
 
784
              dmats_old[t][u] = dmats[t][u];
 
785
              dmats[t][u] = 0.0;
 
786
            }// end loop over 'u'
 
787
          }// end loop over 't'
 
788
          
 
789
          // Update dmats using an inner product.
 
790
          if (combinations_t[r][s] == 0)
 
791
          {
 
792
          for (unsigned int t = 0; t < 6; t++)
 
793
          {
 
794
            for (unsigned int u = 0; u < 6; u++)
 
795
            {
 
796
              for (unsigned int tu = 0; tu < 6; tu++)
 
797
              {
 
798
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
799
              }// end loop over 'tu'
 
800
            }// end loop over 'u'
 
801
          }// end loop over 't'
 
802
          }
 
803
          
 
804
          if (combinations_t[r][s] == 1)
 
805
          {
 
806
          for (unsigned int t = 0; t < 6; t++)
 
807
          {
 
808
            for (unsigned int u = 0; u < 6; u++)
 
809
            {
 
810
              for (unsigned int tu = 0; tu < 6; tu++)
 
811
              {
 
812
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
813
              }// end loop over 'tu'
 
814
            }// end loop over 'u'
 
815
          }// end loop over 't'
 
816
          }
 
817
          
 
818
        }// end loop over 's'
 
819
        for (unsigned int s = 0; s < 6; s++)
 
820
        {
 
821
          for (unsigned int t = 0; t < 6; t++)
 
822
          {
 
823
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
824
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
825
          }// end loop over 't'
 
826
        }// end loop over 's'
 
827
        
 
828
        // Using contravariant Piola transform to map values back to the physical element.
 
829
        const double tmp_ref0 = derivatives[r];
 
830
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
831
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
832
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
833
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
834
      }// end loop over 'r'
 
835
      
 
836
      // Transform derivatives back to physical element
 
837
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
838
      {
 
839
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
840
        {
 
841
          values[r] += transform[r][s]*derivatives_p[s];
 
842
          values[num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
843
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
844
        }// end loop over 's'
 
845
      }// end loop over 'r'
 
846
      
 
847
      // Delete pointer to array of derivatives on FIAT element
 
848
      delete [] derivatives;
 
849
      
 
850
      // Delete pointer to array of reference derivatives on physical element.
 
851
      delete [] derivatives_p;
 
852
      
 
853
      // Delete pointer to array of combinations of derivatives and transform
 
854
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
855
      {
 
856
        delete [] combinations_t[r];
 
857
      }// end loop over 'r'
 
858
      delete [] combinations_t;
 
859
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
860
      {
 
861
        delete [] combinations_g[r];
 
862
      }// end loop over 'r'
 
863
      delete [] combinations_g;
 
864
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
865
      {
 
866
        delete [] transform[r];
 
867
      }// end loop over 'r'
 
868
      delete [] transform;
 
869
        break;
 
870
      }
 
871
    case 1:
 
872
      {
 
873
        
 
874
      // Array of basisvalues
 
875
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
876
      
 
877
      // Declare helper variables
 
878
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
879
      double tmp1 = (1.0 - Y)/2.0;
 
880
      double tmp2 = tmp1*tmp1;
 
881
      
 
882
      // Compute basisvalues
 
883
      basisvalues[0] = 1.0;
 
884
      basisvalues[1] = tmp0;
 
885
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
886
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
887
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
888
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
889
      basisvalues[0] *= std::sqrt(0.5);
 
890
      basisvalues[2] *= std::sqrt(1.0);
 
891
      basisvalues[5] *= std::sqrt(1.5);
 
892
      basisvalues[1] *= std::sqrt(3.0);
 
893
      basisvalues[4] *= std::sqrt(4.5);
 
894
      basisvalues[3] *= std::sqrt(7.5);
 
895
      
 
896
      // Table(s) of coefficients
 
897
      static const double coefficients0[6] = \
 
898
      {-0.11785113, -0.11547005, 0.26666667, 0.0, 0.14142136, -0.12247449};
 
899
      
 
900
      static const double coefficients1[6] = \
 
901
      {0.23570226, 0.0, 0.46666667, 0.0, 0.0, 0.24494897};
 
902
      
 
903
      // Tables of derivatives of the polynomial base (transpose).
 
904
      static const double dmats0[6][6] = \
 
905
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
906
      {4.8989795, 0.0, 0.0, 0.0, 0.0, 0.0},
 
907
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
908
      {0.0, 9.486833, 0.0, 0.0, 0.0, 0.0},
 
909
      {4.0, 0.0, 7.0710678, 0.0, 0.0, 0.0},
 
910
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}};
 
911
      
 
912
      static const double dmats1[6][6] = \
 
913
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
914
      {2.4494897, 0.0, 0.0, 0.0, 0.0, 0.0},
 
915
      {4.2426407, 0.0, 0.0, 0.0, 0.0, 0.0},
 
916
      {2.5819889, 4.7434165, -0.91287093, 0.0, 0.0, 0.0},
 
917
      {2.0, 6.1237244, 3.5355339, 0.0, 0.0, 0.0},
 
918
      {-2.3094011, 0.0, 8.1649658, 0.0, 0.0, 0.0}};
 
919
      
 
920
      // Compute reference derivatives.
 
921
      // Declare pointer to array of derivatives on FIAT element.
 
922
      double *derivatives = new double[2*num_derivatives_t];
 
923
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
924
      {
 
925
        derivatives[r] = 0.0;
 
926
      }// end loop over 'r'
 
927
      
 
928
      // Declare pointer to array of reference derivatives on physical element.
 
929
      double *derivatives_p = new double[3*num_derivatives_t];
 
930
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
931
      {
 
932
        derivatives_p[r] = 0.0;
 
933
      }// end loop over 'r'
 
934
      
 
935
      // Declare derivative matrix (of polynomial basis).
 
936
      double dmats[6][6] = \
 
937
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
938
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
939
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
940
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
941
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
942
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
943
      
 
944
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
945
      double dmats_old[6][6] = \
 
946
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
947
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
948
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
949
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
950
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
951
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
952
      
 
953
      // Loop possible derivatives.
 
954
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
955
      {
 
956
        // Resetting dmats values to compute next derivative.
 
957
        for (unsigned int t = 0; t < 6; t++)
 
958
        {
 
959
          for (unsigned int u = 0; u < 6; u++)
 
960
          {
 
961
            dmats[t][u] = 0.0;
 
962
            if (t == u)
 
963
            {
 
964
            dmats[t][u] = 1.0;
 
965
            }
 
966
            
 
967
          }// end loop over 'u'
 
968
        }// end loop over 't'
 
969
        
 
970
        // Looping derivative order to generate dmats.
 
971
        for (unsigned int s = 0; s < n; s++)
 
972
        {
 
973
          // Updating dmats_old with new values and resetting dmats.
 
974
          for (unsigned int t = 0; t < 6; t++)
 
975
          {
 
976
            for (unsigned int u = 0; u < 6; u++)
 
977
            {
 
978
              dmats_old[t][u] = dmats[t][u];
 
979
              dmats[t][u] = 0.0;
 
980
            }// end loop over 'u'
 
981
          }// end loop over 't'
 
982
          
 
983
          // Update dmats using an inner product.
 
984
          if (combinations_t[r][s] == 0)
 
985
          {
 
986
          for (unsigned int t = 0; t < 6; t++)
 
987
          {
 
988
            for (unsigned int u = 0; u < 6; u++)
 
989
            {
 
990
              for (unsigned int tu = 0; tu < 6; tu++)
 
991
              {
 
992
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
993
              }// end loop over 'tu'
 
994
            }// end loop over 'u'
 
995
          }// end loop over 't'
 
996
          }
 
997
          
 
998
          if (combinations_t[r][s] == 1)
 
999
          {
 
1000
          for (unsigned int t = 0; t < 6; t++)
 
1001
          {
 
1002
            for (unsigned int u = 0; u < 6; u++)
 
1003
            {
 
1004
              for (unsigned int tu = 0; tu < 6; tu++)
 
1005
              {
 
1006
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
1007
              }// end loop over 'tu'
 
1008
            }// end loop over 'u'
 
1009
          }// end loop over 't'
 
1010
          }
 
1011
          
 
1012
        }// end loop over 's'
 
1013
        for (unsigned int s = 0; s < 6; s++)
 
1014
        {
 
1015
          for (unsigned int t = 0; t < 6; t++)
 
1016
          {
 
1017
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
1018
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
1019
          }// end loop over 't'
 
1020
        }// end loop over 's'
 
1021
        
 
1022
        // Using contravariant Piola transform to map values back to the physical element.
 
1023
        const double tmp_ref0 = derivatives[r];
 
1024
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
1025
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
1026
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
1027
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
1028
      }// end loop over 'r'
 
1029
      
 
1030
      // Transform derivatives back to physical element
 
1031
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
1032
      {
 
1033
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
1034
        {
 
1035
          values[r] += transform[r][s]*derivatives_p[s];
 
1036
          values[num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
1037
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
1038
        }// end loop over 's'
 
1039
      }// end loop over 'r'
 
1040
      
 
1041
      // Delete pointer to array of derivatives on FIAT element
 
1042
      delete [] derivatives;
 
1043
      
 
1044
      // Delete pointer to array of reference derivatives on physical element.
 
1045
      delete [] derivatives_p;
 
1046
      
 
1047
      // Delete pointer to array of combinations of derivatives and transform
 
1048
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
1049
      {
 
1050
        delete [] combinations_t[r];
 
1051
      }// end loop over 'r'
 
1052
      delete [] combinations_t;
 
1053
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
1054
      {
 
1055
        delete [] combinations_g[r];
 
1056
      }// end loop over 'r'
 
1057
      delete [] combinations_g;
 
1058
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
1059
      {
 
1060
        delete [] transform[r];
 
1061
      }// end loop over 'r'
 
1062
      delete [] transform;
 
1063
        break;
 
1064
      }
 
1065
    case 2:
 
1066
      {
 
1067
        
 
1068
      // Array of basisvalues
 
1069
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
1070
      
 
1071
      // Declare helper variables
 
1072
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
1073
      double tmp1 = (1.0 - Y)/2.0;
 
1074
      double tmp2 = tmp1*tmp1;
 
1075
      
 
1076
      // Compute basisvalues
 
1077
      basisvalues[0] = 1.0;
 
1078
      basisvalues[1] = tmp0;
 
1079
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
1080
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
1081
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
1082
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
1083
      basisvalues[0] *= std::sqrt(0.5);
 
1084
      basisvalues[2] *= std::sqrt(1.0);
 
1085
      basisvalues[5] *= std::sqrt(1.5);
 
1086
      basisvalues[1] *= std::sqrt(3.0);
 
1087
      basisvalues[4] *= std::sqrt(4.5);
 
1088
      basisvalues[3] *= std::sqrt(7.5);
 
1089
      
 
1090
      // Table(s) of coefficients
 
1091
      static const double coefficients0[6] = \
 
1092
      {0.11785113, -0.57735027, -0.46666667, 0.18257419, 0.0, -0.040824829};
 
1093
      
 
1094
      static const double coefficients1[6] = \
 
1095
      {0.11785113, 0.17320508, 0.23333333, 0.0, 0.14142136, 0.12247449};
 
1096
      
 
1097
      // Tables of derivatives of the polynomial base (transpose).
 
1098
      static const double dmats0[6][6] = \
 
1099
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1100
      {4.8989795, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1101
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1102
      {0.0, 9.486833, 0.0, 0.0, 0.0, 0.0},
 
1103
      {4.0, 0.0, 7.0710678, 0.0, 0.0, 0.0},
 
1104
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}};
 
1105
      
 
1106
      static const double dmats1[6][6] = \
 
1107
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1108
      {2.4494897, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1109
      {4.2426407, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1110
      {2.5819889, 4.7434165, -0.91287093, 0.0, 0.0, 0.0},
 
1111
      {2.0, 6.1237244, 3.5355339, 0.0, 0.0, 0.0},
 
1112
      {-2.3094011, 0.0, 8.1649658, 0.0, 0.0, 0.0}};
 
1113
      
 
1114
      // Compute reference derivatives.
 
1115
      // Declare pointer to array of derivatives on FIAT element.
 
1116
      double *derivatives = new double[2*num_derivatives_t];
 
1117
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
1118
      {
 
1119
        derivatives[r] = 0.0;
 
1120
      }// end loop over 'r'
 
1121
      
 
1122
      // Declare pointer to array of reference derivatives on physical element.
 
1123
      double *derivatives_p = new double[3*num_derivatives_t];
 
1124
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
1125
      {
 
1126
        derivatives_p[r] = 0.0;
 
1127
      }// end loop over 'r'
 
1128
      
 
1129
      // Declare derivative matrix (of polynomial basis).
 
1130
      double dmats[6][6] = \
 
1131
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1132
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
1133
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
1134
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
1135
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
1136
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
1137
      
 
1138
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
1139
      double dmats_old[6][6] = \
 
1140
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1141
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
1142
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
1143
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
1144
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
1145
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
1146
      
 
1147
      // Loop possible derivatives.
 
1148
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
1149
      {
 
1150
        // Resetting dmats values to compute next derivative.
 
1151
        for (unsigned int t = 0; t < 6; t++)
 
1152
        {
 
1153
          for (unsigned int u = 0; u < 6; u++)
 
1154
          {
 
1155
            dmats[t][u] = 0.0;
 
1156
            if (t == u)
 
1157
            {
 
1158
            dmats[t][u] = 1.0;
 
1159
            }
 
1160
            
 
1161
          }// end loop over 'u'
 
1162
        }// end loop over 't'
 
1163
        
 
1164
        // Looping derivative order to generate dmats.
 
1165
        for (unsigned int s = 0; s < n; s++)
 
1166
        {
 
1167
          // Updating dmats_old with new values and resetting dmats.
 
1168
          for (unsigned int t = 0; t < 6; t++)
 
1169
          {
 
1170
            for (unsigned int u = 0; u < 6; u++)
 
1171
            {
 
1172
              dmats_old[t][u] = dmats[t][u];
 
1173
              dmats[t][u] = 0.0;
 
1174
            }// end loop over 'u'
 
1175
          }// end loop over 't'
 
1176
          
 
1177
          // Update dmats using an inner product.
 
1178
          if (combinations_t[r][s] == 0)
 
1179
          {
 
1180
          for (unsigned int t = 0; t < 6; t++)
 
1181
          {
 
1182
            for (unsigned int u = 0; u < 6; u++)
 
1183
            {
 
1184
              for (unsigned int tu = 0; tu < 6; tu++)
 
1185
              {
 
1186
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
1187
              }// end loop over 'tu'
 
1188
            }// end loop over 'u'
 
1189
          }// end loop over 't'
 
1190
          }
 
1191
          
 
1192
          if (combinations_t[r][s] == 1)
 
1193
          {
 
1194
          for (unsigned int t = 0; t < 6; t++)
 
1195
          {
 
1196
            for (unsigned int u = 0; u < 6; u++)
 
1197
            {
 
1198
              for (unsigned int tu = 0; tu < 6; tu++)
 
1199
              {
 
1200
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
1201
              }// end loop over 'tu'
 
1202
            }// end loop over 'u'
 
1203
          }// end loop over 't'
 
1204
          }
 
1205
          
 
1206
        }// end loop over 's'
 
1207
        for (unsigned int s = 0; s < 6; s++)
 
1208
        {
 
1209
          for (unsigned int t = 0; t < 6; t++)
 
1210
          {
 
1211
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
1212
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
1213
          }// end loop over 't'
 
1214
        }// end loop over 's'
 
1215
        
 
1216
        // Using contravariant Piola transform to map values back to the physical element.
 
1217
        const double tmp_ref0 = derivatives[r];
 
1218
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
1219
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
1220
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
1221
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
1222
      }// end loop over 'r'
 
1223
      
 
1224
      // Transform derivatives back to physical element
 
1225
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
1226
      {
 
1227
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
1228
        {
 
1229
          values[r] += transform[r][s]*derivatives_p[s];
 
1230
          values[num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
1231
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
1232
        }// end loop over 's'
 
1233
      }// end loop over 'r'
 
1234
      
 
1235
      // Delete pointer to array of derivatives on FIAT element
 
1236
      delete [] derivatives;
 
1237
      
 
1238
      // Delete pointer to array of reference derivatives on physical element.
 
1239
      delete [] derivatives_p;
 
1240
      
 
1241
      // Delete pointer to array of combinations of derivatives and transform
 
1242
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
1243
      {
 
1244
        delete [] combinations_t[r];
 
1245
      }// end loop over 'r'
 
1246
      delete [] combinations_t;
 
1247
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
1248
      {
 
1249
        delete [] combinations_g[r];
 
1250
      }// end loop over 'r'
 
1251
      delete [] combinations_g;
 
1252
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
1253
      {
 
1254
        delete [] transform[r];
 
1255
      }// end loop over 'r'
 
1256
      delete [] transform;
 
1257
        break;
 
1258
      }
 
1259
    case 3:
 
1260
      {
 
1261
        
 
1262
      // Array of basisvalues
 
1263
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
1264
      
 
1265
      // Declare helper variables
 
1266
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
1267
      double tmp1 = (1.0 - Y)/2.0;
 
1268
      double tmp2 = tmp1*tmp1;
 
1269
      
 
1270
      // Compute basisvalues
 
1271
      basisvalues[0] = 1.0;
 
1272
      basisvalues[1] = tmp0;
 
1273
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
1274
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
1275
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
1276
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
1277
      basisvalues[0] *= std::sqrt(0.5);
 
1278
      basisvalues[2] *= std::sqrt(1.0);
 
1279
      basisvalues[5] *= std::sqrt(1.5);
 
1280
      basisvalues[1] *= std::sqrt(3.0);
 
1281
      basisvalues[4] *= std::sqrt(4.5);
 
1282
      basisvalues[3] *= std::sqrt(7.5);
 
1283
      
 
1284
      // Table(s) of coefficients
 
1285
      static const double coefficients0[6] = \
 
1286
      {0.11785113, 0.11547005, 0.73333333, 0.0, -0.14142136, 0.12247449};
 
1287
      
 
1288
      static const double coefficients1[6] = \
 
1289
      {-0.23570226, 0.0, -0.46666667, 0.0, 0.0, -0.24494897};
 
1290
      
 
1291
      // Tables of derivatives of the polynomial base (transpose).
 
1292
      static const double dmats0[6][6] = \
 
1293
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1294
      {4.8989795, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1295
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1296
      {0.0, 9.486833, 0.0, 0.0, 0.0, 0.0},
 
1297
      {4.0, 0.0, 7.0710678, 0.0, 0.0, 0.0},
 
1298
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}};
 
1299
      
 
1300
      static const double dmats1[6][6] = \
 
1301
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1302
      {2.4494897, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1303
      {4.2426407, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1304
      {2.5819889, 4.7434165, -0.91287093, 0.0, 0.0, 0.0},
 
1305
      {2.0, 6.1237244, 3.5355339, 0.0, 0.0, 0.0},
 
1306
      {-2.3094011, 0.0, 8.1649658, 0.0, 0.0, 0.0}};
 
1307
      
 
1308
      // Compute reference derivatives.
 
1309
      // Declare pointer to array of derivatives on FIAT element.
 
1310
      double *derivatives = new double[2*num_derivatives_t];
 
1311
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
1312
      {
 
1313
        derivatives[r] = 0.0;
 
1314
      }// end loop over 'r'
 
1315
      
 
1316
      // Declare pointer to array of reference derivatives on physical element.
 
1317
      double *derivatives_p = new double[3*num_derivatives_t];
 
1318
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
1319
      {
 
1320
        derivatives_p[r] = 0.0;
 
1321
      }// end loop over 'r'
 
1322
      
 
1323
      // Declare derivative matrix (of polynomial basis).
 
1324
      double dmats[6][6] = \
 
1325
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1326
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
1327
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
1328
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
1329
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
1330
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
1331
      
 
1332
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
1333
      double dmats_old[6][6] = \
 
1334
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1335
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
1336
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
1337
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
1338
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
1339
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
1340
      
 
1341
      // Loop possible derivatives.
 
1342
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
1343
      {
 
1344
        // Resetting dmats values to compute next derivative.
 
1345
        for (unsigned int t = 0; t < 6; t++)
 
1346
        {
 
1347
          for (unsigned int u = 0; u < 6; u++)
 
1348
          {
 
1349
            dmats[t][u] = 0.0;
 
1350
            if (t == u)
 
1351
            {
 
1352
            dmats[t][u] = 1.0;
 
1353
            }
 
1354
            
 
1355
          }// end loop over 'u'
 
1356
        }// end loop over 't'
 
1357
        
 
1358
        // Looping derivative order to generate dmats.
 
1359
        for (unsigned int s = 0; s < n; s++)
 
1360
        {
 
1361
          // Updating dmats_old with new values and resetting dmats.
 
1362
          for (unsigned int t = 0; t < 6; t++)
 
1363
          {
 
1364
            for (unsigned int u = 0; u < 6; u++)
 
1365
            {
 
1366
              dmats_old[t][u] = dmats[t][u];
 
1367
              dmats[t][u] = 0.0;
 
1368
            }// end loop over 'u'
 
1369
          }// end loop over 't'
 
1370
          
 
1371
          // Update dmats using an inner product.
 
1372
          if (combinations_t[r][s] == 0)
 
1373
          {
 
1374
          for (unsigned int t = 0; t < 6; t++)
 
1375
          {
 
1376
            for (unsigned int u = 0; u < 6; u++)
 
1377
            {
 
1378
              for (unsigned int tu = 0; tu < 6; tu++)
 
1379
              {
 
1380
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
1381
              }// end loop over 'tu'
 
1382
            }// end loop over 'u'
 
1383
          }// end loop over 't'
 
1384
          }
 
1385
          
 
1386
          if (combinations_t[r][s] == 1)
 
1387
          {
 
1388
          for (unsigned int t = 0; t < 6; t++)
 
1389
          {
 
1390
            for (unsigned int u = 0; u < 6; u++)
 
1391
            {
 
1392
              for (unsigned int tu = 0; tu < 6; tu++)
 
1393
              {
 
1394
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
1395
              }// end loop over 'tu'
 
1396
            }// end loop over 'u'
 
1397
          }// end loop over 't'
 
1398
          }
 
1399
          
 
1400
        }// end loop over 's'
 
1401
        for (unsigned int s = 0; s < 6; s++)
 
1402
        {
 
1403
          for (unsigned int t = 0; t < 6; t++)
 
1404
          {
 
1405
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
1406
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
1407
          }// end loop over 't'
 
1408
        }// end loop over 's'
 
1409
        
 
1410
        // Using contravariant Piola transform to map values back to the physical element.
 
1411
        const double tmp_ref0 = derivatives[r];
 
1412
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
1413
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
1414
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
1415
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
1416
      }// end loop over 'r'
 
1417
      
 
1418
      // Transform derivatives back to physical element
 
1419
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
1420
      {
 
1421
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
1422
        {
 
1423
          values[r] += transform[r][s]*derivatives_p[s];
 
1424
          values[num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
1425
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
1426
        }// end loop over 's'
 
1427
      }// end loop over 'r'
 
1428
      
 
1429
      // Delete pointer to array of derivatives on FIAT element
 
1430
      delete [] derivatives;
 
1431
      
 
1432
      // Delete pointer to array of reference derivatives on physical element.
 
1433
      delete [] derivatives_p;
 
1434
      
 
1435
      // Delete pointer to array of combinations of derivatives and transform
 
1436
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
1437
      {
 
1438
        delete [] combinations_t[r];
 
1439
      }// end loop over 'r'
 
1440
      delete [] combinations_t;
 
1441
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
1442
      {
 
1443
        delete [] combinations_g[r];
 
1444
      }// end loop over 'r'
 
1445
      delete [] combinations_g;
 
1446
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
1447
      {
 
1448
        delete [] transform[r];
 
1449
      }// end loop over 'r'
 
1450
      delete [] transform;
 
1451
        break;
 
1452
      }
 
1453
    case 4:
 
1454
      {
 
1455
        
 
1456
      // Array of basisvalues
 
1457
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
1458
      
 
1459
      // Declare helper variables
 
1460
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
1461
      double tmp1 = (1.0 - Y)/2.0;
 
1462
      double tmp2 = tmp1*tmp1;
 
1463
      
 
1464
      // Compute basisvalues
 
1465
      basisvalues[0] = 1.0;
 
1466
      basisvalues[1] = tmp0;
 
1467
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
1468
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
1469
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
1470
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
1471
      basisvalues[0] *= std::sqrt(0.5);
 
1472
      basisvalues[2] *= std::sqrt(1.0);
 
1473
      basisvalues[5] *= std::sqrt(1.5);
 
1474
      basisvalues[1] *= std::sqrt(3.0);
 
1475
      basisvalues[4] *= std::sqrt(4.5);
 
1476
      basisvalues[3] *= std::sqrt(7.5);
 
1477
      
 
1478
      // Table(s) of coefficients
 
1479
      static const double coefficients0[6] = \
 
1480
      {-0.11785113, -0.28867513, -0.033333333, -0.18257419, 0.0, 0.040824829};
 
1481
      
 
1482
      static const double coefficients1[6] = \
 
1483
      {-0.11785113, 0.69282032, 0.26666667, 0.0, -0.14142136, -0.12247449};
 
1484
      
 
1485
      // Tables of derivatives of the polynomial base (transpose).
 
1486
      static const double dmats0[6][6] = \
 
1487
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1488
      {4.8989795, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1489
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1490
      {0.0, 9.486833, 0.0, 0.0, 0.0, 0.0},
 
1491
      {4.0, 0.0, 7.0710678, 0.0, 0.0, 0.0},
 
1492
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}};
 
1493
      
 
1494
      static const double dmats1[6][6] = \
 
1495
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1496
      {2.4494897, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1497
      {4.2426407, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1498
      {2.5819889, 4.7434165, -0.91287093, 0.0, 0.0, 0.0},
 
1499
      {2.0, 6.1237244, 3.5355339, 0.0, 0.0, 0.0},
 
1500
      {-2.3094011, 0.0, 8.1649658, 0.0, 0.0, 0.0}};
 
1501
      
 
1502
      // Compute reference derivatives.
 
1503
      // Declare pointer to array of derivatives on FIAT element.
 
1504
      double *derivatives = new double[2*num_derivatives_t];
 
1505
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
1506
      {
 
1507
        derivatives[r] = 0.0;
 
1508
      }// end loop over 'r'
 
1509
      
 
1510
      // Declare pointer to array of reference derivatives on physical element.
 
1511
      double *derivatives_p = new double[3*num_derivatives_t];
 
1512
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
1513
      {
 
1514
        derivatives_p[r] = 0.0;
 
1515
      }// end loop over 'r'
 
1516
      
 
1517
      // Declare derivative matrix (of polynomial basis).
 
1518
      double dmats[6][6] = \
 
1519
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1520
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
1521
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
1522
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
1523
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
1524
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
1525
      
 
1526
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
1527
      double dmats_old[6][6] = \
 
1528
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1529
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
1530
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
1531
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
1532
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
1533
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
1534
      
 
1535
      // Loop possible derivatives.
 
1536
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
1537
      {
 
1538
        // Resetting dmats values to compute next derivative.
 
1539
        for (unsigned int t = 0; t < 6; t++)
 
1540
        {
 
1541
          for (unsigned int u = 0; u < 6; u++)
 
1542
          {
 
1543
            dmats[t][u] = 0.0;
 
1544
            if (t == u)
 
1545
            {
 
1546
            dmats[t][u] = 1.0;
 
1547
            }
 
1548
            
 
1549
          }// end loop over 'u'
 
1550
        }// end loop over 't'
 
1551
        
 
1552
        // Looping derivative order to generate dmats.
 
1553
        for (unsigned int s = 0; s < n; s++)
 
1554
        {
 
1555
          // Updating dmats_old with new values and resetting dmats.
 
1556
          for (unsigned int t = 0; t < 6; t++)
 
1557
          {
 
1558
            for (unsigned int u = 0; u < 6; u++)
 
1559
            {
 
1560
              dmats_old[t][u] = dmats[t][u];
 
1561
              dmats[t][u] = 0.0;
 
1562
            }// end loop over 'u'
 
1563
          }// end loop over 't'
 
1564
          
 
1565
          // Update dmats using an inner product.
 
1566
          if (combinations_t[r][s] == 0)
 
1567
          {
 
1568
          for (unsigned int t = 0; t < 6; t++)
 
1569
          {
 
1570
            for (unsigned int u = 0; u < 6; u++)
 
1571
            {
 
1572
              for (unsigned int tu = 0; tu < 6; tu++)
 
1573
              {
 
1574
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
1575
              }// end loop over 'tu'
 
1576
            }// end loop over 'u'
 
1577
          }// end loop over 't'
 
1578
          }
 
1579
          
 
1580
          if (combinations_t[r][s] == 1)
 
1581
          {
 
1582
          for (unsigned int t = 0; t < 6; t++)
 
1583
          {
 
1584
            for (unsigned int u = 0; u < 6; u++)
 
1585
            {
 
1586
              for (unsigned int tu = 0; tu < 6; tu++)
 
1587
              {
 
1588
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
1589
              }// end loop over 'tu'
 
1590
            }// end loop over 'u'
 
1591
          }// end loop over 't'
 
1592
          }
 
1593
          
 
1594
        }// end loop over 's'
 
1595
        for (unsigned int s = 0; s < 6; s++)
 
1596
        {
 
1597
          for (unsigned int t = 0; t < 6; t++)
 
1598
          {
 
1599
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
1600
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
1601
          }// end loop over 't'
 
1602
        }// end loop over 's'
 
1603
        
 
1604
        // Using contravariant Piola transform to map values back to the physical element.
 
1605
        const double tmp_ref0 = derivatives[r];
 
1606
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
1607
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
1608
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
1609
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
1610
      }// end loop over 'r'
 
1611
      
 
1612
      // Transform derivatives back to physical element
 
1613
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
1614
      {
 
1615
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
1616
        {
 
1617
          values[r] += transform[r][s]*derivatives_p[s];
 
1618
          values[num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
1619
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
1620
        }// end loop over 's'
 
1621
      }// end loop over 'r'
 
1622
      
 
1623
      // Delete pointer to array of derivatives on FIAT element
 
1624
      delete [] derivatives;
 
1625
      
 
1626
      // Delete pointer to array of reference derivatives on physical element.
 
1627
      delete [] derivatives_p;
 
1628
      
 
1629
      // Delete pointer to array of combinations of derivatives and transform
 
1630
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
1631
      {
 
1632
        delete [] combinations_t[r];
 
1633
      }// end loop over 'r'
 
1634
      delete [] combinations_t;
 
1635
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
1636
      {
 
1637
        delete [] combinations_g[r];
 
1638
      }// end loop over 'r'
 
1639
      delete [] combinations_g;
 
1640
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
1641
      {
 
1642
        delete [] transform[r];
 
1643
      }// end loop over 'r'
 
1644
      delete [] transform;
 
1645
        break;
 
1646
      }
 
1647
    case 5:
 
1648
      {
 
1649
        
 
1650
      // Array of basisvalues
 
1651
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
1652
      
 
1653
      // Declare helper variables
 
1654
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
1655
      double tmp1 = (1.0 - Y)/2.0;
 
1656
      double tmp2 = tmp1*tmp1;
 
1657
      
 
1658
      // Compute basisvalues
 
1659
      basisvalues[0] = 1.0;
 
1660
      basisvalues[1] = tmp0;
 
1661
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
1662
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
1663
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
1664
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
1665
      basisvalues[0] *= std::sqrt(0.5);
 
1666
      basisvalues[2] *= std::sqrt(1.0);
 
1667
      basisvalues[5] *= std::sqrt(1.5);
 
1668
      basisvalues[1] *= std::sqrt(3.0);
 
1669
      basisvalues[4] *= std::sqrt(4.5);
 
1670
      basisvalues[3] *= std::sqrt(7.5);
 
1671
      
 
1672
      // Table(s) of coefficients
 
1673
      static const double coefficients0[6] = \
 
1674
      {0.23570226, 0.40414519, -0.23333333, 0.18257419, -0.14142136, 0.081649658};
 
1675
      
 
1676
      static const double coefficients1[6] = \
 
1677
      {-0.11785113, -0.69282032, 0.26666667, 0.0, 0.14142136, -0.12247449};
 
1678
      
 
1679
      // Tables of derivatives of the polynomial base (transpose).
 
1680
      static const double dmats0[6][6] = \
 
1681
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1682
      {4.8989795, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1683
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1684
      {0.0, 9.486833, 0.0, 0.0, 0.0, 0.0},
 
1685
      {4.0, 0.0, 7.0710678, 0.0, 0.0, 0.0},
 
1686
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}};
 
1687
      
 
1688
      static const double dmats1[6][6] = \
 
1689
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1690
      {2.4494897, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1691
      {4.2426407, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1692
      {2.5819889, 4.7434165, -0.91287093, 0.0, 0.0, 0.0},
 
1693
      {2.0, 6.1237244, 3.5355339, 0.0, 0.0, 0.0},
 
1694
      {-2.3094011, 0.0, 8.1649658, 0.0, 0.0, 0.0}};
 
1695
      
 
1696
      // Compute reference derivatives.
 
1697
      // Declare pointer to array of derivatives on FIAT element.
 
1698
      double *derivatives = new double[2*num_derivatives_t];
 
1699
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
1700
      {
 
1701
        derivatives[r] = 0.0;
 
1702
      }// end loop over 'r'
 
1703
      
 
1704
      // Declare pointer to array of reference derivatives on physical element.
 
1705
      double *derivatives_p = new double[3*num_derivatives_t];
 
1706
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
1707
      {
 
1708
        derivatives_p[r] = 0.0;
 
1709
      }// end loop over 'r'
 
1710
      
 
1711
      // Declare derivative matrix (of polynomial basis).
 
1712
      double dmats[6][6] = \
 
1713
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1714
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
1715
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
1716
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
1717
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
1718
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
1719
      
 
1720
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
1721
      double dmats_old[6][6] = \
 
1722
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1723
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
1724
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
1725
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
1726
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
1727
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
1728
      
 
1729
      // Loop possible derivatives.
 
1730
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
1731
      {
 
1732
        // Resetting dmats values to compute next derivative.
 
1733
        for (unsigned int t = 0; t < 6; t++)
 
1734
        {
 
1735
          for (unsigned int u = 0; u < 6; u++)
 
1736
          {
 
1737
            dmats[t][u] = 0.0;
 
1738
            if (t == u)
 
1739
            {
 
1740
            dmats[t][u] = 1.0;
 
1741
            }
 
1742
            
 
1743
          }// end loop over 'u'
 
1744
        }// end loop over 't'
 
1745
        
 
1746
        // Looping derivative order to generate dmats.
 
1747
        for (unsigned int s = 0; s < n; s++)
 
1748
        {
 
1749
          // Updating dmats_old with new values and resetting dmats.
 
1750
          for (unsigned int t = 0; t < 6; t++)
 
1751
          {
 
1752
            for (unsigned int u = 0; u < 6; u++)
 
1753
            {
 
1754
              dmats_old[t][u] = dmats[t][u];
 
1755
              dmats[t][u] = 0.0;
 
1756
            }// end loop over 'u'
 
1757
          }// end loop over 't'
 
1758
          
 
1759
          // Update dmats using an inner product.
 
1760
          if (combinations_t[r][s] == 0)
 
1761
          {
 
1762
          for (unsigned int t = 0; t < 6; t++)
 
1763
          {
 
1764
            for (unsigned int u = 0; u < 6; u++)
 
1765
            {
 
1766
              for (unsigned int tu = 0; tu < 6; tu++)
 
1767
              {
 
1768
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
1769
              }// end loop over 'tu'
 
1770
            }// end loop over 'u'
 
1771
          }// end loop over 't'
 
1772
          }
 
1773
          
 
1774
          if (combinations_t[r][s] == 1)
 
1775
          {
 
1776
          for (unsigned int t = 0; t < 6; t++)
 
1777
          {
 
1778
            for (unsigned int u = 0; u < 6; u++)
 
1779
            {
 
1780
              for (unsigned int tu = 0; tu < 6; tu++)
 
1781
              {
 
1782
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
1783
              }// end loop over 'tu'
 
1784
            }// end loop over 'u'
 
1785
          }// end loop over 't'
 
1786
          }
 
1787
          
 
1788
        }// end loop over 's'
 
1789
        for (unsigned int s = 0; s < 6; s++)
 
1790
        {
 
1791
          for (unsigned int t = 0; t < 6; t++)
 
1792
          {
 
1793
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
1794
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
1795
          }// end loop over 't'
 
1796
        }// end loop over 's'
 
1797
        
 
1798
        // Using contravariant Piola transform to map values back to the physical element.
 
1799
        const double tmp_ref0 = derivatives[r];
 
1800
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
1801
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
1802
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
1803
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
1804
      }// end loop over 'r'
 
1805
      
 
1806
      // Transform derivatives back to physical element
 
1807
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
1808
      {
 
1809
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
1810
        {
 
1811
          values[r] += transform[r][s]*derivatives_p[s];
 
1812
          values[num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
1813
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
1814
        }// end loop over 's'
 
1815
      }// end loop over 'r'
 
1816
      
 
1817
      // Delete pointer to array of derivatives on FIAT element
 
1818
      delete [] derivatives;
 
1819
      
 
1820
      // Delete pointer to array of reference derivatives on physical element.
 
1821
      delete [] derivatives_p;
 
1822
      
 
1823
      // Delete pointer to array of combinations of derivatives and transform
 
1824
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
1825
      {
 
1826
        delete [] combinations_t[r];
 
1827
      }// end loop over 'r'
 
1828
      delete [] combinations_t;
 
1829
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
1830
      {
 
1831
        delete [] combinations_g[r];
 
1832
      }// end loop over 'r'
 
1833
      delete [] combinations_g;
 
1834
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
1835
      {
 
1836
        delete [] transform[r];
 
1837
      }// end loop over 'r'
 
1838
      delete [] transform;
 
1839
        break;
 
1840
      }
 
1841
    case 6:
 
1842
      {
 
1843
        
 
1844
      // Array of basisvalues
 
1845
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
1846
      
 
1847
      // Declare helper variables
 
1848
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
1849
      double tmp1 = (1.0 - Y)/2.0;
 
1850
      double tmp2 = tmp1*tmp1;
 
1851
      
 
1852
      // Compute basisvalues
 
1853
      basisvalues[0] = 1.0;
 
1854
      basisvalues[1] = tmp0;
 
1855
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
1856
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
1857
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
1858
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
1859
      basisvalues[0] *= std::sqrt(0.5);
 
1860
      basisvalues[2] *= std::sqrt(1.0);
 
1861
      basisvalues[5] *= std::sqrt(1.5);
 
1862
      basisvalues[1] *= std::sqrt(3.0);
 
1863
      basisvalues[4] *= std::sqrt(4.5);
 
1864
      basisvalues[3] *= std::sqrt(7.5);
 
1865
      
 
1866
      // Table(s) of coefficients
 
1867
      static const double coefficients0[6] = \
 
1868
      {1.0606602, 0.17320508, -0.3, -0.36514837, 0.14142136, -0.040824829};
 
1869
      
 
1870
      static const double coefficients1[6] = \
 
1871
      {0.0, -0.34641016, 0.0, 0.0, -0.28284271, 0.0};
 
1872
      
 
1873
      // Tables of derivatives of the polynomial base (transpose).
 
1874
      static const double dmats0[6][6] = \
 
1875
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1876
      {4.8989795, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1877
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1878
      {0.0, 9.486833, 0.0, 0.0, 0.0, 0.0},
 
1879
      {4.0, 0.0, 7.0710678, 0.0, 0.0, 0.0},
 
1880
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}};
 
1881
      
 
1882
      static const double dmats1[6][6] = \
 
1883
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1884
      {2.4494897, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1885
      {4.2426407, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1886
      {2.5819889, 4.7434165, -0.91287093, 0.0, 0.0, 0.0},
 
1887
      {2.0, 6.1237244, 3.5355339, 0.0, 0.0, 0.0},
 
1888
      {-2.3094011, 0.0, 8.1649658, 0.0, 0.0, 0.0}};
 
1889
      
 
1890
      // Compute reference derivatives.
 
1891
      // Declare pointer to array of derivatives on FIAT element.
 
1892
      double *derivatives = new double[2*num_derivatives_t];
 
1893
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
1894
      {
 
1895
        derivatives[r] = 0.0;
 
1896
      }// end loop over 'r'
 
1897
      
 
1898
      // Declare pointer to array of reference derivatives on physical element.
 
1899
      double *derivatives_p = new double[3*num_derivatives_t];
 
1900
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
1901
      {
 
1902
        derivatives_p[r] = 0.0;
 
1903
      }// end loop over 'r'
 
1904
      
 
1905
      // Declare derivative matrix (of polynomial basis).
 
1906
      double dmats[6][6] = \
 
1907
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1908
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
1909
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
1910
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
1911
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
1912
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
1913
      
 
1914
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
1915
      double dmats_old[6][6] = \
 
1916
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
1917
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
1918
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
1919
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
1920
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
1921
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
1922
      
 
1923
      // Loop possible derivatives.
 
1924
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
1925
      {
 
1926
        // Resetting dmats values to compute next derivative.
 
1927
        for (unsigned int t = 0; t < 6; t++)
 
1928
        {
 
1929
          for (unsigned int u = 0; u < 6; u++)
 
1930
          {
 
1931
            dmats[t][u] = 0.0;
 
1932
            if (t == u)
 
1933
            {
 
1934
            dmats[t][u] = 1.0;
 
1935
            }
 
1936
            
 
1937
          }// end loop over 'u'
 
1938
        }// end loop over 't'
 
1939
        
 
1940
        // Looping derivative order to generate dmats.
 
1941
        for (unsigned int s = 0; s < n; s++)
 
1942
        {
 
1943
          // Updating dmats_old with new values and resetting dmats.
 
1944
          for (unsigned int t = 0; t < 6; t++)
 
1945
          {
 
1946
            for (unsigned int u = 0; u < 6; u++)
 
1947
            {
 
1948
              dmats_old[t][u] = dmats[t][u];
 
1949
              dmats[t][u] = 0.0;
 
1950
            }// end loop over 'u'
 
1951
          }// end loop over 't'
 
1952
          
 
1953
          // Update dmats using an inner product.
 
1954
          if (combinations_t[r][s] == 0)
 
1955
          {
 
1956
          for (unsigned int t = 0; t < 6; t++)
 
1957
          {
 
1958
            for (unsigned int u = 0; u < 6; u++)
 
1959
            {
 
1960
              for (unsigned int tu = 0; tu < 6; tu++)
 
1961
              {
 
1962
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
1963
              }// end loop over 'tu'
 
1964
            }// end loop over 'u'
 
1965
          }// end loop over 't'
 
1966
          }
 
1967
          
 
1968
          if (combinations_t[r][s] == 1)
 
1969
          {
 
1970
          for (unsigned int t = 0; t < 6; t++)
 
1971
          {
 
1972
            for (unsigned int u = 0; u < 6; u++)
 
1973
            {
 
1974
              for (unsigned int tu = 0; tu < 6; tu++)
 
1975
              {
 
1976
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
1977
              }// end loop over 'tu'
 
1978
            }// end loop over 'u'
 
1979
          }// end loop over 't'
 
1980
          }
 
1981
          
 
1982
        }// end loop over 's'
 
1983
        for (unsigned int s = 0; s < 6; s++)
 
1984
        {
 
1985
          for (unsigned int t = 0; t < 6; t++)
 
1986
          {
 
1987
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
1988
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
1989
          }// end loop over 't'
 
1990
        }// end loop over 's'
 
1991
        
 
1992
        // Using contravariant Piola transform to map values back to the physical element.
 
1993
        const double tmp_ref0 = derivatives[r];
 
1994
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
1995
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
1996
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
1997
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
1998
      }// end loop over 'r'
 
1999
      
 
2000
      // Transform derivatives back to physical element
 
2001
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
2002
      {
 
2003
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
2004
        {
 
2005
          values[r] += transform[r][s]*derivatives_p[s];
 
2006
          values[num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
2007
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
2008
        }// end loop over 's'
 
2009
      }// end loop over 'r'
 
2010
      
 
2011
      // Delete pointer to array of derivatives on FIAT element
 
2012
      delete [] derivatives;
 
2013
      
 
2014
      // Delete pointer to array of reference derivatives on physical element.
 
2015
      delete [] derivatives_p;
 
2016
      
 
2017
      // Delete pointer to array of combinations of derivatives and transform
 
2018
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
2019
      {
 
2020
        delete [] combinations_t[r];
 
2021
      }// end loop over 'r'
 
2022
      delete [] combinations_t;
 
2023
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
2024
      {
 
2025
        delete [] combinations_g[r];
 
2026
      }// end loop over 'r'
 
2027
      delete [] combinations_g;
 
2028
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
2029
      {
 
2030
        delete [] transform[r];
 
2031
      }// end loop over 'r'
 
2032
      delete [] transform;
 
2033
        break;
 
2034
      }
 
2035
    case 7:
 
2036
      {
 
2037
        
 
2038
      // Array of basisvalues
 
2039
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
2040
      
 
2041
      // Declare helper variables
 
2042
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
2043
      double tmp1 = (1.0 - Y)/2.0;
 
2044
      double tmp2 = tmp1*tmp1;
 
2045
      
 
2046
      // Compute basisvalues
 
2047
      basisvalues[0] = 1.0;
 
2048
      basisvalues[1] = tmp0;
 
2049
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
2050
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
2051
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
2052
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
2053
      basisvalues[0] *= std::sqrt(0.5);
 
2054
      basisvalues[2] *= std::sqrt(1.0);
 
2055
      basisvalues[5] *= std::sqrt(1.5);
 
2056
      basisvalues[1] *= std::sqrt(3.0);
 
2057
      basisvalues[4] *= std::sqrt(4.5);
 
2058
      basisvalues[3] *= std::sqrt(7.5);
 
2059
      
 
2060
      // Table(s) of coefficients
 
2061
      static const double coefficients0[6] = \
 
2062
      {0.0, -0.17320508, -0.3, -0.18257419, -0.14142136, 0.16329932};
 
2063
      
 
2064
      static const double coefficients1[6] = \
 
2065
      {1.0606602, -0.17320508, 0.3, 0.0, -0.14142136, -0.36742346};
 
2066
      
 
2067
      // Tables of derivatives of the polynomial base (transpose).
 
2068
      static const double dmats0[6][6] = \
 
2069
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
2070
      {4.8989795, 0.0, 0.0, 0.0, 0.0, 0.0},
 
2071
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
2072
      {0.0, 9.486833, 0.0, 0.0, 0.0, 0.0},
 
2073
      {4.0, 0.0, 7.0710678, 0.0, 0.0, 0.0},
 
2074
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}};
 
2075
      
 
2076
      static const double dmats1[6][6] = \
 
2077
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
2078
      {2.4494897, 0.0, 0.0, 0.0, 0.0, 0.0},
 
2079
      {4.2426407, 0.0, 0.0, 0.0, 0.0, 0.0},
 
2080
      {2.5819889, 4.7434165, -0.91287093, 0.0, 0.0, 0.0},
 
2081
      {2.0, 6.1237244, 3.5355339, 0.0, 0.0, 0.0},
 
2082
      {-2.3094011, 0.0, 8.1649658, 0.0, 0.0, 0.0}};
 
2083
      
 
2084
      // Compute reference derivatives.
 
2085
      // Declare pointer to array of derivatives on FIAT element.
 
2086
      double *derivatives = new double[2*num_derivatives_t];
 
2087
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
2088
      {
 
2089
        derivatives[r] = 0.0;
 
2090
      }// end loop over 'r'
 
2091
      
 
2092
      // Declare pointer to array of reference derivatives on physical element.
 
2093
      double *derivatives_p = new double[3*num_derivatives_t];
 
2094
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
2095
      {
 
2096
        derivatives_p[r] = 0.0;
 
2097
      }// end loop over 'r'
 
2098
      
 
2099
      // Declare derivative matrix (of polynomial basis).
 
2100
      double dmats[6][6] = \
 
2101
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
2102
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
2103
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
2104
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
2105
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
2106
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
2107
      
 
2108
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
2109
      double dmats_old[6][6] = \
 
2110
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
2111
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
2112
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
2113
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
2114
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
2115
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
2116
      
 
2117
      // Loop possible derivatives.
 
2118
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
2119
      {
 
2120
        // Resetting dmats values to compute next derivative.
 
2121
        for (unsigned int t = 0; t < 6; t++)
 
2122
        {
 
2123
          for (unsigned int u = 0; u < 6; u++)
 
2124
          {
 
2125
            dmats[t][u] = 0.0;
 
2126
            if (t == u)
 
2127
            {
 
2128
            dmats[t][u] = 1.0;
 
2129
            }
 
2130
            
 
2131
          }// end loop over 'u'
 
2132
        }// end loop over 't'
 
2133
        
 
2134
        // Looping derivative order to generate dmats.
 
2135
        for (unsigned int s = 0; s < n; s++)
 
2136
        {
 
2137
          // Updating dmats_old with new values and resetting dmats.
 
2138
          for (unsigned int t = 0; t < 6; t++)
 
2139
          {
 
2140
            for (unsigned int u = 0; u < 6; u++)
 
2141
            {
 
2142
              dmats_old[t][u] = dmats[t][u];
 
2143
              dmats[t][u] = 0.0;
 
2144
            }// end loop over 'u'
 
2145
          }// end loop over 't'
 
2146
          
 
2147
          // Update dmats using an inner product.
 
2148
          if (combinations_t[r][s] == 0)
 
2149
          {
 
2150
          for (unsigned int t = 0; t < 6; t++)
 
2151
          {
 
2152
            for (unsigned int u = 0; u < 6; u++)
 
2153
            {
 
2154
              for (unsigned int tu = 0; tu < 6; tu++)
 
2155
              {
 
2156
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
2157
              }// end loop over 'tu'
 
2158
            }// end loop over 'u'
 
2159
          }// end loop over 't'
 
2160
          }
 
2161
          
 
2162
          if (combinations_t[r][s] == 1)
 
2163
          {
 
2164
          for (unsigned int t = 0; t < 6; t++)
 
2165
          {
 
2166
            for (unsigned int u = 0; u < 6; u++)
 
2167
            {
 
2168
              for (unsigned int tu = 0; tu < 6; tu++)
 
2169
              {
 
2170
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
2171
              }// end loop over 'tu'
 
2172
            }// end loop over 'u'
 
2173
          }// end loop over 't'
 
2174
          }
 
2175
          
 
2176
        }// end loop over 's'
 
2177
        for (unsigned int s = 0; s < 6; s++)
 
2178
        {
 
2179
          for (unsigned int t = 0; t < 6; t++)
 
2180
          {
 
2181
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
2182
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
2183
          }// end loop over 't'
 
2184
        }// end loop over 's'
 
2185
        
 
2186
        // Using contravariant Piola transform to map values back to the physical element.
 
2187
        const double tmp_ref0 = derivatives[r];
 
2188
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
2189
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
2190
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
2191
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
2192
      }// end loop over 'r'
 
2193
      
 
2194
      // Transform derivatives back to physical element
 
2195
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
2196
      {
 
2197
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
2198
        {
 
2199
          values[r] += transform[r][s]*derivatives_p[s];
 
2200
          values[num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
2201
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
2202
        }// end loop over 's'
 
2203
      }// end loop over 'r'
 
2204
      
 
2205
      // Delete pointer to array of derivatives on FIAT element
 
2206
      delete [] derivatives;
 
2207
      
 
2208
      // Delete pointer to array of reference derivatives on physical element.
 
2209
      delete [] derivatives_p;
 
2210
      
 
2211
      // Delete pointer to array of combinations of derivatives and transform
 
2212
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
2213
      {
 
2214
        delete [] combinations_t[r];
 
2215
      }// end loop over 'r'
 
2216
      delete [] combinations_t;
 
2217
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
2218
      {
 
2219
        delete [] combinations_g[r];
 
2220
      }// end loop over 'r'
 
2221
      delete [] combinations_g;
 
2222
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
2223
      {
 
2224
        delete [] transform[r];
 
2225
      }// end loop over 'r'
 
2226
      delete [] transform;
 
2227
        break;
 
2228
      }
 
2229
    }
 
2230
    
 
2231
  }
 
2232
 
 
2233
  /// Evaluate order n derivatives of all basis functions at given point x in cell
 
2234
  virtual void evaluate_basis_derivatives_all(std::size_t n,
 
2235
                                              double* values,
 
2236
                                              const double* x,
 
2237
                                              const double* vertex_coordinates,
 
2238
                                              int cell_orientation) const
 
2239
  {
 
2240
    // Compute number of derivatives.
 
2241
    unsigned int num_derivatives_g = 1;
 
2242
    for (unsigned int r = 0; r < n; r++)
 
2243
    {
 
2244
      num_derivatives_g *= 3;
 
2245
    }// end loop over 'r'
 
2246
    
 
2247
    // Helper variable to hold values of a single dof.
 
2248
    double *dof_values = new double[3*num_derivatives_g];
 
2249
    for (unsigned int r = 0; r < 3*num_derivatives_g; r++)
 
2250
    {
 
2251
      dof_values[r] = 0.0;
 
2252
    }// end loop over 'r'
 
2253
    
 
2254
    // Loop dofs and call evaluate_basis_derivatives.
 
2255
    for (unsigned int r = 0; r < 8; r++)
 
2256
    {
 
2257
      evaluate_basis_derivatives(r, n, dof_values, x, vertex_coordinates, cell_orientation);
 
2258
      for (unsigned int s = 0; s < 3*num_derivatives_g; s++)
 
2259
      {
 
2260
        values[r*3*num_derivatives_g + s] = dof_values[s];
 
2261
      }// end loop over 's'
 
2262
    }// end loop over 'r'
 
2263
    
 
2264
    // Delete pointer.
 
2265
    delete [] dof_values;
 
2266
  }
 
2267
 
 
2268
  /// Evaluate linear functional for dof i on the function f
 
2269
  virtual double evaluate_dof(std::size_t i,
 
2270
                              const ufc::function& f,
 
2271
                              const double* vertex_coordinates,
 
2272
                              int cell_orientation,
 
2273
                              const ufc::cell& c) const
 
2274
  {
 
2275
    // Declare variables for result of evaluation
 
2276
    double vals[3];
 
2277
    
 
2278
    // Declare variable for physical coordinates
 
2279
    double y[3];
 
2280
    
 
2281
    double result;
 
2282
    // Compute Jacobian
 
2283
    double J[6];
 
2284
    compute_jacobian_triangle_3d(J, vertex_coordinates);
 
2285
    
 
2286
    
 
2287
    // Compute Jacobian inverse and determinant
 
2288
    double K[6];
 
2289
    double detJ;
 
2290
    compute_jacobian_inverse_triangle_3d(K, detJ, J);
 
2291
    
 
2292
    
 
2293
    
 
2294
    // Check orientation
 
2295
    if (cell_orientation == -1)
 
2296
      throw std::runtime_error("cell orientation must be defined (not -1)");
 
2297
    // (If cell_orientation == 1 = down, multiply det(J) by -1)
 
2298
    else if (cell_orientation == 1)
 
2299
      detJ *= -1;
 
2300
    switch (i)
 
2301
    {
 
2302
    case 0:
 
2303
      {
 
2304
        y[0] = 0.66666667*vertex_coordinates[3] + 0.33333333*vertex_coordinates[6];
 
2305
      y[1] = 0.66666667*vertex_coordinates[4] + 0.33333333*vertex_coordinates[7];
 
2306
      y[2] = 0.66666667*vertex_coordinates[5] + 0.33333333*vertex_coordinates[8];
 
2307
      f.evaluate(vals, y, c);
 
2308
      result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2])) + (detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
2309
      return result;
 
2310
        break;
 
2311
      }
 
2312
    case 1:
 
2313
      {
 
2314
        y[0] = 0.33333333*vertex_coordinates[3] + 0.66666667*vertex_coordinates[6];
 
2315
      y[1] = 0.33333333*vertex_coordinates[4] + 0.66666667*vertex_coordinates[7];
 
2316
      y[2] = 0.33333333*vertex_coordinates[5] + 0.66666667*vertex_coordinates[8];
 
2317
      f.evaluate(vals, y, c);
 
2318
      result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2])) + (detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
2319
      return result;
 
2320
        break;
 
2321
      }
 
2322
    case 2:
 
2323
      {
 
2324
        y[0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[6];
 
2325
      y[1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[7];
 
2326
      y[2] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[8];
 
2327
      f.evaluate(vals, y, c);
 
2328
      result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2]));
 
2329
      return result;
 
2330
        break;
 
2331
      }
 
2332
    case 3:
 
2333
      {
 
2334
        y[0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[6];
 
2335
      y[1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[7];
 
2336
      y[2] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[8];
 
2337
      f.evaluate(vals, y, c);
 
2338
      result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2]));
 
2339
      return result;
 
2340
        break;
 
2341
      }
 
2342
    case 4:
 
2343
      {
 
2344
        y[0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[3];
 
2345
      y[1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[4];
 
2346
      y[2] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[5];
 
2347
      f.evaluate(vals, y, c);
 
2348
      result = (-1.0)*(detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
2349
      return result;
 
2350
        break;
 
2351
      }
 
2352
    case 5:
 
2353
      {
 
2354
        y[0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[3];
 
2355
      y[1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[4];
 
2356
      y[2] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[5];
 
2357
      f.evaluate(vals, y, c);
 
2358
      result = (-1.0)*(detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
2359
      return result;
 
2360
        break;
 
2361
      }
 
2362
    case 6:
 
2363
      {
 
2364
        y[0] = 0.33333333*vertex_coordinates[0] + 0.33333333*vertex_coordinates[3] + 0.33333333*vertex_coordinates[6];
 
2365
      y[1] = 0.33333333*vertex_coordinates[1] + 0.33333333*vertex_coordinates[4] + 0.33333333*vertex_coordinates[7];
 
2366
      y[2] = 0.33333333*vertex_coordinates[2] + 0.33333333*vertex_coordinates[5] + 0.33333333*vertex_coordinates[8];
 
2367
      f.evaluate(vals, y, c);
 
2368
      result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2]));
 
2369
      return result;
 
2370
        break;
 
2371
      }
 
2372
    case 7:
 
2373
      {
 
2374
        y[0] = 0.33333333*vertex_coordinates[0] + 0.33333333*vertex_coordinates[3] + 0.33333333*vertex_coordinates[6];
 
2375
      y[1] = 0.33333333*vertex_coordinates[1] + 0.33333333*vertex_coordinates[4] + 0.33333333*vertex_coordinates[7];
 
2376
      y[2] = 0.33333333*vertex_coordinates[2] + 0.33333333*vertex_coordinates[5] + 0.33333333*vertex_coordinates[8];
 
2377
      f.evaluate(vals, y, c);
 
2378
      result = (detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
2379
      return result;
 
2380
        break;
 
2381
      }
 
2382
    }
 
2383
    
 
2384
    return 0.0;
 
2385
  }
 
2386
 
 
2387
  /// Evaluate linear functionals for all dofs on the function f
 
2388
  virtual void evaluate_dofs(double* values,
 
2389
                             const ufc::function& f,
 
2390
                             const double* vertex_coordinates,
 
2391
                             int cell_orientation,
 
2392
                             const ufc::cell& c) const
 
2393
  {
 
2394
    // Declare variables for result of evaluation
 
2395
    double vals[3];
 
2396
    
 
2397
    // Declare variable for physical coordinates
 
2398
    double y[3];
 
2399
    
 
2400
    double result;
 
2401
    // Compute Jacobian
 
2402
    double J[6];
 
2403
    compute_jacobian_triangle_3d(J, vertex_coordinates);
 
2404
    
 
2405
    
 
2406
    // Compute Jacobian inverse and determinant
 
2407
    double K[6];
 
2408
    double detJ;
 
2409
    compute_jacobian_inverse_triangle_3d(K, detJ, J);
 
2410
    
 
2411
    
 
2412
    
 
2413
    // Check orientation
 
2414
    if (cell_orientation == -1)
 
2415
      throw std::runtime_error("cell orientation must be defined (not -1)");
 
2416
    // (If cell_orientation == 1 = down, multiply det(J) by -1)
 
2417
    else if (cell_orientation == 1)
 
2418
      detJ *= -1;
 
2419
    y[0] = 0.66666667*vertex_coordinates[3] + 0.33333333*vertex_coordinates[6];
 
2420
    y[1] = 0.66666667*vertex_coordinates[4] + 0.33333333*vertex_coordinates[7];
 
2421
    y[2] = 0.66666667*vertex_coordinates[5] + 0.33333333*vertex_coordinates[8];
 
2422
    f.evaluate(vals, y, c);
 
2423
    result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2])) + (detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
2424
    values[0] = result;
 
2425
    y[0] = 0.33333333*vertex_coordinates[3] + 0.66666667*vertex_coordinates[6];
 
2426
    y[1] = 0.33333333*vertex_coordinates[4] + 0.66666667*vertex_coordinates[7];
 
2427
    y[2] = 0.33333333*vertex_coordinates[5] + 0.66666667*vertex_coordinates[8];
 
2428
    f.evaluate(vals, y, c);
 
2429
    result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2])) + (detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
2430
    values[1] = result;
 
2431
    y[0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[6];
 
2432
    y[1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[7];
 
2433
    y[2] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[8];
 
2434
    f.evaluate(vals, y, c);
 
2435
    result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2]));
 
2436
    values[2] = result;
 
2437
    y[0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[6];
 
2438
    y[1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[7];
 
2439
    y[2] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[8];
 
2440
    f.evaluate(vals, y, c);
 
2441
    result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2]));
 
2442
    values[3] = result;
 
2443
    y[0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[3];
 
2444
    y[1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[4];
 
2445
    y[2] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[5];
 
2446
    f.evaluate(vals, y, c);
 
2447
    result = (-1.0)*(detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
2448
    values[4] = result;
 
2449
    y[0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[3];
 
2450
    y[1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[4];
 
2451
    y[2] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[5];
 
2452
    f.evaluate(vals, y, c);
 
2453
    result = (-1.0)*(detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
2454
    values[5] = result;
 
2455
    y[0] = 0.33333333*vertex_coordinates[0] + 0.33333333*vertex_coordinates[3] + 0.33333333*vertex_coordinates[6];
 
2456
    y[1] = 0.33333333*vertex_coordinates[1] + 0.33333333*vertex_coordinates[4] + 0.33333333*vertex_coordinates[7];
 
2457
    y[2] = 0.33333333*vertex_coordinates[2] + 0.33333333*vertex_coordinates[5] + 0.33333333*vertex_coordinates[8];
 
2458
    f.evaluate(vals, y, c);
 
2459
    result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2]));
 
2460
    values[6] = result;
 
2461
    y[0] = 0.33333333*vertex_coordinates[0] + 0.33333333*vertex_coordinates[3] + 0.33333333*vertex_coordinates[6];
 
2462
    y[1] = 0.33333333*vertex_coordinates[1] + 0.33333333*vertex_coordinates[4] + 0.33333333*vertex_coordinates[7];
 
2463
    y[2] = 0.33333333*vertex_coordinates[2] + 0.33333333*vertex_coordinates[5] + 0.33333333*vertex_coordinates[8];
 
2464
    f.evaluate(vals, y, c);
 
2465
    result = (detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
2466
    values[7] = result;
 
2467
  }
 
2468
 
 
2469
  /// Interpolate vertex values from dof values
 
2470
  virtual void interpolate_vertex_values(double* vertex_values,
 
2471
                                         const double* dof_values,
 
2472
                                         const double* vertex_coordinates,
 
2473
                                         int cell_orientation,
 
2474
                                         const ufc::cell& c) const
 
2475
  {
 
2476
    // Compute Jacobian
 
2477
    double J[6];
 
2478
    compute_jacobian_triangle_3d(J, vertex_coordinates);
 
2479
    
 
2480
    
 
2481
    // Compute Jacobian inverse and determinant
 
2482
    double K[6];
 
2483
    double detJ;
 
2484
    compute_jacobian_inverse_triangle_3d(K, detJ, J);
 
2485
    
 
2486
    
 
2487
    
 
2488
    // Check orientation
 
2489
    if (cell_orientation == -1)
 
2490
      throw std::runtime_error("cell orientation must be defined (not -1)");
 
2491
    // (If cell_orientation == 1 = down, multiply det(J) by -1)
 
2492
    else if (cell_orientation == 1)
 
2493
      detJ *= -1;
 
2494
    
 
2495
    // Evaluate function and change variables
 
2496
    vertex_values[0] = dof_values[2]*(1.0/detJ)*J[0]*2.0 + dof_values[3]*((1.0/detJ)*(J[0]*(-1.0))) + dof_values[4]*((1.0/detJ)*(J[1]*(-2.0))) + dof_values[5]*(1.0/detJ)*J[1];
 
2497
    vertex_values[2] = dof_values[0]*(1.0/detJ)*J[0]*2.0 + dof_values[1]*((1.0/detJ)*(J[0]*(-1.0))) + dof_values[4]*((1.0/detJ)*(J[0]*(-1.0) + J[1])) + dof_values[5]*((1.0/detJ)*(J[0]*2.0 + J[1]*(-2.0)));
 
2498
    vertex_values[4] = dof_values[0]*((1.0/detJ)*(J[1]*(-1.0))) + dof_values[1]*(1.0/detJ)*J[1]*2.0 + dof_values[2]*((1.0/detJ)*(J[0]*(-1.0) + J[1])) + dof_values[3]*((1.0/detJ)*(J[0]*2.0 + J[1]*(-2.0)));
 
2499
    vertex_values[1] = dof_values[2]*(1.0/detJ)*J[2]*2.0 + dof_values[3]*((1.0/detJ)*(J[2]*(-1.0))) + dof_values[4]*((1.0/detJ)*(J[3]*(-2.0))) + dof_values[5]*(1.0/detJ)*J[3];
 
2500
    vertex_values[3] = dof_values[0]*(1.0/detJ)*J[2]*2.0 + dof_values[1]*((1.0/detJ)*(J[2]*(-1.0))) + dof_values[4]*((1.0/detJ)*(J[2]*(-1.0) + J[3])) + dof_values[5]*((1.0/detJ)*(J[2]*2.0 + J[3]*(-2.0)));
 
2501
    vertex_values[5] = dof_values[0]*((1.0/detJ)*(J[3]*(-1.0))) + dof_values[1]*(1.0/detJ)*J[3]*2.0 + dof_values[2]*((1.0/detJ)*(J[2]*(-1.0) + J[3])) + dof_values[3]*((1.0/detJ)*(J[2]*2.0 + J[3]*(-2.0)));
 
2502
  }
 
2503
 
 
2504
  /// Map coordinate xhat from reference cell to coordinate x in cell
 
2505
  virtual void map_from_reference_cell(double* x,
 
2506
                                       const double* xhat,
 
2507
                                       const ufc::cell& c) const
 
2508
  {
 
2509
    std::cerr << "*** FFC warning: " << "map_from_reference_cell not yet implemented." << std::endl;
 
2510
  }
 
2511
 
 
2512
  /// Map from coordinate x in cell to coordinate xhat in reference cell
 
2513
  virtual void map_to_reference_cell(double* xhat,
 
2514
                                     const double* x,
 
2515
                                     const ufc::cell& c) const
 
2516
  {
 
2517
    std::cerr << "*** FFC warning: " << "map_to_reference_cell not yet implemented." << std::endl;
 
2518
  }
 
2519
 
 
2520
  /// Return the number of sub elements (for a mixed element)
 
2521
  virtual std::size_t num_sub_elements() const
 
2522
  {
 
2523
    return 0;
 
2524
  }
 
2525
 
 
2526
  /// Create a new finite element for sub element i (for a mixed element)
 
2527
  virtual ufc::finite_element* create_sub_element(std::size_t i) const
 
2528
  {
 
2529
    return 0;
 
2530
  }
 
2531
 
 
2532
  /// Create a new class instance
 
2533
  virtual ufc::finite_element* create() const
 
2534
  {
 
2535
    return new x_element9_finite_element_0();
 
2536
  }
 
2537
 
 
2538
};
 
2539
 
 
2540
/// This class defines the interface for a finite element.
 
2541
 
 
2542
class x_element9_finite_element_1: public ufc::finite_element
 
2543
{
 
2544
public:
 
2545
 
 
2546
  /// Constructor
 
2547
  x_element9_finite_element_1() : ufc::finite_element()
 
2548
  {
 
2549
    // Do nothing
 
2550
  }
 
2551
 
 
2552
  /// Destructor
 
2553
  virtual ~x_element9_finite_element_1()
 
2554
  {
 
2555
    // Do nothing
 
2556
  }
 
2557
 
 
2558
  /// Return a string identifying the finite element
 
2559
  virtual const char* signature() const
 
2560
  {
 
2561
    return "FiniteElement('Brezzi-Douglas-Marini', Domain(Cell('triangle', 3), 'triangle_multiverse', 3, 2), 1, None)";
 
2562
  }
 
2563
 
 
2564
  /// Return the cell shape
 
2565
  virtual ufc::shape cell_shape() const
 
2566
  {
 
2567
    return ufc::triangle;
 
2568
  }
 
2569
 
 
2570
  /// Return the topological dimension of the cell shape
 
2571
  virtual std::size_t topological_dimension() const
 
2572
  {
 
2573
    return 2;
 
2574
  }
 
2575
 
 
2576
  /// Return the geometric dimension of the cell shape
 
2577
  virtual std::size_t geometric_dimension() const
 
2578
  {
 
2579
    return 3;
 
2580
  }
 
2581
 
 
2582
  /// Return the dimension of the finite element function space
 
2583
  virtual std::size_t space_dimension() const
 
2584
  {
 
2585
    return 6;
 
2586
  }
 
2587
 
 
2588
  /// Return the rank of the value space
 
2589
  virtual std::size_t value_rank() const
 
2590
  {
 
2591
    return 1;
 
2592
  }
 
2593
 
 
2594
  /// Return the dimension of the value space for axis i
 
2595
  virtual std::size_t value_dimension(std::size_t i) const
 
2596
  {
 
2597
    switch (i)
 
2598
    {
 
2599
    case 0:
 
2600
      {
 
2601
        return 3;
 
2602
        break;
 
2603
      }
 
2604
    }
 
2605
    
 
2606
    return 0;
 
2607
  }
 
2608
 
 
2609
  /// Evaluate basis function i at given point x in cell
 
2610
  virtual void evaluate_basis(std::size_t i,
 
2611
                              double* values,
 
2612
                              const double* x,
 
2613
                              const double* vertex_coordinates,
 
2614
                              int cell_orientation) const
 
2615
  {
 
2616
    // Compute Jacobian
 
2617
    double J[6];
 
2618
    compute_jacobian_triangle_3d(J, vertex_coordinates);
 
2619
    
 
2620
    // Compute Jacobian inverse and determinant
 
2621
    double K[6];
 
2622
    double detJ;
 
2623
    compute_jacobian_inverse_triangle_3d(K, detJ, J);
 
2624
    
 
2625
    
 
2626
    // Check orientation
 
2627
    if (cell_orientation == -1)
 
2628
      throw std::runtime_error("cell orientation must be defined (not -1)");
 
2629
    // (If cell_orientation == 1 = down, multiply det(J) by -1)
 
2630
    else if (cell_orientation == 1)
 
2631
      detJ *= -1;
 
2632
    
 
2633
    
 
2634
    const double b0 = vertex_coordinates[0];
 
2635
    const double b1 = vertex_coordinates[1];
 
2636
    const double b2 = vertex_coordinates[2];
 
2637
    
 
2638
    // P_FFC = J^dag (p - b), P_FIAT = 2*P_FFC - (1, 1)
 
2639
    double X = 2*(K[0]*(x[0] - b0) + K[1]*(x[1] - b1) + K[2]*(x[2] - b2)) - 1.0;
 
2640
    double Y = 2*(K[3]*(x[0] - b0) + K[4]*(x[1] - b1) + K[5]*(x[2] - b2)) - 1.0;
 
2641
    
 
2642
    
 
2643
    // Reset values
 
2644
    values[0] = 0.0;
 
2645
    values[1] = 0.0;
 
2646
    switch (i)
 
2647
    {
 
2648
    case 0:
 
2649
      {
 
2650
        
 
2651
      // Array of basisvalues
 
2652
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
2653
      
 
2654
      // Declare helper variables
 
2655
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
2656
      
 
2657
      // Compute basisvalues
 
2658
      basisvalues[0] = 1.0;
 
2659
      basisvalues[1] = tmp0;
 
2660
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
2661
      basisvalues[0] *= std::sqrt(0.5);
 
2662
      basisvalues[2] *= std::sqrt(1.0);
 
2663
      basisvalues[1] *= std::sqrt(3.0);
 
2664
      
 
2665
      // Table(s) of coefficients
 
2666
      static const double coefficients0[3] = \
 
2667
      {0.94280904, 0.57735027, -0.33333333};
 
2668
      
 
2669
      static const double coefficients1[3] = \
 
2670
      {-0.47140452, 0.0, -0.33333333};
 
2671
      
 
2672
      // Compute value(s)
 
2673
      for (unsigned int r = 0; r < 3; r++)
 
2674
      {
 
2675
        values[0] += coefficients0[r]*basisvalues[r];
 
2676
        values[1] += coefficients1[r]*basisvalues[r];
 
2677
      }// end loop over 'r'
 
2678
      
 
2679
      // Using contravariant Piola transform to map values back to the physical element
 
2680
      const double tmp_ref0 = values[0];
 
2681
      const double tmp_ref1 = values[1];
 
2682
      values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
2683
      values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
2684
      values[2] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
2685
        break;
 
2686
      }
 
2687
    case 1:
 
2688
      {
 
2689
        
 
2690
      // Array of basisvalues
 
2691
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
2692
      
 
2693
      // Declare helper variables
 
2694
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
2695
      
 
2696
      // Compute basisvalues
 
2697
      basisvalues[0] = 1.0;
 
2698
      basisvalues[1] = tmp0;
 
2699
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
2700
      basisvalues[0] *= std::sqrt(0.5);
 
2701
      basisvalues[2] *= std::sqrt(1.0);
 
2702
      basisvalues[1] *= std::sqrt(3.0);
 
2703
      
 
2704
      // Table(s) of coefficients
 
2705
      static const double coefficients0[3] = \
 
2706
      {-0.47140452, -0.28867513, 0.16666667};
 
2707
      
 
2708
      static const double coefficients1[3] = \
 
2709
      {0.94280904, 0.0, 0.66666667};
 
2710
      
 
2711
      // Compute value(s)
 
2712
      for (unsigned int r = 0; r < 3; r++)
 
2713
      {
 
2714
        values[0] += coefficients0[r]*basisvalues[r];
 
2715
        values[1] += coefficients1[r]*basisvalues[r];
 
2716
      }// end loop over 'r'
 
2717
      
 
2718
      // Using contravariant Piola transform to map values back to the physical element
 
2719
      const double tmp_ref0 = values[0];
 
2720
      const double tmp_ref1 = values[1];
 
2721
      values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
2722
      values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
2723
      values[2] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
2724
        break;
 
2725
      }
 
2726
    case 2:
 
2727
      {
 
2728
        
 
2729
      // Array of basisvalues
 
2730
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
2731
      
 
2732
      // Declare helper variables
 
2733
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
2734
      
 
2735
      // Compute basisvalues
 
2736
      basisvalues[0] = 1.0;
 
2737
      basisvalues[1] = tmp0;
 
2738
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
2739
      basisvalues[0] *= std::sqrt(0.5);
 
2740
      basisvalues[2] *= std::sqrt(1.0);
 
2741
      basisvalues[1] *= std::sqrt(3.0);
 
2742
      
 
2743
      // Table(s) of coefficients
 
2744
      static const double coefficients0[3] = \
 
2745
      {0.47140452, -0.57735027, -0.66666667};
 
2746
      
 
2747
      static const double coefficients1[3] = \
 
2748
      {0.47140452, 0.0, 0.33333333};
 
2749
      
 
2750
      // Compute value(s)
 
2751
      for (unsigned int r = 0; r < 3; r++)
 
2752
      {
 
2753
        values[0] += coefficients0[r]*basisvalues[r];
 
2754
        values[1] += coefficients1[r]*basisvalues[r];
 
2755
      }// end loop over 'r'
 
2756
      
 
2757
      // Using contravariant Piola transform to map values back to the physical element
 
2758
      const double tmp_ref0 = values[0];
 
2759
      const double tmp_ref1 = values[1];
 
2760
      values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
2761
      values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
2762
      values[2] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
2763
        break;
 
2764
      }
 
2765
    case 3:
 
2766
      {
 
2767
        
 
2768
      // Array of basisvalues
 
2769
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
2770
      
 
2771
      // Declare helper variables
 
2772
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
2773
      
 
2774
      // Compute basisvalues
 
2775
      basisvalues[0] = 1.0;
 
2776
      basisvalues[1] = tmp0;
 
2777
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
2778
      basisvalues[0] *= std::sqrt(0.5);
 
2779
      basisvalues[2] *= std::sqrt(1.0);
 
2780
      basisvalues[1] *= std::sqrt(3.0);
 
2781
      
 
2782
      // Table(s) of coefficients
 
2783
      static const double coefficients0[3] = \
 
2784
      {0.47140452, 0.28867513, 0.83333333};
 
2785
      
 
2786
      static const double coefficients1[3] = \
 
2787
      {-0.94280904, 0.0, -0.66666667};
 
2788
      
 
2789
      // Compute value(s)
 
2790
      for (unsigned int r = 0; r < 3; r++)
 
2791
      {
 
2792
        values[0] += coefficients0[r]*basisvalues[r];
 
2793
        values[1] += coefficients1[r]*basisvalues[r];
 
2794
      }// end loop over 'r'
 
2795
      
 
2796
      // Using contravariant Piola transform to map values back to the physical element
 
2797
      const double tmp_ref0 = values[0];
 
2798
      const double tmp_ref1 = values[1];
 
2799
      values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
2800
      values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
2801
      values[2] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
2802
        break;
 
2803
      }
 
2804
    case 4:
 
2805
      {
 
2806
        
 
2807
      // Array of basisvalues
 
2808
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
2809
      
 
2810
      // Declare helper variables
 
2811
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
2812
      
 
2813
      // Compute basisvalues
 
2814
      basisvalues[0] = 1.0;
 
2815
      basisvalues[1] = tmp0;
 
2816
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
2817
      basisvalues[0] *= std::sqrt(0.5);
 
2818
      basisvalues[2] *= std::sqrt(1.0);
 
2819
      basisvalues[1] *= std::sqrt(3.0);
 
2820
      
 
2821
      // Table(s) of coefficients
 
2822
      static const double coefficients0[3] = \
 
2823
      {-0.47140452, -0.28867513, 0.16666667};
 
2824
      
 
2825
      static const double coefficients1[3] = \
 
2826
      {-0.47140452, 0.8660254, 0.16666667};
 
2827
      
 
2828
      // Compute value(s)
 
2829
      for (unsigned int r = 0; r < 3; r++)
 
2830
      {
 
2831
        values[0] += coefficients0[r]*basisvalues[r];
 
2832
        values[1] += coefficients1[r]*basisvalues[r];
 
2833
      }// end loop over 'r'
 
2834
      
 
2835
      // Using contravariant Piola transform to map values back to the physical element
 
2836
      const double tmp_ref0 = values[0];
 
2837
      const double tmp_ref1 = values[1];
 
2838
      values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
2839
      values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
2840
      values[2] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
2841
        break;
 
2842
      }
 
2843
    case 5:
 
2844
      {
 
2845
        
 
2846
      // Array of basisvalues
 
2847
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
2848
      
 
2849
      // Declare helper variables
 
2850
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
2851
      
 
2852
      // Compute basisvalues
 
2853
      basisvalues[0] = 1.0;
 
2854
      basisvalues[1] = tmp0;
 
2855
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
2856
      basisvalues[0] *= std::sqrt(0.5);
 
2857
      basisvalues[2] *= std::sqrt(1.0);
 
2858
      basisvalues[1] *= std::sqrt(3.0);
 
2859
      
 
2860
      // Table(s) of coefficients
 
2861
      static const double coefficients0[3] = \
 
2862
      {0.94280904, 0.57735027, -0.33333333};
 
2863
      
 
2864
      static const double coefficients1[3] = \
 
2865
      {-0.47140452, -0.8660254, 0.16666667};
 
2866
      
 
2867
      // Compute value(s)
 
2868
      for (unsigned int r = 0; r < 3; r++)
 
2869
      {
 
2870
        values[0] += coefficients0[r]*basisvalues[r];
 
2871
        values[1] += coefficients1[r]*basisvalues[r];
 
2872
      }// end loop over 'r'
 
2873
      
 
2874
      // Using contravariant Piola transform to map values back to the physical element
 
2875
      const double tmp_ref0 = values[0];
 
2876
      const double tmp_ref1 = values[1];
 
2877
      values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
2878
      values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
2879
      values[2] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
2880
        break;
 
2881
      }
 
2882
    }
 
2883
    
 
2884
  }
 
2885
 
 
2886
  /// Evaluate all basis functions at given point x in cell
 
2887
  virtual void evaluate_basis_all(double* values,
 
2888
                                  const double* x,
 
2889
                                  const double* vertex_coordinates,
 
2890
                                  int cell_orientation) const
 
2891
  {
 
2892
    // Helper variable to hold values of a single dof.
 
2893
    double dof_values[3] = {0.0, 0.0, 0.0};
 
2894
    
 
2895
    // Loop dofs and call evaluate_basis
 
2896
    for (unsigned int r = 0; r < 6; r++)
 
2897
    {
 
2898
      evaluate_basis(r, dof_values, x, vertex_coordinates, cell_orientation);
 
2899
      for (unsigned int s = 0; s < 3; s++)
 
2900
      {
 
2901
        values[r*3 + s] = dof_values[s];
 
2902
      }// end loop over 's'
 
2903
    }// end loop over 'r'
 
2904
  }
 
2905
 
 
2906
  /// Evaluate order n derivatives of basis function i at given point x in cell
 
2907
  virtual void evaluate_basis_derivatives(std::size_t i,
 
2908
                                          std::size_t n,
 
2909
                                          double* values,
 
2910
                                          const double* x,
 
2911
                                          const double* vertex_coordinates,
 
2912
                                          int cell_orientation) const
 
2913
  {
 
2914
    // Compute Jacobian
 
2915
    double J[6];
 
2916
    compute_jacobian_triangle_3d(J, vertex_coordinates);
 
2917
    
 
2918
    // Compute Jacobian inverse and determinant
 
2919
    double K[6];
 
2920
    double detJ;
 
2921
    compute_jacobian_inverse_triangle_3d(K, detJ, J);
 
2922
    
 
2923
    
 
2924
    // Check orientation
 
2925
    if (cell_orientation == -1)
 
2926
      throw std::runtime_error("cell orientation must be defined (not -1)");
 
2927
    // (If cell_orientation == 1 = down, multiply det(J) by -1)
 
2928
    else if (cell_orientation == 1)
 
2929
      detJ *= -1;
 
2930
    
 
2931
    
 
2932
    const double b0 = vertex_coordinates[0];
 
2933
    const double b1 = vertex_coordinates[1];
 
2934
    const double b2 = vertex_coordinates[2];
 
2935
    
 
2936
    // P_FFC = J^dag (p - b), P_FIAT = 2*P_FFC - (1, 1)
 
2937
    double X = 2*(K[0]*(x[0] - b0) + K[1]*(x[1] - b1) + K[2]*(x[2] - b2)) - 1.0;
 
2938
    double Y = 2*(K[3]*(x[0] - b0) + K[4]*(x[1] - b1) + K[5]*(x[2] - b2)) - 1.0;
 
2939
    
 
2940
    
 
2941
    // Compute number of derivatives.
 
2942
    unsigned int num_derivatives_t = 1;
 
2943
    for (unsigned int r = 0; r < n; r++)
 
2944
    {
 
2945
      num_derivatives_t *= 2;
 
2946
    }// end loop over 'r'
 
2947
    
 
2948
    // Compute number of derivatives.
 
2949
    unsigned int num_derivatives_g = 1;
 
2950
    for (unsigned int r = 0; r < n; r++)
 
2951
    {
 
2952
      num_derivatives_g *= 3;
 
2953
    }// end loop over 'r'
 
2954
    
 
2955
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
2956
    unsigned int **combinations_t = new unsigned int *[num_derivatives_t];
 
2957
    for (unsigned int row = 0; row < num_derivatives_t; row++)
 
2958
    {
 
2959
      combinations_t[row] = new unsigned int [n];
 
2960
      for (unsigned int col = 0; col < n; col++)
 
2961
        combinations_t[row][col] = 0;
 
2962
    }
 
2963
    
 
2964
    // Generate combinations of derivatives
 
2965
    for (unsigned int row = 1; row < num_derivatives_t; row++)
 
2966
    {
 
2967
      for (unsigned int num = 0; num < row; num++)
 
2968
      {
 
2969
        for (unsigned int col = n-1; col+1 > 0; col--)
 
2970
        {
 
2971
          if (combinations_t[row][col] + 1 > 1)
 
2972
            combinations_t[row][col] = 0;
 
2973
          else
 
2974
          {
 
2975
            combinations_t[row][col] += 1;
 
2976
            break;
 
2977
          }
 
2978
        }
 
2979
      }
 
2980
    }
 
2981
    
 
2982
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
2983
    unsigned int **combinations_g = new unsigned int *[num_derivatives_g];
 
2984
    for (unsigned int row = 0; row < num_derivatives_g; row++)
 
2985
    {
 
2986
      combinations_g[row] = new unsigned int [n];
 
2987
      for (unsigned int col = 0; col < n; col++)
 
2988
        combinations_g[row][col] = 0;
 
2989
    }
 
2990
    
 
2991
    // Generate combinations of derivatives
 
2992
    for (unsigned int row = 1; row < num_derivatives_g; row++)
 
2993
    {
 
2994
      for (unsigned int num = 0; num < row; num++)
 
2995
      {
 
2996
        for (unsigned int col = n-1; col+1 > 0; col--)
 
2997
        {
 
2998
          if (combinations_g[row][col] + 1 > 2)
 
2999
            combinations_g[row][col] = 0;
 
3000
          else
 
3001
          {
 
3002
            combinations_g[row][col] += 1;
 
3003
            break;
 
3004
          }
 
3005
        }
 
3006
      }
 
3007
    }
 
3008
    
 
3009
    // Compute inverse of Jacobian
 
3010
    const double Jinv[2][3] = {{K[0], K[1], K[2]}, {K[3], K[4], K[5]}};
 
3011
    
 
3012
    // Declare transformation matrix
 
3013
    // Declare pointer to two dimensional array and initialise
 
3014
    double **transform = new double *[num_derivatives_g];
 
3015
    
 
3016
    for (unsigned int j = 0; j < num_derivatives_g; j++)
 
3017
    {
 
3018
      transform[j] = new double [num_derivatives_t];
 
3019
      for (unsigned int k = 0; k < num_derivatives_t; k++)
 
3020
        transform[j][k] = 1;
 
3021
    }
 
3022
    
 
3023
    // Construct transformation matrix
 
3024
    for (unsigned int row = 0; row < num_derivatives_g; row++)
 
3025
    {
 
3026
      for (unsigned int col = 0; col < num_derivatives_t; col++)
 
3027
      {
 
3028
        for (unsigned int k = 0; k < n; k++)
 
3029
          transform[row][col] *= Jinv[combinations_t[col][k]][combinations_g[row][k]];
 
3030
      }
 
3031
    }
 
3032
    
 
3033
    // Reset values. Assuming that values is always an array.
 
3034
    for (unsigned int r = 0; r < 3*num_derivatives_g; r++)
 
3035
    {
 
3036
      values[r] = 0.0;
 
3037
    }// end loop over 'r'
 
3038
    
 
3039
    switch (i)
 
3040
    {
 
3041
    case 0:
 
3042
      {
 
3043
        
 
3044
      // Array of basisvalues
 
3045
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
3046
      
 
3047
      // Declare helper variables
 
3048
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
3049
      
 
3050
      // Compute basisvalues
 
3051
      basisvalues[0] = 1.0;
 
3052
      basisvalues[1] = tmp0;
 
3053
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
3054
      basisvalues[0] *= std::sqrt(0.5);
 
3055
      basisvalues[2] *= std::sqrt(1.0);
 
3056
      basisvalues[1] *= std::sqrt(3.0);
 
3057
      
 
3058
      // Table(s) of coefficients
 
3059
      static const double coefficients0[3] = \
 
3060
      {0.94280904, 0.57735027, -0.33333333};
 
3061
      
 
3062
      static const double coefficients1[3] = \
 
3063
      {-0.47140452, 0.0, -0.33333333};
 
3064
      
 
3065
      // Tables of derivatives of the polynomial base (transpose).
 
3066
      static const double dmats0[3][3] = \
 
3067
      {{0.0, 0.0, 0.0},
 
3068
      {4.8989795, 0.0, 0.0},
 
3069
      {0.0, 0.0, 0.0}};
 
3070
      
 
3071
      static const double dmats1[3][3] = \
 
3072
      {{0.0, 0.0, 0.0},
 
3073
      {2.4494897, 0.0, 0.0},
 
3074
      {4.2426407, 0.0, 0.0}};
 
3075
      
 
3076
      // Compute reference derivatives.
 
3077
      // Declare pointer to array of derivatives on FIAT element.
 
3078
      double *derivatives = new double[2*num_derivatives_t];
 
3079
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
3080
      {
 
3081
        derivatives[r] = 0.0;
 
3082
      }// end loop over 'r'
 
3083
      
 
3084
      // Declare pointer to array of reference derivatives on physical element.
 
3085
      double *derivatives_p = new double[3*num_derivatives_t];
 
3086
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
3087
      {
 
3088
        derivatives_p[r] = 0.0;
 
3089
      }// end loop over 'r'
 
3090
      
 
3091
      // Declare derivative matrix (of polynomial basis).
 
3092
      double dmats[3][3] = \
 
3093
      {{1.0, 0.0, 0.0},
 
3094
      {0.0, 1.0, 0.0},
 
3095
      {0.0, 0.0, 1.0}};
 
3096
      
 
3097
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
3098
      double dmats_old[3][3] = \
 
3099
      {{1.0, 0.0, 0.0},
 
3100
      {0.0, 1.0, 0.0},
 
3101
      {0.0, 0.0, 1.0}};
 
3102
      
 
3103
      // Loop possible derivatives.
 
3104
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
3105
      {
 
3106
        // Resetting dmats values to compute next derivative.
 
3107
        for (unsigned int t = 0; t < 3; t++)
 
3108
        {
 
3109
          for (unsigned int u = 0; u < 3; u++)
 
3110
          {
 
3111
            dmats[t][u] = 0.0;
 
3112
            if (t == u)
 
3113
            {
 
3114
            dmats[t][u] = 1.0;
 
3115
            }
 
3116
            
 
3117
          }// end loop over 'u'
 
3118
        }// end loop over 't'
 
3119
        
 
3120
        // Looping derivative order to generate dmats.
 
3121
        for (unsigned int s = 0; s < n; s++)
 
3122
        {
 
3123
          // Updating dmats_old with new values and resetting dmats.
 
3124
          for (unsigned int t = 0; t < 3; t++)
 
3125
          {
 
3126
            for (unsigned int u = 0; u < 3; u++)
 
3127
            {
 
3128
              dmats_old[t][u] = dmats[t][u];
 
3129
              dmats[t][u] = 0.0;
 
3130
            }// end loop over 'u'
 
3131
          }// end loop over 't'
 
3132
          
 
3133
          // Update dmats using an inner product.
 
3134
          if (combinations_t[r][s] == 0)
 
3135
          {
 
3136
          for (unsigned int t = 0; t < 3; t++)
 
3137
          {
 
3138
            for (unsigned int u = 0; u < 3; u++)
 
3139
            {
 
3140
              for (unsigned int tu = 0; tu < 3; tu++)
 
3141
              {
 
3142
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
3143
              }// end loop over 'tu'
 
3144
            }// end loop over 'u'
 
3145
          }// end loop over 't'
 
3146
          }
 
3147
          
 
3148
          if (combinations_t[r][s] == 1)
 
3149
          {
 
3150
          for (unsigned int t = 0; t < 3; t++)
 
3151
          {
 
3152
            for (unsigned int u = 0; u < 3; u++)
 
3153
            {
 
3154
              for (unsigned int tu = 0; tu < 3; tu++)
 
3155
              {
 
3156
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
3157
              }// end loop over 'tu'
 
3158
            }// end loop over 'u'
 
3159
          }// end loop over 't'
 
3160
          }
 
3161
          
 
3162
        }// end loop over 's'
 
3163
        for (unsigned int s = 0; s < 3; s++)
 
3164
        {
 
3165
          for (unsigned int t = 0; t < 3; t++)
 
3166
          {
 
3167
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
3168
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
3169
          }// end loop over 't'
 
3170
        }// end loop over 's'
 
3171
        
 
3172
        // Using contravariant Piola transform to map values back to the physical element.
 
3173
        const double tmp_ref0 = derivatives[r];
 
3174
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
3175
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
3176
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
3177
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
3178
      }// end loop over 'r'
 
3179
      
 
3180
      // Transform derivatives back to physical element
 
3181
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
3182
      {
 
3183
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
3184
        {
 
3185
          values[r] += transform[r][s]*derivatives_p[s];
 
3186
          values[num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
3187
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
3188
        }// end loop over 's'
 
3189
      }// end loop over 'r'
 
3190
      
 
3191
      // Delete pointer to array of derivatives on FIAT element
 
3192
      delete [] derivatives;
 
3193
      
 
3194
      // Delete pointer to array of reference derivatives on physical element.
 
3195
      delete [] derivatives_p;
 
3196
      
 
3197
      // Delete pointer to array of combinations of derivatives and transform
 
3198
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
3199
      {
 
3200
        delete [] combinations_t[r];
 
3201
      }// end loop over 'r'
 
3202
      delete [] combinations_t;
 
3203
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
3204
      {
 
3205
        delete [] combinations_g[r];
 
3206
      }// end loop over 'r'
 
3207
      delete [] combinations_g;
 
3208
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
3209
      {
 
3210
        delete [] transform[r];
 
3211
      }// end loop over 'r'
 
3212
      delete [] transform;
 
3213
        break;
 
3214
      }
 
3215
    case 1:
 
3216
      {
 
3217
        
 
3218
      // Array of basisvalues
 
3219
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
3220
      
 
3221
      // Declare helper variables
 
3222
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
3223
      
 
3224
      // Compute basisvalues
 
3225
      basisvalues[0] = 1.0;
 
3226
      basisvalues[1] = tmp0;
 
3227
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
3228
      basisvalues[0] *= std::sqrt(0.5);
 
3229
      basisvalues[2] *= std::sqrt(1.0);
 
3230
      basisvalues[1] *= std::sqrt(3.0);
 
3231
      
 
3232
      // Table(s) of coefficients
 
3233
      static const double coefficients0[3] = \
 
3234
      {-0.47140452, -0.28867513, 0.16666667};
 
3235
      
 
3236
      static const double coefficients1[3] = \
 
3237
      {0.94280904, 0.0, 0.66666667};
 
3238
      
 
3239
      // Tables of derivatives of the polynomial base (transpose).
 
3240
      static const double dmats0[3][3] = \
 
3241
      {{0.0, 0.0, 0.0},
 
3242
      {4.8989795, 0.0, 0.0},
 
3243
      {0.0, 0.0, 0.0}};
 
3244
      
 
3245
      static const double dmats1[3][3] = \
 
3246
      {{0.0, 0.0, 0.0},
 
3247
      {2.4494897, 0.0, 0.0},
 
3248
      {4.2426407, 0.0, 0.0}};
 
3249
      
 
3250
      // Compute reference derivatives.
 
3251
      // Declare pointer to array of derivatives on FIAT element.
 
3252
      double *derivatives = new double[2*num_derivatives_t];
 
3253
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
3254
      {
 
3255
        derivatives[r] = 0.0;
 
3256
      }// end loop over 'r'
 
3257
      
 
3258
      // Declare pointer to array of reference derivatives on physical element.
 
3259
      double *derivatives_p = new double[3*num_derivatives_t];
 
3260
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
3261
      {
 
3262
        derivatives_p[r] = 0.0;
 
3263
      }// end loop over 'r'
 
3264
      
 
3265
      // Declare derivative matrix (of polynomial basis).
 
3266
      double dmats[3][3] = \
 
3267
      {{1.0, 0.0, 0.0},
 
3268
      {0.0, 1.0, 0.0},
 
3269
      {0.0, 0.0, 1.0}};
 
3270
      
 
3271
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
3272
      double dmats_old[3][3] = \
 
3273
      {{1.0, 0.0, 0.0},
 
3274
      {0.0, 1.0, 0.0},
 
3275
      {0.0, 0.0, 1.0}};
 
3276
      
 
3277
      // Loop possible derivatives.
 
3278
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
3279
      {
 
3280
        // Resetting dmats values to compute next derivative.
 
3281
        for (unsigned int t = 0; t < 3; t++)
 
3282
        {
 
3283
          for (unsigned int u = 0; u < 3; u++)
 
3284
          {
 
3285
            dmats[t][u] = 0.0;
 
3286
            if (t == u)
 
3287
            {
 
3288
            dmats[t][u] = 1.0;
 
3289
            }
 
3290
            
 
3291
          }// end loop over 'u'
 
3292
        }// end loop over 't'
 
3293
        
 
3294
        // Looping derivative order to generate dmats.
 
3295
        for (unsigned int s = 0; s < n; s++)
 
3296
        {
 
3297
          // Updating dmats_old with new values and resetting dmats.
 
3298
          for (unsigned int t = 0; t < 3; t++)
 
3299
          {
 
3300
            for (unsigned int u = 0; u < 3; u++)
 
3301
            {
 
3302
              dmats_old[t][u] = dmats[t][u];
 
3303
              dmats[t][u] = 0.0;
 
3304
            }// end loop over 'u'
 
3305
          }// end loop over 't'
 
3306
          
 
3307
          // Update dmats using an inner product.
 
3308
          if (combinations_t[r][s] == 0)
 
3309
          {
 
3310
          for (unsigned int t = 0; t < 3; t++)
 
3311
          {
 
3312
            for (unsigned int u = 0; u < 3; u++)
 
3313
            {
 
3314
              for (unsigned int tu = 0; tu < 3; tu++)
 
3315
              {
 
3316
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
3317
              }// end loop over 'tu'
 
3318
            }// end loop over 'u'
 
3319
          }// end loop over 't'
 
3320
          }
 
3321
          
 
3322
          if (combinations_t[r][s] == 1)
 
3323
          {
 
3324
          for (unsigned int t = 0; t < 3; t++)
 
3325
          {
 
3326
            for (unsigned int u = 0; u < 3; u++)
 
3327
            {
 
3328
              for (unsigned int tu = 0; tu < 3; tu++)
 
3329
              {
 
3330
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
3331
              }// end loop over 'tu'
 
3332
            }// end loop over 'u'
 
3333
          }// end loop over 't'
 
3334
          }
 
3335
          
 
3336
        }// end loop over 's'
 
3337
        for (unsigned int s = 0; s < 3; s++)
 
3338
        {
 
3339
          for (unsigned int t = 0; t < 3; t++)
 
3340
          {
 
3341
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
3342
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
3343
          }// end loop over 't'
 
3344
        }// end loop over 's'
 
3345
        
 
3346
        // Using contravariant Piola transform to map values back to the physical element.
 
3347
        const double tmp_ref0 = derivatives[r];
 
3348
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
3349
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
3350
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
3351
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
3352
      }// end loop over 'r'
 
3353
      
 
3354
      // Transform derivatives back to physical element
 
3355
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
3356
      {
 
3357
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
3358
        {
 
3359
          values[r] += transform[r][s]*derivatives_p[s];
 
3360
          values[num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
3361
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
3362
        }// end loop over 's'
 
3363
      }// end loop over 'r'
 
3364
      
 
3365
      // Delete pointer to array of derivatives on FIAT element
 
3366
      delete [] derivatives;
 
3367
      
 
3368
      // Delete pointer to array of reference derivatives on physical element.
 
3369
      delete [] derivatives_p;
 
3370
      
 
3371
      // Delete pointer to array of combinations of derivatives and transform
 
3372
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
3373
      {
 
3374
        delete [] combinations_t[r];
 
3375
      }// end loop over 'r'
 
3376
      delete [] combinations_t;
 
3377
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
3378
      {
 
3379
        delete [] combinations_g[r];
 
3380
      }// end loop over 'r'
 
3381
      delete [] combinations_g;
 
3382
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
3383
      {
 
3384
        delete [] transform[r];
 
3385
      }// end loop over 'r'
 
3386
      delete [] transform;
 
3387
        break;
 
3388
      }
 
3389
    case 2:
 
3390
      {
 
3391
        
 
3392
      // Array of basisvalues
 
3393
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
3394
      
 
3395
      // Declare helper variables
 
3396
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
3397
      
 
3398
      // Compute basisvalues
 
3399
      basisvalues[0] = 1.0;
 
3400
      basisvalues[1] = tmp0;
 
3401
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
3402
      basisvalues[0] *= std::sqrt(0.5);
 
3403
      basisvalues[2] *= std::sqrt(1.0);
 
3404
      basisvalues[1] *= std::sqrt(3.0);
 
3405
      
 
3406
      // Table(s) of coefficients
 
3407
      static const double coefficients0[3] = \
 
3408
      {0.47140452, -0.57735027, -0.66666667};
 
3409
      
 
3410
      static const double coefficients1[3] = \
 
3411
      {0.47140452, 0.0, 0.33333333};
 
3412
      
 
3413
      // Tables of derivatives of the polynomial base (transpose).
 
3414
      static const double dmats0[3][3] = \
 
3415
      {{0.0, 0.0, 0.0},
 
3416
      {4.8989795, 0.0, 0.0},
 
3417
      {0.0, 0.0, 0.0}};
 
3418
      
 
3419
      static const double dmats1[3][3] = \
 
3420
      {{0.0, 0.0, 0.0},
 
3421
      {2.4494897, 0.0, 0.0},
 
3422
      {4.2426407, 0.0, 0.0}};
 
3423
      
 
3424
      // Compute reference derivatives.
 
3425
      // Declare pointer to array of derivatives on FIAT element.
 
3426
      double *derivatives = new double[2*num_derivatives_t];
 
3427
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
3428
      {
 
3429
        derivatives[r] = 0.0;
 
3430
      }// end loop over 'r'
 
3431
      
 
3432
      // Declare pointer to array of reference derivatives on physical element.
 
3433
      double *derivatives_p = new double[3*num_derivatives_t];
 
3434
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
3435
      {
 
3436
        derivatives_p[r] = 0.0;
 
3437
      }// end loop over 'r'
 
3438
      
 
3439
      // Declare derivative matrix (of polynomial basis).
 
3440
      double dmats[3][3] = \
 
3441
      {{1.0, 0.0, 0.0},
 
3442
      {0.0, 1.0, 0.0},
 
3443
      {0.0, 0.0, 1.0}};
 
3444
      
 
3445
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
3446
      double dmats_old[3][3] = \
 
3447
      {{1.0, 0.0, 0.0},
 
3448
      {0.0, 1.0, 0.0},
 
3449
      {0.0, 0.0, 1.0}};
 
3450
      
 
3451
      // Loop possible derivatives.
 
3452
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
3453
      {
 
3454
        // Resetting dmats values to compute next derivative.
 
3455
        for (unsigned int t = 0; t < 3; t++)
 
3456
        {
 
3457
          for (unsigned int u = 0; u < 3; u++)
 
3458
          {
 
3459
            dmats[t][u] = 0.0;
 
3460
            if (t == u)
 
3461
            {
 
3462
            dmats[t][u] = 1.0;
 
3463
            }
 
3464
            
 
3465
          }// end loop over 'u'
 
3466
        }// end loop over 't'
 
3467
        
 
3468
        // Looping derivative order to generate dmats.
 
3469
        for (unsigned int s = 0; s < n; s++)
 
3470
        {
 
3471
          // Updating dmats_old with new values and resetting dmats.
 
3472
          for (unsigned int t = 0; t < 3; t++)
 
3473
          {
 
3474
            for (unsigned int u = 0; u < 3; u++)
 
3475
            {
 
3476
              dmats_old[t][u] = dmats[t][u];
 
3477
              dmats[t][u] = 0.0;
 
3478
            }// end loop over 'u'
 
3479
          }// end loop over 't'
 
3480
          
 
3481
          // Update dmats using an inner product.
 
3482
          if (combinations_t[r][s] == 0)
 
3483
          {
 
3484
          for (unsigned int t = 0; t < 3; t++)
 
3485
          {
 
3486
            for (unsigned int u = 0; u < 3; u++)
 
3487
            {
 
3488
              for (unsigned int tu = 0; tu < 3; tu++)
 
3489
              {
 
3490
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
3491
              }// end loop over 'tu'
 
3492
            }// end loop over 'u'
 
3493
          }// end loop over 't'
 
3494
          }
 
3495
          
 
3496
          if (combinations_t[r][s] == 1)
 
3497
          {
 
3498
          for (unsigned int t = 0; t < 3; t++)
 
3499
          {
 
3500
            for (unsigned int u = 0; u < 3; u++)
 
3501
            {
 
3502
              for (unsigned int tu = 0; tu < 3; tu++)
 
3503
              {
 
3504
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
3505
              }// end loop over 'tu'
 
3506
            }// end loop over 'u'
 
3507
          }// end loop over 't'
 
3508
          }
 
3509
          
 
3510
        }// end loop over 's'
 
3511
        for (unsigned int s = 0; s < 3; s++)
 
3512
        {
 
3513
          for (unsigned int t = 0; t < 3; t++)
 
3514
          {
 
3515
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
3516
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
3517
          }// end loop over 't'
 
3518
        }// end loop over 's'
 
3519
        
 
3520
        // Using contravariant Piola transform to map values back to the physical element.
 
3521
        const double tmp_ref0 = derivatives[r];
 
3522
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
3523
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
3524
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
3525
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
3526
      }// end loop over 'r'
 
3527
      
 
3528
      // Transform derivatives back to physical element
 
3529
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
3530
      {
 
3531
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
3532
        {
 
3533
          values[r] += transform[r][s]*derivatives_p[s];
 
3534
          values[num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
3535
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
3536
        }// end loop over 's'
 
3537
      }// end loop over 'r'
 
3538
      
 
3539
      // Delete pointer to array of derivatives on FIAT element
 
3540
      delete [] derivatives;
 
3541
      
 
3542
      // Delete pointer to array of reference derivatives on physical element.
 
3543
      delete [] derivatives_p;
 
3544
      
 
3545
      // Delete pointer to array of combinations of derivatives and transform
 
3546
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
3547
      {
 
3548
        delete [] combinations_t[r];
 
3549
      }// end loop over 'r'
 
3550
      delete [] combinations_t;
 
3551
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
3552
      {
 
3553
        delete [] combinations_g[r];
 
3554
      }// end loop over 'r'
 
3555
      delete [] combinations_g;
 
3556
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
3557
      {
 
3558
        delete [] transform[r];
 
3559
      }// end loop over 'r'
 
3560
      delete [] transform;
 
3561
        break;
 
3562
      }
 
3563
    case 3:
 
3564
      {
 
3565
        
 
3566
      // Array of basisvalues
 
3567
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
3568
      
 
3569
      // Declare helper variables
 
3570
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
3571
      
 
3572
      // Compute basisvalues
 
3573
      basisvalues[0] = 1.0;
 
3574
      basisvalues[1] = tmp0;
 
3575
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
3576
      basisvalues[0] *= std::sqrt(0.5);
 
3577
      basisvalues[2] *= std::sqrt(1.0);
 
3578
      basisvalues[1] *= std::sqrt(3.0);
 
3579
      
 
3580
      // Table(s) of coefficients
 
3581
      static const double coefficients0[3] = \
 
3582
      {0.47140452, 0.28867513, 0.83333333};
 
3583
      
 
3584
      static const double coefficients1[3] = \
 
3585
      {-0.94280904, 0.0, -0.66666667};
 
3586
      
 
3587
      // Tables of derivatives of the polynomial base (transpose).
 
3588
      static const double dmats0[3][3] = \
 
3589
      {{0.0, 0.0, 0.0},
 
3590
      {4.8989795, 0.0, 0.0},
 
3591
      {0.0, 0.0, 0.0}};
 
3592
      
 
3593
      static const double dmats1[3][3] = \
 
3594
      {{0.0, 0.0, 0.0},
 
3595
      {2.4494897, 0.0, 0.0},
 
3596
      {4.2426407, 0.0, 0.0}};
 
3597
      
 
3598
      // Compute reference derivatives.
 
3599
      // Declare pointer to array of derivatives on FIAT element.
 
3600
      double *derivatives = new double[2*num_derivatives_t];
 
3601
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
3602
      {
 
3603
        derivatives[r] = 0.0;
 
3604
      }// end loop over 'r'
 
3605
      
 
3606
      // Declare pointer to array of reference derivatives on physical element.
 
3607
      double *derivatives_p = new double[3*num_derivatives_t];
 
3608
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
3609
      {
 
3610
        derivatives_p[r] = 0.0;
 
3611
      }// end loop over 'r'
 
3612
      
 
3613
      // Declare derivative matrix (of polynomial basis).
 
3614
      double dmats[3][3] = \
 
3615
      {{1.0, 0.0, 0.0},
 
3616
      {0.0, 1.0, 0.0},
 
3617
      {0.0, 0.0, 1.0}};
 
3618
      
 
3619
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
3620
      double dmats_old[3][3] = \
 
3621
      {{1.0, 0.0, 0.0},
 
3622
      {0.0, 1.0, 0.0},
 
3623
      {0.0, 0.0, 1.0}};
 
3624
      
 
3625
      // Loop possible derivatives.
 
3626
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
3627
      {
 
3628
        // Resetting dmats values to compute next derivative.
 
3629
        for (unsigned int t = 0; t < 3; t++)
 
3630
        {
 
3631
          for (unsigned int u = 0; u < 3; u++)
 
3632
          {
 
3633
            dmats[t][u] = 0.0;
 
3634
            if (t == u)
 
3635
            {
 
3636
            dmats[t][u] = 1.0;
 
3637
            }
 
3638
            
 
3639
          }// end loop over 'u'
 
3640
        }// end loop over 't'
 
3641
        
 
3642
        // Looping derivative order to generate dmats.
 
3643
        for (unsigned int s = 0; s < n; s++)
 
3644
        {
 
3645
          // Updating dmats_old with new values and resetting dmats.
 
3646
          for (unsigned int t = 0; t < 3; t++)
 
3647
          {
 
3648
            for (unsigned int u = 0; u < 3; u++)
 
3649
            {
 
3650
              dmats_old[t][u] = dmats[t][u];
 
3651
              dmats[t][u] = 0.0;
 
3652
            }// end loop over 'u'
 
3653
          }// end loop over 't'
 
3654
          
 
3655
          // Update dmats using an inner product.
 
3656
          if (combinations_t[r][s] == 0)
 
3657
          {
 
3658
          for (unsigned int t = 0; t < 3; t++)
 
3659
          {
 
3660
            for (unsigned int u = 0; u < 3; u++)
 
3661
            {
 
3662
              for (unsigned int tu = 0; tu < 3; tu++)
 
3663
              {
 
3664
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
3665
              }// end loop over 'tu'
 
3666
            }// end loop over 'u'
 
3667
          }// end loop over 't'
 
3668
          }
 
3669
          
 
3670
          if (combinations_t[r][s] == 1)
 
3671
          {
 
3672
          for (unsigned int t = 0; t < 3; t++)
 
3673
          {
 
3674
            for (unsigned int u = 0; u < 3; u++)
 
3675
            {
 
3676
              for (unsigned int tu = 0; tu < 3; tu++)
 
3677
              {
 
3678
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
3679
              }// end loop over 'tu'
 
3680
            }// end loop over 'u'
 
3681
          }// end loop over 't'
 
3682
          }
 
3683
          
 
3684
        }// end loop over 's'
 
3685
        for (unsigned int s = 0; s < 3; s++)
 
3686
        {
 
3687
          for (unsigned int t = 0; t < 3; t++)
 
3688
          {
 
3689
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
3690
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
3691
          }// end loop over 't'
 
3692
        }// end loop over 's'
 
3693
        
 
3694
        // Using contravariant Piola transform to map values back to the physical element.
 
3695
        const double tmp_ref0 = derivatives[r];
 
3696
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
3697
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
3698
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
3699
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
3700
      }// end loop over 'r'
 
3701
      
 
3702
      // Transform derivatives back to physical element
 
3703
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
3704
      {
 
3705
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
3706
        {
 
3707
          values[r] += transform[r][s]*derivatives_p[s];
 
3708
          values[num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
3709
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
3710
        }// end loop over 's'
 
3711
      }// end loop over 'r'
 
3712
      
 
3713
      // Delete pointer to array of derivatives on FIAT element
 
3714
      delete [] derivatives;
 
3715
      
 
3716
      // Delete pointer to array of reference derivatives on physical element.
 
3717
      delete [] derivatives_p;
 
3718
      
 
3719
      // Delete pointer to array of combinations of derivatives and transform
 
3720
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
3721
      {
 
3722
        delete [] combinations_t[r];
 
3723
      }// end loop over 'r'
 
3724
      delete [] combinations_t;
 
3725
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
3726
      {
 
3727
        delete [] combinations_g[r];
 
3728
      }// end loop over 'r'
 
3729
      delete [] combinations_g;
 
3730
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
3731
      {
 
3732
        delete [] transform[r];
 
3733
      }// end loop over 'r'
 
3734
      delete [] transform;
 
3735
        break;
 
3736
      }
 
3737
    case 4:
 
3738
      {
 
3739
        
 
3740
      // Array of basisvalues
 
3741
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
3742
      
 
3743
      // Declare helper variables
 
3744
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
3745
      
 
3746
      // Compute basisvalues
 
3747
      basisvalues[0] = 1.0;
 
3748
      basisvalues[1] = tmp0;
 
3749
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
3750
      basisvalues[0] *= std::sqrt(0.5);
 
3751
      basisvalues[2] *= std::sqrt(1.0);
 
3752
      basisvalues[1] *= std::sqrt(3.0);
 
3753
      
 
3754
      // Table(s) of coefficients
 
3755
      static const double coefficients0[3] = \
 
3756
      {-0.47140452, -0.28867513, 0.16666667};
 
3757
      
 
3758
      static const double coefficients1[3] = \
 
3759
      {-0.47140452, 0.8660254, 0.16666667};
 
3760
      
 
3761
      // Tables of derivatives of the polynomial base (transpose).
 
3762
      static const double dmats0[3][3] = \
 
3763
      {{0.0, 0.0, 0.0},
 
3764
      {4.8989795, 0.0, 0.0},
 
3765
      {0.0, 0.0, 0.0}};
 
3766
      
 
3767
      static const double dmats1[3][3] = \
 
3768
      {{0.0, 0.0, 0.0},
 
3769
      {2.4494897, 0.0, 0.0},
 
3770
      {4.2426407, 0.0, 0.0}};
 
3771
      
 
3772
      // Compute reference derivatives.
 
3773
      // Declare pointer to array of derivatives on FIAT element.
 
3774
      double *derivatives = new double[2*num_derivatives_t];
 
3775
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
3776
      {
 
3777
        derivatives[r] = 0.0;
 
3778
      }// end loop over 'r'
 
3779
      
 
3780
      // Declare pointer to array of reference derivatives on physical element.
 
3781
      double *derivatives_p = new double[3*num_derivatives_t];
 
3782
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
3783
      {
 
3784
        derivatives_p[r] = 0.0;
 
3785
      }// end loop over 'r'
 
3786
      
 
3787
      // Declare derivative matrix (of polynomial basis).
 
3788
      double dmats[3][3] = \
 
3789
      {{1.0, 0.0, 0.0},
 
3790
      {0.0, 1.0, 0.0},
 
3791
      {0.0, 0.0, 1.0}};
 
3792
      
 
3793
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
3794
      double dmats_old[3][3] = \
 
3795
      {{1.0, 0.0, 0.0},
 
3796
      {0.0, 1.0, 0.0},
 
3797
      {0.0, 0.0, 1.0}};
 
3798
      
 
3799
      // Loop possible derivatives.
 
3800
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
3801
      {
 
3802
        // Resetting dmats values to compute next derivative.
 
3803
        for (unsigned int t = 0; t < 3; t++)
 
3804
        {
 
3805
          for (unsigned int u = 0; u < 3; u++)
 
3806
          {
 
3807
            dmats[t][u] = 0.0;
 
3808
            if (t == u)
 
3809
            {
 
3810
            dmats[t][u] = 1.0;
 
3811
            }
 
3812
            
 
3813
          }// end loop over 'u'
 
3814
        }// end loop over 't'
 
3815
        
 
3816
        // Looping derivative order to generate dmats.
 
3817
        for (unsigned int s = 0; s < n; s++)
 
3818
        {
 
3819
          // Updating dmats_old with new values and resetting dmats.
 
3820
          for (unsigned int t = 0; t < 3; t++)
 
3821
          {
 
3822
            for (unsigned int u = 0; u < 3; u++)
 
3823
            {
 
3824
              dmats_old[t][u] = dmats[t][u];
 
3825
              dmats[t][u] = 0.0;
 
3826
            }// end loop over 'u'
 
3827
          }// end loop over 't'
 
3828
          
 
3829
          // Update dmats using an inner product.
 
3830
          if (combinations_t[r][s] == 0)
 
3831
          {
 
3832
          for (unsigned int t = 0; t < 3; t++)
 
3833
          {
 
3834
            for (unsigned int u = 0; u < 3; u++)
 
3835
            {
 
3836
              for (unsigned int tu = 0; tu < 3; tu++)
 
3837
              {
 
3838
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
3839
              }// end loop over 'tu'
 
3840
            }// end loop over 'u'
 
3841
          }// end loop over 't'
 
3842
          }
 
3843
          
 
3844
          if (combinations_t[r][s] == 1)
 
3845
          {
 
3846
          for (unsigned int t = 0; t < 3; t++)
 
3847
          {
 
3848
            for (unsigned int u = 0; u < 3; u++)
 
3849
            {
 
3850
              for (unsigned int tu = 0; tu < 3; tu++)
 
3851
              {
 
3852
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
3853
              }// end loop over 'tu'
 
3854
            }// end loop over 'u'
 
3855
          }// end loop over 't'
 
3856
          }
 
3857
          
 
3858
        }// end loop over 's'
 
3859
        for (unsigned int s = 0; s < 3; s++)
 
3860
        {
 
3861
          for (unsigned int t = 0; t < 3; t++)
 
3862
          {
 
3863
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
3864
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
3865
          }// end loop over 't'
 
3866
        }// end loop over 's'
 
3867
        
 
3868
        // Using contravariant Piola transform to map values back to the physical element.
 
3869
        const double tmp_ref0 = derivatives[r];
 
3870
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
3871
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
3872
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
3873
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
3874
      }// end loop over 'r'
 
3875
      
 
3876
      // Transform derivatives back to physical element
 
3877
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
3878
      {
 
3879
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
3880
        {
 
3881
          values[r] += transform[r][s]*derivatives_p[s];
 
3882
          values[num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
3883
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
3884
        }// end loop over 's'
 
3885
      }// end loop over 'r'
 
3886
      
 
3887
      // Delete pointer to array of derivatives on FIAT element
 
3888
      delete [] derivatives;
 
3889
      
 
3890
      // Delete pointer to array of reference derivatives on physical element.
 
3891
      delete [] derivatives_p;
 
3892
      
 
3893
      // Delete pointer to array of combinations of derivatives and transform
 
3894
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
3895
      {
 
3896
        delete [] combinations_t[r];
 
3897
      }// end loop over 'r'
 
3898
      delete [] combinations_t;
 
3899
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
3900
      {
 
3901
        delete [] combinations_g[r];
 
3902
      }// end loop over 'r'
 
3903
      delete [] combinations_g;
 
3904
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
3905
      {
 
3906
        delete [] transform[r];
 
3907
      }// end loop over 'r'
 
3908
      delete [] transform;
 
3909
        break;
 
3910
      }
 
3911
    case 5:
 
3912
      {
 
3913
        
 
3914
      // Array of basisvalues
 
3915
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
3916
      
 
3917
      // Declare helper variables
 
3918
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
3919
      
 
3920
      // Compute basisvalues
 
3921
      basisvalues[0] = 1.0;
 
3922
      basisvalues[1] = tmp0;
 
3923
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
3924
      basisvalues[0] *= std::sqrt(0.5);
 
3925
      basisvalues[2] *= std::sqrt(1.0);
 
3926
      basisvalues[1] *= std::sqrt(3.0);
 
3927
      
 
3928
      // Table(s) of coefficients
 
3929
      static const double coefficients0[3] = \
 
3930
      {0.94280904, 0.57735027, -0.33333333};
 
3931
      
 
3932
      static const double coefficients1[3] = \
 
3933
      {-0.47140452, -0.8660254, 0.16666667};
 
3934
      
 
3935
      // Tables of derivatives of the polynomial base (transpose).
 
3936
      static const double dmats0[3][3] = \
 
3937
      {{0.0, 0.0, 0.0},
 
3938
      {4.8989795, 0.0, 0.0},
 
3939
      {0.0, 0.0, 0.0}};
 
3940
      
 
3941
      static const double dmats1[3][3] = \
 
3942
      {{0.0, 0.0, 0.0},
 
3943
      {2.4494897, 0.0, 0.0},
 
3944
      {4.2426407, 0.0, 0.0}};
 
3945
      
 
3946
      // Compute reference derivatives.
 
3947
      // Declare pointer to array of derivatives on FIAT element.
 
3948
      double *derivatives = new double[2*num_derivatives_t];
 
3949
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
3950
      {
 
3951
        derivatives[r] = 0.0;
 
3952
      }// end loop over 'r'
 
3953
      
 
3954
      // Declare pointer to array of reference derivatives on physical element.
 
3955
      double *derivatives_p = new double[3*num_derivatives_t];
 
3956
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
3957
      {
 
3958
        derivatives_p[r] = 0.0;
 
3959
      }// end loop over 'r'
 
3960
      
 
3961
      // Declare derivative matrix (of polynomial basis).
 
3962
      double dmats[3][3] = \
 
3963
      {{1.0, 0.0, 0.0},
 
3964
      {0.0, 1.0, 0.0},
 
3965
      {0.0, 0.0, 1.0}};
 
3966
      
 
3967
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
3968
      double dmats_old[3][3] = \
 
3969
      {{1.0, 0.0, 0.0},
 
3970
      {0.0, 1.0, 0.0},
 
3971
      {0.0, 0.0, 1.0}};
 
3972
      
 
3973
      // Loop possible derivatives.
 
3974
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
3975
      {
 
3976
        // Resetting dmats values to compute next derivative.
 
3977
        for (unsigned int t = 0; t < 3; t++)
 
3978
        {
 
3979
          for (unsigned int u = 0; u < 3; u++)
 
3980
          {
 
3981
            dmats[t][u] = 0.0;
 
3982
            if (t == u)
 
3983
            {
 
3984
            dmats[t][u] = 1.0;
 
3985
            }
 
3986
            
 
3987
          }// end loop over 'u'
 
3988
        }// end loop over 't'
 
3989
        
 
3990
        // Looping derivative order to generate dmats.
 
3991
        for (unsigned int s = 0; s < n; s++)
 
3992
        {
 
3993
          // Updating dmats_old with new values and resetting dmats.
 
3994
          for (unsigned int t = 0; t < 3; t++)
 
3995
          {
 
3996
            for (unsigned int u = 0; u < 3; u++)
 
3997
            {
 
3998
              dmats_old[t][u] = dmats[t][u];
 
3999
              dmats[t][u] = 0.0;
 
4000
            }// end loop over 'u'
 
4001
          }// end loop over 't'
 
4002
          
 
4003
          // Update dmats using an inner product.
 
4004
          if (combinations_t[r][s] == 0)
 
4005
          {
 
4006
          for (unsigned int t = 0; t < 3; t++)
 
4007
          {
 
4008
            for (unsigned int u = 0; u < 3; u++)
 
4009
            {
 
4010
              for (unsigned int tu = 0; tu < 3; tu++)
 
4011
              {
 
4012
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
4013
              }// end loop over 'tu'
 
4014
            }// end loop over 'u'
 
4015
          }// end loop over 't'
 
4016
          }
 
4017
          
 
4018
          if (combinations_t[r][s] == 1)
 
4019
          {
 
4020
          for (unsigned int t = 0; t < 3; t++)
 
4021
          {
 
4022
            for (unsigned int u = 0; u < 3; u++)
 
4023
            {
 
4024
              for (unsigned int tu = 0; tu < 3; tu++)
 
4025
              {
 
4026
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
4027
              }// end loop over 'tu'
 
4028
            }// end loop over 'u'
 
4029
          }// end loop over 't'
 
4030
          }
 
4031
          
 
4032
        }// end loop over 's'
 
4033
        for (unsigned int s = 0; s < 3; s++)
 
4034
        {
 
4035
          for (unsigned int t = 0; t < 3; t++)
 
4036
          {
 
4037
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
4038
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
4039
          }// end loop over 't'
 
4040
        }// end loop over 's'
 
4041
        
 
4042
        // Using contravariant Piola transform to map values back to the physical element.
 
4043
        const double tmp_ref0 = derivatives[r];
 
4044
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
4045
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
4046
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
4047
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
4048
      }// end loop over 'r'
 
4049
      
 
4050
      // Transform derivatives back to physical element
 
4051
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
4052
      {
 
4053
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
4054
        {
 
4055
          values[r] += transform[r][s]*derivatives_p[s];
 
4056
          values[num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
4057
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
4058
        }// end loop over 's'
 
4059
      }// end loop over 'r'
 
4060
      
 
4061
      // Delete pointer to array of derivatives on FIAT element
 
4062
      delete [] derivatives;
 
4063
      
 
4064
      // Delete pointer to array of reference derivatives on physical element.
 
4065
      delete [] derivatives_p;
 
4066
      
 
4067
      // Delete pointer to array of combinations of derivatives and transform
 
4068
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
4069
      {
 
4070
        delete [] combinations_t[r];
 
4071
      }// end loop over 'r'
 
4072
      delete [] combinations_t;
 
4073
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
4074
      {
 
4075
        delete [] combinations_g[r];
 
4076
      }// end loop over 'r'
 
4077
      delete [] combinations_g;
 
4078
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
4079
      {
 
4080
        delete [] transform[r];
 
4081
      }// end loop over 'r'
 
4082
      delete [] transform;
 
4083
        break;
 
4084
      }
 
4085
    }
 
4086
    
 
4087
  }
 
4088
 
 
4089
  /// Evaluate order n derivatives of all basis functions at given point x in cell
 
4090
  virtual void evaluate_basis_derivatives_all(std::size_t n,
 
4091
                                              double* values,
 
4092
                                              const double* x,
 
4093
                                              const double* vertex_coordinates,
 
4094
                                              int cell_orientation) const
 
4095
  {
 
4096
    // Compute number of derivatives.
 
4097
    unsigned int num_derivatives_g = 1;
 
4098
    for (unsigned int r = 0; r < n; r++)
 
4099
    {
 
4100
      num_derivatives_g *= 3;
 
4101
    }// end loop over 'r'
 
4102
    
 
4103
    // Helper variable to hold values of a single dof.
 
4104
    double *dof_values = new double[3*num_derivatives_g];
 
4105
    for (unsigned int r = 0; r < 3*num_derivatives_g; r++)
 
4106
    {
 
4107
      dof_values[r] = 0.0;
 
4108
    }// end loop over 'r'
 
4109
    
 
4110
    // Loop dofs and call evaluate_basis_derivatives.
 
4111
    for (unsigned int r = 0; r < 6; r++)
 
4112
    {
 
4113
      evaluate_basis_derivatives(r, n, dof_values, x, vertex_coordinates, cell_orientation);
 
4114
      for (unsigned int s = 0; s < 3*num_derivatives_g; s++)
 
4115
      {
 
4116
        values[r*3*num_derivatives_g + s] = dof_values[s];
 
4117
      }// end loop over 's'
 
4118
    }// end loop over 'r'
 
4119
    
 
4120
    // Delete pointer.
 
4121
    delete [] dof_values;
 
4122
  }
 
4123
 
 
4124
  /// Evaluate linear functional for dof i on the function f
 
4125
  virtual double evaluate_dof(std::size_t i,
 
4126
                              const ufc::function& f,
 
4127
                              const double* vertex_coordinates,
 
4128
                              int cell_orientation,
 
4129
                              const ufc::cell& c) const
 
4130
  {
 
4131
    // Declare variables for result of evaluation
 
4132
    double vals[3];
 
4133
    
 
4134
    // Declare variable for physical coordinates
 
4135
    double y[3];
 
4136
    
 
4137
    double result;
 
4138
    // Compute Jacobian
 
4139
    double J[6];
 
4140
    compute_jacobian_triangle_3d(J, vertex_coordinates);
 
4141
    
 
4142
    
 
4143
    // Compute Jacobian inverse and determinant
 
4144
    double K[6];
 
4145
    double detJ;
 
4146
    compute_jacobian_inverse_triangle_3d(K, detJ, J);
 
4147
    
 
4148
    
 
4149
    
 
4150
    // Check orientation
 
4151
    if (cell_orientation == -1)
 
4152
      throw std::runtime_error("cell orientation must be defined (not -1)");
 
4153
    // (If cell_orientation == 1 = down, multiply det(J) by -1)
 
4154
    else if (cell_orientation == 1)
 
4155
      detJ *= -1;
 
4156
    switch (i)
 
4157
    {
 
4158
    case 0:
 
4159
      {
 
4160
        y[0] = 0.66666667*vertex_coordinates[3] + 0.33333333*vertex_coordinates[6];
 
4161
      y[1] = 0.66666667*vertex_coordinates[4] + 0.33333333*vertex_coordinates[7];
 
4162
      y[2] = 0.66666667*vertex_coordinates[5] + 0.33333333*vertex_coordinates[8];
 
4163
      f.evaluate(vals, y, c);
 
4164
      result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2])) + (detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
4165
      return result;
 
4166
        break;
 
4167
      }
 
4168
    case 1:
 
4169
      {
 
4170
        y[0] = 0.33333333*vertex_coordinates[3] + 0.66666667*vertex_coordinates[6];
 
4171
      y[1] = 0.33333333*vertex_coordinates[4] + 0.66666667*vertex_coordinates[7];
 
4172
      y[2] = 0.33333333*vertex_coordinates[5] + 0.66666667*vertex_coordinates[8];
 
4173
      f.evaluate(vals, y, c);
 
4174
      result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2])) + (detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
4175
      return result;
 
4176
        break;
 
4177
      }
 
4178
    case 2:
 
4179
      {
 
4180
        y[0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[6];
 
4181
      y[1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[7];
 
4182
      y[2] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[8];
 
4183
      f.evaluate(vals, y, c);
 
4184
      result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2]));
 
4185
      return result;
 
4186
        break;
 
4187
      }
 
4188
    case 3:
 
4189
      {
 
4190
        y[0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[6];
 
4191
      y[1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[7];
 
4192
      y[2] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[8];
 
4193
      f.evaluate(vals, y, c);
 
4194
      result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2]));
 
4195
      return result;
 
4196
        break;
 
4197
      }
 
4198
    case 4:
 
4199
      {
 
4200
        y[0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[3];
 
4201
      y[1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[4];
 
4202
      y[2] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[5];
 
4203
      f.evaluate(vals, y, c);
 
4204
      result = (-1.0)*(detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
4205
      return result;
 
4206
        break;
 
4207
      }
 
4208
    case 5:
 
4209
      {
 
4210
        y[0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[3];
 
4211
      y[1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[4];
 
4212
      y[2] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[5];
 
4213
      f.evaluate(vals, y, c);
 
4214
      result = (-1.0)*(detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
4215
      return result;
 
4216
        break;
 
4217
      }
 
4218
    }
 
4219
    
 
4220
    return 0.0;
 
4221
  }
 
4222
 
 
4223
  /// Evaluate linear functionals for all dofs on the function f
 
4224
  virtual void evaluate_dofs(double* values,
 
4225
                             const ufc::function& f,
 
4226
                             const double* vertex_coordinates,
 
4227
                             int cell_orientation,
 
4228
                             const ufc::cell& c) const
 
4229
  {
 
4230
    // Declare variables for result of evaluation
 
4231
    double vals[3];
 
4232
    
 
4233
    // Declare variable for physical coordinates
 
4234
    double y[3];
 
4235
    
 
4236
    double result;
 
4237
    // Compute Jacobian
 
4238
    double J[6];
 
4239
    compute_jacobian_triangle_3d(J, vertex_coordinates);
 
4240
    
 
4241
    
 
4242
    // Compute Jacobian inverse and determinant
 
4243
    double K[6];
 
4244
    double detJ;
 
4245
    compute_jacobian_inverse_triangle_3d(K, detJ, J);
 
4246
    
 
4247
    
 
4248
    
 
4249
    // Check orientation
 
4250
    if (cell_orientation == -1)
 
4251
      throw std::runtime_error("cell orientation must be defined (not -1)");
 
4252
    // (If cell_orientation == 1 = down, multiply det(J) by -1)
 
4253
    else if (cell_orientation == 1)
 
4254
      detJ *= -1;
 
4255
    y[0] = 0.66666667*vertex_coordinates[3] + 0.33333333*vertex_coordinates[6];
 
4256
    y[1] = 0.66666667*vertex_coordinates[4] + 0.33333333*vertex_coordinates[7];
 
4257
    y[2] = 0.66666667*vertex_coordinates[5] + 0.33333333*vertex_coordinates[8];
 
4258
    f.evaluate(vals, y, c);
 
4259
    result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2])) + (detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
4260
    values[0] = result;
 
4261
    y[0] = 0.33333333*vertex_coordinates[3] + 0.66666667*vertex_coordinates[6];
 
4262
    y[1] = 0.33333333*vertex_coordinates[4] + 0.66666667*vertex_coordinates[7];
 
4263
    y[2] = 0.33333333*vertex_coordinates[5] + 0.66666667*vertex_coordinates[8];
 
4264
    f.evaluate(vals, y, c);
 
4265
    result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2])) + (detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
4266
    values[1] = result;
 
4267
    y[0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[6];
 
4268
    y[1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[7];
 
4269
    y[2] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[8];
 
4270
    f.evaluate(vals, y, c);
 
4271
    result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2]));
 
4272
    values[2] = result;
 
4273
    y[0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[6];
 
4274
    y[1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[7];
 
4275
    y[2] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[8];
 
4276
    f.evaluate(vals, y, c);
 
4277
    result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2]));
 
4278
    values[3] = result;
 
4279
    y[0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[3];
 
4280
    y[1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[4];
 
4281
    y[2] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[5];
 
4282
    f.evaluate(vals, y, c);
 
4283
    result = (-1.0)*(detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
4284
    values[4] = result;
 
4285
    y[0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[3];
 
4286
    y[1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[4];
 
4287
    y[2] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[5];
 
4288
    f.evaluate(vals, y, c);
 
4289
    result = (-1.0)*(detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
4290
    values[5] = result;
 
4291
  }
 
4292
 
 
4293
  /// Interpolate vertex values from dof values
 
4294
  virtual void interpolate_vertex_values(double* vertex_values,
 
4295
                                         const double* dof_values,
 
4296
                                         const double* vertex_coordinates,
 
4297
                                         int cell_orientation,
 
4298
                                         const ufc::cell& c) const
 
4299
  {
 
4300
    // Compute Jacobian
 
4301
    double J[6];
 
4302
    compute_jacobian_triangle_3d(J, vertex_coordinates);
 
4303
    
 
4304
    
 
4305
    // Compute Jacobian inverse and determinant
 
4306
    double K[6];
 
4307
    double detJ;
 
4308
    compute_jacobian_inverse_triangle_3d(K, detJ, J);
 
4309
    
 
4310
    
 
4311
    
 
4312
    // Check orientation
 
4313
    if (cell_orientation == -1)
 
4314
      throw std::runtime_error("cell orientation must be defined (not -1)");
 
4315
    // (If cell_orientation == 1 = down, multiply det(J) by -1)
 
4316
    else if (cell_orientation == 1)
 
4317
      detJ *= -1;
 
4318
    
 
4319
    // Evaluate function and change variables
 
4320
    vertex_values[0] = dof_values[2]*(1.0/detJ)*J[0]*2.0 + dof_values[3]*((1.0/detJ)*(J[0]*(-1.0))) + dof_values[4]*((1.0/detJ)*(J[1]*(-2.0))) + dof_values[5]*(1.0/detJ)*J[1];
 
4321
    vertex_values[2] = dof_values[0]*(1.0/detJ)*J[0]*2.0 + dof_values[1]*((1.0/detJ)*(J[0]*(-1.0))) + dof_values[4]*((1.0/detJ)*(J[0]*(-1.0) + J[1])) + dof_values[5]*((1.0/detJ)*(J[0]*2.0 + J[1]*(-2.0)));
 
4322
    vertex_values[4] = dof_values[0]*((1.0/detJ)*(J[1]*(-1.0))) + dof_values[1]*(1.0/detJ)*J[1]*2.0 + dof_values[2]*((1.0/detJ)*(J[0]*(-1.0) + J[1])) + dof_values[3]*((1.0/detJ)*(J[0]*2.0 + J[1]*(-2.0)));
 
4323
    vertex_values[1] = dof_values[2]*(1.0/detJ)*J[2]*2.0 + dof_values[3]*((1.0/detJ)*(J[2]*(-1.0))) + dof_values[4]*((1.0/detJ)*(J[3]*(-2.0))) + dof_values[5]*(1.0/detJ)*J[3];
 
4324
    vertex_values[3] = dof_values[0]*(1.0/detJ)*J[2]*2.0 + dof_values[1]*((1.0/detJ)*(J[2]*(-1.0))) + dof_values[4]*((1.0/detJ)*(J[2]*(-1.0) + J[3])) + dof_values[5]*((1.0/detJ)*(J[2]*2.0 + J[3]*(-2.0)));
 
4325
    vertex_values[5] = dof_values[0]*((1.0/detJ)*(J[3]*(-1.0))) + dof_values[1]*(1.0/detJ)*J[3]*2.0 + dof_values[2]*((1.0/detJ)*(J[2]*(-1.0) + J[3])) + dof_values[3]*((1.0/detJ)*(J[2]*2.0 + J[3]*(-2.0)));
 
4326
  }
 
4327
 
 
4328
  /// Map coordinate xhat from reference cell to coordinate x in cell
 
4329
  virtual void map_from_reference_cell(double* x,
 
4330
                                       const double* xhat,
 
4331
                                       const ufc::cell& c) const
 
4332
  {
 
4333
    std::cerr << "*** FFC warning: " << "map_from_reference_cell not yet implemented." << std::endl;
 
4334
  }
 
4335
 
 
4336
  /// Map from coordinate x in cell to coordinate xhat in reference cell
 
4337
  virtual void map_to_reference_cell(double* xhat,
 
4338
                                     const double* x,
 
4339
                                     const ufc::cell& c) const
 
4340
  {
 
4341
    std::cerr << "*** FFC warning: " << "map_to_reference_cell not yet implemented." << std::endl;
 
4342
  }
 
4343
 
 
4344
  /// Return the number of sub elements (for a mixed element)
 
4345
  virtual std::size_t num_sub_elements() const
 
4346
  {
 
4347
    return 0;
 
4348
  }
 
4349
 
 
4350
  /// Create a new finite element for sub element i (for a mixed element)
 
4351
  virtual ufc::finite_element* create_sub_element(std::size_t i) const
 
4352
  {
 
4353
    return 0;
 
4354
  }
 
4355
 
 
4356
  /// Create a new class instance
 
4357
  virtual ufc::finite_element* create() const
 
4358
  {
 
4359
    return new x_element9_finite_element_1();
 
4360
  }
 
4361
 
 
4362
};
 
4363
 
 
4364
/// This class defines the interface for a finite element.
 
4365
 
 
4366
class x_element9_finite_element_2: public ufc::finite_element
 
4367
{
 
4368
public:
 
4369
 
 
4370
  /// Constructor
 
4371
  x_element9_finite_element_2() : ufc::finite_element()
 
4372
  {
 
4373
    // Do nothing
 
4374
  }
 
4375
 
 
4376
  /// Destructor
 
4377
  virtual ~x_element9_finite_element_2()
 
4378
  {
 
4379
    // Do nothing
 
4380
  }
 
4381
 
 
4382
  /// Return a string identifying the finite element
 
4383
  virtual const char* signature() const
 
4384
  {
 
4385
    return "FiniteElement('Nedelec 1st kind H(curl)', Domain(Cell('triangle', 3), 'triangle_multiverse', 3, 2), 1, None)";
 
4386
  }
 
4387
 
 
4388
  /// Return the cell shape
 
4389
  virtual ufc::shape cell_shape() const
 
4390
  {
 
4391
    return ufc::triangle;
 
4392
  }
 
4393
 
 
4394
  /// Return the topological dimension of the cell shape
 
4395
  virtual std::size_t topological_dimension() const
 
4396
  {
 
4397
    return 2;
 
4398
  }
 
4399
 
 
4400
  /// Return the geometric dimension of the cell shape
 
4401
  virtual std::size_t geometric_dimension() const
 
4402
  {
 
4403
    return 3;
 
4404
  }
 
4405
 
 
4406
  /// Return the dimension of the finite element function space
 
4407
  virtual std::size_t space_dimension() const
 
4408
  {
 
4409
    return 3;
 
4410
  }
 
4411
 
 
4412
  /// Return the rank of the value space
 
4413
  virtual std::size_t value_rank() const
 
4414
  {
 
4415
    return 1;
 
4416
  }
 
4417
 
 
4418
  /// Return the dimension of the value space for axis i
 
4419
  virtual std::size_t value_dimension(std::size_t i) const
 
4420
  {
 
4421
    switch (i)
 
4422
    {
 
4423
    case 0:
 
4424
      {
 
4425
        return 3;
 
4426
        break;
 
4427
      }
 
4428
    }
 
4429
    
 
4430
    return 0;
 
4431
  }
 
4432
 
 
4433
  /// Evaluate basis function i at given point x in cell
 
4434
  virtual void evaluate_basis(std::size_t i,
 
4435
                              double* values,
 
4436
                              const double* x,
 
4437
                              const double* vertex_coordinates,
 
4438
                              int cell_orientation) const
 
4439
  {
 
4440
    // Compute Jacobian
 
4441
    double J[6];
 
4442
    compute_jacobian_triangle_3d(J, vertex_coordinates);
 
4443
    
 
4444
    // Compute Jacobian inverse and determinant
 
4445
    double K[6];
 
4446
    double detJ;
 
4447
    compute_jacobian_inverse_triangle_3d(K, detJ, J);
 
4448
    
 
4449
    
 
4450
    const double b0 = vertex_coordinates[0];
 
4451
    const double b1 = vertex_coordinates[1];
 
4452
    const double b2 = vertex_coordinates[2];
 
4453
    
 
4454
    // P_FFC = J^dag (p - b), P_FIAT = 2*P_FFC - (1, 1)
 
4455
    double X = 2*(K[0]*(x[0] - b0) + K[1]*(x[1] - b1) + K[2]*(x[2] - b2)) - 1.0;
 
4456
    double Y = 2*(K[3]*(x[0] - b0) + K[4]*(x[1] - b1) + K[5]*(x[2] - b2)) - 1.0;
 
4457
    
 
4458
    
 
4459
    // Reset values
 
4460
    values[0] = 0.0;
 
4461
    values[1] = 0.0;
 
4462
    switch (i)
 
4463
    {
 
4464
    case 0:
 
4465
      {
 
4466
        
 
4467
      // Array of basisvalues
 
4468
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
4469
      
 
4470
      // Declare helper variables
 
4471
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
4472
      
 
4473
      // Compute basisvalues
 
4474
      basisvalues[0] = 1.0;
 
4475
      basisvalues[1] = tmp0;
 
4476
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
4477
      basisvalues[0] *= std::sqrt(0.5);
 
4478
      basisvalues[2] *= std::sqrt(1.0);
 
4479
      basisvalues[1] *= std::sqrt(3.0);
 
4480
      
 
4481
      // Table(s) of coefficients
 
4482
      static const double coefficients0[3] = \
 
4483
      {-0.47140452, 0.0, -0.33333333};
 
4484
      
 
4485
      static const double coefficients1[3] = \
 
4486
      {0.47140452, 0.28867513, -0.16666667};
 
4487
      
 
4488
      // Compute value(s)
 
4489
      for (unsigned int r = 0; r < 3; r++)
 
4490
      {
 
4491
        values[0] += coefficients0[r]*basisvalues[r];
 
4492
        values[1] += coefficients1[r]*basisvalues[r];
 
4493
      }// end loop over 'r'
 
4494
      
 
4495
      // Using covariant Piola transform to map values back to the physical element
 
4496
      const double tmp_ref0 = values[0];
 
4497
      const double tmp_ref1 = values[1];
 
4498
      values[0] = (K[0]*tmp_ref0 + K[3]*tmp_ref1);
 
4499
      values[1] = (K[1]*tmp_ref0 + K[4]*tmp_ref1);
 
4500
      values[2] = (K[2]*tmp_ref0 + K[5]*tmp_ref1);
 
4501
        break;
 
4502
      }
 
4503
    case 1:
 
4504
      {
 
4505
        
 
4506
      // Array of basisvalues
 
4507
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
4508
      
 
4509
      // Declare helper variables
 
4510
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
4511
      
 
4512
      // Compute basisvalues
 
4513
      basisvalues[0] = 1.0;
 
4514
      basisvalues[1] = tmp0;
 
4515
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
4516
      basisvalues[0] *= std::sqrt(0.5);
 
4517
      basisvalues[2] *= std::sqrt(1.0);
 
4518
      basisvalues[1] *= std::sqrt(3.0);
 
4519
      
 
4520
      // Table(s) of coefficients
 
4521
      static const double coefficients0[3] = \
 
4522
      {0.47140452, 0.0, 0.33333333};
 
4523
      
 
4524
      static const double coefficients1[3] = \
 
4525
      {0.94280904, -0.28867513, 0.16666667};
 
4526
      
 
4527
      // Compute value(s)
 
4528
      for (unsigned int r = 0; r < 3; r++)
 
4529
      {
 
4530
        values[0] += coefficients0[r]*basisvalues[r];
 
4531
        values[1] += coefficients1[r]*basisvalues[r];
 
4532
      }// end loop over 'r'
 
4533
      
 
4534
      // Using covariant Piola transform to map values back to the physical element
 
4535
      const double tmp_ref0 = values[0];
 
4536
      const double tmp_ref1 = values[1];
 
4537
      values[0] = (K[0]*tmp_ref0 + K[3]*tmp_ref1);
 
4538
      values[1] = (K[1]*tmp_ref0 + K[4]*tmp_ref1);
 
4539
      values[2] = (K[2]*tmp_ref0 + K[5]*tmp_ref1);
 
4540
        break;
 
4541
      }
 
4542
    case 2:
 
4543
      {
 
4544
        
 
4545
      // Array of basisvalues
 
4546
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
4547
      
 
4548
      // Declare helper variables
 
4549
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
4550
      
 
4551
      // Compute basisvalues
 
4552
      basisvalues[0] = 1.0;
 
4553
      basisvalues[1] = tmp0;
 
4554
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
4555
      basisvalues[0] *= std::sqrt(0.5);
 
4556
      basisvalues[2] *= std::sqrt(1.0);
 
4557
      basisvalues[1] *= std::sqrt(3.0);
 
4558
      
 
4559
      // Table(s) of coefficients
 
4560
      static const double coefficients0[3] = \
 
4561
      {0.94280904, 0.0, -0.33333333};
 
4562
      
 
4563
      static const double coefficients1[3] = \
 
4564
      {0.47140452, 0.28867513, -0.16666667};
 
4565
      
 
4566
      // Compute value(s)
 
4567
      for (unsigned int r = 0; r < 3; r++)
 
4568
      {
 
4569
        values[0] += coefficients0[r]*basisvalues[r];
 
4570
        values[1] += coefficients1[r]*basisvalues[r];
 
4571
      }// end loop over 'r'
 
4572
      
 
4573
      // Using covariant Piola transform to map values back to the physical element
 
4574
      const double tmp_ref0 = values[0];
 
4575
      const double tmp_ref1 = values[1];
 
4576
      values[0] = (K[0]*tmp_ref0 + K[3]*tmp_ref1);
 
4577
      values[1] = (K[1]*tmp_ref0 + K[4]*tmp_ref1);
 
4578
      values[2] = (K[2]*tmp_ref0 + K[5]*tmp_ref1);
 
4579
        break;
 
4580
      }
 
4581
    }
 
4582
    
 
4583
  }
 
4584
 
 
4585
  /// Evaluate all basis functions at given point x in cell
 
4586
  virtual void evaluate_basis_all(double* values,
 
4587
                                  const double* x,
 
4588
                                  const double* vertex_coordinates,
 
4589
                                  int cell_orientation) const
 
4590
  {
 
4591
    // Helper variable to hold values of a single dof.
 
4592
    double dof_values[3] = {0.0, 0.0, 0.0};
 
4593
    
 
4594
    // Loop dofs and call evaluate_basis
 
4595
    for (unsigned int r = 0; r < 3; r++)
 
4596
    {
 
4597
      evaluate_basis(r, dof_values, x, vertex_coordinates, cell_orientation);
 
4598
      for (unsigned int s = 0; s < 3; s++)
 
4599
      {
 
4600
        values[r*3 + s] = dof_values[s];
 
4601
      }// end loop over 's'
 
4602
    }// end loop over 'r'
 
4603
  }
 
4604
 
 
4605
  /// Evaluate order n derivatives of basis function i at given point x in cell
 
4606
  virtual void evaluate_basis_derivatives(std::size_t i,
 
4607
                                          std::size_t n,
 
4608
                                          double* values,
 
4609
                                          const double* x,
 
4610
                                          const double* vertex_coordinates,
 
4611
                                          int cell_orientation) const
 
4612
  {
 
4613
    // Compute Jacobian
 
4614
    double J[6];
 
4615
    compute_jacobian_triangle_3d(J, vertex_coordinates);
 
4616
    
 
4617
    // Compute Jacobian inverse and determinant
 
4618
    double K[6];
 
4619
    double detJ;
 
4620
    compute_jacobian_inverse_triangle_3d(K, detJ, J);
 
4621
    
 
4622
    
 
4623
    const double b0 = vertex_coordinates[0];
 
4624
    const double b1 = vertex_coordinates[1];
 
4625
    const double b2 = vertex_coordinates[2];
 
4626
    
 
4627
    // P_FFC = J^dag (p - b), P_FIAT = 2*P_FFC - (1, 1)
 
4628
    double X = 2*(K[0]*(x[0] - b0) + K[1]*(x[1] - b1) + K[2]*(x[2] - b2)) - 1.0;
 
4629
    double Y = 2*(K[3]*(x[0] - b0) + K[4]*(x[1] - b1) + K[5]*(x[2] - b2)) - 1.0;
 
4630
    
 
4631
    
 
4632
    // Compute number of derivatives.
 
4633
    unsigned int num_derivatives_t = 1;
 
4634
    for (unsigned int r = 0; r < n; r++)
 
4635
    {
 
4636
      num_derivatives_t *= 2;
 
4637
    }// end loop over 'r'
 
4638
    
 
4639
    // Compute number of derivatives.
 
4640
    unsigned int num_derivatives_g = 1;
 
4641
    for (unsigned int r = 0; r < n; r++)
 
4642
    {
 
4643
      num_derivatives_g *= 3;
 
4644
    }// end loop over 'r'
 
4645
    
 
4646
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
4647
    unsigned int **combinations_t = new unsigned int *[num_derivatives_t];
 
4648
    for (unsigned int row = 0; row < num_derivatives_t; row++)
 
4649
    {
 
4650
      combinations_t[row] = new unsigned int [n];
 
4651
      for (unsigned int col = 0; col < n; col++)
 
4652
        combinations_t[row][col] = 0;
 
4653
    }
 
4654
    
 
4655
    // Generate combinations of derivatives
 
4656
    for (unsigned int row = 1; row < num_derivatives_t; row++)
 
4657
    {
 
4658
      for (unsigned int num = 0; num < row; num++)
 
4659
      {
 
4660
        for (unsigned int col = n-1; col+1 > 0; col--)
 
4661
        {
 
4662
          if (combinations_t[row][col] + 1 > 1)
 
4663
            combinations_t[row][col] = 0;
 
4664
          else
 
4665
          {
 
4666
            combinations_t[row][col] += 1;
 
4667
            break;
 
4668
          }
 
4669
        }
 
4670
      }
 
4671
    }
 
4672
    
 
4673
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
4674
    unsigned int **combinations_g = new unsigned int *[num_derivatives_g];
 
4675
    for (unsigned int row = 0; row < num_derivatives_g; row++)
 
4676
    {
 
4677
      combinations_g[row] = new unsigned int [n];
 
4678
      for (unsigned int col = 0; col < n; col++)
 
4679
        combinations_g[row][col] = 0;
 
4680
    }
 
4681
    
 
4682
    // Generate combinations of derivatives
 
4683
    for (unsigned int row = 1; row < num_derivatives_g; row++)
 
4684
    {
 
4685
      for (unsigned int num = 0; num < row; num++)
 
4686
      {
 
4687
        for (unsigned int col = n-1; col+1 > 0; col--)
 
4688
        {
 
4689
          if (combinations_g[row][col] + 1 > 2)
 
4690
            combinations_g[row][col] = 0;
 
4691
          else
 
4692
          {
 
4693
            combinations_g[row][col] += 1;
 
4694
            break;
 
4695
          }
 
4696
        }
 
4697
      }
 
4698
    }
 
4699
    
 
4700
    // Compute inverse of Jacobian
 
4701
    const double Jinv[2][3] = {{K[0], K[1], K[2]}, {K[3], K[4], K[5]}};
 
4702
    
 
4703
    // Declare transformation matrix
 
4704
    // Declare pointer to two dimensional array and initialise
 
4705
    double **transform = new double *[num_derivatives_g];
 
4706
    
 
4707
    for (unsigned int j = 0; j < num_derivatives_g; j++)
 
4708
    {
 
4709
      transform[j] = new double [num_derivatives_t];
 
4710
      for (unsigned int k = 0; k < num_derivatives_t; k++)
 
4711
        transform[j][k] = 1;
 
4712
    }
 
4713
    
 
4714
    // Construct transformation matrix
 
4715
    for (unsigned int row = 0; row < num_derivatives_g; row++)
 
4716
    {
 
4717
      for (unsigned int col = 0; col < num_derivatives_t; col++)
 
4718
      {
 
4719
        for (unsigned int k = 0; k < n; k++)
 
4720
          transform[row][col] *= Jinv[combinations_t[col][k]][combinations_g[row][k]];
 
4721
      }
 
4722
    }
 
4723
    
 
4724
    // Reset values. Assuming that values is always an array.
 
4725
    for (unsigned int r = 0; r < 3*num_derivatives_g; r++)
 
4726
    {
 
4727
      values[r] = 0.0;
 
4728
    }// end loop over 'r'
 
4729
    
 
4730
    switch (i)
 
4731
    {
 
4732
    case 0:
 
4733
      {
 
4734
        
 
4735
      // Array of basisvalues
 
4736
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
4737
      
 
4738
      // Declare helper variables
 
4739
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
4740
      
 
4741
      // Compute basisvalues
 
4742
      basisvalues[0] = 1.0;
 
4743
      basisvalues[1] = tmp0;
 
4744
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
4745
      basisvalues[0] *= std::sqrt(0.5);
 
4746
      basisvalues[2] *= std::sqrt(1.0);
 
4747
      basisvalues[1] *= std::sqrt(3.0);
 
4748
      
 
4749
      // Table(s) of coefficients
 
4750
      static const double coefficients0[3] = \
 
4751
      {-0.47140452, 0.0, -0.33333333};
 
4752
      
 
4753
      static const double coefficients1[3] = \
 
4754
      {0.47140452, 0.28867513, -0.16666667};
 
4755
      
 
4756
      // Tables of derivatives of the polynomial base (transpose).
 
4757
      static const double dmats0[3][3] = \
 
4758
      {{0.0, 0.0, 0.0},
 
4759
      {4.8989795, 0.0, 0.0},
 
4760
      {0.0, 0.0, 0.0}};
 
4761
      
 
4762
      static const double dmats1[3][3] = \
 
4763
      {{0.0, 0.0, 0.0},
 
4764
      {2.4494897, 0.0, 0.0},
 
4765
      {4.2426407, 0.0, 0.0}};
 
4766
      
 
4767
      // Compute reference derivatives.
 
4768
      // Declare pointer to array of derivatives on FIAT element.
 
4769
      double *derivatives = new double[2*num_derivatives_t];
 
4770
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
4771
      {
 
4772
        derivatives[r] = 0.0;
 
4773
      }// end loop over 'r'
 
4774
      
 
4775
      // Declare pointer to array of reference derivatives on physical element.
 
4776
      double *derivatives_p = new double[3*num_derivatives_t];
 
4777
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
4778
      {
 
4779
        derivatives_p[r] = 0.0;
 
4780
      }// end loop over 'r'
 
4781
      
 
4782
      // Declare derivative matrix (of polynomial basis).
 
4783
      double dmats[3][3] = \
 
4784
      {{1.0, 0.0, 0.0},
 
4785
      {0.0, 1.0, 0.0},
 
4786
      {0.0, 0.0, 1.0}};
 
4787
      
 
4788
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
4789
      double dmats_old[3][3] = \
 
4790
      {{1.0, 0.0, 0.0},
 
4791
      {0.0, 1.0, 0.0},
 
4792
      {0.0, 0.0, 1.0}};
 
4793
      
 
4794
      // Loop possible derivatives.
 
4795
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
4796
      {
 
4797
        // Resetting dmats values to compute next derivative.
 
4798
        for (unsigned int t = 0; t < 3; t++)
 
4799
        {
 
4800
          for (unsigned int u = 0; u < 3; u++)
 
4801
          {
 
4802
            dmats[t][u] = 0.0;
 
4803
            if (t == u)
 
4804
            {
 
4805
            dmats[t][u] = 1.0;
 
4806
            }
 
4807
            
 
4808
          }// end loop over 'u'
 
4809
        }// end loop over 't'
 
4810
        
 
4811
        // Looping derivative order to generate dmats.
 
4812
        for (unsigned int s = 0; s < n; s++)
 
4813
        {
 
4814
          // Updating dmats_old with new values and resetting dmats.
 
4815
          for (unsigned int t = 0; t < 3; t++)
 
4816
          {
 
4817
            for (unsigned int u = 0; u < 3; u++)
 
4818
            {
 
4819
              dmats_old[t][u] = dmats[t][u];
 
4820
              dmats[t][u] = 0.0;
 
4821
            }// end loop over 'u'
 
4822
          }// end loop over 't'
 
4823
          
 
4824
          // Update dmats using an inner product.
 
4825
          if (combinations_t[r][s] == 0)
 
4826
          {
 
4827
          for (unsigned int t = 0; t < 3; t++)
 
4828
          {
 
4829
            for (unsigned int u = 0; u < 3; u++)
 
4830
            {
 
4831
              for (unsigned int tu = 0; tu < 3; tu++)
 
4832
              {
 
4833
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
4834
              }// end loop over 'tu'
 
4835
            }// end loop over 'u'
 
4836
          }// end loop over 't'
 
4837
          }
 
4838
          
 
4839
          if (combinations_t[r][s] == 1)
 
4840
          {
 
4841
          for (unsigned int t = 0; t < 3; t++)
 
4842
          {
 
4843
            for (unsigned int u = 0; u < 3; u++)
 
4844
            {
 
4845
              for (unsigned int tu = 0; tu < 3; tu++)
 
4846
              {
 
4847
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
4848
              }// end loop over 'tu'
 
4849
            }// end loop over 'u'
 
4850
          }// end loop over 't'
 
4851
          }
 
4852
          
 
4853
        }// end loop over 's'
 
4854
        for (unsigned int s = 0; s < 3; s++)
 
4855
        {
 
4856
          for (unsigned int t = 0; t < 3; t++)
 
4857
          {
 
4858
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
4859
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
4860
          }// end loop over 't'
 
4861
        }// end loop over 's'
 
4862
        
 
4863
        // Using covariant Piola transform to map values back to the physical element
 
4864
        const double tmp_ref0 = derivatives[r];
 
4865
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
4866
        derivatives_p[r] = (K[0]*tmp_ref0 + K[3]*tmp_ref1);
 
4867
        derivatives_p[num_derivatives_t + r] = (K[1]*tmp_ref0 + K[4]*tmp_ref1);
 
4868
        derivatives_p[2*num_derivatives_t + r] = (K[2]*tmp_ref0 + K[5]*tmp_ref1);
 
4869
      }// end loop over 'r'
 
4870
      
 
4871
      // Transform derivatives back to physical element
 
4872
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
4873
      {
 
4874
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
4875
        {
 
4876
          values[r] += transform[r][s]*derivatives_p[s];
 
4877
          values[num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
4878
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
4879
        }// end loop over 's'
 
4880
      }// end loop over 'r'
 
4881
      
 
4882
      // Delete pointer to array of derivatives on FIAT element
 
4883
      delete [] derivatives;
 
4884
      
 
4885
      // Delete pointer to array of reference derivatives on physical element.
 
4886
      delete [] derivatives_p;
 
4887
      
 
4888
      // Delete pointer to array of combinations of derivatives and transform
 
4889
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
4890
      {
 
4891
        delete [] combinations_t[r];
 
4892
      }// end loop over 'r'
 
4893
      delete [] combinations_t;
 
4894
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
4895
      {
 
4896
        delete [] combinations_g[r];
 
4897
      }// end loop over 'r'
 
4898
      delete [] combinations_g;
 
4899
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
4900
      {
 
4901
        delete [] transform[r];
 
4902
      }// end loop over 'r'
 
4903
      delete [] transform;
 
4904
        break;
 
4905
      }
 
4906
    case 1:
 
4907
      {
 
4908
        
 
4909
      // Array of basisvalues
 
4910
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
4911
      
 
4912
      // Declare helper variables
 
4913
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
4914
      
 
4915
      // Compute basisvalues
 
4916
      basisvalues[0] = 1.0;
 
4917
      basisvalues[1] = tmp0;
 
4918
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
4919
      basisvalues[0] *= std::sqrt(0.5);
 
4920
      basisvalues[2] *= std::sqrt(1.0);
 
4921
      basisvalues[1] *= std::sqrt(3.0);
 
4922
      
 
4923
      // Table(s) of coefficients
 
4924
      static const double coefficients0[3] = \
 
4925
      {0.47140452, 0.0, 0.33333333};
 
4926
      
 
4927
      static const double coefficients1[3] = \
 
4928
      {0.94280904, -0.28867513, 0.16666667};
 
4929
      
 
4930
      // Tables of derivatives of the polynomial base (transpose).
 
4931
      static const double dmats0[3][3] = \
 
4932
      {{0.0, 0.0, 0.0},
 
4933
      {4.8989795, 0.0, 0.0},
 
4934
      {0.0, 0.0, 0.0}};
 
4935
      
 
4936
      static const double dmats1[3][3] = \
 
4937
      {{0.0, 0.0, 0.0},
 
4938
      {2.4494897, 0.0, 0.0},
 
4939
      {4.2426407, 0.0, 0.0}};
 
4940
      
 
4941
      // Compute reference derivatives.
 
4942
      // Declare pointer to array of derivatives on FIAT element.
 
4943
      double *derivatives = new double[2*num_derivatives_t];
 
4944
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
4945
      {
 
4946
        derivatives[r] = 0.0;
 
4947
      }// end loop over 'r'
 
4948
      
 
4949
      // Declare pointer to array of reference derivatives on physical element.
 
4950
      double *derivatives_p = new double[3*num_derivatives_t];
 
4951
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
4952
      {
 
4953
        derivatives_p[r] = 0.0;
 
4954
      }// end loop over 'r'
 
4955
      
 
4956
      // Declare derivative matrix (of polynomial basis).
 
4957
      double dmats[3][3] = \
 
4958
      {{1.0, 0.0, 0.0},
 
4959
      {0.0, 1.0, 0.0},
 
4960
      {0.0, 0.0, 1.0}};
 
4961
      
 
4962
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
4963
      double dmats_old[3][3] = \
 
4964
      {{1.0, 0.0, 0.0},
 
4965
      {0.0, 1.0, 0.0},
 
4966
      {0.0, 0.0, 1.0}};
 
4967
      
 
4968
      // Loop possible derivatives.
 
4969
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
4970
      {
 
4971
        // Resetting dmats values to compute next derivative.
 
4972
        for (unsigned int t = 0; t < 3; t++)
 
4973
        {
 
4974
          for (unsigned int u = 0; u < 3; u++)
 
4975
          {
 
4976
            dmats[t][u] = 0.0;
 
4977
            if (t == u)
 
4978
            {
 
4979
            dmats[t][u] = 1.0;
 
4980
            }
 
4981
            
 
4982
          }// end loop over 'u'
 
4983
        }// end loop over 't'
 
4984
        
 
4985
        // Looping derivative order to generate dmats.
 
4986
        for (unsigned int s = 0; s < n; s++)
 
4987
        {
 
4988
          // Updating dmats_old with new values and resetting dmats.
 
4989
          for (unsigned int t = 0; t < 3; t++)
 
4990
          {
 
4991
            for (unsigned int u = 0; u < 3; u++)
 
4992
            {
 
4993
              dmats_old[t][u] = dmats[t][u];
 
4994
              dmats[t][u] = 0.0;
 
4995
            }// end loop over 'u'
 
4996
          }// end loop over 't'
 
4997
          
 
4998
          // Update dmats using an inner product.
 
4999
          if (combinations_t[r][s] == 0)
 
5000
          {
 
5001
          for (unsigned int t = 0; t < 3; t++)
 
5002
          {
 
5003
            for (unsigned int u = 0; u < 3; u++)
 
5004
            {
 
5005
              for (unsigned int tu = 0; tu < 3; tu++)
 
5006
              {
 
5007
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
5008
              }// end loop over 'tu'
 
5009
            }// end loop over 'u'
 
5010
          }// end loop over 't'
 
5011
          }
 
5012
          
 
5013
          if (combinations_t[r][s] == 1)
 
5014
          {
 
5015
          for (unsigned int t = 0; t < 3; t++)
 
5016
          {
 
5017
            for (unsigned int u = 0; u < 3; u++)
 
5018
            {
 
5019
              for (unsigned int tu = 0; tu < 3; tu++)
 
5020
              {
 
5021
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
5022
              }// end loop over 'tu'
 
5023
            }// end loop over 'u'
 
5024
          }// end loop over 't'
 
5025
          }
 
5026
          
 
5027
        }// end loop over 's'
 
5028
        for (unsigned int s = 0; s < 3; s++)
 
5029
        {
 
5030
          for (unsigned int t = 0; t < 3; t++)
 
5031
          {
 
5032
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
5033
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
5034
          }// end loop over 't'
 
5035
        }// end loop over 's'
 
5036
        
 
5037
        // Using covariant Piola transform to map values back to the physical element
 
5038
        const double tmp_ref0 = derivatives[r];
 
5039
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
5040
        derivatives_p[r] = (K[0]*tmp_ref0 + K[3]*tmp_ref1);
 
5041
        derivatives_p[num_derivatives_t + r] = (K[1]*tmp_ref0 + K[4]*tmp_ref1);
 
5042
        derivatives_p[2*num_derivatives_t + r] = (K[2]*tmp_ref0 + K[5]*tmp_ref1);
 
5043
      }// end loop over 'r'
 
5044
      
 
5045
      // Transform derivatives back to physical element
 
5046
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
5047
      {
 
5048
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
5049
        {
 
5050
          values[r] += transform[r][s]*derivatives_p[s];
 
5051
          values[num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
5052
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
5053
        }// end loop over 's'
 
5054
      }// end loop over 'r'
 
5055
      
 
5056
      // Delete pointer to array of derivatives on FIAT element
 
5057
      delete [] derivatives;
 
5058
      
 
5059
      // Delete pointer to array of reference derivatives on physical element.
 
5060
      delete [] derivatives_p;
 
5061
      
 
5062
      // Delete pointer to array of combinations of derivatives and transform
 
5063
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
5064
      {
 
5065
        delete [] combinations_t[r];
 
5066
      }// end loop over 'r'
 
5067
      delete [] combinations_t;
 
5068
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
5069
      {
 
5070
        delete [] combinations_g[r];
 
5071
      }// end loop over 'r'
 
5072
      delete [] combinations_g;
 
5073
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
5074
      {
 
5075
        delete [] transform[r];
 
5076
      }// end loop over 'r'
 
5077
      delete [] transform;
 
5078
        break;
 
5079
      }
 
5080
    case 2:
 
5081
      {
 
5082
        
 
5083
      // Array of basisvalues
 
5084
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
5085
      
 
5086
      // Declare helper variables
 
5087
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
5088
      
 
5089
      // Compute basisvalues
 
5090
      basisvalues[0] = 1.0;
 
5091
      basisvalues[1] = tmp0;
 
5092
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
5093
      basisvalues[0] *= std::sqrt(0.5);
 
5094
      basisvalues[2] *= std::sqrt(1.0);
 
5095
      basisvalues[1] *= std::sqrt(3.0);
 
5096
      
 
5097
      // Table(s) of coefficients
 
5098
      static const double coefficients0[3] = \
 
5099
      {0.94280904, 0.0, -0.33333333};
 
5100
      
 
5101
      static const double coefficients1[3] = \
 
5102
      {0.47140452, 0.28867513, -0.16666667};
 
5103
      
 
5104
      // Tables of derivatives of the polynomial base (transpose).
 
5105
      static const double dmats0[3][3] = \
 
5106
      {{0.0, 0.0, 0.0},
 
5107
      {4.8989795, 0.0, 0.0},
 
5108
      {0.0, 0.0, 0.0}};
 
5109
      
 
5110
      static const double dmats1[3][3] = \
 
5111
      {{0.0, 0.0, 0.0},
 
5112
      {2.4494897, 0.0, 0.0},
 
5113
      {4.2426407, 0.0, 0.0}};
 
5114
      
 
5115
      // Compute reference derivatives.
 
5116
      // Declare pointer to array of derivatives on FIAT element.
 
5117
      double *derivatives = new double[2*num_derivatives_t];
 
5118
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
5119
      {
 
5120
        derivatives[r] = 0.0;
 
5121
      }// end loop over 'r'
 
5122
      
 
5123
      // Declare pointer to array of reference derivatives on physical element.
 
5124
      double *derivatives_p = new double[3*num_derivatives_t];
 
5125
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
5126
      {
 
5127
        derivatives_p[r] = 0.0;
 
5128
      }// end loop over 'r'
 
5129
      
 
5130
      // Declare derivative matrix (of polynomial basis).
 
5131
      double dmats[3][3] = \
 
5132
      {{1.0, 0.0, 0.0},
 
5133
      {0.0, 1.0, 0.0},
 
5134
      {0.0, 0.0, 1.0}};
 
5135
      
 
5136
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
5137
      double dmats_old[3][3] = \
 
5138
      {{1.0, 0.0, 0.0},
 
5139
      {0.0, 1.0, 0.0},
 
5140
      {0.0, 0.0, 1.0}};
 
5141
      
 
5142
      // Loop possible derivatives.
 
5143
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
5144
      {
 
5145
        // Resetting dmats values to compute next derivative.
 
5146
        for (unsigned int t = 0; t < 3; t++)
 
5147
        {
 
5148
          for (unsigned int u = 0; u < 3; u++)
 
5149
          {
 
5150
            dmats[t][u] = 0.0;
 
5151
            if (t == u)
 
5152
            {
 
5153
            dmats[t][u] = 1.0;
 
5154
            }
 
5155
            
 
5156
          }// end loop over 'u'
 
5157
        }// end loop over 't'
 
5158
        
 
5159
        // Looping derivative order to generate dmats.
 
5160
        for (unsigned int s = 0; s < n; s++)
 
5161
        {
 
5162
          // Updating dmats_old with new values and resetting dmats.
 
5163
          for (unsigned int t = 0; t < 3; t++)
 
5164
          {
 
5165
            for (unsigned int u = 0; u < 3; u++)
 
5166
            {
 
5167
              dmats_old[t][u] = dmats[t][u];
 
5168
              dmats[t][u] = 0.0;
 
5169
            }// end loop over 'u'
 
5170
          }// end loop over 't'
 
5171
          
 
5172
          // Update dmats using an inner product.
 
5173
          if (combinations_t[r][s] == 0)
 
5174
          {
 
5175
          for (unsigned int t = 0; t < 3; t++)
 
5176
          {
 
5177
            for (unsigned int u = 0; u < 3; u++)
 
5178
            {
 
5179
              for (unsigned int tu = 0; tu < 3; tu++)
 
5180
              {
 
5181
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
5182
              }// end loop over 'tu'
 
5183
            }// end loop over 'u'
 
5184
          }// end loop over 't'
 
5185
          }
 
5186
          
 
5187
          if (combinations_t[r][s] == 1)
 
5188
          {
 
5189
          for (unsigned int t = 0; t < 3; t++)
 
5190
          {
 
5191
            for (unsigned int u = 0; u < 3; u++)
 
5192
            {
 
5193
              for (unsigned int tu = 0; tu < 3; tu++)
 
5194
              {
 
5195
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
5196
              }// end loop over 'tu'
 
5197
            }// end loop over 'u'
 
5198
          }// end loop over 't'
 
5199
          }
 
5200
          
 
5201
        }// end loop over 's'
 
5202
        for (unsigned int s = 0; s < 3; s++)
 
5203
        {
 
5204
          for (unsigned int t = 0; t < 3; t++)
 
5205
          {
 
5206
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
5207
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
5208
          }// end loop over 't'
 
5209
        }// end loop over 's'
 
5210
        
 
5211
        // Using covariant Piola transform to map values back to the physical element
 
5212
        const double tmp_ref0 = derivatives[r];
 
5213
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
5214
        derivatives_p[r] = (K[0]*tmp_ref0 + K[3]*tmp_ref1);
 
5215
        derivatives_p[num_derivatives_t + r] = (K[1]*tmp_ref0 + K[4]*tmp_ref1);
 
5216
        derivatives_p[2*num_derivatives_t + r] = (K[2]*tmp_ref0 + K[5]*tmp_ref1);
 
5217
      }// end loop over 'r'
 
5218
      
 
5219
      // Transform derivatives back to physical element
 
5220
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
5221
      {
 
5222
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
5223
        {
 
5224
          values[r] += transform[r][s]*derivatives_p[s];
 
5225
          values[num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
5226
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
5227
        }// end loop over 's'
 
5228
      }// end loop over 'r'
 
5229
      
 
5230
      // Delete pointer to array of derivatives on FIAT element
 
5231
      delete [] derivatives;
 
5232
      
 
5233
      // Delete pointer to array of reference derivatives on physical element.
 
5234
      delete [] derivatives_p;
 
5235
      
 
5236
      // Delete pointer to array of combinations of derivatives and transform
 
5237
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
5238
      {
 
5239
        delete [] combinations_t[r];
 
5240
      }// end loop over 'r'
 
5241
      delete [] combinations_t;
 
5242
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
5243
      {
 
5244
        delete [] combinations_g[r];
 
5245
      }// end loop over 'r'
 
5246
      delete [] combinations_g;
 
5247
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
5248
      {
 
5249
        delete [] transform[r];
 
5250
      }// end loop over 'r'
 
5251
      delete [] transform;
 
5252
        break;
 
5253
      }
 
5254
    }
 
5255
    
 
5256
  }
 
5257
 
 
5258
  /// Evaluate order n derivatives of all basis functions at given point x in cell
 
5259
  virtual void evaluate_basis_derivatives_all(std::size_t n,
 
5260
                                              double* values,
 
5261
                                              const double* x,
 
5262
                                              const double* vertex_coordinates,
 
5263
                                              int cell_orientation) const
 
5264
  {
 
5265
    // Compute number of derivatives.
 
5266
    unsigned int num_derivatives_g = 1;
 
5267
    for (unsigned int r = 0; r < n; r++)
 
5268
    {
 
5269
      num_derivatives_g *= 3;
 
5270
    }// end loop over 'r'
 
5271
    
 
5272
    // Helper variable to hold values of a single dof.
 
5273
    double *dof_values = new double[3*num_derivatives_g];
 
5274
    for (unsigned int r = 0; r < 3*num_derivatives_g; r++)
 
5275
    {
 
5276
      dof_values[r] = 0.0;
 
5277
    }// end loop over 'r'
 
5278
    
 
5279
    // Loop dofs and call evaluate_basis_derivatives.
 
5280
    for (unsigned int r = 0; r < 3; r++)
 
5281
    {
 
5282
      evaluate_basis_derivatives(r, n, dof_values, x, vertex_coordinates, cell_orientation);
 
5283
      for (unsigned int s = 0; s < 3*num_derivatives_g; s++)
 
5284
      {
 
5285
        values[r*3*num_derivatives_g + s] = dof_values[s];
 
5286
      }// end loop over 's'
 
5287
    }// end loop over 'r'
 
5288
    
 
5289
    // Delete pointer.
 
5290
    delete [] dof_values;
 
5291
  }
 
5292
 
 
5293
  /// Evaluate linear functional for dof i on the function f
 
5294
  virtual double evaluate_dof(std::size_t i,
 
5295
                              const ufc::function& f,
 
5296
                              const double* vertex_coordinates,
 
5297
                              int cell_orientation,
 
5298
                              const ufc::cell& c) const
 
5299
  {
 
5300
    // Declare variables for result of evaluation
 
5301
    double vals[3];
 
5302
    
 
5303
    // Declare variable for physical coordinates
 
5304
    double y[3];
 
5305
    
 
5306
    double result;
 
5307
    // Compute Jacobian
 
5308
    double J[6];
 
5309
    compute_jacobian_triangle_3d(J, vertex_coordinates);
 
5310
    switch (i)
 
5311
    {
 
5312
    case 0:
 
5313
      {
 
5314
        y[0] = 0.5*vertex_coordinates[3] + 0.5*vertex_coordinates[6];
 
5315
      y[1] = 0.5*vertex_coordinates[4] + 0.5*vertex_coordinates[7];
 
5316
      y[2] = 0.5*vertex_coordinates[5] + 0.5*vertex_coordinates[8];
 
5317
      f.evaluate(vals, y, c);
 
5318
      result = (-1.0)*(J[0]*vals[0] + J[2]*vals[1] + J[4]*vals[2]) + (J[1]*vals[0] + J[3]*vals[1] + J[5]*vals[2]);
 
5319
      return result;
 
5320
        break;
 
5321
      }
 
5322
    case 1:
 
5323
      {
 
5324
        y[0] = 0.5*vertex_coordinates[0] + 0.5*vertex_coordinates[6];
 
5325
      y[1] = 0.5*vertex_coordinates[1] + 0.5*vertex_coordinates[7];
 
5326
      y[2] = 0.5*vertex_coordinates[2] + 0.5*vertex_coordinates[8];
 
5327
      f.evaluate(vals, y, c);
 
5328
      result = (J[1]*vals[0] + J[3]*vals[1] + J[5]*vals[2]);
 
5329
      return result;
 
5330
        break;
 
5331
      }
 
5332
    case 2:
 
5333
      {
 
5334
        y[0] = 0.5*vertex_coordinates[0] + 0.5*vertex_coordinates[3];
 
5335
      y[1] = 0.5*vertex_coordinates[1] + 0.5*vertex_coordinates[4];
 
5336
      y[2] = 0.5*vertex_coordinates[2] + 0.5*vertex_coordinates[5];
 
5337
      f.evaluate(vals, y, c);
 
5338
      result = (J[0]*vals[0] + J[2]*vals[1] + J[4]*vals[2]);
 
5339
      return result;
 
5340
        break;
 
5341
      }
 
5342
    }
 
5343
    
 
5344
    return 0.0;
 
5345
  }
 
5346
 
 
5347
  /// Evaluate linear functionals for all dofs on the function f
 
5348
  virtual void evaluate_dofs(double* values,
 
5349
                             const ufc::function& f,
 
5350
                             const double* vertex_coordinates,
 
5351
                             int cell_orientation,
 
5352
                             const ufc::cell& c) const
 
5353
  {
 
5354
    // Declare variables for result of evaluation
 
5355
    double vals[3];
 
5356
    
 
5357
    // Declare variable for physical coordinates
 
5358
    double y[3];
 
5359
    
 
5360
    double result;
 
5361
    // Compute Jacobian
 
5362
    double J[6];
 
5363
    compute_jacobian_triangle_3d(J, vertex_coordinates);
 
5364
    y[0] = 0.5*vertex_coordinates[3] + 0.5*vertex_coordinates[6];
 
5365
    y[1] = 0.5*vertex_coordinates[4] + 0.5*vertex_coordinates[7];
 
5366
    y[2] = 0.5*vertex_coordinates[5] + 0.5*vertex_coordinates[8];
 
5367
    f.evaluate(vals, y, c);
 
5368
    result = (-1.0)*(J[0]*vals[0] + J[2]*vals[1] + J[4]*vals[2]) + (J[1]*vals[0] + J[3]*vals[1] + J[5]*vals[2]);
 
5369
    values[0] = result;
 
5370
    y[0] = 0.5*vertex_coordinates[0] + 0.5*vertex_coordinates[6];
 
5371
    y[1] = 0.5*vertex_coordinates[1] + 0.5*vertex_coordinates[7];
 
5372
    y[2] = 0.5*vertex_coordinates[2] + 0.5*vertex_coordinates[8];
 
5373
    f.evaluate(vals, y, c);
 
5374
    result = (J[1]*vals[0] + J[3]*vals[1] + J[5]*vals[2]);
 
5375
    values[1] = result;
 
5376
    y[0] = 0.5*vertex_coordinates[0] + 0.5*vertex_coordinates[3];
 
5377
    y[1] = 0.5*vertex_coordinates[1] + 0.5*vertex_coordinates[4];
 
5378
    y[2] = 0.5*vertex_coordinates[2] + 0.5*vertex_coordinates[5];
 
5379
    f.evaluate(vals, y, c);
 
5380
    result = (J[0]*vals[0] + J[2]*vals[1] + J[4]*vals[2]);
 
5381
    values[2] = result;
 
5382
  }
 
5383
 
 
5384
  /// Interpolate vertex values from dof values
 
5385
  virtual void interpolate_vertex_values(double* vertex_values,
 
5386
                                         const double* dof_values,
 
5387
                                         const double* vertex_coordinates,
 
5388
                                         int cell_orientation,
 
5389
                                         const ufc::cell& c) const
 
5390
  {
 
5391
    // Compute Jacobian
 
5392
    double J[6];
 
5393
    compute_jacobian_triangle_3d(J, vertex_coordinates);
 
5394
    
 
5395
    
 
5396
    // Compute Jacobian inverse and determinant
 
5397
    double K[6];
 
5398
    double detJ;
 
5399
    compute_jacobian_inverse_triangle_3d(K, detJ, J);
 
5400
    
 
5401
    // Evaluate function and change variables
 
5402
    vertex_values[0] = dof_values[1]*K[3] + dof_values[2]*K[0];
 
5403
    vertex_values[2] = dof_values[0]*K[3] + dof_values[2]*(K[0] + K[3]);
 
5404
    vertex_values[4] = dof_values[0]*(K[0]*(-1.0)) + dof_values[1]*(K[0] + K[3]);
 
5405
    vertex_values[1] = dof_values[1]*K[4] + dof_values[2]*K[1];
 
5406
    vertex_values[3] = dof_values[0]*K[4] + dof_values[2]*(K[1] + K[4]);
 
5407
    vertex_values[5] = dof_values[0]*(K[1]*(-1.0)) + dof_values[1]*(K[1] + K[4]);
 
5408
  }
 
5409
 
 
5410
  /// Map coordinate xhat from reference cell to coordinate x in cell
 
5411
  virtual void map_from_reference_cell(double* x,
 
5412
                                       const double* xhat,
 
5413
                                       const ufc::cell& c) const
 
5414
  {
 
5415
    std::cerr << "*** FFC warning: " << "map_from_reference_cell not yet implemented." << std::endl;
 
5416
  }
 
5417
 
 
5418
  /// Map from coordinate x in cell to coordinate xhat in reference cell
 
5419
  virtual void map_to_reference_cell(double* xhat,
 
5420
                                     const double* x,
 
5421
                                     const ufc::cell& c) const
 
5422
  {
 
5423
    std::cerr << "*** FFC warning: " << "map_to_reference_cell not yet implemented." << std::endl;
 
5424
  }
 
5425
 
 
5426
  /// Return the number of sub elements (for a mixed element)
 
5427
  virtual std::size_t num_sub_elements() const
 
5428
  {
 
5429
    return 0;
 
5430
  }
 
5431
 
 
5432
  /// Create a new finite element for sub element i (for a mixed element)
 
5433
  virtual ufc::finite_element* create_sub_element(std::size_t i) const
 
5434
  {
 
5435
    return 0;
 
5436
  }
 
5437
 
 
5438
  /// Create a new class instance
 
5439
  virtual ufc::finite_element* create() const
 
5440
  {
 
5441
    return new x_element9_finite_element_2();
 
5442
  }
 
5443
 
 
5444
};
 
5445
 
 
5446
/// This class defines the interface for a finite element.
 
5447
 
 
5448
class x_element9_finite_element_3: public ufc::finite_element
 
5449
{
 
5450
public:
 
5451
 
 
5452
  /// Constructor
 
5453
  x_element9_finite_element_3() : ufc::finite_element()
 
5454
  {
 
5455
    // Do nothing
 
5456
  }
 
5457
 
 
5458
  /// Destructor
 
5459
  virtual ~x_element9_finite_element_3()
 
5460
  {
 
5461
    // Do nothing
 
5462
  }
 
5463
 
 
5464
  /// Return a string identifying the finite element
 
5465
  virtual const char* signature() const
 
5466
  {
 
5467
    return "FiniteElement('Discontinuous Lagrange', Domain(Cell('triangle', 3), 'triangle_multiverse', 3, 2), 1, None)";
 
5468
  }
 
5469
 
 
5470
  /// Return the cell shape
 
5471
  virtual ufc::shape cell_shape() const
 
5472
  {
 
5473
    return ufc::triangle;
 
5474
  }
 
5475
 
 
5476
  /// Return the topological dimension of the cell shape
 
5477
  virtual std::size_t topological_dimension() const
 
5478
  {
 
5479
    return 2;
 
5480
  }
 
5481
 
 
5482
  /// Return the geometric dimension of the cell shape
 
5483
  virtual std::size_t geometric_dimension() const
 
5484
  {
 
5485
    return 3;
 
5486
  }
 
5487
 
 
5488
  /// Return the dimension of the finite element function space
 
5489
  virtual std::size_t space_dimension() const
 
5490
  {
 
5491
    return 3;
 
5492
  }
 
5493
 
 
5494
  /// Return the rank of the value space
 
5495
  virtual std::size_t value_rank() const
 
5496
  {
 
5497
    return 0;
 
5498
  }
 
5499
 
 
5500
  /// Return the dimension of the value space for axis i
 
5501
  virtual std::size_t value_dimension(std::size_t i) const
 
5502
  {
 
5503
    return 1;
 
5504
  }
 
5505
 
 
5506
  /// Evaluate basis function i at given point x in cell
 
5507
  virtual void evaluate_basis(std::size_t i,
 
5508
                              double* values,
 
5509
                              const double* x,
 
5510
                              const double* vertex_coordinates,
 
5511
                              int cell_orientation) const
 
5512
  {
 
5513
    // Compute Jacobian
 
5514
    double J[6];
 
5515
    compute_jacobian_triangle_3d(J, vertex_coordinates);
 
5516
    
 
5517
    // Compute Jacobian inverse and determinant
 
5518
    double K[6];
 
5519
    double detJ;
 
5520
    compute_jacobian_inverse_triangle_3d(K, detJ, J);
 
5521
    
 
5522
    
 
5523
    const double b0 = vertex_coordinates[0];
 
5524
    const double b1 = vertex_coordinates[1];
 
5525
    const double b2 = vertex_coordinates[2];
 
5526
    
 
5527
    // P_FFC = J^dag (p - b), P_FIAT = 2*P_FFC - (1, 1)
 
5528
    double X = 2*(K[0]*(x[0] - b0) + K[1]*(x[1] - b1) + K[2]*(x[2] - b2)) - 1.0;
 
5529
    double Y = 2*(K[3]*(x[0] - b0) + K[4]*(x[1] - b1) + K[5]*(x[2] - b2)) - 1.0;
 
5530
    
 
5531
    
 
5532
    // Reset values
 
5533
    *values = 0.0;
 
5534
    switch (i)
 
5535
    {
 
5536
    case 0:
 
5537
      {
 
5538
        
 
5539
      // Array of basisvalues
 
5540
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
5541
      
 
5542
      // Declare helper variables
 
5543
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
5544
      
 
5545
      // Compute basisvalues
 
5546
      basisvalues[0] = 1.0;
 
5547
      basisvalues[1] = tmp0;
 
5548
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
5549
      basisvalues[0] *= std::sqrt(0.5);
 
5550
      basisvalues[2] *= std::sqrt(1.0);
 
5551
      basisvalues[1] *= std::sqrt(3.0);
 
5552
      
 
5553
      // Table(s) of coefficients
 
5554
      static const double coefficients0[3] = \
 
5555
      {0.47140452, -0.28867513, -0.16666667};
 
5556
      
 
5557
      // Compute value(s)
 
5558
      for (unsigned int r = 0; r < 3; r++)
 
5559
      {
 
5560
        *values += coefficients0[r]*basisvalues[r];
 
5561
      }// end loop over 'r'
 
5562
        break;
 
5563
      }
 
5564
    case 1:
 
5565
      {
 
5566
        
 
5567
      // Array of basisvalues
 
5568
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
5569
      
 
5570
      // Declare helper variables
 
5571
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
5572
      
 
5573
      // Compute basisvalues
 
5574
      basisvalues[0] = 1.0;
 
5575
      basisvalues[1] = tmp0;
 
5576
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
5577
      basisvalues[0] *= std::sqrt(0.5);
 
5578
      basisvalues[2] *= std::sqrt(1.0);
 
5579
      basisvalues[1] *= std::sqrt(3.0);
 
5580
      
 
5581
      // Table(s) of coefficients
 
5582
      static const double coefficients0[3] = \
 
5583
      {0.47140452, 0.28867513, -0.16666667};
 
5584
      
 
5585
      // Compute value(s)
 
5586
      for (unsigned int r = 0; r < 3; r++)
 
5587
      {
 
5588
        *values += coefficients0[r]*basisvalues[r];
 
5589
      }// end loop over 'r'
 
5590
        break;
 
5591
      }
 
5592
    case 2:
 
5593
      {
 
5594
        
 
5595
      // Array of basisvalues
 
5596
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
5597
      
 
5598
      // Declare helper variables
 
5599
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
5600
      
 
5601
      // Compute basisvalues
 
5602
      basisvalues[0] = 1.0;
 
5603
      basisvalues[1] = tmp0;
 
5604
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
5605
      basisvalues[0] *= std::sqrt(0.5);
 
5606
      basisvalues[2] *= std::sqrt(1.0);
 
5607
      basisvalues[1] *= std::sqrt(3.0);
 
5608
      
 
5609
      // Table(s) of coefficients
 
5610
      static const double coefficients0[3] = \
 
5611
      {0.47140452, 0.0, 0.33333333};
 
5612
      
 
5613
      // Compute value(s)
 
5614
      for (unsigned int r = 0; r < 3; r++)
 
5615
      {
 
5616
        *values += coefficients0[r]*basisvalues[r];
 
5617
      }// end loop over 'r'
 
5618
        break;
 
5619
      }
 
5620
    }
 
5621
    
 
5622
  }
 
5623
 
 
5624
  /// Evaluate all basis functions at given point x in cell
 
5625
  virtual void evaluate_basis_all(double* values,
 
5626
                                  const double* x,
 
5627
                                  const double* vertex_coordinates,
 
5628
                                  int cell_orientation) const
 
5629
  {
 
5630
    // Helper variable to hold values of a single dof.
 
5631
    double dof_values = 0.0;
 
5632
    
 
5633
    // Loop dofs and call evaluate_basis
 
5634
    for (unsigned int r = 0; r < 3; r++)
 
5635
    {
 
5636
      evaluate_basis(r, &dof_values, x, vertex_coordinates, cell_orientation);
 
5637
      values[r] = dof_values;
 
5638
    }// end loop over 'r'
 
5639
  }
 
5640
 
 
5641
  /// Evaluate order n derivatives of basis function i at given point x in cell
 
5642
  virtual void evaluate_basis_derivatives(std::size_t i,
 
5643
                                          std::size_t n,
 
5644
                                          double* values,
 
5645
                                          const double* x,
 
5646
                                          const double* vertex_coordinates,
 
5647
                                          int cell_orientation) const
 
5648
  {
 
5649
    // Compute Jacobian
 
5650
    double J[6];
 
5651
    compute_jacobian_triangle_3d(J, vertex_coordinates);
 
5652
    
 
5653
    // Compute Jacobian inverse and determinant
 
5654
    double K[6];
 
5655
    double detJ;
 
5656
    compute_jacobian_inverse_triangle_3d(K, detJ, J);
 
5657
    
 
5658
    
 
5659
    const double b0 = vertex_coordinates[0];
 
5660
    const double b1 = vertex_coordinates[1];
 
5661
    const double b2 = vertex_coordinates[2];
 
5662
    
 
5663
    // P_FFC = J^dag (p - b), P_FIAT = 2*P_FFC - (1, 1)
 
5664
    double X = 2*(K[0]*(x[0] - b0) + K[1]*(x[1] - b1) + K[2]*(x[2] - b2)) - 1.0;
 
5665
    double Y = 2*(K[3]*(x[0] - b0) + K[4]*(x[1] - b1) + K[5]*(x[2] - b2)) - 1.0;
 
5666
    
 
5667
    
 
5668
    // Compute number of derivatives.
 
5669
    unsigned int num_derivatives_t = 1;
 
5670
    for (unsigned int r = 0; r < n; r++)
 
5671
    {
 
5672
      num_derivatives_t *= 2;
 
5673
    }// end loop over 'r'
 
5674
    
 
5675
    // Compute number of derivatives.
 
5676
    unsigned int num_derivatives_g = 1;
 
5677
    for (unsigned int r = 0; r < n; r++)
 
5678
    {
 
5679
      num_derivatives_g *= 3;
 
5680
    }// end loop over 'r'
 
5681
    
 
5682
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
5683
    unsigned int **combinations_t = new unsigned int *[num_derivatives_t];
 
5684
    for (unsigned int row = 0; row < num_derivatives_t; row++)
 
5685
    {
 
5686
      combinations_t[row] = new unsigned int [n];
 
5687
      for (unsigned int col = 0; col < n; col++)
 
5688
        combinations_t[row][col] = 0;
 
5689
    }
 
5690
    
 
5691
    // Generate combinations of derivatives
 
5692
    for (unsigned int row = 1; row < num_derivatives_t; row++)
 
5693
    {
 
5694
      for (unsigned int num = 0; num < row; num++)
 
5695
      {
 
5696
        for (unsigned int col = n-1; col+1 > 0; col--)
 
5697
        {
 
5698
          if (combinations_t[row][col] + 1 > 1)
 
5699
            combinations_t[row][col] = 0;
 
5700
          else
 
5701
          {
 
5702
            combinations_t[row][col] += 1;
 
5703
            break;
 
5704
          }
 
5705
        }
 
5706
      }
 
5707
    }
 
5708
    
 
5709
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
5710
    unsigned int **combinations_g = new unsigned int *[num_derivatives_g];
 
5711
    for (unsigned int row = 0; row < num_derivatives_g; row++)
 
5712
    {
 
5713
      combinations_g[row] = new unsigned int [n];
 
5714
      for (unsigned int col = 0; col < n; col++)
 
5715
        combinations_g[row][col] = 0;
 
5716
    }
 
5717
    
 
5718
    // Generate combinations of derivatives
 
5719
    for (unsigned int row = 1; row < num_derivatives_g; row++)
 
5720
    {
 
5721
      for (unsigned int num = 0; num < row; num++)
 
5722
      {
 
5723
        for (unsigned int col = n-1; col+1 > 0; col--)
 
5724
        {
 
5725
          if (combinations_g[row][col] + 1 > 2)
 
5726
            combinations_g[row][col] = 0;
 
5727
          else
 
5728
          {
 
5729
            combinations_g[row][col] += 1;
 
5730
            break;
 
5731
          }
 
5732
        }
 
5733
      }
 
5734
    }
 
5735
    
 
5736
    // Compute inverse of Jacobian
 
5737
    const double Jinv[2][3] = {{K[0], K[1], K[2]}, {K[3], K[4], K[5]}};
 
5738
    
 
5739
    // Declare transformation matrix
 
5740
    // Declare pointer to two dimensional array and initialise
 
5741
    double **transform = new double *[num_derivatives_g];
 
5742
    
 
5743
    for (unsigned int j = 0; j < num_derivatives_g; j++)
 
5744
    {
 
5745
      transform[j] = new double [num_derivatives_t];
 
5746
      for (unsigned int k = 0; k < num_derivatives_t; k++)
 
5747
        transform[j][k] = 1;
 
5748
    }
 
5749
    
 
5750
    // Construct transformation matrix
 
5751
    for (unsigned int row = 0; row < num_derivatives_g; row++)
 
5752
    {
 
5753
      for (unsigned int col = 0; col < num_derivatives_t; col++)
 
5754
      {
 
5755
        for (unsigned int k = 0; k < n; k++)
 
5756
          transform[row][col] *= Jinv[combinations_t[col][k]][combinations_g[row][k]];
 
5757
      }
 
5758
    }
 
5759
    
 
5760
    // Reset values. Assuming that values is always an array.
 
5761
    for (unsigned int r = 0; r < num_derivatives_g; r++)
 
5762
    {
 
5763
      values[r] = 0.0;
 
5764
    }// end loop over 'r'
 
5765
    
 
5766
    switch (i)
 
5767
    {
 
5768
    case 0:
 
5769
      {
 
5770
        
 
5771
      // Array of basisvalues
 
5772
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
5773
      
 
5774
      // Declare helper variables
 
5775
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
5776
      
 
5777
      // Compute basisvalues
 
5778
      basisvalues[0] = 1.0;
 
5779
      basisvalues[1] = tmp0;
 
5780
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
5781
      basisvalues[0] *= std::sqrt(0.5);
 
5782
      basisvalues[2] *= std::sqrt(1.0);
 
5783
      basisvalues[1] *= std::sqrt(3.0);
 
5784
      
 
5785
      // Table(s) of coefficients
 
5786
      static const double coefficients0[3] = \
 
5787
      {0.47140452, -0.28867513, -0.16666667};
 
5788
      
 
5789
      // Tables of derivatives of the polynomial base (transpose).
 
5790
      static const double dmats0[3][3] = \
 
5791
      {{0.0, 0.0, 0.0},
 
5792
      {4.8989795, 0.0, 0.0},
 
5793
      {0.0, 0.0, 0.0}};
 
5794
      
 
5795
      static const double dmats1[3][3] = \
 
5796
      {{0.0, 0.0, 0.0},
 
5797
      {2.4494897, 0.0, 0.0},
 
5798
      {4.2426407, 0.0, 0.0}};
 
5799
      
 
5800
      // Compute reference derivatives.
 
5801
      // Declare pointer to array of derivatives on FIAT element.
 
5802
      double *derivatives = new double[num_derivatives_t];
 
5803
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
5804
      {
 
5805
        derivatives[r] = 0.0;
 
5806
      }// end loop over 'r'
 
5807
      
 
5808
      // Declare derivative matrix (of polynomial basis).
 
5809
      double dmats[3][3] = \
 
5810
      {{1.0, 0.0, 0.0},
 
5811
      {0.0, 1.0, 0.0},
 
5812
      {0.0, 0.0, 1.0}};
 
5813
      
 
5814
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
5815
      double dmats_old[3][3] = \
 
5816
      {{1.0, 0.0, 0.0},
 
5817
      {0.0, 1.0, 0.0},
 
5818
      {0.0, 0.0, 1.0}};
 
5819
      
 
5820
      // Loop possible derivatives.
 
5821
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
5822
      {
 
5823
        // Resetting dmats values to compute next derivative.
 
5824
        for (unsigned int t = 0; t < 3; t++)
 
5825
        {
 
5826
          for (unsigned int u = 0; u < 3; u++)
 
5827
          {
 
5828
            dmats[t][u] = 0.0;
 
5829
            if (t == u)
 
5830
            {
 
5831
            dmats[t][u] = 1.0;
 
5832
            }
 
5833
            
 
5834
          }// end loop over 'u'
 
5835
        }// end loop over 't'
 
5836
        
 
5837
        // Looping derivative order to generate dmats.
 
5838
        for (unsigned int s = 0; s < n; s++)
 
5839
        {
 
5840
          // Updating dmats_old with new values and resetting dmats.
 
5841
          for (unsigned int t = 0; t < 3; t++)
 
5842
          {
 
5843
            for (unsigned int u = 0; u < 3; u++)
 
5844
            {
 
5845
              dmats_old[t][u] = dmats[t][u];
 
5846
              dmats[t][u] = 0.0;
 
5847
            }// end loop over 'u'
 
5848
          }// end loop over 't'
 
5849
          
 
5850
          // Update dmats using an inner product.
 
5851
          if (combinations_t[r][s] == 0)
 
5852
          {
 
5853
          for (unsigned int t = 0; t < 3; t++)
 
5854
          {
 
5855
            for (unsigned int u = 0; u < 3; u++)
 
5856
            {
 
5857
              for (unsigned int tu = 0; tu < 3; tu++)
 
5858
              {
 
5859
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
5860
              }// end loop over 'tu'
 
5861
            }// end loop over 'u'
 
5862
          }// end loop over 't'
 
5863
          }
 
5864
          
 
5865
          if (combinations_t[r][s] == 1)
 
5866
          {
 
5867
          for (unsigned int t = 0; t < 3; t++)
 
5868
          {
 
5869
            for (unsigned int u = 0; u < 3; u++)
 
5870
            {
 
5871
              for (unsigned int tu = 0; tu < 3; tu++)
 
5872
              {
 
5873
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
5874
              }// end loop over 'tu'
 
5875
            }// end loop over 'u'
 
5876
          }// end loop over 't'
 
5877
          }
 
5878
          
 
5879
        }// end loop over 's'
 
5880
        for (unsigned int s = 0; s < 3; s++)
 
5881
        {
 
5882
          for (unsigned int t = 0; t < 3; t++)
 
5883
          {
 
5884
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
5885
          }// end loop over 't'
 
5886
        }// end loop over 's'
 
5887
      }// end loop over 'r'
 
5888
      
 
5889
      // Transform derivatives back to physical element
 
5890
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
5891
      {
 
5892
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
5893
        {
 
5894
          values[r] += transform[r][s]*derivatives[s];
 
5895
        }// end loop over 's'
 
5896
      }// end loop over 'r'
 
5897
      
 
5898
      // Delete pointer to array of derivatives on FIAT element
 
5899
      delete [] derivatives;
 
5900
      
 
5901
      // Delete pointer to array of combinations of derivatives and transform
 
5902
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
5903
      {
 
5904
        delete [] combinations_t[r];
 
5905
      }// end loop over 'r'
 
5906
      delete [] combinations_t;
 
5907
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
5908
      {
 
5909
        delete [] combinations_g[r];
 
5910
      }// end loop over 'r'
 
5911
      delete [] combinations_g;
 
5912
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
5913
      {
 
5914
        delete [] transform[r];
 
5915
      }// end loop over 'r'
 
5916
      delete [] transform;
 
5917
        break;
 
5918
      }
 
5919
    case 1:
 
5920
      {
 
5921
        
 
5922
      // Array of basisvalues
 
5923
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
5924
      
 
5925
      // Declare helper variables
 
5926
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
5927
      
 
5928
      // Compute basisvalues
 
5929
      basisvalues[0] = 1.0;
 
5930
      basisvalues[1] = tmp0;
 
5931
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
5932
      basisvalues[0] *= std::sqrt(0.5);
 
5933
      basisvalues[2] *= std::sqrt(1.0);
 
5934
      basisvalues[1] *= std::sqrt(3.0);
 
5935
      
 
5936
      // Table(s) of coefficients
 
5937
      static const double coefficients0[3] = \
 
5938
      {0.47140452, 0.28867513, -0.16666667};
 
5939
      
 
5940
      // Tables of derivatives of the polynomial base (transpose).
 
5941
      static const double dmats0[3][3] = \
 
5942
      {{0.0, 0.0, 0.0},
 
5943
      {4.8989795, 0.0, 0.0},
 
5944
      {0.0, 0.0, 0.0}};
 
5945
      
 
5946
      static const double dmats1[3][3] = \
 
5947
      {{0.0, 0.0, 0.0},
 
5948
      {2.4494897, 0.0, 0.0},
 
5949
      {4.2426407, 0.0, 0.0}};
 
5950
      
 
5951
      // Compute reference derivatives.
 
5952
      // Declare pointer to array of derivatives on FIAT element.
 
5953
      double *derivatives = new double[num_derivatives_t];
 
5954
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
5955
      {
 
5956
        derivatives[r] = 0.0;
 
5957
      }// end loop over 'r'
 
5958
      
 
5959
      // Declare derivative matrix (of polynomial basis).
 
5960
      double dmats[3][3] = \
 
5961
      {{1.0, 0.0, 0.0},
 
5962
      {0.0, 1.0, 0.0},
 
5963
      {0.0, 0.0, 1.0}};
 
5964
      
 
5965
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
5966
      double dmats_old[3][3] = \
 
5967
      {{1.0, 0.0, 0.0},
 
5968
      {0.0, 1.0, 0.0},
 
5969
      {0.0, 0.0, 1.0}};
 
5970
      
 
5971
      // Loop possible derivatives.
 
5972
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
5973
      {
 
5974
        // Resetting dmats values to compute next derivative.
 
5975
        for (unsigned int t = 0; t < 3; t++)
 
5976
        {
 
5977
          for (unsigned int u = 0; u < 3; u++)
 
5978
          {
 
5979
            dmats[t][u] = 0.0;
 
5980
            if (t == u)
 
5981
            {
 
5982
            dmats[t][u] = 1.0;
 
5983
            }
 
5984
            
 
5985
          }// end loop over 'u'
 
5986
        }// end loop over 't'
 
5987
        
 
5988
        // Looping derivative order to generate dmats.
 
5989
        for (unsigned int s = 0; s < n; s++)
 
5990
        {
 
5991
          // Updating dmats_old with new values and resetting dmats.
 
5992
          for (unsigned int t = 0; t < 3; t++)
 
5993
          {
 
5994
            for (unsigned int u = 0; u < 3; u++)
 
5995
            {
 
5996
              dmats_old[t][u] = dmats[t][u];
 
5997
              dmats[t][u] = 0.0;
 
5998
            }// end loop over 'u'
 
5999
          }// end loop over 't'
 
6000
          
 
6001
          // Update dmats using an inner product.
 
6002
          if (combinations_t[r][s] == 0)
 
6003
          {
 
6004
          for (unsigned int t = 0; t < 3; t++)
 
6005
          {
 
6006
            for (unsigned int u = 0; u < 3; u++)
 
6007
            {
 
6008
              for (unsigned int tu = 0; tu < 3; tu++)
 
6009
              {
 
6010
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
6011
              }// end loop over 'tu'
 
6012
            }// end loop over 'u'
 
6013
          }// end loop over 't'
 
6014
          }
 
6015
          
 
6016
          if (combinations_t[r][s] == 1)
 
6017
          {
 
6018
          for (unsigned int t = 0; t < 3; t++)
 
6019
          {
 
6020
            for (unsigned int u = 0; u < 3; u++)
 
6021
            {
 
6022
              for (unsigned int tu = 0; tu < 3; tu++)
 
6023
              {
 
6024
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
6025
              }// end loop over 'tu'
 
6026
            }// end loop over 'u'
 
6027
          }// end loop over 't'
 
6028
          }
 
6029
          
 
6030
        }// end loop over 's'
 
6031
        for (unsigned int s = 0; s < 3; s++)
 
6032
        {
 
6033
          for (unsigned int t = 0; t < 3; t++)
 
6034
          {
 
6035
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
6036
          }// end loop over 't'
 
6037
        }// end loop over 's'
 
6038
      }// end loop over 'r'
 
6039
      
 
6040
      // Transform derivatives back to physical element
 
6041
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
6042
      {
 
6043
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
6044
        {
 
6045
          values[r] += transform[r][s]*derivatives[s];
 
6046
        }// end loop over 's'
 
6047
      }// end loop over 'r'
 
6048
      
 
6049
      // Delete pointer to array of derivatives on FIAT element
 
6050
      delete [] derivatives;
 
6051
      
 
6052
      // Delete pointer to array of combinations of derivatives and transform
 
6053
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
6054
      {
 
6055
        delete [] combinations_t[r];
 
6056
      }// end loop over 'r'
 
6057
      delete [] combinations_t;
 
6058
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
6059
      {
 
6060
        delete [] combinations_g[r];
 
6061
      }// end loop over 'r'
 
6062
      delete [] combinations_g;
 
6063
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
6064
      {
 
6065
        delete [] transform[r];
 
6066
      }// end loop over 'r'
 
6067
      delete [] transform;
 
6068
        break;
 
6069
      }
 
6070
    case 2:
 
6071
      {
 
6072
        
 
6073
      // Array of basisvalues
 
6074
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
6075
      
 
6076
      // Declare helper variables
 
6077
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
6078
      
 
6079
      // Compute basisvalues
 
6080
      basisvalues[0] = 1.0;
 
6081
      basisvalues[1] = tmp0;
 
6082
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
6083
      basisvalues[0] *= std::sqrt(0.5);
 
6084
      basisvalues[2] *= std::sqrt(1.0);
 
6085
      basisvalues[1] *= std::sqrt(3.0);
 
6086
      
 
6087
      // Table(s) of coefficients
 
6088
      static const double coefficients0[3] = \
 
6089
      {0.47140452, 0.0, 0.33333333};
 
6090
      
 
6091
      // Tables of derivatives of the polynomial base (transpose).
 
6092
      static const double dmats0[3][3] = \
 
6093
      {{0.0, 0.0, 0.0},
 
6094
      {4.8989795, 0.0, 0.0},
 
6095
      {0.0, 0.0, 0.0}};
 
6096
      
 
6097
      static const double dmats1[3][3] = \
 
6098
      {{0.0, 0.0, 0.0},
 
6099
      {2.4494897, 0.0, 0.0},
 
6100
      {4.2426407, 0.0, 0.0}};
 
6101
      
 
6102
      // Compute reference derivatives.
 
6103
      // Declare pointer to array of derivatives on FIAT element.
 
6104
      double *derivatives = new double[num_derivatives_t];
 
6105
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
6106
      {
 
6107
        derivatives[r] = 0.0;
 
6108
      }// end loop over 'r'
 
6109
      
 
6110
      // Declare derivative matrix (of polynomial basis).
 
6111
      double dmats[3][3] = \
 
6112
      {{1.0, 0.0, 0.0},
 
6113
      {0.0, 1.0, 0.0},
 
6114
      {0.0, 0.0, 1.0}};
 
6115
      
 
6116
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
6117
      double dmats_old[3][3] = \
 
6118
      {{1.0, 0.0, 0.0},
 
6119
      {0.0, 1.0, 0.0},
 
6120
      {0.0, 0.0, 1.0}};
 
6121
      
 
6122
      // Loop possible derivatives.
 
6123
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
6124
      {
 
6125
        // Resetting dmats values to compute next derivative.
 
6126
        for (unsigned int t = 0; t < 3; t++)
 
6127
        {
 
6128
          for (unsigned int u = 0; u < 3; u++)
 
6129
          {
 
6130
            dmats[t][u] = 0.0;
 
6131
            if (t == u)
 
6132
            {
 
6133
            dmats[t][u] = 1.0;
 
6134
            }
 
6135
            
 
6136
          }// end loop over 'u'
 
6137
        }// end loop over 't'
 
6138
        
 
6139
        // Looping derivative order to generate dmats.
 
6140
        for (unsigned int s = 0; s < n; s++)
 
6141
        {
 
6142
          // Updating dmats_old with new values and resetting dmats.
 
6143
          for (unsigned int t = 0; t < 3; t++)
 
6144
          {
 
6145
            for (unsigned int u = 0; u < 3; u++)
 
6146
            {
 
6147
              dmats_old[t][u] = dmats[t][u];
 
6148
              dmats[t][u] = 0.0;
 
6149
            }// end loop over 'u'
 
6150
          }// end loop over 't'
 
6151
          
 
6152
          // Update dmats using an inner product.
 
6153
          if (combinations_t[r][s] == 0)
 
6154
          {
 
6155
          for (unsigned int t = 0; t < 3; t++)
 
6156
          {
 
6157
            for (unsigned int u = 0; u < 3; u++)
 
6158
            {
 
6159
              for (unsigned int tu = 0; tu < 3; tu++)
 
6160
              {
 
6161
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
6162
              }// end loop over 'tu'
 
6163
            }// end loop over 'u'
 
6164
          }// end loop over 't'
 
6165
          }
 
6166
          
 
6167
          if (combinations_t[r][s] == 1)
 
6168
          {
 
6169
          for (unsigned int t = 0; t < 3; t++)
 
6170
          {
 
6171
            for (unsigned int u = 0; u < 3; u++)
 
6172
            {
 
6173
              for (unsigned int tu = 0; tu < 3; tu++)
 
6174
              {
 
6175
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
6176
              }// end loop over 'tu'
 
6177
            }// end loop over 'u'
 
6178
          }// end loop over 't'
 
6179
          }
 
6180
          
 
6181
        }// end loop over 's'
 
6182
        for (unsigned int s = 0; s < 3; s++)
 
6183
        {
 
6184
          for (unsigned int t = 0; t < 3; t++)
 
6185
          {
 
6186
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
6187
          }// end loop over 't'
 
6188
        }// end loop over 's'
 
6189
      }// end loop over 'r'
 
6190
      
 
6191
      // Transform derivatives back to physical element
 
6192
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
6193
      {
 
6194
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
6195
        {
 
6196
          values[r] += transform[r][s]*derivatives[s];
 
6197
        }// end loop over 's'
 
6198
      }// end loop over 'r'
 
6199
      
 
6200
      // Delete pointer to array of derivatives on FIAT element
 
6201
      delete [] derivatives;
 
6202
      
 
6203
      // Delete pointer to array of combinations of derivatives and transform
 
6204
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
6205
      {
 
6206
        delete [] combinations_t[r];
 
6207
      }// end loop over 'r'
 
6208
      delete [] combinations_t;
 
6209
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
6210
      {
 
6211
        delete [] combinations_g[r];
 
6212
      }// end loop over 'r'
 
6213
      delete [] combinations_g;
 
6214
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
6215
      {
 
6216
        delete [] transform[r];
 
6217
      }// end loop over 'r'
 
6218
      delete [] transform;
 
6219
        break;
 
6220
      }
 
6221
    }
 
6222
    
 
6223
  }
 
6224
 
 
6225
  /// Evaluate order n derivatives of all basis functions at given point x in cell
 
6226
  virtual void evaluate_basis_derivatives_all(std::size_t n,
 
6227
                                              double* values,
 
6228
                                              const double* x,
 
6229
                                              const double* vertex_coordinates,
 
6230
                                              int cell_orientation) const
 
6231
  {
 
6232
    // Compute number of derivatives.
 
6233
    unsigned int num_derivatives_g = 1;
 
6234
    for (unsigned int r = 0; r < n; r++)
 
6235
    {
 
6236
      num_derivatives_g *= 3;
 
6237
    }// end loop over 'r'
 
6238
    
 
6239
    // Helper variable to hold values of a single dof.
 
6240
    double *dof_values = new double[num_derivatives_g];
 
6241
    for (unsigned int r = 0; r < num_derivatives_g; r++)
 
6242
    {
 
6243
      dof_values[r] = 0.0;
 
6244
    }// end loop over 'r'
 
6245
    
 
6246
    // Loop dofs and call evaluate_basis_derivatives.
 
6247
    for (unsigned int r = 0; r < 3; r++)
 
6248
    {
 
6249
      evaluate_basis_derivatives(r, n, dof_values, x, vertex_coordinates, cell_orientation);
 
6250
      for (unsigned int s = 0; s < num_derivatives_g; s++)
 
6251
      {
 
6252
        values[r*num_derivatives_g + s] = dof_values[s];
 
6253
      }// end loop over 's'
 
6254
    }// end loop over 'r'
 
6255
    
 
6256
    // Delete pointer.
 
6257
    delete [] dof_values;
 
6258
  }
 
6259
 
 
6260
  /// Evaluate linear functional for dof i on the function f
 
6261
  virtual double evaluate_dof(std::size_t i,
 
6262
                              const ufc::function& f,
 
6263
                              const double* vertex_coordinates,
 
6264
                              int cell_orientation,
 
6265
                              const ufc::cell& c) const
 
6266
  {
 
6267
    // Declare variables for result of evaluation
 
6268
    double vals[1];
 
6269
    
 
6270
    // Declare variable for physical coordinates
 
6271
    double y[3];
 
6272
    switch (i)
 
6273
    {
 
6274
    case 0:
 
6275
      {
 
6276
        y[0] = vertex_coordinates[0];
 
6277
      y[1] = vertex_coordinates[1];
 
6278
      y[2] = vertex_coordinates[2];
 
6279
      f.evaluate(vals, y, c);
 
6280
      return vals[0];
 
6281
        break;
 
6282
      }
 
6283
    case 1:
 
6284
      {
 
6285
        y[0] = vertex_coordinates[3];
 
6286
      y[1] = vertex_coordinates[4];
 
6287
      y[2] = vertex_coordinates[5];
 
6288
      f.evaluate(vals, y, c);
 
6289
      return vals[0];
 
6290
        break;
 
6291
      }
 
6292
    case 2:
 
6293
      {
 
6294
        y[0] = vertex_coordinates[6];
 
6295
      y[1] = vertex_coordinates[7];
 
6296
      y[2] = vertex_coordinates[8];
 
6297
      f.evaluate(vals, y, c);
 
6298
      return vals[0];
 
6299
        break;
 
6300
      }
 
6301
    }
 
6302
    
 
6303
    return 0.0;
 
6304
  }
 
6305
 
 
6306
  /// Evaluate linear functionals for all dofs on the function f
 
6307
  virtual void evaluate_dofs(double* values,
 
6308
                             const ufc::function& f,
 
6309
                             const double* vertex_coordinates,
 
6310
                             int cell_orientation,
 
6311
                             const ufc::cell& c) const
 
6312
  {
 
6313
    // Declare variables for result of evaluation
 
6314
    double vals[1];
 
6315
    
 
6316
    // Declare variable for physical coordinates
 
6317
    double y[3];
 
6318
    y[0] = vertex_coordinates[0];
 
6319
    y[1] = vertex_coordinates[1];
 
6320
    y[2] = vertex_coordinates[2];
 
6321
    f.evaluate(vals, y, c);
 
6322
    values[0] = vals[0];
 
6323
    y[0] = vertex_coordinates[3];
 
6324
    y[1] = vertex_coordinates[4];
 
6325
    y[2] = vertex_coordinates[5];
 
6326
    f.evaluate(vals, y, c);
 
6327
    values[1] = vals[0];
 
6328
    y[0] = vertex_coordinates[6];
 
6329
    y[1] = vertex_coordinates[7];
 
6330
    y[2] = vertex_coordinates[8];
 
6331
    f.evaluate(vals, y, c);
 
6332
    values[2] = vals[0];
 
6333
  }
 
6334
 
 
6335
  /// Interpolate vertex values from dof values
 
6336
  virtual void interpolate_vertex_values(double* vertex_values,
 
6337
                                         const double* dof_values,
 
6338
                                         const double* vertex_coordinates,
 
6339
                                         int cell_orientation,
 
6340
                                         const ufc::cell& c) const
 
6341
  {
 
6342
    // Evaluate function and change variables
 
6343
    vertex_values[0] = dof_values[0];
 
6344
    vertex_values[1] = dof_values[1];
 
6345
    vertex_values[2] = dof_values[2];
 
6346
  }
 
6347
 
 
6348
  /// Map coordinate xhat from reference cell to coordinate x in cell
 
6349
  virtual void map_from_reference_cell(double* x,
 
6350
                                       const double* xhat,
 
6351
                                       const ufc::cell& c) const
 
6352
  {
 
6353
    std::cerr << "*** FFC warning: " << "map_from_reference_cell not yet implemented." << std::endl;
 
6354
  }
 
6355
 
 
6356
  /// Map from coordinate x in cell to coordinate xhat in reference cell
 
6357
  virtual void map_to_reference_cell(double* xhat,
 
6358
                                     const double* x,
 
6359
                                     const ufc::cell& c) const
 
6360
  {
 
6361
    std::cerr << "*** FFC warning: " << "map_to_reference_cell not yet implemented." << std::endl;
 
6362
  }
 
6363
 
 
6364
  /// Return the number of sub elements (for a mixed element)
 
6365
  virtual std::size_t num_sub_elements() const
 
6366
  {
 
6367
    return 0;
 
6368
  }
 
6369
 
 
6370
  /// Create a new finite element for sub element i (for a mixed element)
 
6371
  virtual ufc::finite_element* create_sub_element(std::size_t i) const
 
6372
  {
 
6373
    return 0;
 
6374
  }
 
6375
 
 
6376
  /// Create a new class instance
 
6377
  virtual ufc::finite_element* create() const
 
6378
  {
 
6379
    return new x_element9_finite_element_3();
 
6380
  }
 
6381
 
 
6382
};
 
6383
 
 
6384
/// This class defines the interface for a finite element.
 
6385
 
 
6386
class x_element9_finite_element_4: public ufc::finite_element
 
6387
{
 
6388
public:
 
6389
 
 
6390
  /// Constructor
 
6391
  x_element9_finite_element_4() : ufc::finite_element()
 
6392
  {
 
6393
    // Do nothing
 
6394
  }
 
6395
 
 
6396
  /// Destructor
 
6397
  virtual ~x_element9_finite_element_4()
 
6398
  {
 
6399
    // Do nothing
 
6400
  }
 
6401
 
 
6402
  /// Return a string identifying the finite element
 
6403
  virtual const char* signature() const
 
6404
  {
 
6405
    return "MixedElement(*[FiniteElement('Raviart-Thomas', Domain(Cell('triangle', 3), 'triangle_multiverse', 3, 2), 2, None), FiniteElement('Brezzi-Douglas-Marini', Domain(Cell('triangle', 3), 'triangle_multiverse', 3, 2), 1, None), FiniteElement('Nedelec 1st kind H(curl)', Domain(Cell('triangle', 3), 'triangle_multiverse', 3, 2), 1, None), FiniteElement('Discontinuous Lagrange', Domain(Cell('triangle', 3), 'triangle_multiverse', 3, 2), 1, None)], **{'value_shape': (10,) })";
 
6406
  }
 
6407
 
 
6408
  /// Return the cell shape
 
6409
  virtual ufc::shape cell_shape() const
 
6410
  {
 
6411
    return ufc::triangle;
 
6412
  }
 
6413
 
 
6414
  /// Return the topological dimension of the cell shape
 
6415
  virtual std::size_t topological_dimension() const
 
6416
  {
 
6417
    return 2;
 
6418
  }
 
6419
 
 
6420
  /// Return the geometric dimension of the cell shape
 
6421
  virtual std::size_t geometric_dimension() const
 
6422
  {
 
6423
    return 3;
 
6424
  }
 
6425
 
 
6426
  /// Return the dimension of the finite element function space
 
6427
  virtual std::size_t space_dimension() const
 
6428
  {
 
6429
    return 20;
 
6430
  }
 
6431
 
 
6432
  /// Return the rank of the value space
 
6433
  virtual std::size_t value_rank() const
 
6434
  {
 
6435
    return 1;
 
6436
  }
 
6437
 
 
6438
  /// Return the dimension of the value space for axis i
 
6439
  virtual std::size_t value_dimension(std::size_t i) const
 
6440
  {
 
6441
    switch (i)
 
6442
    {
 
6443
    case 0:
 
6444
      {
 
6445
        return 10;
 
6446
        break;
 
6447
      }
 
6448
    }
 
6449
    
 
6450
    return 0;
 
6451
  }
 
6452
 
 
6453
  /// Evaluate basis function i at given point x in cell
 
6454
  virtual void evaluate_basis(std::size_t i,
 
6455
                              double* values,
 
6456
                              const double* x,
 
6457
                              const double* vertex_coordinates,
 
6458
                              int cell_orientation) const
 
6459
  {
 
6460
    // Compute Jacobian
 
6461
    double J[6];
 
6462
    compute_jacobian_triangle_3d(J, vertex_coordinates);
 
6463
    
 
6464
    // Compute Jacobian inverse and determinant
 
6465
    double K[6];
 
6466
    double detJ;
 
6467
    compute_jacobian_inverse_triangle_3d(K, detJ, J);
 
6468
    
 
6469
    
 
6470
    // Check orientation
 
6471
    if (cell_orientation == -1)
 
6472
      throw std::runtime_error("cell orientation must be defined (not -1)");
 
6473
    // (If cell_orientation == 1 = down, multiply det(J) by -1)
 
6474
    else if (cell_orientation == 1)
 
6475
      detJ *= -1;
 
6476
    
 
6477
    
 
6478
    const double b0 = vertex_coordinates[0];
 
6479
    const double b1 = vertex_coordinates[1];
 
6480
    const double b2 = vertex_coordinates[2];
 
6481
    
 
6482
    // P_FFC = J^dag (p - b), P_FIAT = 2*P_FFC - (1, 1)
 
6483
    double X = 2*(K[0]*(x[0] - b0) + K[1]*(x[1] - b1) + K[2]*(x[2] - b2)) - 1.0;
 
6484
    double Y = 2*(K[3]*(x[0] - b0) + K[4]*(x[1] - b1) + K[5]*(x[2] - b2)) - 1.0;
 
6485
    
 
6486
    
 
6487
    // Reset values
 
6488
    values[0] = 0.0;
 
6489
    values[1] = 0.0;
 
6490
    values[2] = 0.0;
 
6491
    values[3] = 0.0;
 
6492
    values[4] = 0.0;
 
6493
    values[5] = 0.0;
 
6494
    values[6] = 0.0;
 
6495
    switch (i)
 
6496
    {
 
6497
    case 0:
 
6498
      {
 
6499
        
 
6500
      // Array of basisvalues
 
6501
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
6502
      
 
6503
      // Declare helper variables
 
6504
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
6505
      double tmp1 = (1.0 - Y)/2.0;
 
6506
      double tmp2 = tmp1*tmp1;
 
6507
      
 
6508
      // Compute basisvalues
 
6509
      basisvalues[0] = 1.0;
 
6510
      basisvalues[1] = tmp0;
 
6511
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
6512
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
6513
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
6514
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
6515
      basisvalues[0] *= std::sqrt(0.5);
 
6516
      basisvalues[2] *= std::sqrt(1.0);
 
6517
      basisvalues[5] *= std::sqrt(1.5);
 
6518
      basisvalues[1] *= std::sqrt(3.0);
 
6519
      basisvalues[4] *= std::sqrt(4.5);
 
6520
      basisvalues[3] *= std::sqrt(7.5);
 
6521
      
 
6522
      // Table(s) of coefficients
 
6523
      static const double coefficients0[6] = \
 
6524
      {0.23570226, 0.40414519, -0.23333333, 0.18257419, -0.14142136, 0.081649658};
 
6525
      
 
6526
      static const double coefficients1[6] = \
 
6527
      {-0.11785113, 0.17320508, -0.23333333, 0.0, 0.14142136, -0.12247449};
 
6528
      
 
6529
      // Compute value(s)
 
6530
      for (unsigned int r = 0; r < 6; r++)
 
6531
      {
 
6532
        values[0] += coefficients0[r]*basisvalues[r];
 
6533
        values[1] += coefficients1[r]*basisvalues[r];
 
6534
      }// end loop over 'r'
 
6535
      
 
6536
      // Using contravariant Piola transform to map values back to the physical element
 
6537
      const double tmp_ref0 = values[0];
 
6538
      const double tmp_ref1 = values[1];
 
6539
      values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
6540
      values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
6541
      values[2] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
6542
        break;
 
6543
      }
 
6544
    case 1:
 
6545
      {
 
6546
        
 
6547
      // Array of basisvalues
 
6548
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
6549
      
 
6550
      // Declare helper variables
 
6551
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
6552
      double tmp1 = (1.0 - Y)/2.0;
 
6553
      double tmp2 = tmp1*tmp1;
 
6554
      
 
6555
      // Compute basisvalues
 
6556
      basisvalues[0] = 1.0;
 
6557
      basisvalues[1] = tmp0;
 
6558
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
6559
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
6560
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
6561
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
6562
      basisvalues[0] *= std::sqrt(0.5);
 
6563
      basisvalues[2] *= std::sqrt(1.0);
 
6564
      basisvalues[5] *= std::sqrt(1.5);
 
6565
      basisvalues[1] *= std::sqrt(3.0);
 
6566
      basisvalues[4] *= std::sqrt(4.5);
 
6567
      basisvalues[3] *= std::sqrt(7.5);
 
6568
      
 
6569
      // Table(s) of coefficients
 
6570
      static const double coefficients0[6] = \
 
6571
      {-0.11785113, -0.11547005, 0.26666667, 0.0, 0.14142136, -0.12247449};
 
6572
      
 
6573
      static const double coefficients1[6] = \
 
6574
      {0.23570226, 0.0, 0.46666667, 0.0, 0.0, 0.24494897};
 
6575
      
 
6576
      // Compute value(s)
 
6577
      for (unsigned int r = 0; r < 6; r++)
 
6578
      {
 
6579
        values[0] += coefficients0[r]*basisvalues[r];
 
6580
        values[1] += coefficients1[r]*basisvalues[r];
 
6581
      }// end loop over 'r'
 
6582
      
 
6583
      // Using contravariant Piola transform to map values back to the physical element
 
6584
      const double tmp_ref0 = values[0];
 
6585
      const double tmp_ref1 = values[1];
 
6586
      values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
6587
      values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
6588
      values[2] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
6589
        break;
 
6590
      }
 
6591
    case 2:
 
6592
      {
 
6593
        
 
6594
      // Array of basisvalues
 
6595
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
6596
      
 
6597
      // Declare helper variables
 
6598
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
6599
      double tmp1 = (1.0 - Y)/2.0;
 
6600
      double tmp2 = tmp1*tmp1;
 
6601
      
 
6602
      // Compute basisvalues
 
6603
      basisvalues[0] = 1.0;
 
6604
      basisvalues[1] = tmp0;
 
6605
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
6606
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
6607
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
6608
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
6609
      basisvalues[0] *= std::sqrt(0.5);
 
6610
      basisvalues[2] *= std::sqrt(1.0);
 
6611
      basisvalues[5] *= std::sqrt(1.5);
 
6612
      basisvalues[1] *= std::sqrt(3.0);
 
6613
      basisvalues[4] *= std::sqrt(4.5);
 
6614
      basisvalues[3] *= std::sqrt(7.5);
 
6615
      
 
6616
      // Table(s) of coefficients
 
6617
      static const double coefficients0[6] = \
 
6618
      {0.11785113, -0.57735027, -0.46666667, 0.18257419, 0.0, -0.040824829};
 
6619
      
 
6620
      static const double coefficients1[6] = \
 
6621
      {0.11785113, 0.17320508, 0.23333333, 0.0, 0.14142136, 0.12247449};
 
6622
      
 
6623
      // Compute value(s)
 
6624
      for (unsigned int r = 0; r < 6; r++)
 
6625
      {
 
6626
        values[0] += coefficients0[r]*basisvalues[r];
 
6627
        values[1] += coefficients1[r]*basisvalues[r];
 
6628
      }// end loop over 'r'
 
6629
      
 
6630
      // Using contravariant Piola transform to map values back to the physical element
 
6631
      const double tmp_ref0 = values[0];
 
6632
      const double tmp_ref1 = values[1];
 
6633
      values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
6634
      values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
6635
      values[2] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
6636
        break;
 
6637
      }
 
6638
    case 3:
 
6639
      {
 
6640
        
 
6641
      // Array of basisvalues
 
6642
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
6643
      
 
6644
      // Declare helper variables
 
6645
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
6646
      double tmp1 = (1.0 - Y)/2.0;
 
6647
      double tmp2 = tmp1*tmp1;
 
6648
      
 
6649
      // Compute basisvalues
 
6650
      basisvalues[0] = 1.0;
 
6651
      basisvalues[1] = tmp0;
 
6652
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
6653
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
6654
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
6655
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
6656
      basisvalues[0] *= std::sqrt(0.5);
 
6657
      basisvalues[2] *= std::sqrt(1.0);
 
6658
      basisvalues[5] *= std::sqrt(1.5);
 
6659
      basisvalues[1] *= std::sqrt(3.0);
 
6660
      basisvalues[4] *= std::sqrt(4.5);
 
6661
      basisvalues[3] *= std::sqrt(7.5);
 
6662
      
 
6663
      // Table(s) of coefficients
 
6664
      static const double coefficients0[6] = \
 
6665
      {0.11785113, 0.11547005, 0.73333333, 0.0, -0.14142136, 0.12247449};
 
6666
      
 
6667
      static const double coefficients1[6] = \
 
6668
      {-0.23570226, 0.0, -0.46666667, 0.0, 0.0, -0.24494897};
 
6669
      
 
6670
      // Compute value(s)
 
6671
      for (unsigned int r = 0; r < 6; r++)
 
6672
      {
 
6673
        values[0] += coefficients0[r]*basisvalues[r];
 
6674
        values[1] += coefficients1[r]*basisvalues[r];
 
6675
      }// end loop over 'r'
 
6676
      
 
6677
      // Using contravariant Piola transform to map values back to the physical element
 
6678
      const double tmp_ref0 = values[0];
 
6679
      const double tmp_ref1 = values[1];
 
6680
      values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
6681
      values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
6682
      values[2] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
6683
        break;
 
6684
      }
 
6685
    case 4:
 
6686
      {
 
6687
        
 
6688
      // Array of basisvalues
 
6689
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
6690
      
 
6691
      // Declare helper variables
 
6692
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
6693
      double tmp1 = (1.0 - Y)/2.0;
 
6694
      double tmp2 = tmp1*tmp1;
 
6695
      
 
6696
      // Compute basisvalues
 
6697
      basisvalues[0] = 1.0;
 
6698
      basisvalues[1] = tmp0;
 
6699
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
6700
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
6701
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
6702
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
6703
      basisvalues[0] *= std::sqrt(0.5);
 
6704
      basisvalues[2] *= std::sqrt(1.0);
 
6705
      basisvalues[5] *= std::sqrt(1.5);
 
6706
      basisvalues[1] *= std::sqrt(3.0);
 
6707
      basisvalues[4] *= std::sqrt(4.5);
 
6708
      basisvalues[3] *= std::sqrt(7.5);
 
6709
      
 
6710
      // Table(s) of coefficients
 
6711
      static const double coefficients0[6] = \
 
6712
      {-0.11785113, -0.28867513, -0.033333333, -0.18257419, 0.0, 0.040824829};
 
6713
      
 
6714
      static const double coefficients1[6] = \
 
6715
      {-0.11785113, 0.69282032, 0.26666667, 0.0, -0.14142136, -0.12247449};
 
6716
      
 
6717
      // Compute value(s)
 
6718
      for (unsigned int r = 0; r < 6; r++)
 
6719
      {
 
6720
        values[0] += coefficients0[r]*basisvalues[r];
 
6721
        values[1] += coefficients1[r]*basisvalues[r];
 
6722
      }// end loop over 'r'
 
6723
      
 
6724
      // Using contravariant Piola transform to map values back to the physical element
 
6725
      const double tmp_ref0 = values[0];
 
6726
      const double tmp_ref1 = values[1];
 
6727
      values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
6728
      values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
6729
      values[2] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
6730
        break;
 
6731
      }
 
6732
    case 5:
 
6733
      {
 
6734
        
 
6735
      // Array of basisvalues
 
6736
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
6737
      
 
6738
      // Declare helper variables
 
6739
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
6740
      double tmp1 = (1.0 - Y)/2.0;
 
6741
      double tmp2 = tmp1*tmp1;
 
6742
      
 
6743
      // Compute basisvalues
 
6744
      basisvalues[0] = 1.0;
 
6745
      basisvalues[1] = tmp0;
 
6746
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
6747
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
6748
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
6749
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
6750
      basisvalues[0] *= std::sqrt(0.5);
 
6751
      basisvalues[2] *= std::sqrt(1.0);
 
6752
      basisvalues[5] *= std::sqrt(1.5);
 
6753
      basisvalues[1] *= std::sqrt(3.0);
 
6754
      basisvalues[4] *= std::sqrt(4.5);
 
6755
      basisvalues[3] *= std::sqrt(7.5);
 
6756
      
 
6757
      // Table(s) of coefficients
 
6758
      static const double coefficients0[6] = \
 
6759
      {0.23570226, 0.40414519, -0.23333333, 0.18257419, -0.14142136, 0.081649658};
 
6760
      
 
6761
      static const double coefficients1[6] = \
 
6762
      {-0.11785113, -0.69282032, 0.26666667, 0.0, 0.14142136, -0.12247449};
 
6763
      
 
6764
      // Compute value(s)
 
6765
      for (unsigned int r = 0; r < 6; r++)
 
6766
      {
 
6767
        values[0] += coefficients0[r]*basisvalues[r];
 
6768
        values[1] += coefficients1[r]*basisvalues[r];
 
6769
      }// end loop over 'r'
 
6770
      
 
6771
      // Using contravariant Piola transform to map values back to the physical element
 
6772
      const double tmp_ref0 = values[0];
 
6773
      const double tmp_ref1 = values[1];
 
6774
      values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
6775
      values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
6776
      values[2] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
6777
        break;
 
6778
      }
 
6779
    case 6:
 
6780
      {
 
6781
        
 
6782
      // Array of basisvalues
 
6783
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
6784
      
 
6785
      // Declare helper variables
 
6786
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
6787
      double tmp1 = (1.0 - Y)/2.0;
 
6788
      double tmp2 = tmp1*tmp1;
 
6789
      
 
6790
      // Compute basisvalues
 
6791
      basisvalues[0] = 1.0;
 
6792
      basisvalues[1] = tmp0;
 
6793
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
6794
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
6795
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
6796
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
6797
      basisvalues[0] *= std::sqrt(0.5);
 
6798
      basisvalues[2] *= std::sqrt(1.0);
 
6799
      basisvalues[5] *= std::sqrt(1.5);
 
6800
      basisvalues[1] *= std::sqrt(3.0);
 
6801
      basisvalues[4] *= std::sqrt(4.5);
 
6802
      basisvalues[3] *= std::sqrt(7.5);
 
6803
      
 
6804
      // Table(s) of coefficients
 
6805
      static const double coefficients0[6] = \
 
6806
      {1.0606602, 0.17320508, -0.3, -0.36514837, 0.14142136, -0.040824829};
 
6807
      
 
6808
      static const double coefficients1[6] = \
 
6809
      {0.0, -0.34641016, 0.0, 0.0, -0.28284271, 0.0};
 
6810
      
 
6811
      // Compute value(s)
 
6812
      for (unsigned int r = 0; r < 6; r++)
 
6813
      {
 
6814
        values[0] += coefficients0[r]*basisvalues[r];
 
6815
        values[1] += coefficients1[r]*basisvalues[r];
 
6816
      }// end loop over 'r'
 
6817
      
 
6818
      // Using contravariant Piola transform to map values back to the physical element
 
6819
      const double tmp_ref0 = values[0];
 
6820
      const double tmp_ref1 = values[1];
 
6821
      values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
6822
      values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
6823
      values[2] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
6824
        break;
 
6825
      }
 
6826
    case 7:
 
6827
      {
 
6828
        
 
6829
      // Array of basisvalues
 
6830
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
6831
      
 
6832
      // Declare helper variables
 
6833
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
6834
      double tmp1 = (1.0 - Y)/2.0;
 
6835
      double tmp2 = tmp1*tmp1;
 
6836
      
 
6837
      // Compute basisvalues
 
6838
      basisvalues[0] = 1.0;
 
6839
      basisvalues[1] = tmp0;
 
6840
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
6841
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
6842
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
6843
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
6844
      basisvalues[0] *= std::sqrt(0.5);
 
6845
      basisvalues[2] *= std::sqrt(1.0);
 
6846
      basisvalues[5] *= std::sqrt(1.5);
 
6847
      basisvalues[1] *= std::sqrt(3.0);
 
6848
      basisvalues[4] *= std::sqrt(4.5);
 
6849
      basisvalues[3] *= std::sqrt(7.5);
 
6850
      
 
6851
      // Table(s) of coefficients
 
6852
      static const double coefficients0[6] = \
 
6853
      {0.0, -0.17320508, -0.3, -0.18257419, -0.14142136, 0.16329932};
 
6854
      
 
6855
      static const double coefficients1[6] = \
 
6856
      {1.0606602, -0.17320508, 0.3, 0.0, -0.14142136, -0.36742346};
 
6857
      
 
6858
      // Compute value(s)
 
6859
      for (unsigned int r = 0; r < 6; r++)
 
6860
      {
 
6861
        values[0] += coefficients0[r]*basisvalues[r];
 
6862
        values[1] += coefficients1[r]*basisvalues[r];
 
6863
      }// end loop over 'r'
 
6864
      
 
6865
      // Using contravariant Piola transform to map values back to the physical element
 
6866
      const double tmp_ref0 = values[0];
 
6867
      const double tmp_ref1 = values[1];
 
6868
      values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
6869
      values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
6870
      values[2] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
6871
        break;
 
6872
      }
 
6873
    case 8:
 
6874
      {
 
6875
        
 
6876
      // Array of basisvalues
 
6877
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
6878
      
 
6879
      // Declare helper variables
 
6880
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
6881
      
 
6882
      // Compute basisvalues
 
6883
      basisvalues[0] = 1.0;
 
6884
      basisvalues[1] = tmp0;
 
6885
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
6886
      basisvalues[0] *= std::sqrt(0.5);
 
6887
      basisvalues[2] *= std::sqrt(1.0);
 
6888
      basisvalues[1] *= std::sqrt(3.0);
 
6889
      
 
6890
      // Table(s) of coefficients
 
6891
      static const double coefficients0[3] = \
 
6892
      {0.94280904, 0.57735027, -0.33333333};
 
6893
      
 
6894
      static const double coefficients1[3] = \
 
6895
      {-0.47140452, 0.0, -0.33333333};
 
6896
      
 
6897
      // Compute value(s)
 
6898
      for (unsigned int r = 0; r < 3; r++)
 
6899
      {
 
6900
        values[2] += coefficients0[r]*basisvalues[r];
 
6901
        values[3] += coefficients1[r]*basisvalues[r];
 
6902
      }// end loop over 'r'
 
6903
      
 
6904
      // Using contravariant Piola transform to map values back to the physical element
 
6905
      const double tmp_ref0 = values[2];
 
6906
      const double tmp_ref1 = values[3];
 
6907
      values[2] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
6908
      values[3] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
6909
      values[4] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
6910
        break;
 
6911
      }
 
6912
    case 9:
 
6913
      {
 
6914
        
 
6915
      // Array of basisvalues
 
6916
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
6917
      
 
6918
      // Declare helper variables
 
6919
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
6920
      
 
6921
      // Compute basisvalues
 
6922
      basisvalues[0] = 1.0;
 
6923
      basisvalues[1] = tmp0;
 
6924
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
6925
      basisvalues[0] *= std::sqrt(0.5);
 
6926
      basisvalues[2] *= std::sqrt(1.0);
 
6927
      basisvalues[1] *= std::sqrt(3.0);
 
6928
      
 
6929
      // Table(s) of coefficients
 
6930
      static const double coefficients0[3] = \
 
6931
      {-0.47140452, -0.28867513, 0.16666667};
 
6932
      
 
6933
      static const double coefficients1[3] = \
 
6934
      {0.94280904, 0.0, 0.66666667};
 
6935
      
 
6936
      // Compute value(s)
 
6937
      for (unsigned int r = 0; r < 3; r++)
 
6938
      {
 
6939
        values[2] += coefficients0[r]*basisvalues[r];
 
6940
        values[3] += coefficients1[r]*basisvalues[r];
 
6941
      }// end loop over 'r'
 
6942
      
 
6943
      // Using contravariant Piola transform to map values back to the physical element
 
6944
      const double tmp_ref0 = values[2];
 
6945
      const double tmp_ref1 = values[3];
 
6946
      values[2] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
6947
      values[3] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
6948
      values[4] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
6949
        break;
 
6950
      }
 
6951
    case 10:
 
6952
      {
 
6953
        
 
6954
      // Array of basisvalues
 
6955
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
6956
      
 
6957
      // Declare helper variables
 
6958
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
6959
      
 
6960
      // Compute basisvalues
 
6961
      basisvalues[0] = 1.0;
 
6962
      basisvalues[1] = tmp0;
 
6963
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
6964
      basisvalues[0] *= std::sqrt(0.5);
 
6965
      basisvalues[2] *= std::sqrt(1.0);
 
6966
      basisvalues[1] *= std::sqrt(3.0);
 
6967
      
 
6968
      // Table(s) of coefficients
 
6969
      static const double coefficients0[3] = \
 
6970
      {0.47140452, -0.57735027, -0.66666667};
 
6971
      
 
6972
      static const double coefficients1[3] = \
 
6973
      {0.47140452, 0.0, 0.33333333};
 
6974
      
 
6975
      // Compute value(s)
 
6976
      for (unsigned int r = 0; r < 3; r++)
 
6977
      {
 
6978
        values[2] += coefficients0[r]*basisvalues[r];
 
6979
        values[3] += coefficients1[r]*basisvalues[r];
 
6980
      }// end loop over 'r'
 
6981
      
 
6982
      // Using contravariant Piola transform to map values back to the physical element
 
6983
      const double tmp_ref0 = values[2];
 
6984
      const double tmp_ref1 = values[3];
 
6985
      values[2] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
6986
      values[3] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
6987
      values[4] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
6988
        break;
 
6989
      }
 
6990
    case 11:
 
6991
      {
 
6992
        
 
6993
      // Array of basisvalues
 
6994
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
6995
      
 
6996
      // Declare helper variables
 
6997
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
6998
      
 
6999
      // Compute basisvalues
 
7000
      basisvalues[0] = 1.0;
 
7001
      basisvalues[1] = tmp0;
 
7002
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
7003
      basisvalues[0] *= std::sqrt(0.5);
 
7004
      basisvalues[2] *= std::sqrt(1.0);
 
7005
      basisvalues[1] *= std::sqrt(3.0);
 
7006
      
 
7007
      // Table(s) of coefficients
 
7008
      static const double coefficients0[3] = \
 
7009
      {0.47140452, 0.28867513, 0.83333333};
 
7010
      
 
7011
      static const double coefficients1[3] = \
 
7012
      {-0.94280904, 0.0, -0.66666667};
 
7013
      
 
7014
      // Compute value(s)
 
7015
      for (unsigned int r = 0; r < 3; r++)
 
7016
      {
 
7017
        values[2] += coefficients0[r]*basisvalues[r];
 
7018
        values[3] += coefficients1[r]*basisvalues[r];
 
7019
      }// end loop over 'r'
 
7020
      
 
7021
      // Using contravariant Piola transform to map values back to the physical element
 
7022
      const double tmp_ref0 = values[2];
 
7023
      const double tmp_ref1 = values[3];
 
7024
      values[2] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
7025
      values[3] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
7026
      values[4] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
7027
        break;
 
7028
      }
 
7029
    case 12:
 
7030
      {
 
7031
        
 
7032
      // Array of basisvalues
 
7033
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
7034
      
 
7035
      // Declare helper variables
 
7036
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
7037
      
 
7038
      // Compute basisvalues
 
7039
      basisvalues[0] = 1.0;
 
7040
      basisvalues[1] = tmp0;
 
7041
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
7042
      basisvalues[0] *= std::sqrt(0.5);
 
7043
      basisvalues[2] *= std::sqrt(1.0);
 
7044
      basisvalues[1] *= std::sqrt(3.0);
 
7045
      
 
7046
      // Table(s) of coefficients
 
7047
      static const double coefficients0[3] = \
 
7048
      {-0.47140452, -0.28867513, 0.16666667};
 
7049
      
 
7050
      static const double coefficients1[3] = \
 
7051
      {-0.47140452, 0.8660254, 0.16666667};
 
7052
      
 
7053
      // Compute value(s)
 
7054
      for (unsigned int r = 0; r < 3; r++)
 
7055
      {
 
7056
        values[2] += coefficients0[r]*basisvalues[r];
 
7057
        values[3] += coefficients1[r]*basisvalues[r];
 
7058
      }// end loop over 'r'
 
7059
      
 
7060
      // Using contravariant Piola transform to map values back to the physical element
 
7061
      const double tmp_ref0 = values[2];
 
7062
      const double tmp_ref1 = values[3];
 
7063
      values[2] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
7064
      values[3] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
7065
      values[4] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
7066
        break;
 
7067
      }
 
7068
    case 13:
 
7069
      {
 
7070
        
 
7071
      // Array of basisvalues
 
7072
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
7073
      
 
7074
      // Declare helper variables
 
7075
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
7076
      
 
7077
      // Compute basisvalues
 
7078
      basisvalues[0] = 1.0;
 
7079
      basisvalues[1] = tmp0;
 
7080
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
7081
      basisvalues[0] *= std::sqrt(0.5);
 
7082
      basisvalues[2] *= std::sqrt(1.0);
 
7083
      basisvalues[1] *= std::sqrt(3.0);
 
7084
      
 
7085
      // Table(s) of coefficients
 
7086
      static const double coefficients0[3] = \
 
7087
      {0.94280904, 0.57735027, -0.33333333};
 
7088
      
 
7089
      static const double coefficients1[3] = \
 
7090
      {-0.47140452, -0.8660254, 0.16666667};
 
7091
      
 
7092
      // Compute value(s)
 
7093
      for (unsigned int r = 0; r < 3; r++)
 
7094
      {
 
7095
        values[2] += coefficients0[r]*basisvalues[r];
 
7096
        values[3] += coefficients1[r]*basisvalues[r];
 
7097
      }// end loop over 'r'
 
7098
      
 
7099
      // Using contravariant Piola transform to map values back to the physical element
 
7100
      const double tmp_ref0 = values[2];
 
7101
      const double tmp_ref1 = values[3];
 
7102
      values[2] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
7103
      values[3] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
7104
      values[4] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
7105
        break;
 
7106
      }
 
7107
    case 14:
 
7108
      {
 
7109
        
 
7110
      // Array of basisvalues
 
7111
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
7112
      
 
7113
      // Declare helper variables
 
7114
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
7115
      
 
7116
      // Compute basisvalues
 
7117
      basisvalues[0] = 1.0;
 
7118
      basisvalues[1] = tmp0;
 
7119
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
7120
      basisvalues[0] *= std::sqrt(0.5);
 
7121
      basisvalues[2] *= std::sqrt(1.0);
 
7122
      basisvalues[1] *= std::sqrt(3.0);
 
7123
      
 
7124
      // Table(s) of coefficients
 
7125
      static const double coefficients0[3] = \
 
7126
      {-0.47140452, 0.0, -0.33333333};
 
7127
      
 
7128
      static const double coefficients1[3] = \
 
7129
      {0.47140452, 0.28867513, -0.16666667};
 
7130
      
 
7131
      // Compute value(s)
 
7132
      for (unsigned int r = 0; r < 3; r++)
 
7133
      {
 
7134
        values[4] += coefficients0[r]*basisvalues[r];
 
7135
        values[5] += coefficients1[r]*basisvalues[r];
 
7136
      }// end loop over 'r'
 
7137
      
 
7138
      // Using covariant Piola transform to map values back to the physical element
 
7139
      const double tmp_ref0 = values[4];
 
7140
      const double tmp_ref1 = values[5];
 
7141
      values[4] = (K[0]*tmp_ref0 + K[3]*tmp_ref1);
 
7142
      values[5] = (K[1]*tmp_ref0 + K[4]*tmp_ref1);
 
7143
      values[6] = (K[2]*tmp_ref0 + K[5]*tmp_ref1);
 
7144
        break;
 
7145
      }
 
7146
    case 15:
 
7147
      {
 
7148
        
 
7149
      // Array of basisvalues
 
7150
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
7151
      
 
7152
      // Declare helper variables
 
7153
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
7154
      
 
7155
      // Compute basisvalues
 
7156
      basisvalues[0] = 1.0;
 
7157
      basisvalues[1] = tmp0;
 
7158
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
7159
      basisvalues[0] *= std::sqrt(0.5);
 
7160
      basisvalues[2] *= std::sqrt(1.0);
 
7161
      basisvalues[1] *= std::sqrt(3.0);
 
7162
      
 
7163
      // Table(s) of coefficients
 
7164
      static const double coefficients0[3] = \
 
7165
      {0.47140452, 0.0, 0.33333333};
 
7166
      
 
7167
      static const double coefficients1[3] = \
 
7168
      {0.94280904, -0.28867513, 0.16666667};
 
7169
      
 
7170
      // Compute value(s)
 
7171
      for (unsigned int r = 0; r < 3; r++)
 
7172
      {
 
7173
        values[4] += coefficients0[r]*basisvalues[r];
 
7174
        values[5] += coefficients1[r]*basisvalues[r];
 
7175
      }// end loop over 'r'
 
7176
      
 
7177
      // Using covariant Piola transform to map values back to the physical element
 
7178
      const double tmp_ref0 = values[4];
 
7179
      const double tmp_ref1 = values[5];
 
7180
      values[4] = (K[0]*tmp_ref0 + K[3]*tmp_ref1);
 
7181
      values[5] = (K[1]*tmp_ref0 + K[4]*tmp_ref1);
 
7182
      values[6] = (K[2]*tmp_ref0 + K[5]*tmp_ref1);
 
7183
        break;
 
7184
      }
 
7185
    case 16:
 
7186
      {
 
7187
        
 
7188
      // Array of basisvalues
 
7189
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
7190
      
 
7191
      // Declare helper variables
 
7192
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
7193
      
 
7194
      // Compute basisvalues
 
7195
      basisvalues[0] = 1.0;
 
7196
      basisvalues[1] = tmp0;
 
7197
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
7198
      basisvalues[0] *= std::sqrt(0.5);
 
7199
      basisvalues[2] *= std::sqrt(1.0);
 
7200
      basisvalues[1] *= std::sqrt(3.0);
 
7201
      
 
7202
      // Table(s) of coefficients
 
7203
      static const double coefficients0[3] = \
 
7204
      {0.94280904, 0.0, -0.33333333};
 
7205
      
 
7206
      static const double coefficients1[3] = \
 
7207
      {0.47140452, 0.28867513, -0.16666667};
 
7208
      
 
7209
      // Compute value(s)
 
7210
      for (unsigned int r = 0; r < 3; r++)
 
7211
      {
 
7212
        values[4] += coefficients0[r]*basisvalues[r];
 
7213
        values[5] += coefficients1[r]*basisvalues[r];
 
7214
      }// end loop over 'r'
 
7215
      
 
7216
      // Using covariant Piola transform to map values back to the physical element
 
7217
      const double tmp_ref0 = values[4];
 
7218
      const double tmp_ref1 = values[5];
 
7219
      values[4] = (K[0]*tmp_ref0 + K[3]*tmp_ref1);
 
7220
      values[5] = (K[1]*tmp_ref0 + K[4]*tmp_ref1);
 
7221
      values[6] = (K[2]*tmp_ref0 + K[5]*tmp_ref1);
 
7222
        break;
 
7223
      }
 
7224
    case 17:
 
7225
      {
 
7226
        
 
7227
      // Array of basisvalues
 
7228
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
7229
      
 
7230
      // Declare helper variables
 
7231
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
7232
      
 
7233
      // Compute basisvalues
 
7234
      basisvalues[0] = 1.0;
 
7235
      basisvalues[1] = tmp0;
 
7236
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
7237
      basisvalues[0] *= std::sqrt(0.5);
 
7238
      basisvalues[2] *= std::sqrt(1.0);
 
7239
      basisvalues[1] *= std::sqrt(3.0);
 
7240
      
 
7241
      // Table(s) of coefficients
 
7242
      static const double coefficients0[3] = \
 
7243
      {0.47140452, -0.28867513, -0.16666667};
 
7244
      
 
7245
      // Compute value(s)
 
7246
      for (unsigned int r = 0; r < 3; r++)
 
7247
      {
 
7248
        values[6] += coefficients0[r]*basisvalues[r];
 
7249
      }// end loop over 'r'
 
7250
        break;
 
7251
      }
 
7252
    case 18:
 
7253
      {
 
7254
        
 
7255
      // Array of basisvalues
 
7256
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
7257
      
 
7258
      // Declare helper variables
 
7259
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
7260
      
 
7261
      // Compute basisvalues
 
7262
      basisvalues[0] = 1.0;
 
7263
      basisvalues[1] = tmp0;
 
7264
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
7265
      basisvalues[0] *= std::sqrt(0.5);
 
7266
      basisvalues[2] *= std::sqrt(1.0);
 
7267
      basisvalues[1] *= std::sqrt(3.0);
 
7268
      
 
7269
      // Table(s) of coefficients
 
7270
      static const double coefficients0[3] = \
 
7271
      {0.47140452, 0.28867513, -0.16666667};
 
7272
      
 
7273
      // Compute value(s)
 
7274
      for (unsigned int r = 0; r < 3; r++)
 
7275
      {
 
7276
        values[6] += coefficients0[r]*basisvalues[r];
 
7277
      }// end loop over 'r'
 
7278
        break;
 
7279
      }
 
7280
    case 19:
 
7281
      {
 
7282
        
 
7283
      // Array of basisvalues
 
7284
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
7285
      
 
7286
      // Declare helper variables
 
7287
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
7288
      
 
7289
      // Compute basisvalues
 
7290
      basisvalues[0] = 1.0;
 
7291
      basisvalues[1] = tmp0;
 
7292
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
7293
      basisvalues[0] *= std::sqrt(0.5);
 
7294
      basisvalues[2] *= std::sqrt(1.0);
 
7295
      basisvalues[1] *= std::sqrt(3.0);
 
7296
      
 
7297
      // Table(s) of coefficients
 
7298
      static const double coefficients0[3] = \
 
7299
      {0.47140452, 0.0, 0.33333333};
 
7300
      
 
7301
      // Compute value(s)
 
7302
      for (unsigned int r = 0; r < 3; r++)
 
7303
      {
 
7304
        values[6] += coefficients0[r]*basisvalues[r];
 
7305
      }// end loop over 'r'
 
7306
        break;
 
7307
      }
 
7308
    }
 
7309
    
 
7310
  }
 
7311
 
 
7312
  /// Evaluate all basis functions at given point x in cell
 
7313
  virtual void evaluate_basis_all(double* values,
 
7314
                                  const double* x,
 
7315
                                  const double* vertex_coordinates,
 
7316
                                  int cell_orientation) const
 
7317
  {
 
7318
    // Helper variable to hold values of a single dof.
 
7319
    double dof_values[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
7320
    
 
7321
    // Loop dofs and call evaluate_basis
 
7322
    for (unsigned int r = 0; r < 20; r++)
 
7323
    {
 
7324
      evaluate_basis(r, dof_values, x, vertex_coordinates, cell_orientation);
 
7325
      for (unsigned int s = 0; s < 10; s++)
 
7326
      {
 
7327
        values[r*10 + s] = dof_values[s];
 
7328
      }// end loop over 's'
 
7329
    }// end loop over 'r'
 
7330
  }
 
7331
 
 
7332
  /// Evaluate order n derivatives of basis function i at given point x in cell
 
7333
  virtual void evaluate_basis_derivatives(std::size_t i,
 
7334
                                          std::size_t n,
 
7335
                                          double* values,
 
7336
                                          const double* x,
 
7337
                                          const double* vertex_coordinates,
 
7338
                                          int cell_orientation) const
 
7339
  {
 
7340
    // Compute Jacobian
 
7341
    double J[6];
 
7342
    compute_jacobian_triangle_3d(J, vertex_coordinates);
 
7343
    
 
7344
    // Compute Jacobian inverse and determinant
 
7345
    double K[6];
 
7346
    double detJ;
 
7347
    compute_jacobian_inverse_triangle_3d(K, detJ, J);
 
7348
    
 
7349
    
 
7350
    // Check orientation
 
7351
    if (cell_orientation == -1)
 
7352
      throw std::runtime_error("cell orientation must be defined (not -1)");
 
7353
    // (If cell_orientation == 1 = down, multiply det(J) by -1)
 
7354
    else if (cell_orientation == 1)
 
7355
      detJ *= -1;
 
7356
    
 
7357
    
 
7358
    const double b0 = vertex_coordinates[0];
 
7359
    const double b1 = vertex_coordinates[1];
 
7360
    const double b2 = vertex_coordinates[2];
 
7361
    
 
7362
    // P_FFC = J^dag (p - b), P_FIAT = 2*P_FFC - (1, 1)
 
7363
    double X = 2*(K[0]*(x[0] - b0) + K[1]*(x[1] - b1) + K[2]*(x[2] - b2)) - 1.0;
 
7364
    double Y = 2*(K[3]*(x[0] - b0) + K[4]*(x[1] - b1) + K[5]*(x[2] - b2)) - 1.0;
 
7365
    
 
7366
    
 
7367
    // Compute number of derivatives.
 
7368
    unsigned int num_derivatives_t = 1;
 
7369
    for (unsigned int r = 0; r < n; r++)
 
7370
    {
 
7371
      num_derivatives_t *= 2;
 
7372
    }// end loop over 'r'
 
7373
    
 
7374
    // Compute number of derivatives.
 
7375
    unsigned int num_derivatives_g = 1;
 
7376
    for (unsigned int r = 0; r < n; r++)
 
7377
    {
 
7378
      num_derivatives_g *= 3;
 
7379
    }// end loop over 'r'
 
7380
    
 
7381
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
7382
    unsigned int **combinations_t = new unsigned int *[num_derivatives_t];
 
7383
    for (unsigned int row = 0; row < num_derivatives_t; row++)
 
7384
    {
 
7385
      combinations_t[row] = new unsigned int [n];
 
7386
      for (unsigned int col = 0; col < n; col++)
 
7387
        combinations_t[row][col] = 0;
 
7388
    }
 
7389
    
 
7390
    // Generate combinations of derivatives
 
7391
    for (unsigned int row = 1; row < num_derivatives_t; row++)
 
7392
    {
 
7393
      for (unsigned int num = 0; num < row; num++)
 
7394
      {
 
7395
        for (unsigned int col = n-1; col+1 > 0; col--)
 
7396
        {
 
7397
          if (combinations_t[row][col] + 1 > 1)
 
7398
            combinations_t[row][col] = 0;
 
7399
          else
 
7400
          {
 
7401
            combinations_t[row][col] += 1;
 
7402
            break;
 
7403
          }
 
7404
        }
 
7405
      }
 
7406
    }
 
7407
    
 
7408
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
 
7409
    unsigned int **combinations_g = new unsigned int *[num_derivatives_g];
 
7410
    for (unsigned int row = 0; row < num_derivatives_g; row++)
 
7411
    {
 
7412
      combinations_g[row] = new unsigned int [n];
 
7413
      for (unsigned int col = 0; col < n; col++)
 
7414
        combinations_g[row][col] = 0;
 
7415
    }
 
7416
    
 
7417
    // Generate combinations of derivatives
 
7418
    for (unsigned int row = 1; row < num_derivatives_g; row++)
 
7419
    {
 
7420
      for (unsigned int num = 0; num < row; num++)
 
7421
      {
 
7422
        for (unsigned int col = n-1; col+1 > 0; col--)
 
7423
        {
 
7424
          if (combinations_g[row][col] + 1 > 2)
 
7425
            combinations_g[row][col] = 0;
 
7426
          else
 
7427
          {
 
7428
            combinations_g[row][col] += 1;
 
7429
            break;
 
7430
          }
 
7431
        }
 
7432
      }
 
7433
    }
 
7434
    
 
7435
    // Compute inverse of Jacobian
 
7436
    const double Jinv[2][3] = {{K[0], K[1], K[2]}, {K[3], K[4], K[5]}};
 
7437
    
 
7438
    // Declare transformation matrix
 
7439
    // Declare pointer to two dimensional array and initialise
 
7440
    double **transform = new double *[num_derivatives_g];
 
7441
    
 
7442
    for (unsigned int j = 0; j < num_derivatives_g; j++)
 
7443
    {
 
7444
      transform[j] = new double [num_derivatives_t];
 
7445
      for (unsigned int k = 0; k < num_derivatives_t; k++)
 
7446
        transform[j][k] = 1;
 
7447
    }
 
7448
    
 
7449
    // Construct transformation matrix
 
7450
    for (unsigned int row = 0; row < num_derivatives_g; row++)
 
7451
    {
 
7452
      for (unsigned int col = 0; col < num_derivatives_t; col++)
 
7453
      {
 
7454
        for (unsigned int k = 0; k < n; k++)
 
7455
          transform[row][col] *= Jinv[combinations_t[col][k]][combinations_g[row][k]];
 
7456
      }
 
7457
    }
 
7458
    
 
7459
    // Reset values. Assuming that values is always an array.
 
7460
    for (unsigned int r = 0; r < 10*num_derivatives_g; r++)
 
7461
    {
 
7462
      values[r] = 0.0;
 
7463
    }// end loop over 'r'
 
7464
    
 
7465
    switch (i)
 
7466
    {
 
7467
    case 0:
 
7468
      {
 
7469
        
 
7470
      // Array of basisvalues
 
7471
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
7472
      
 
7473
      // Declare helper variables
 
7474
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
7475
      double tmp1 = (1.0 - Y)/2.0;
 
7476
      double tmp2 = tmp1*tmp1;
 
7477
      
 
7478
      // Compute basisvalues
 
7479
      basisvalues[0] = 1.0;
 
7480
      basisvalues[1] = tmp0;
 
7481
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
7482
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
7483
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
7484
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
7485
      basisvalues[0] *= std::sqrt(0.5);
 
7486
      basisvalues[2] *= std::sqrt(1.0);
 
7487
      basisvalues[5] *= std::sqrt(1.5);
 
7488
      basisvalues[1] *= std::sqrt(3.0);
 
7489
      basisvalues[4] *= std::sqrt(4.5);
 
7490
      basisvalues[3] *= std::sqrt(7.5);
 
7491
      
 
7492
      // Table(s) of coefficients
 
7493
      static const double coefficients0[6] = \
 
7494
      {0.23570226, 0.40414519, -0.23333333, 0.18257419, -0.14142136, 0.081649658};
 
7495
      
 
7496
      static const double coefficients1[6] = \
 
7497
      {-0.11785113, 0.17320508, -0.23333333, 0.0, 0.14142136, -0.12247449};
 
7498
      
 
7499
      // Tables of derivatives of the polynomial base (transpose).
 
7500
      static const double dmats0[6][6] = \
 
7501
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
7502
      {4.8989795, 0.0, 0.0, 0.0, 0.0, 0.0},
 
7503
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
7504
      {0.0, 9.486833, 0.0, 0.0, 0.0, 0.0},
 
7505
      {4.0, 0.0, 7.0710678, 0.0, 0.0, 0.0},
 
7506
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}};
 
7507
      
 
7508
      static const double dmats1[6][6] = \
 
7509
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
7510
      {2.4494897, 0.0, 0.0, 0.0, 0.0, 0.0},
 
7511
      {4.2426407, 0.0, 0.0, 0.0, 0.0, 0.0},
 
7512
      {2.5819889, 4.7434165, -0.91287093, 0.0, 0.0, 0.0},
 
7513
      {2.0, 6.1237244, 3.5355339, 0.0, 0.0, 0.0},
 
7514
      {-2.3094011, 0.0, 8.1649658, 0.0, 0.0, 0.0}};
 
7515
      
 
7516
      // Compute reference derivatives.
 
7517
      // Declare pointer to array of derivatives on FIAT element.
 
7518
      double *derivatives = new double[2*num_derivatives_t];
 
7519
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
7520
      {
 
7521
        derivatives[r] = 0.0;
 
7522
      }// end loop over 'r'
 
7523
      
 
7524
      // Declare pointer to array of reference derivatives on physical element.
 
7525
      double *derivatives_p = new double[3*num_derivatives_t];
 
7526
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
7527
      {
 
7528
        derivatives_p[r] = 0.0;
 
7529
      }// end loop over 'r'
 
7530
      
 
7531
      // Declare derivative matrix (of polynomial basis).
 
7532
      double dmats[6][6] = \
 
7533
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
7534
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
7535
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
7536
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
7537
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
7538
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
7539
      
 
7540
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
7541
      double dmats_old[6][6] = \
 
7542
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
7543
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
7544
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
7545
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
7546
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
7547
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
7548
      
 
7549
      // Loop possible derivatives.
 
7550
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
7551
      {
 
7552
        // Resetting dmats values to compute next derivative.
 
7553
        for (unsigned int t = 0; t < 6; t++)
 
7554
        {
 
7555
          for (unsigned int u = 0; u < 6; u++)
 
7556
          {
 
7557
            dmats[t][u] = 0.0;
 
7558
            if (t == u)
 
7559
            {
 
7560
            dmats[t][u] = 1.0;
 
7561
            }
 
7562
            
 
7563
          }// end loop over 'u'
 
7564
        }// end loop over 't'
 
7565
        
 
7566
        // Looping derivative order to generate dmats.
 
7567
        for (unsigned int s = 0; s < n; s++)
 
7568
        {
 
7569
          // Updating dmats_old with new values and resetting dmats.
 
7570
          for (unsigned int t = 0; t < 6; t++)
 
7571
          {
 
7572
            for (unsigned int u = 0; u < 6; u++)
 
7573
            {
 
7574
              dmats_old[t][u] = dmats[t][u];
 
7575
              dmats[t][u] = 0.0;
 
7576
            }// end loop over 'u'
 
7577
          }// end loop over 't'
 
7578
          
 
7579
          // Update dmats using an inner product.
 
7580
          if (combinations_t[r][s] == 0)
 
7581
          {
 
7582
          for (unsigned int t = 0; t < 6; t++)
 
7583
          {
 
7584
            for (unsigned int u = 0; u < 6; u++)
 
7585
            {
 
7586
              for (unsigned int tu = 0; tu < 6; tu++)
 
7587
              {
 
7588
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
7589
              }// end loop over 'tu'
 
7590
            }// end loop over 'u'
 
7591
          }// end loop over 't'
 
7592
          }
 
7593
          
 
7594
          if (combinations_t[r][s] == 1)
 
7595
          {
 
7596
          for (unsigned int t = 0; t < 6; t++)
 
7597
          {
 
7598
            for (unsigned int u = 0; u < 6; u++)
 
7599
            {
 
7600
              for (unsigned int tu = 0; tu < 6; tu++)
 
7601
              {
 
7602
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
7603
              }// end loop over 'tu'
 
7604
            }// end loop over 'u'
 
7605
          }// end loop over 't'
 
7606
          }
 
7607
          
 
7608
        }// end loop over 's'
 
7609
        for (unsigned int s = 0; s < 6; s++)
 
7610
        {
 
7611
          for (unsigned int t = 0; t < 6; t++)
 
7612
          {
 
7613
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
7614
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
7615
          }// end loop over 't'
 
7616
        }// end loop over 's'
 
7617
        
 
7618
        // Using contravariant Piola transform to map values back to the physical element.
 
7619
        const double tmp_ref0 = derivatives[r];
 
7620
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
7621
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
7622
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
7623
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
7624
      }// end loop over 'r'
 
7625
      
 
7626
      // Transform derivatives back to physical element
 
7627
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
7628
      {
 
7629
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
7630
        {
 
7631
          values[r] += transform[r][s]*derivatives_p[s];
 
7632
          values[num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
7633
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
7634
        }// end loop over 's'
 
7635
      }// end loop over 'r'
 
7636
      
 
7637
      // Delete pointer to array of derivatives on FIAT element
 
7638
      delete [] derivatives;
 
7639
      
 
7640
      // Delete pointer to array of reference derivatives on physical element.
 
7641
      delete [] derivatives_p;
 
7642
      
 
7643
      // Delete pointer to array of combinations of derivatives and transform
 
7644
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
7645
      {
 
7646
        delete [] combinations_t[r];
 
7647
      }// end loop over 'r'
 
7648
      delete [] combinations_t;
 
7649
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
7650
      {
 
7651
        delete [] combinations_g[r];
 
7652
      }// end loop over 'r'
 
7653
      delete [] combinations_g;
 
7654
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
7655
      {
 
7656
        delete [] transform[r];
 
7657
      }// end loop over 'r'
 
7658
      delete [] transform;
 
7659
        break;
 
7660
      }
 
7661
    case 1:
 
7662
      {
 
7663
        
 
7664
      // Array of basisvalues
 
7665
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
7666
      
 
7667
      // Declare helper variables
 
7668
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
7669
      double tmp1 = (1.0 - Y)/2.0;
 
7670
      double tmp2 = tmp1*tmp1;
 
7671
      
 
7672
      // Compute basisvalues
 
7673
      basisvalues[0] = 1.0;
 
7674
      basisvalues[1] = tmp0;
 
7675
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
7676
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
7677
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
7678
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
7679
      basisvalues[0] *= std::sqrt(0.5);
 
7680
      basisvalues[2] *= std::sqrt(1.0);
 
7681
      basisvalues[5] *= std::sqrt(1.5);
 
7682
      basisvalues[1] *= std::sqrt(3.0);
 
7683
      basisvalues[4] *= std::sqrt(4.5);
 
7684
      basisvalues[3] *= std::sqrt(7.5);
 
7685
      
 
7686
      // Table(s) of coefficients
 
7687
      static const double coefficients0[6] = \
 
7688
      {-0.11785113, -0.11547005, 0.26666667, 0.0, 0.14142136, -0.12247449};
 
7689
      
 
7690
      static const double coefficients1[6] = \
 
7691
      {0.23570226, 0.0, 0.46666667, 0.0, 0.0, 0.24494897};
 
7692
      
 
7693
      // Tables of derivatives of the polynomial base (transpose).
 
7694
      static const double dmats0[6][6] = \
 
7695
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
7696
      {4.8989795, 0.0, 0.0, 0.0, 0.0, 0.0},
 
7697
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
7698
      {0.0, 9.486833, 0.0, 0.0, 0.0, 0.0},
 
7699
      {4.0, 0.0, 7.0710678, 0.0, 0.0, 0.0},
 
7700
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}};
 
7701
      
 
7702
      static const double dmats1[6][6] = \
 
7703
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
7704
      {2.4494897, 0.0, 0.0, 0.0, 0.0, 0.0},
 
7705
      {4.2426407, 0.0, 0.0, 0.0, 0.0, 0.0},
 
7706
      {2.5819889, 4.7434165, -0.91287093, 0.0, 0.0, 0.0},
 
7707
      {2.0, 6.1237244, 3.5355339, 0.0, 0.0, 0.0},
 
7708
      {-2.3094011, 0.0, 8.1649658, 0.0, 0.0, 0.0}};
 
7709
      
 
7710
      // Compute reference derivatives.
 
7711
      // Declare pointer to array of derivatives on FIAT element.
 
7712
      double *derivatives = new double[2*num_derivatives_t];
 
7713
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
7714
      {
 
7715
        derivatives[r] = 0.0;
 
7716
      }// end loop over 'r'
 
7717
      
 
7718
      // Declare pointer to array of reference derivatives on physical element.
 
7719
      double *derivatives_p = new double[3*num_derivatives_t];
 
7720
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
7721
      {
 
7722
        derivatives_p[r] = 0.0;
 
7723
      }// end loop over 'r'
 
7724
      
 
7725
      // Declare derivative matrix (of polynomial basis).
 
7726
      double dmats[6][6] = \
 
7727
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
7728
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
7729
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
7730
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
7731
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
7732
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
7733
      
 
7734
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
7735
      double dmats_old[6][6] = \
 
7736
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
7737
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
7738
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
7739
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
7740
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
7741
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
7742
      
 
7743
      // Loop possible derivatives.
 
7744
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
7745
      {
 
7746
        // Resetting dmats values to compute next derivative.
 
7747
        for (unsigned int t = 0; t < 6; t++)
 
7748
        {
 
7749
          for (unsigned int u = 0; u < 6; u++)
 
7750
          {
 
7751
            dmats[t][u] = 0.0;
 
7752
            if (t == u)
 
7753
            {
 
7754
            dmats[t][u] = 1.0;
 
7755
            }
 
7756
            
 
7757
          }// end loop over 'u'
 
7758
        }// end loop over 't'
 
7759
        
 
7760
        // Looping derivative order to generate dmats.
 
7761
        for (unsigned int s = 0; s < n; s++)
 
7762
        {
 
7763
          // Updating dmats_old with new values and resetting dmats.
 
7764
          for (unsigned int t = 0; t < 6; t++)
 
7765
          {
 
7766
            for (unsigned int u = 0; u < 6; u++)
 
7767
            {
 
7768
              dmats_old[t][u] = dmats[t][u];
 
7769
              dmats[t][u] = 0.0;
 
7770
            }// end loop over 'u'
 
7771
          }// end loop over 't'
 
7772
          
 
7773
          // Update dmats using an inner product.
 
7774
          if (combinations_t[r][s] == 0)
 
7775
          {
 
7776
          for (unsigned int t = 0; t < 6; t++)
 
7777
          {
 
7778
            for (unsigned int u = 0; u < 6; u++)
 
7779
            {
 
7780
              for (unsigned int tu = 0; tu < 6; tu++)
 
7781
              {
 
7782
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
7783
              }// end loop over 'tu'
 
7784
            }// end loop over 'u'
 
7785
          }// end loop over 't'
 
7786
          }
 
7787
          
 
7788
          if (combinations_t[r][s] == 1)
 
7789
          {
 
7790
          for (unsigned int t = 0; t < 6; t++)
 
7791
          {
 
7792
            for (unsigned int u = 0; u < 6; u++)
 
7793
            {
 
7794
              for (unsigned int tu = 0; tu < 6; tu++)
 
7795
              {
 
7796
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
7797
              }// end loop over 'tu'
 
7798
            }// end loop over 'u'
 
7799
          }// end loop over 't'
 
7800
          }
 
7801
          
 
7802
        }// end loop over 's'
 
7803
        for (unsigned int s = 0; s < 6; s++)
 
7804
        {
 
7805
          for (unsigned int t = 0; t < 6; t++)
 
7806
          {
 
7807
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
7808
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
7809
          }// end loop over 't'
 
7810
        }// end loop over 's'
 
7811
        
 
7812
        // Using contravariant Piola transform to map values back to the physical element.
 
7813
        const double tmp_ref0 = derivatives[r];
 
7814
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
7815
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
7816
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
7817
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
7818
      }// end loop over 'r'
 
7819
      
 
7820
      // Transform derivatives back to physical element
 
7821
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
7822
      {
 
7823
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
7824
        {
 
7825
          values[r] += transform[r][s]*derivatives_p[s];
 
7826
          values[num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
7827
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
7828
        }// end loop over 's'
 
7829
      }// end loop over 'r'
 
7830
      
 
7831
      // Delete pointer to array of derivatives on FIAT element
 
7832
      delete [] derivatives;
 
7833
      
 
7834
      // Delete pointer to array of reference derivatives on physical element.
 
7835
      delete [] derivatives_p;
 
7836
      
 
7837
      // Delete pointer to array of combinations of derivatives and transform
 
7838
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
7839
      {
 
7840
        delete [] combinations_t[r];
 
7841
      }// end loop over 'r'
 
7842
      delete [] combinations_t;
 
7843
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
7844
      {
 
7845
        delete [] combinations_g[r];
 
7846
      }// end loop over 'r'
 
7847
      delete [] combinations_g;
 
7848
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
7849
      {
 
7850
        delete [] transform[r];
 
7851
      }// end loop over 'r'
 
7852
      delete [] transform;
 
7853
        break;
 
7854
      }
 
7855
    case 2:
 
7856
      {
 
7857
        
 
7858
      // Array of basisvalues
 
7859
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
7860
      
 
7861
      // Declare helper variables
 
7862
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
7863
      double tmp1 = (1.0 - Y)/2.0;
 
7864
      double tmp2 = tmp1*tmp1;
 
7865
      
 
7866
      // Compute basisvalues
 
7867
      basisvalues[0] = 1.0;
 
7868
      basisvalues[1] = tmp0;
 
7869
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
7870
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
7871
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
7872
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
7873
      basisvalues[0] *= std::sqrt(0.5);
 
7874
      basisvalues[2] *= std::sqrt(1.0);
 
7875
      basisvalues[5] *= std::sqrt(1.5);
 
7876
      basisvalues[1] *= std::sqrt(3.0);
 
7877
      basisvalues[4] *= std::sqrt(4.5);
 
7878
      basisvalues[3] *= std::sqrt(7.5);
 
7879
      
 
7880
      // Table(s) of coefficients
 
7881
      static const double coefficients0[6] = \
 
7882
      {0.11785113, -0.57735027, -0.46666667, 0.18257419, 0.0, -0.040824829};
 
7883
      
 
7884
      static const double coefficients1[6] = \
 
7885
      {0.11785113, 0.17320508, 0.23333333, 0.0, 0.14142136, 0.12247449};
 
7886
      
 
7887
      // Tables of derivatives of the polynomial base (transpose).
 
7888
      static const double dmats0[6][6] = \
 
7889
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
7890
      {4.8989795, 0.0, 0.0, 0.0, 0.0, 0.0},
 
7891
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
7892
      {0.0, 9.486833, 0.0, 0.0, 0.0, 0.0},
 
7893
      {4.0, 0.0, 7.0710678, 0.0, 0.0, 0.0},
 
7894
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}};
 
7895
      
 
7896
      static const double dmats1[6][6] = \
 
7897
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
7898
      {2.4494897, 0.0, 0.0, 0.0, 0.0, 0.0},
 
7899
      {4.2426407, 0.0, 0.0, 0.0, 0.0, 0.0},
 
7900
      {2.5819889, 4.7434165, -0.91287093, 0.0, 0.0, 0.0},
 
7901
      {2.0, 6.1237244, 3.5355339, 0.0, 0.0, 0.0},
 
7902
      {-2.3094011, 0.0, 8.1649658, 0.0, 0.0, 0.0}};
 
7903
      
 
7904
      // Compute reference derivatives.
 
7905
      // Declare pointer to array of derivatives on FIAT element.
 
7906
      double *derivatives = new double[2*num_derivatives_t];
 
7907
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
7908
      {
 
7909
        derivatives[r] = 0.0;
 
7910
      }// end loop over 'r'
 
7911
      
 
7912
      // Declare pointer to array of reference derivatives on physical element.
 
7913
      double *derivatives_p = new double[3*num_derivatives_t];
 
7914
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
7915
      {
 
7916
        derivatives_p[r] = 0.0;
 
7917
      }// end loop over 'r'
 
7918
      
 
7919
      // Declare derivative matrix (of polynomial basis).
 
7920
      double dmats[6][6] = \
 
7921
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
7922
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
7923
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
7924
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
7925
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
7926
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
7927
      
 
7928
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
7929
      double dmats_old[6][6] = \
 
7930
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
7931
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
7932
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
7933
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
7934
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
7935
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
7936
      
 
7937
      // Loop possible derivatives.
 
7938
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
7939
      {
 
7940
        // Resetting dmats values to compute next derivative.
 
7941
        for (unsigned int t = 0; t < 6; t++)
 
7942
        {
 
7943
          for (unsigned int u = 0; u < 6; u++)
 
7944
          {
 
7945
            dmats[t][u] = 0.0;
 
7946
            if (t == u)
 
7947
            {
 
7948
            dmats[t][u] = 1.0;
 
7949
            }
 
7950
            
 
7951
          }// end loop over 'u'
 
7952
        }// end loop over 't'
 
7953
        
 
7954
        // Looping derivative order to generate dmats.
 
7955
        for (unsigned int s = 0; s < n; s++)
 
7956
        {
 
7957
          // Updating dmats_old with new values and resetting dmats.
 
7958
          for (unsigned int t = 0; t < 6; t++)
 
7959
          {
 
7960
            for (unsigned int u = 0; u < 6; u++)
 
7961
            {
 
7962
              dmats_old[t][u] = dmats[t][u];
 
7963
              dmats[t][u] = 0.0;
 
7964
            }// end loop over 'u'
 
7965
          }// end loop over 't'
 
7966
          
 
7967
          // Update dmats using an inner product.
 
7968
          if (combinations_t[r][s] == 0)
 
7969
          {
 
7970
          for (unsigned int t = 0; t < 6; t++)
 
7971
          {
 
7972
            for (unsigned int u = 0; u < 6; u++)
 
7973
            {
 
7974
              for (unsigned int tu = 0; tu < 6; tu++)
 
7975
              {
 
7976
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
7977
              }// end loop over 'tu'
 
7978
            }// end loop over 'u'
 
7979
          }// end loop over 't'
 
7980
          }
 
7981
          
 
7982
          if (combinations_t[r][s] == 1)
 
7983
          {
 
7984
          for (unsigned int t = 0; t < 6; t++)
 
7985
          {
 
7986
            for (unsigned int u = 0; u < 6; u++)
 
7987
            {
 
7988
              for (unsigned int tu = 0; tu < 6; tu++)
 
7989
              {
 
7990
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
7991
              }// end loop over 'tu'
 
7992
            }// end loop over 'u'
 
7993
          }// end loop over 't'
 
7994
          }
 
7995
          
 
7996
        }// end loop over 's'
 
7997
        for (unsigned int s = 0; s < 6; s++)
 
7998
        {
 
7999
          for (unsigned int t = 0; t < 6; t++)
 
8000
          {
 
8001
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
8002
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
8003
          }// end loop over 't'
 
8004
        }// end loop over 's'
 
8005
        
 
8006
        // Using contravariant Piola transform to map values back to the physical element.
 
8007
        const double tmp_ref0 = derivatives[r];
 
8008
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
8009
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
8010
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
8011
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
8012
      }// end loop over 'r'
 
8013
      
 
8014
      // Transform derivatives back to physical element
 
8015
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
8016
      {
 
8017
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
8018
        {
 
8019
          values[r] += transform[r][s]*derivatives_p[s];
 
8020
          values[num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
8021
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
8022
        }// end loop over 's'
 
8023
      }// end loop over 'r'
 
8024
      
 
8025
      // Delete pointer to array of derivatives on FIAT element
 
8026
      delete [] derivatives;
 
8027
      
 
8028
      // Delete pointer to array of reference derivatives on physical element.
 
8029
      delete [] derivatives_p;
 
8030
      
 
8031
      // Delete pointer to array of combinations of derivatives and transform
 
8032
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
8033
      {
 
8034
        delete [] combinations_t[r];
 
8035
      }// end loop over 'r'
 
8036
      delete [] combinations_t;
 
8037
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
8038
      {
 
8039
        delete [] combinations_g[r];
 
8040
      }// end loop over 'r'
 
8041
      delete [] combinations_g;
 
8042
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
8043
      {
 
8044
        delete [] transform[r];
 
8045
      }// end loop over 'r'
 
8046
      delete [] transform;
 
8047
        break;
 
8048
      }
 
8049
    case 3:
 
8050
      {
 
8051
        
 
8052
      // Array of basisvalues
 
8053
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
8054
      
 
8055
      // Declare helper variables
 
8056
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
8057
      double tmp1 = (1.0 - Y)/2.0;
 
8058
      double tmp2 = tmp1*tmp1;
 
8059
      
 
8060
      // Compute basisvalues
 
8061
      basisvalues[0] = 1.0;
 
8062
      basisvalues[1] = tmp0;
 
8063
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
8064
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
8065
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
8066
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
8067
      basisvalues[0] *= std::sqrt(0.5);
 
8068
      basisvalues[2] *= std::sqrt(1.0);
 
8069
      basisvalues[5] *= std::sqrt(1.5);
 
8070
      basisvalues[1] *= std::sqrt(3.0);
 
8071
      basisvalues[4] *= std::sqrt(4.5);
 
8072
      basisvalues[3] *= std::sqrt(7.5);
 
8073
      
 
8074
      // Table(s) of coefficients
 
8075
      static const double coefficients0[6] = \
 
8076
      {0.11785113, 0.11547005, 0.73333333, 0.0, -0.14142136, 0.12247449};
 
8077
      
 
8078
      static const double coefficients1[6] = \
 
8079
      {-0.23570226, 0.0, -0.46666667, 0.0, 0.0, -0.24494897};
 
8080
      
 
8081
      // Tables of derivatives of the polynomial base (transpose).
 
8082
      static const double dmats0[6][6] = \
 
8083
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8084
      {4.8989795, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8085
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8086
      {0.0, 9.486833, 0.0, 0.0, 0.0, 0.0},
 
8087
      {4.0, 0.0, 7.0710678, 0.0, 0.0, 0.0},
 
8088
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}};
 
8089
      
 
8090
      static const double dmats1[6][6] = \
 
8091
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8092
      {2.4494897, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8093
      {4.2426407, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8094
      {2.5819889, 4.7434165, -0.91287093, 0.0, 0.0, 0.0},
 
8095
      {2.0, 6.1237244, 3.5355339, 0.0, 0.0, 0.0},
 
8096
      {-2.3094011, 0.0, 8.1649658, 0.0, 0.0, 0.0}};
 
8097
      
 
8098
      // Compute reference derivatives.
 
8099
      // Declare pointer to array of derivatives on FIAT element.
 
8100
      double *derivatives = new double[2*num_derivatives_t];
 
8101
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
8102
      {
 
8103
        derivatives[r] = 0.0;
 
8104
      }// end loop over 'r'
 
8105
      
 
8106
      // Declare pointer to array of reference derivatives on physical element.
 
8107
      double *derivatives_p = new double[3*num_derivatives_t];
 
8108
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
8109
      {
 
8110
        derivatives_p[r] = 0.0;
 
8111
      }// end loop over 'r'
 
8112
      
 
8113
      // Declare derivative matrix (of polynomial basis).
 
8114
      double dmats[6][6] = \
 
8115
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8116
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
8117
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
8118
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
8119
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
8120
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
8121
      
 
8122
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
8123
      double dmats_old[6][6] = \
 
8124
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8125
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
8126
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
8127
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
8128
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
8129
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
8130
      
 
8131
      // Loop possible derivatives.
 
8132
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
8133
      {
 
8134
        // Resetting dmats values to compute next derivative.
 
8135
        for (unsigned int t = 0; t < 6; t++)
 
8136
        {
 
8137
          for (unsigned int u = 0; u < 6; u++)
 
8138
          {
 
8139
            dmats[t][u] = 0.0;
 
8140
            if (t == u)
 
8141
            {
 
8142
            dmats[t][u] = 1.0;
 
8143
            }
 
8144
            
 
8145
          }// end loop over 'u'
 
8146
        }// end loop over 't'
 
8147
        
 
8148
        // Looping derivative order to generate dmats.
 
8149
        for (unsigned int s = 0; s < n; s++)
 
8150
        {
 
8151
          // Updating dmats_old with new values and resetting dmats.
 
8152
          for (unsigned int t = 0; t < 6; t++)
 
8153
          {
 
8154
            for (unsigned int u = 0; u < 6; u++)
 
8155
            {
 
8156
              dmats_old[t][u] = dmats[t][u];
 
8157
              dmats[t][u] = 0.0;
 
8158
            }// end loop over 'u'
 
8159
          }// end loop over 't'
 
8160
          
 
8161
          // Update dmats using an inner product.
 
8162
          if (combinations_t[r][s] == 0)
 
8163
          {
 
8164
          for (unsigned int t = 0; t < 6; t++)
 
8165
          {
 
8166
            for (unsigned int u = 0; u < 6; u++)
 
8167
            {
 
8168
              for (unsigned int tu = 0; tu < 6; tu++)
 
8169
              {
 
8170
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
8171
              }// end loop over 'tu'
 
8172
            }// end loop over 'u'
 
8173
          }// end loop over 't'
 
8174
          }
 
8175
          
 
8176
          if (combinations_t[r][s] == 1)
 
8177
          {
 
8178
          for (unsigned int t = 0; t < 6; t++)
 
8179
          {
 
8180
            for (unsigned int u = 0; u < 6; u++)
 
8181
            {
 
8182
              for (unsigned int tu = 0; tu < 6; tu++)
 
8183
              {
 
8184
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
8185
              }// end loop over 'tu'
 
8186
            }// end loop over 'u'
 
8187
          }// end loop over 't'
 
8188
          }
 
8189
          
 
8190
        }// end loop over 's'
 
8191
        for (unsigned int s = 0; s < 6; s++)
 
8192
        {
 
8193
          for (unsigned int t = 0; t < 6; t++)
 
8194
          {
 
8195
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
8196
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
8197
          }// end loop over 't'
 
8198
        }// end loop over 's'
 
8199
        
 
8200
        // Using contravariant Piola transform to map values back to the physical element.
 
8201
        const double tmp_ref0 = derivatives[r];
 
8202
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
8203
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
8204
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
8205
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
8206
      }// end loop over 'r'
 
8207
      
 
8208
      // Transform derivatives back to physical element
 
8209
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
8210
      {
 
8211
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
8212
        {
 
8213
          values[r] += transform[r][s]*derivatives_p[s];
 
8214
          values[num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
8215
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
8216
        }// end loop over 's'
 
8217
      }// end loop over 'r'
 
8218
      
 
8219
      // Delete pointer to array of derivatives on FIAT element
 
8220
      delete [] derivatives;
 
8221
      
 
8222
      // Delete pointer to array of reference derivatives on physical element.
 
8223
      delete [] derivatives_p;
 
8224
      
 
8225
      // Delete pointer to array of combinations of derivatives and transform
 
8226
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
8227
      {
 
8228
        delete [] combinations_t[r];
 
8229
      }// end loop over 'r'
 
8230
      delete [] combinations_t;
 
8231
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
8232
      {
 
8233
        delete [] combinations_g[r];
 
8234
      }// end loop over 'r'
 
8235
      delete [] combinations_g;
 
8236
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
8237
      {
 
8238
        delete [] transform[r];
 
8239
      }// end loop over 'r'
 
8240
      delete [] transform;
 
8241
        break;
 
8242
      }
 
8243
    case 4:
 
8244
      {
 
8245
        
 
8246
      // Array of basisvalues
 
8247
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
8248
      
 
8249
      // Declare helper variables
 
8250
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
8251
      double tmp1 = (1.0 - Y)/2.0;
 
8252
      double tmp2 = tmp1*tmp1;
 
8253
      
 
8254
      // Compute basisvalues
 
8255
      basisvalues[0] = 1.0;
 
8256
      basisvalues[1] = tmp0;
 
8257
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
8258
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
8259
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
8260
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
8261
      basisvalues[0] *= std::sqrt(0.5);
 
8262
      basisvalues[2] *= std::sqrt(1.0);
 
8263
      basisvalues[5] *= std::sqrt(1.5);
 
8264
      basisvalues[1] *= std::sqrt(3.0);
 
8265
      basisvalues[4] *= std::sqrt(4.5);
 
8266
      basisvalues[3] *= std::sqrt(7.5);
 
8267
      
 
8268
      // Table(s) of coefficients
 
8269
      static const double coefficients0[6] = \
 
8270
      {-0.11785113, -0.28867513, -0.033333333, -0.18257419, 0.0, 0.040824829};
 
8271
      
 
8272
      static const double coefficients1[6] = \
 
8273
      {-0.11785113, 0.69282032, 0.26666667, 0.0, -0.14142136, -0.12247449};
 
8274
      
 
8275
      // Tables of derivatives of the polynomial base (transpose).
 
8276
      static const double dmats0[6][6] = \
 
8277
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8278
      {4.8989795, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8279
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8280
      {0.0, 9.486833, 0.0, 0.0, 0.0, 0.0},
 
8281
      {4.0, 0.0, 7.0710678, 0.0, 0.0, 0.0},
 
8282
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}};
 
8283
      
 
8284
      static const double dmats1[6][6] = \
 
8285
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8286
      {2.4494897, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8287
      {4.2426407, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8288
      {2.5819889, 4.7434165, -0.91287093, 0.0, 0.0, 0.0},
 
8289
      {2.0, 6.1237244, 3.5355339, 0.0, 0.0, 0.0},
 
8290
      {-2.3094011, 0.0, 8.1649658, 0.0, 0.0, 0.0}};
 
8291
      
 
8292
      // Compute reference derivatives.
 
8293
      // Declare pointer to array of derivatives on FIAT element.
 
8294
      double *derivatives = new double[2*num_derivatives_t];
 
8295
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
8296
      {
 
8297
        derivatives[r] = 0.0;
 
8298
      }// end loop over 'r'
 
8299
      
 
8300
      // Declare pointer to array of reference derivatives on physical element.
 
8301
      double *derivatives_p = new double[3*num_derivatives_t];
 
8302
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
8303
      {
 
8304
        derivatives_p[r] = 0.0;
 
8305
      }// end loop over 'r'
 
8306
      
 
8307
      // Declare derivative matrix (of polynomial basis).
 
8308
      double dmats[6][6] = \
 
8309
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8310
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
8311
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
8312
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
8313
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
8314
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
8315
      
 
8316
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
8317
      double dmats_old[6][6] = \
 
8318
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8319
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
8320
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
8321
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
8322
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
8323
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
8324
      
 
8325
      // Loop possible derivatives.
 
8326
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
8327
      {
 
8328
        // Resetting dmats values to compute next derivative.
 
8329
        for (unsigned int t = 0; t < 6; t++)
 
8330
        {
 
8331
          for (unsigned int u = 0; u < 6; u++)
 
8332
          {
 
8333
            dmats[t][u] = 0.0;
 
8334
            if (t == u)
 
8335
            {
 
8336
            dmats[t][u] = 1.0;
 
8337
            }
 
8338
            
 
8339
          }// end loop over 'u'
 
8340
        }// end loop over 't'
 
8341
        
 
8342
        // Looping derivative order to generate dmats.
 
8343
        for (unsigned int s = 0; s < n; s++)
 
8344
        {
 
8345
          // Updating dmats_old with new values and resetting dmats.
 
8346
          for (unsigned int t = 0; t < 6; t++)
 
8347
          {
 
8348
            for (unsigned int u = 0; u < 6; u++)
 
8349
            {
 
8350
              dmats_old[t][u] = dmats[t][u];
 
8351
              dmats[t][u] = 0.0;
 
8352
            }// end loop over 'u'
 
8353
          }// end loop over 't'
 
8354
          
 
8355
          // Update dmats using an inner product.
 
8356
          if (combinations_t[r][s] == 0)
 
8357
          {
 
8358
          for (unsigned int t = 0; t < 6; t++)
 
8359
          {
 
8360
            for (unsigned int u = 0; u < 6; u++)
 
8361
            {
 
8362
              for (unsigned int tu = 0; tu < 6; tu++)
 
8363
              {
 
8364
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
8365
              }// end loop over 'tu'
 
8366
            }// end loop over 'u'
 
8367
          }// end loop over 't'
 
8368
          }
 
8369
          
 
8370
          if (combinations_t[r][s] == 1)
 
8371
          {
 
8372
          for (unsigned int t = 0; t < 6; t++)
 
8373
          {
 
8374
            for (unsigned int u = 0; u < 6; u++)
 
8375
            {
 
8376
              for (unsigned int tu = 0; tu < 6; tu++)
 
8377
              {
 
8378
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
8379
              }// end loop over 'tu'
 
8380
            }// end loop over 'u'
 
8381
          }// end loop over 't'
 
8382
          }
 
8383
          
 
8384
        }// end loop over 's'
 
8385
        for (unsigned int s = 0; s < 6; s++)
 
8386
        {
 
8387
          for (unsigned int t = 0; t < 6; t++)
 
8388
          {
 
8389
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
8390
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
8391
          }// end loop over 't'
 
8392
        }// end loop over 's'
 
8393
        
 
8394
        // Using contravariant Piola transform to map values back to the physical element.
 
8395
        const double tmp_ref0 = derivatives[r];
 
8396
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
8397
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
8398
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
8399
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
8400
      }// end loop over 'r'
 
8401
      
 
8402
      // Transform derivatives back to physical element
 
8403
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
8404
      {
 
8405
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
8406
        {
 
8407
          values[r] += transform[r][s]*derivatives_p[s];
 
8408
          values[num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
8409
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
8410
        }// end loop over 's'
 
8411
      }// end loop over 'r'
 
8412
      
 
8413
      // Delete pointer to array of derivatives on FIAT element
 
8414
      delete [] derivatives;
 
8415
      
 
8416
      // Delete pointer to array of reference derivatives on physical element.
 
8417
      delete [] derivatives_p;
 
8418
      
 
8419
      // Delete pointer to array of combinations of derivatives and transform
 
8420
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
8421
      {
 
8422
        delete [] combinations_t[r];
 
8423
      }// end loop over 'r'
 
8424
      delete [] combinations_t;
 
8425
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
8426
      {
 
8427
        delete [] combinations_g[r];
 
8428
      }// end loop over 'r'
 
8429
      delete [] combinations_g;
 
8430
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
8431
      {
 
8432
        delete [] transform[r];
 
8433
      }// end loop over 'r'
 
8434
      delete [] transform;
 
8435
        break;
 
8436
      }
 
8437
    case 5:
 
8438
      {
 
8439
        
 
8440
      // Array of basisvalues
 
8441
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
8442
      
 
8443
      // Declare helper variables
 
8444
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
8445
      double tmp1 = (1.0 - Y)/2.0;
 
8446
      double tmp2 = tmp1*tmp1;
 
8447
      
 
8448
      // Compute basisvalues
 
8449
      basisvalues[0] = 1.0;
 
8450
      basisvalues[1] = tmp0;
 
8451
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
8452
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
8453
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
8454
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
8455
      basisvalues[0] *= std::sqrt(0.5);
 
8456
      basisvalues[2] *= std::sqrt(1.0);
 
8457
      basisvalues[5] *= std::sqrt(1.5);
 
8458
      basisvalues[1] *= std::sqrt(3.0);
 
8459
      basisvalues[4] *= std::sqrt(4.5);
 
8460
      basisvalues[3] *= std::sqrt(7.5);
 
8461
      
 
8462
      // Table(s) of coefficients
 
8463
      static const double coefficients0[6] = \
 
8464
      {0.23570226, 0.40414519, -0.23333333, 0.18257419, -0.14142136, 0.081649658};
 
8465
      
 
8466
      static const double coefficients1[6] = \
 
8467
      {-0.11785113, -0.69282032, 0.26666667, 0.0, 0.14142136, -0.12247449};
 
8468
      
 
8469
      // Tables of derivatives of the polynomial base (transpose).
 
8470
      static const double dmats0[6][6] = \
 
8471
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8472
      {4.8989795, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8473
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8474
      {0.0, 9.486833, 0.0, 0.0, 0.0, 0.0},
 
8475
      {4.0, 0.0, 7.0710678, 0.0, 0.0, 0.0},
 
8476
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}};
 
8477
      
 
8478
      static const double dmats1[6][6] = \
 
8479
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8480
      {2.4494897, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8481
      {4.2426407, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8482
      {2.5819889, 4.7434165, -0.91287093, 0.0, 0.0, 0.0},
 
8483
      {2.0, 6.1237244, 3.5355339, 0.0, 0.0, 0.0},
 
8484
      {-2.3094011, 0.0, 8.1649658, 0.0, 0.0, 0.0}};
 
8485
      
 
8486
      // Compute reference derivatives.
 
8487
      // Declare pointer to array of derivatives on FIAT element.
 
8488
      double *derivatives = new double[2*num_derivatives_t];
 
8489
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
8490
      {
 
8491
        derivatives[r] = 0.0;
 
8492
      }// end loop over 'r'
 
8493
      
 
8494
      // Declare pointer to array of reference derivatives on physical element.
 
8495
      double *derivatives_p = new double[3*num_derivatives_t];
 
8496
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
8497
      {
 
8498
        derivatives_p[r] = 0.0;
 
8499
      }// end loop over 'r'
 
8500
      
 
8501
      // Declare derivative matrix (of polynomial basis).
 
8502
      double dmats[6][6] = \
 
8503
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8504
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
8505
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
8506
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
8507
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
8508
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
8509
      
 
8510
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
8511
      double dmats_old[6][6] = \
 
8512
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8513
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
8514
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
8515
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
8516
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
8517
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
8518
      
 
8519
      // Loop possible derivatives.
 
8520
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
8521
      {
 
8522
        // Resetting dmats values to compute next derivative.
 
8523
        for (unsigned int t = 0; t < 6; t++)
 
8524
        {
 
8525
          for (unsigned int u = 0; u < 6; u++)
 
8526
          {
 
8527
            dmats[t][u] = 0.0;
 
8528
            if (t == u)
 
8529
            {
 
8530
            dmats[t][u] = 1.0;
 
8531
            }
 
8532
            
 
8533
          }// end loop over 'u'
 
8534
        }// end loop over 't'
 
8535
        
 
8536
        // Looping derivative order to generate dmats.
 
8537
        for (unsigned int s = 0; s < n; s++)
 
8538
        {
 
8539
          // Updating dmats_old with new values and resetting dmats.
 
8540
          for (unsigned int t = 0; t < 6; t++)
 
8541
          {
 
8542
            for (unsigned int u = 0; u < 6; u++)
 
8543
            {
 
8544
              dmats_old[t][u] = dmats[t][u];
 
8545
              dmats[t][u] = 0.0;
 
8546
            }// end loop over 'u'
 
8547
          }// end loop over 't'
 
8548
          
 
8549
          // Update dmats using an inner product.
 
8550
          if (combinations_t[r][s] == 0)
 
8551
          {
 
8552
          for (unsigned int t = 0; t < 6; t++)
 
8553
          {
 
8554
            for (unsigned int u = 0; u < 6; u++)
 
8555
            {
 
8556
              for (unsigned int tu = 0; tu < 6; tu++)
 
8557
              {
 
8558
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
8559
              }// end loop over 'tu'
 
8560
            }// end loop over 'u'
 
8561
          }// end loop over 't'
 
8562
          }
 
8563
          
 
8564
          if (combinations_t[r][s] == 1)
 
8565
          {
 
8566
          for (unsigned int t = 0; t < 6; t++)
 
8567
          {
 
8568
            for (unsigned int u = 0; u < 6; u++)
 
8569
            {
 
8570
              for (unsigned int tu = 0; tu < 6; tu++)
 
8571
              {
 
8572
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
8573
              }// end loop over 'tu'
 
8574
            }// end loop over 'u'
 
8575
          }// end loop over 't'
 
8576
          }
 
8577
          
 
8578
        }// end loop over 's'
 
8579
        for (unsigned int s = 0; s < 6; s++)
 
8580
        {
 
8581
          for (unsigned int t = 0; t < 6; t++)
 
8582
          {
 
8583
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
8584
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
8585
          }// end loop over 't'
 
8586
        }// end loop over 's'
 
8587
        
 
8588
        // Using contravariant Piola transform to map values back to the physical element.
 
8589
        const double tmp_ref0 = derivatives[r];
 
8590
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
8591
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
8592
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
8593
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
8594
      }// end loop over 'r'
 
8595
      
 
8596
      // Transform derivatives back to physical element
 
8597
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
8598
      {
 
8599
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
8600
        {
 
8601
          values[r] += transform[r][s]*derivatives_p[s];
 
8602
          values[num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
8603
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
8604
        }// end loop over 's'
 
8605
      }// end loop over 'r'
 
8606
      
 
8607
      // Delete pointer to array of derivatives on FIAT element
 
8608
      delete [] derivatives;
 
8609
      
 
8610
      // Delete pointer to array of reference derivatives on physical element.
 
8611
      delete [] derivatives_p;
 
8612
      
 
8613
      // Delete pointer to array of combinations of derivatives and transform
 
8614
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
8615
      {
 
8616
        delete [] combinations_t[r];
 
8617
      }// end loop over 'r'
 
8618
      delete [] combinations_t;
 
8619
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
8620
      {
 
8621
        delete [] combinations_g[r];
 
8622
      }// end loop over 'r'
 
8623
      delete [] combinations_g;
 
8624
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
8625
      {
 
8626
        delete [] transform[r];
 
8627
      }// end loop over 'r'
 
8628
      delete [] transform;
 
8629
        break;
 
8630
      }
 
8631
    case 6:
 
8632
      {
 
8633
        
 
8634
      // Array of basisvalues
 
8635
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
8636
      
 
8637
      // Declare helper variables
 
8638
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
8639
      double tmp1 = (1.0 - Y)/2.0;
 
8640
      double tmp2 = tmp1*tmp1;
 
8641
      
 
8642
      // Compute basisvalues
 
8643
      basisvalues[0] = 1.0;
 
8644
      basisvalues[1] = tmp0;
 
8645
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
8646
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
8647
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
8648
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
8649
      basisvalues[0] *= std::sqrt(0.5);
 
8650
      basisvalues[2] *= std::sqrt(1.0);
 
8651
      basisvalues[5] *= std::sqrt(1.5);
 
8652
      basisvalues[1] *= std::sqrt(3.0);
 
8653
      basisvalues[4] *= std::sqrt(4.5);
 
8654
      basisvalues[3] *= std::sqrt(7.5);
 
8655
      
 
8656
      // Table(s) of coefficients
 
8657
      static const double coefficients0[6] = \
 
8658
      {1.0606602, 0.17320508, -0.3, -0.36514837, 0.14142136, -0.040824829};
 
8659
      
 
8660
      static const double coefficients1[6] = \
 
8661
      {0.0, -0.34641016, 0.0, 0.0, -0.28284271, 0.0};
 
8662
      
 
8663
      // Tables of derivatives of the polynomial base (transpose).
 
8664
      static const double dmats0[6][6] = \
 
8665
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8666
      {4.8989795, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8667
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8668
      {0.0, 9.486833, 0.0, 0.0, 0.0, 0.0},
 
8669
      {4.0, 0.0, 7.0710678, 0.0, 0.0, 0.0},
 
8670
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}};
 
8671
      
 
8672
      static const double dmats1[6][6] = \
 
8673
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8674
      {2.4494897, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8675
      {4.2426407, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8676
      {2.5819889, 4.7434165, -0.91287093, 0.0, 0.0, 0.0},
 
8677
      {2.0, 6.1237244, 3.5355339, 0.0, 0.0, 0.0},
 
8678
      {-2.3094011, 0.0, 8.1649658, 0.0, 0.0, 0.0}};
 
8679
      
 
8680
      // Compute reference derivatives.
 
8681
      // Declare pointer to array of derivatives on FIAT element.
 
8682
      double *derivatives = new double[2*num_derivatives_t];
 
8683
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
8684
      {
 
8685
        derivatives[r] = 0.0;
 
8686
      }// end loop over 'r'
 
8687
      
 
8688
      // Declare pointer to array of reference derivatives on physical element.
 
8689
      double *derivatives_p = new double[3*num_derivatives_t];
 
8690
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
8691
      {
 
8692
        derivatives_p[r] = 0.0;
 
8693
      }// end loop over 'r'
 
8694
      
 
8695
      // Declare derivative matrix (of polynomial basis).
 
8696
      double dmats[6][6] = \
 
8697
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8698
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
8699
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
8700
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
8701
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
8702
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
8703
      
 
8704
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
8705
      double dmats_old[6][6] = \
 
8706
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8707
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
8708
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
8709
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
8710
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
8711
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
8712
      
 
8713
      // Loop possible derivatives.
 
8714
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
8715
      {
 
8716
        // Resetting dmats values to compute next derivative.
 
8717
        for (unsigned int t = 0; t < 6; t++)
 
8718
        {
 
8719
          for (unsigned int u = 0; u < 6; u++)
 
8720
          {
 
8721
            dmats[t][u] = 0.0;
 
8722
            if (t == u)
 
8723
            {
 
8724
            dmats[t][u] = 1.0;
 
8725
            }
 
8726
            
 
8727
          }// end loop over 'u'
 
8728
        }// end loop over 't'
 
8729
        
 
8730
        // Looping derivative order to generate dmats.
 
8731
        for (unsigned int s = 0; s < n; s++)
 
8732
        {
 
8733
          // Updating dmats_old with new values and resetting dmats.
 
8734
          for (unsigned int t = 0; t < 6; t++)
 
8735
          {
 
8736
            for (unsigned int u = 0; u < 6; u++)
 
8737
            {
 
8738
              dmats_old[t][u] = dmats[t][u];
 
8739
              dmats[t][u] = 0.0;
 
8740
            }// end loop over 'u'
 
8741
          }// end loop over 't'
 
8742
          
 
8743
          // Update dmats using an inner product.
 
8744
          if (combinations_t[r][s] == 0)
 
8745
          {
 
8746
          for (unsigned int t = 0; t < 6; t++)
 
8747
          {
 
8748
            for (unsigned int u = 0; u < 6; u++)
 
8749
            {
 
8750
              for (unsigned int tu = 0; tu < 6; tu++)
 
8751
              {
 
8752
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
8753
              }// end loop over 'tu'
 
8754
            }// end loop over 'u'
 
8755
          }// end loop over 't'
 
8756
          }
 
8757
          
 
8758
          if (combinations_t[r][s] == 1)
 
8759
          {
 
8760
          for (unsigned int t = 0; t < 6; t++)
 
8761
          {
 
8762
            for (unsigned int u = 0; u < 6; u++)
 
8763
            {
 
8764
              for (unsigned int tu = 0; tu < 6; tu++)
 
8765
              {
 
8766
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
8767
              }// end loop over 'tu'
 
8768
            }// end loop over 'u'
 
8769
          }// end loop over 't'
 
8770
          }
 
8771
          
 
8772
        }// end loop over 's'
 
8773
        for (unsigned int s = 0; s < 6; s++)
 
8774
        {
 
8775
          for (unsigned int t = 0; t < 6; t++)
 
8776
          {
 
8777
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
8778
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
8779
          }// end loop over 't'
 
8780
        }// end loop over 's'
 
8781
        
 
8782
        // Using contravariant Piola transform to map values back to the physical element.
 
8783
        const double tmp_ref0 = derivatives[r];
 
8784
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
8785
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
8786
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
8787
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
8788
      }// end loop over 'r'
 
8789
      
 
8790
      // Transform derivatives back to physical element
 
8791
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
8792
      {
 
8793
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
8794
        {
 
8795
          values[r] += transform[r][s]*derivatives_p[s];
 
8796
          values[num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
8797
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
8798
        }// end loop over 's'
 
8799
      }// end loop over 'r'
 
8800
      
 
8801
      // Delete pointer to array of derivatives on FIAT element
 
8802
      delete [] derivatives;
 
8803
      
 
8804
      // Delete pointer to array of reference derivatives on physical element.
 
8805
      delete [] derivatives_p;
 
8806
      
 
8807
      // Delete pointer to array of combinations of derivatives and transform
 
8808
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
8809
      {
 
8810
        delete [] combinations_t[r];
 
8811
      }// end loop over 'r'
 
8812
      delete [] combinations_t;
 
8813
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
8814
      {
 
8815
        delete [] combinations_g[r];
 
8816
      }// end loop over 'r'
 
8817
      delete [] combinations_g;
 
8818
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
8819
      {
 
8820
        delete [] transform[r];
 
8821
      }// end loop over 'r'
 
8822
      delete [] transform;
 
8823
        break;
 
8824
      }
 
8825
    case 7:
 
8826
      {
 
8827
        
 
8828
      // Array of basisvalues
 
8829
      double basisvalues[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
 
8830
      
 
8831
      // Declare helper variables
 
8832
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
8833
      double tmp1 = (1.0 - Y)/2.0;
 
8834
      double tmp2 = tmp1*tmp1;
 
8835
      
 
8836
      // Compute basisvalues
 
8837
      basisvalues[0] = 1.0;
 
8838
      basisvalues[1] = tmp0;
 
8839
      basisvalues[3] = basisvalues[1]*1.5*tmp0 - basisvalues[0]*0.5*tmp2;
 
8840
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
8841
      basisvalues[4] = basisvalues[1]*(1.5 + 2.5*Y);
 
8842
      basisvalues[5] = basisvalues[2]*(0.11111111 + Y*1.6666667) - basisvalues[0]*0.55555556;
 
8843
      basisvalues[0] *= std::sqrt(0.5);
 
8844
      basisvalues[2] *= std::sqrt(1.0);
 
8845
      basisvalues[5] *= std::sqrt(1.5);
 
8846
      basisvalues[1] *= std::sqrt(3.0);
 
8847
      basisvalues[4] *= std::sqrt(4.5);
 
8848
      basisvalues[3] *= std::sqrt(7.5);
 
8849
      
 
8850
      // Table(s) of coefficients
 
8851
      static const double coefficients0[6] = \
 
8852
      {0.0, -0.17320508, -0.3, -0.18257419, -0.14142136, 0.16329932};
 
8853
      
 
8854
      static const double coefficients1[6] = \
 
8855
      {1.0606602, -0.17320508, 0.3, 0.0, -0.14142136, -0.36742346};
 
8856
      
 
8857
      // Tables of derivatives of the polynomial base (transpose).
 
8858
      static const double dmats0[6][6] = \
 
8859
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8860
      {4.8989795, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8861
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8862
      {0.0, 9.486833, 0.0, 0.0, 0.0, 0.0},
 
8863
      {4.0, 0.0, 7.0710678, 0.0, 0.0, 0.0},
 
8864
      {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}};
 
8865
      
 
8866
      static const double dmats1[6][6] = \
 
8867
      {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8868
      {2.4494897, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8869
      {4.2426407, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8870
      {2.5819889, 4.7434165, -0.91287093, 0.0, 0.0, 0.0},
 
8871
      {2.0, 6.1237244, 3.5355339, 0.0, 0.0, 0.0},
 
8872
      {-2.3094011, 0.0, 8.1649658, 0.0, 0.0, 0.0}};
 
8873
      
 
8874
      // Compute reference derivatives.
 
8875
      // Declare pointer to array of derivatives on FIAT element.
 
8876
      double *derivatives = new double[2*num_derivatives_t];
 
8877
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
8878
      {
 
8879
        derivatives[r] = 0.0;
 
8880
      }// end loop over 'r'
 
8881
      
 
8882
      // Declare pointer to array of reference derivatives on physical element.
 
8883
      double *derivatives_p = new double[3*num_derivatives_t];
 
8884
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
8885
      {
 
8886
        derivatives_p[r] = 0.0;
 
8887
      }// end loop over 'r'
 
8888
      
 
8889
      // Declare derivative matrix (of polynomial basis).
 
8890
      double dmats[6][6] = \
 
8891
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8892
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
8893
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
8894
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
8895
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
8896
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
8897
      
 
8898
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
8899
      double dmats_old[6][6] = \
 
8900
      {{1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
 
8901
      {0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
 
8902
      {0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
 
8903
      {0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
 
8904
      {0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
 
8905
      {0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
 
8906
      
 
8907
      // Loop possible derivatives.
 
8908
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
8909
      {
 
8910
        // Resetting dmats values to compute next derivative.
 
8911
        for (unsigned int t = 0; t < 6; t++)
 
8912
        {
 
8913
          for (unsigned int u = 0; u < 6; u++)
 
8914
          {
 
8915
            dmats[t][u] = 0.0;
 
8916
            if (t == u)
 
8917
            {
 
8918
            dmats[t][u] = 1.0;
 
8919
            }
 
8920
            
 
8921
          }// end loop over 'u'
 
8922
        }// end loop over 't'
 
8923
        
 
8924
        // Looping derivative order to generate dmats.
 
8925
        for (unsigned int s = 0; s < n; s++)
 
8926
        {
 
8927
          // Updating dmats_old with new values and resetting dmats.
 
8928
          for (unsigned int t = 0; t < 6; t++)
 
8929
          {
 
8930
            for (unsigned int u = 0; u < 6; u++)
 
8931
            {
 
8932
              dmats_old[t][u] = dmats[t][u];
 
8933
              dmats[t][u] = 0.0;
 
8934
            }// end loop over 'u'
 
8935
          }// end loop over 't'
 
8936
          
 
8937
          // Update dmats using an inner product.
 
8938
          if (combinations_t[r][s] == 0)
 
8939
          {
 
8940
          for (unsigned int t = 0; t < 6; t++)
 
8941
          {
 
8942
            for (unsigned int u = 0; u < 6; u++)
 
8943
            {
 
8944
              for (unsigned int tu = 0; tu < 6; tu++)
 
8945
              {
 
8946
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
8947
              }// end loop over 'tu'
 
8948
            }// end loop over 'u'
 
8949
          }// end loop over 't'
 
8950
          }
 
8951
          
 
8952
          if (combinations_t[r][s] == 1)
 
8953
          {
 
8954
          for (unsigned int t = 0; t < 6; t++)
 
8955
          {
 
8956
            for (unsigned int u = 0; u < 6; u++)
 
8957
            {
 
8958
              for (unsigned int tu = 0; tu < 6; tu++)
 
8959
              {
 
8960
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
8961
              }// end loop over 'tu'
 
8962
            }// end loop over 'u'
 
8963
          }// end loop over 't'
 
8964
          }
 
8965
          
 
8966
        }// end loop over 's'
 
8967
        for (unsigned int s = 0; s < 6; s++)
 
8968
        {
 
8969
          for (unsigned int t = 0; t < 6; t++)
 
8970
          {
 
8971
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
8972
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
8973
          }// end loop over 't'
 
8974
        }// end loop over 's'
 
8975
        
 
8976
        // Using contravariant Piola transform to map values back to the physical element.
 
8977
        const double tmp_ref0 = derivatives[r];
 
8978
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
8979
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
8980
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
8981
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
8982
      }// end loop over 'r'
 
8983
      
 
8984
      // Transform derivatives back to physical element
 
8985
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
8986
      {
 
8987
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
8988
        {
 
8989
          values[r] += transform[r][s]*derivatives_p[s];
 
8990
          values[num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
8991
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
8992
        }// end loop over 's'
 
8993
      }// end loop over 'r'
 
8994
      
 
8995
      // Delete pointer to array of derivatives on FIAT element
 
8996
      delete [] derivatives;
 
8997
      
 
8998
      // Delete pointer to array of reference derivatives on physical element.
 
8999
      delete [] derivatives_p;
 
9000
      
 
9001
      // Delete pointer to array of combinations of derivatives and transform
 
9002
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
9003
      {
 
9004
        delete [] combinations_t[r];
 
9005
      }// end loop over 'r'
 
9006
      delete [] combinations_t;
 
9007
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
9008
      {
 
9009
        delete [] combinations_g[r];
 
9010
      }// end loop over 'r'
 
9011
      delete [] combinations_g;
 
9012
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
9013
      {
 
9014
        delete [] transform[r];
 
9015
      }// end loop over 'r'
 
9016
      delete [] transform;
 
9017
        break;
 
9018
      }
 
9019
    case 8:
 
9020
      {
 
9021
        
 
9022
      // Array of basisvalues
 
9023
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
9024
      
 
9025
      // Declare helper variables
 
9026
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
9027
      
 
9028
      // Compute basisvalues
 
9029
      basisvalues[0] = 1.0;
 
9030
      basisvalues[1] = tmp0;
 
9031
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
9032
      basisvalues[0] *= std::sqrt(0.5);
 
9033
      basisvalues[2] *= std::sqrt(1.0);
 
9034
      basisvalues[1] *= std::sqrt(3.0);
 
9035
      
 
9036
      // Table(s) of coefficients
 
9037
      static const double coefficients0[3] = \
 
9038
      {0.94280904, 0.57735027, -0.33333333};
 
9039
      
 
9040
      static const double coefficients1[3] = \
 
9041
      {-0.47140452, 0.0, -0.33333333};
 
9042
      
 
9043
      // Tables of derivatives of the polynomial base (transpose).
 
9044
      static const double dmats0[3][3] = \
 
9045
      {{0.0, 0.0, 0.0},
 
9046
      {4.8989795, 0.0, 0.0},
 
9047
      {0.0, 0.0, 0.0}};
 
9048
      
 
9049
      static const double dmats1[3][3] = \
 
9050
      {{0.0, 0.0, 0.0},
 
9051
      {2.4494897, 0.0, 0.0},
 
9052
      {4.2426407, 0.0, 0.0}};
 
9053
      
 
9054
      // Compute reference derivatives.
 
9055
      // Declare pointer to array of derivatives on FIAT element.
 
9056
      double *derivatives = new double[2*num_derivatives_t];
 
9057
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
9058
      {
 
9059
        derivatives[r] = 0.0;
 
9060
      }// end loop over 'r'
 
9061
      
 
9062
      // Declare pointer to array of reference derivatives on physical element.
 
9063
      double *derivatives_p = new double[3*num_derivatives_t];
 
9064
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
9065
      {
 
9066
        derivatives_p[r] = 0.0;
 
9067
      }// end loop over 'r'
 
9068
      
 
9069
      // Declare derivative matrix (of polynomial basis).
 
9070
      double dmats[3][3] = \
 
9071
      {{1.0, 0.0, 0.0},
 
9072
      {0.0, 1.0, 0.0},
 
9073
      {0.0, 0.0, 1.0}};
 
9074
      
 
9075
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
9076
      double dmats_old[3][3] = \
 
9077
      {{1.0, 0.0, 0.0},
 
9078
      {0.0, 1.0, 0.0},
 
9079
      {0.0, 0.0, 1.0}};
 
9080
      
 
9081
      // Loop possible derivatives.
 
9082
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
9083
      {
 
9084
        // Resetting dmats values to compute next derivative.
 
9085
        for (unsigned int t = 0; t < 3; t++)
 
9086
        {
 
9087
          for (unsigned int u = 0; u < 3; u++)
 
9088
          {
 
9089
            dmats[t][u] = 0.0;
 
9090
            if (t == u)
 
9091
            {
 
9092
            dmats[t][u] = 1.0;
 
9093
            }
 
9094
            
 
9095
          }// end loop over 'u'
 
9096
        }// end loop over 't'
 
9097
        
 
9098
        // Looping derivative order to generate dmats.
 
9099
        for (unsigned int s = 0; s < n; s++)
 
9100
        {
 
9101
          // Updating dmats_old with new values and resetting dmats.
 
9102
          for (unsigned int t = 0; t < 3; t++)
 
9103
          {
 
9104
            for (unsigned int u = 0; u < 3; u++)
 
9105
            {
 
9106
              dmats_old[t][u] = dmats[t][u];
 
9107
              dmats[t][u] = 0.0;
 
9108
            }// end loop over 'u'
 
9109
          }// end loop over 't'
 
9110
          
 
9111
          // Update dmats using an inner product.
 
9112
          if (combinations_t[r][s] == 0)
 
9113
          {
 
9114
          for (unsigned int t = 0; t < 3; t++)
 
9115
          {
 
9116
            for (unsigned int u = 0; u < 3; u++)
 
9117
            {
 
9118
              for (unsigned int tu = 0; tu < 3; tu++)
 
9119
              {
 
9120
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
9121
              }// end loop over 'tu'
 
9122
            }// end loop over 'u'
 
9123
          }// end loop over 't'
 
9124
          }
 
9125
          
 
9126
          if (combinations_t[r][s] == 1)
 
9127
          {
 
9128
          for (unsigned int t = 0; t < 3; t++)
 
9129
          {
 
9130
            for (unsigned int u = 0; u < 3; u++)
 
9131
            {
 
9132
              for (unsigned int tu = 0; tu < 3; tu++)
 
9133
              {
 
9134
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
9135
              }// end loop over 'tu'
 
9136
            }// end loop over 'u'
 
9137
          }// end loop over 't'
 
9138
          }
 
9139
          
 
9140
        }// end loop over 's'
 
9141
        for (unsigned int s = 0; s < 3; s++)
 
9142
        {
 
9143
          for (unsigned int t = 0; t < 3; t++)
 
9144
          {
 
9145
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
9146
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
9147
          }// end loop over 't'
 
9148
        }// end loop over 's'
 
9149
        
 
9150
        // Using contravariant Piola transform to map values back to the physical element.
 
9151
        const double tmp_ref0 = derivatives[r];
 
9152
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
9153
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
9154
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
9155
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
9156
      }// end loop over 'r'
 
9157
      
 
9158
      // Transform derivatives back to physical element
 
9159
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
9160
      {
 
9161
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
9162
        {
 
9163
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[s];
 
9164
          values[3*num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
9165
          values[4*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
9166
        }// end loop over 's'
 
9167
      }// end loop over 'r'
 
9168
      
 
9169
      // Delete pointer to array of derivatives on FIAT element
 
9170
      delete [] derivatives;
 
9171
      
 
9172
      // Delete pointer to array of reference derivatives on physical element.
 
9173
      delete [] derivatives_p;
 
9174
      
 
9175
      // Delete pointer to array of combinations of derivatives and transform
 
9176
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
9177
      {
 
9178
        delete [] combinations_t[r];
 
9179
      }// end loop over 'r'
 
9180
      delete [] combinations_t;
 
9181
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
9182
      {
 
9183
        delete [] combinations_g[r];
 
9184
      }// end loop over 'r'
 
9185
      delete [] combinations_g;
 
9186
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
9187
      {
 
9188
        delete [] transform[r];
 
9189
      }// end loop over 'r'
 
9190
      delete [] transform;
 
9191
        break;
 
9192
      }
 
9193
    case 9:
 
9194
      {
 
9195
        
 
9196
      // Array of basisvalues
 
9197
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
9198
      
 
9199
      // Declare helper variables
 
9200
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
9201
      
 
9202
      // Compute basisvalues
 
9203
      basisvalues[0] = 1.0;
 
9204
      basisvalues[1] = tmp0;
 
9205
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
9206
      basisvalues[0] *= std::sqrt(0.5);
 
9207
      basisvalues[2] *= std::sqrt(1.0);
 
9208
      basisvalues[1] *= std::sqrt(3.0);
 
9209
      
 
9210
      // Table(s) of coefficients
 
9211
      static const double coefficients0[3] = \
 
9212
      {-0.47140452, -0.28867513, 0.16666667};
 
9213
      
 
9214
      static const double coefficients1[3] = \
 
9215
      {0.94280904, 0.0, 0.66666667};
 
9216
      
 
9217
      // Tables of derivatives of the polynomial base (transpose).
 
9218
      static const double dmats0[3][3] = \
 
9219
      {{0.0, 0.0, 0.0},
 
9220
      {4.8989795, 0.0, 0.0},
 
9221
      {0.0, 0.0, 0.0}};
 
9222
      
 
9223
      static const double dmats1[3][3] = \
 
9224
      {{0.0, 0.0, 0.0},
 
9225
      {2.4494897, 0.0, 0.0},
 
9226
      {4.2426407, 0.0, 0.0}};
 
9227
      
 
9228
      // Compute reference derivatives.
 
9229
      // Declare pointer to array of derivatives on FIAT element.
 
9230
      double *derivatives = new double[2*num_derivatives_t];
 
9231
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
9232
      {
 
9233
        derivatives[r] = 0.0;
 
9234
      }// end loop over 'r'
 
9235
      
 
9236
      // Declare pointer to array of reference derivatives on physical element.
 
9237
      double *derivatives_p = new double[3*num_derivatives_t];
 
9238
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
9239
      {
 
9240
        derivatives_p[r] = 0.0;
 
9241
      }// end loop over 'r'
 
9242
      
 
9243
      // Declare derivative matrix (of polynomial basis).
 
9244
      double dmats[3][3] = \
 
9245
      {{1.0, 0.0, 0.0},
 
9246
      {0.0, 1.0, 0.0},
 
9247
      {0.0, 0.0, 1.0}};
 
9248
      
 
9249
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
9250
      double dmats_old[3][3] = \
 
9251
      {{1.0, 0.0, 0.0},
 
9252
      {0.0, 1.0, 0.0},
 
9253
      {0.0, 0.0, 1.0}};
 
9254
      
 
9255
      // Loop possible derivatives.
 
9256
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
9257
      {
 
9258
        // Resetting dmats values to compute next derivative.
 
9259
        for (unsigned int t = 0; t < 3; t++)
 
9260
        {
 
9261
          for (unsigned int u = 0; u < 3; u++)
 
9262
          {
 
9263
            dmats[t][u] = 0.0;
 
9264
            if (t == u)
 
9265
            {
 
9266
            dmats[t][u] = 1.0;
 
9267
            }
 
9268
            
 
9269
          }// end loop over 'u'
 
9270
        }// end loop over 't'
 
9271
        
 
9272
        // Looping derivative order to generate dmats.
 
9273
        for (unsigned int s = 0; s < n; s++)
 
9274
        {
 
9275
          // Updating dmats_old with new values and resetting dmats.
 
9276
          for (unsigned int t = 0; t < 3; t++)
 
9277
          {
 
9278
            for (unsigned int u = 0; u < 3; u++)
 
9279
            {
 
9280
              dmats_old[t][u] = dmats[t][u];
 
9281
              dmats[t][u] = 0.0;
 
9282
            }// end loop over 'u'
 
9283
          }// end loop over 't'
 
9284
          
 
9285
          // Update dmats using an inner product.
 
9286
          if (combinations_t[r][s] == 0)
 
9287
          {
 
9288
          for (unsigned int t = 0; t < 3; t++)
 
9289
          {
 
9290
            for (unsigned int u = 0; u < 3; u++)
 
9291
            {
 
9292
              for (unsigned int tu = 0; tu < 3; tu++)
 
9293
              {
 
9294
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
9295
              }// end loop over 'tu'
 
9296
            }// end loop over 'u'
 
9297
          }// end loop over 't'
 
9298
          }
 
9299
          
 
9300
          if (combinations_t[r][s] == 1)
 
9301
          {
 
9302
          for (unsigned int t = 0; t < 3; t++)
 
9303
          {
 
9304
            for (unsigned int u = 0; u < 3; u++)
 
9305
            {
 
9306
              for (unsigned int tu = 0; tu < 3; tu++)
 
9307
              {
 
9308
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
9309
              }// end loop over 'tu'
 
9310
            }// end loop over 'u'
 
9311
          }// end loop over 't'
 
9312
          }
 
9313
          
 
9314
        }// end loop over 's'
 
9315
        for (unsigned int s = 0; s < 3; s++)
 
9316
        {
 
9317
          for (unsigned int t = 0; t < 3; t++)
 
9318
          {
 
9319
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
9320
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
9321
          }// end loop over 't'
 
9322
        }// end loop over 's'
 
9323
        
 
9324
        // Using contravariant Piola transform to map values back to the physical element.
 
9325
        const double tmp_ref0 = derivatives[r];
 
9326
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
9327
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
9328
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
9329
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
9330
      }// end loop over 'r'
 
9331
      
 
9332
      // Transform derivatives back to physical element
 
9333
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
9334
      {
 
9335
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
9336
        {
 
9337
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[s];
 
9338
          values[3*num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
9339
          values[4*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
9340
        }// end loop over 's'
 
9341
      }// end loop over 'r'
 
9342
      
 
9343
      // Delete pointer to array of derivatives on FIAT element
 
9344
      delete [] derivatives;
 
9345
      
 
9346
      // Delete pointer to array of reference derivatives on physical element.
 
9347
      delete [] derivatives_p;
 
9348
      
 
9349
      // Delete pointer to array of combinations of derivatives and transform
 
9350
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
9351
      {
 
9352
        delete [] combinations_t[r];
 
9353
      }// end loop over 'r'
 
9354
      delete [] combinations_t;
 
9355
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
9356
      {
 
9357
        delete [] combinations_g[r];
 
9358
      }// end loop over 'r'
 
9359
      delete [] combinations_g;
 
9360
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
9361
      {
 
9362
        delete [] transform[r];
 
9363
      }// end loop over 'r'
 
9364
      delete [] transform;
 
9365
        break;
 
9366
      }
 
9367
    case 10:
 
9368
      {
 
9369
        
 
9370
      // Array of basisvalues
 
9371
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
9372
      
 
9373
      // Declare helper variables
 
9374
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
9375
      
 
9376
      // Compute basisvalues
 
9377
      basisvalues[0] = 1.0;
 
9378
      basisvalues[1] = tmp0;
 
9379
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
9380
      basisvalues[0] *= std::sqrt(0.5);
 
9381
      basisvalues[2] *= std::sqrt(1.0);
 
9382
      basisvalues[1] *= std::sqrt(3.0);
 
9383
      
 
9384
      // Table(s) of coefficients
 
9385
      static const double coefficients0[3] = \
 
9386
      {0.47140452, -0.57735027, -0.66666667};
 
9387
      
 
9388
      static const double coefficients1[3] = \
 
9389
      {0.47140452, 0.0, 0.33333333};
 
9390
      
 
9391
      // Tables of derivatives of the polynomial base (transpose).
 
9392
      static const double dmats0[3][3] = \
 
9393
      {{0.0, 0.0, 0.0},
 
9394
      {4.8989795, 0.0, 0.0},
 
9395
      {0.0, 0.0, 0.0}};
 
9396
      
 
9397
      static const double dmats1[3][3] = \
 
9398
      {{0.0, 0.0, 0.0},
 
9399
      {2.4494897, 0.0, 0.0},
 
9400
      {4.2426407, 0.0, 0.0}};
 
9401
      
 
9402
      // Compute reference derivatives.
 
9403
      // Declare pointer to array of derivatives on FIAT element.
 
9404
      double *derivatives = new double[2*num_derivatives_t];
 
9405
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
9406
      {
 
9407
        derivatives[r] = 0.0;
 
9408
      }// end loop over 'r'
 
9409
      
 
9410
      // Declare pointer to array of reference derivatives on physical element.
 
9411
      double *derivatives_p = new double[3*num_derivatives_t];
 
9412
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
9413
      {
 
9414
        derivatives_p[r] = 0.0;
 
9415
      }// end loop over 'r'
 
9416
      
 
9417
      // Declare derivative matrix (of polynomial basis).
 
9418
      double dmats[3][3] = \
 
9419
      {{1.0, 0.0, 0.0},
 
9420
      {0.0, 1.0, 0.0},
 
9421
      {0.0, 0.0, 1.0}};
 
9422
      
 
9423
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
9424
      double dmats_old[3][3] = \
 
9425
      {{1.0, 0.0, 0.0},
 
9426
      {0.0, 1.0, 0.0},
 
9427
      {0.0, 0.0, 1.0}};
 
9428
      
 
9429
      // Loop possible derivatives.
 
9430
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
9431
      {
 
9432
        // Resetting dmats values to compute next derivative.
 
9433
        for (unsigned int t = 0; t < 3; t++)
 
9434
        {
 
9435
          for (unsigned int u = 0; u < 3; u++)
 
9436
          {
 
9437
            dmats[t][u] = 0.0;
 
9438
            if (t == u)
 
9439
            {
 
9440
            dmats[t][u] = 1.0;
 
9441
            }
 
9442
            
 
9443
          }// end loop over 'u'
 
9444
        }// end loop over 't'
 
9445
        
 
9446
        // Looping derivative order to generate dmats.
 
9447
        for (unsigned int s = 0; s < n; s++)
 
9448
        {
 
9449
          // Updating dmats_old with new values and resetting dmats.
 
9450
          for (unsigned int t = 0; t < 3; t++)
 
9451
          {
 
9452
            for (unsigned int u = 0; u < 3; u++)
 
9453
            {
 
9454
              dmats_old[t][u] = dmats[t][u];
 
9455
              dmats[t][u] = 0.0;
 
9456
            }// end loop over 'u'
 
9457
          }// end loop over 't'
 
9458
          
 
9459
          // Update dmats using an inner product.
 
9460
          if (combinations_t[r][s] == 0)
 
9461
          {
 
9462
          for (unsigned int t = 0; t < 3; t++)
 
9463
          {
 
9464
            for (unsigned int u = 0; u < 3; u++)
 
9465
            {
 
9466
              for (unsigned int tu = 0; tu < 3; tu++)
 
9467
              {
 
9468
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
9469
              }// end loop over 'tu'
 
9470
            }// end loop over 'u'
 
9471
          }// end loop over 't'
 
9472
          }
 
9473
          
 
9474
          if (combinations_t[r][s] == 1)
 
9475
          {
 
9476
          for (unsigned int t = 0; t < 3; t++)
 
9477
          {
 
9478
            for (unsigned int u = 0; u < 3; u++)
 
9479
            {
 
9480
              for (unsigned int tu = 0; tu < 3; tu++)
 
9481
              {
 
9482
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
9483
              }// end loop over 'tu'
 
9484
            }// end loop over 'u'
 
9485
          }// end loop over 't'
 
9486
          }
 
9487
          
 
9488
        }// end loop over 's'
 
9489
        for (unsigned int s = 0; s < 3; s++)
 
9490
        {
 
9491
          for (unsigned int t = 0; t < 3; t++)
 
9492
          {
 
9493
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
9494
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
9495
          }// end loop over 't'
 
9496
        }// end loop over 's'
 
9497
        
 
9498
        // Using contravariant Piola transform to map values back to the physical element.
 
9499
        const double tmp_ref0 = derivatives[r];
 
9500
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
9501
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
9502
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
9503
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
9504
      }// end loop over 'r'
 
9505
      
 
9506
      // Transform derivatives back to physical element
 
9507
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
9508
      {
 
9509
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
9510
        {
 
9511
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[s];
 
9512
          values[3*num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
9513
          values[4*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
9514
        }// end loop over 's'
 
9515
      }// end loop over 'r'
 
9516
      
 
9517
      // Delete pointer to array of derivatives on FIAT element
 
9518
      delete [] derivatives;
 
9519
      
 
9520
      // Delete pointer to array of reference derivatives on physical element.
 
9521
      delete [] derivatives_p;
 
9522
      
 
9523
      // Delete pointer to array of combinations of derivatives and transform
 
9524
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
9525
      {
 
9526
        delete [] combinations_t[r];
 
9527
      }// end loop over 'r'
 
9528
      delete [] combinations_t;
 
9529
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
9530
      {
 
9531
        delete [] combinations_g[r];
 
9532
      }// end loop over 'r'
 
9533
      delete [] combinations_g;
 
9534
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
9535
      {
 
9536
        delete [] transform[r];
 
9537
      }// end loop over 'r'
 
9538
      delete [] transform;
 
9539
        break;
 
9540
      }
 
9541
    case 11:
 
9542
      {
 
9543
        
 
9544
      // Array of basisvalues
 
9545
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
9546
      
 
9547
      // Declare helper variables
 
9548
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
9549
      
 
9550
      // Compute basisvalues
 
9551
      basisvalues[0] = 1.0;
 
9552
      basisvalues[1] = tmp0;
 
9553
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
9554
      basisvalues[0] *= std::sqrt(0.5);
 
9555
      basisvalues[2] *= std::sqrt(1.0);
 
9556
      basisvalues[1] *= std::sqrt(3.0);
 
9557
      
 
9558
      // Table(s) of coefficients
 
9559
      static const double coefficients0[3] = \
 
9560
      {0.47140452, 0.28867513, 0.83333333};
 
9561
      
 
9562
      static const double coefficients1[3] = \
 
9563
      {-0.94280904, 0.0, -0.66666667};
 
9564
      
 
9565
      // Tables of derivatives of the polynomial base (transpose).
 
9566
      static const double dmats0[3][3] = \
 
9567
      {{0.0, 0.0, 0.0},
 
9568
      {4.8989795, 0.0, 0.0},
 
9569
      {0.0, 0.0, 0.0}};
 
9570
      
 
9571
      static const double dmats1[3][3] = \
 
9572
      {{0.0, 0.0, 0.0},
 
9573
      {2.4494897, 0.0, 0.0},
 
9574
      {4.2426407, 0.0, 0.0}};
 
9575
      
 
9576
      // Compute reference derivatives.
 
9577
      // Declare pointer to array of derivatives on FIAT element.
 
9578
      double *derivatives = new double[2*num_derivatives_t];
 
9579
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
9580
      {
 
9581
        derivatives[r] = 0.0;
 
9582
      }// end loop over 'r'
 
9583
      
 
9584
      // Declare pointer to array of reference derivatives on physical element.
 
9585
      double *derivatives_p = new double[3*num_derivatives_t];
 
9586
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
9587
      {
 
9588
        derivatives_p[r] = 0.0;
 
9589
      }// end loop over 'r'
 
9590
      
 
9591
      // Declare derivative matrix (of polynomial basis).
 
9592
      double dmats[3][3] = \
 
9593
      {{1.0, 0.0, 0.0},
 
9594
      {0.0, 1.0, 0.0},
 
9595
      {0.0, 0.0, 1.0}};
 
9596
      
 
9597
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
9598
      double dmats_old[3][3] = \
 
9599
      {{1.0, 0.0, 0.0},
 
9600
      {0.0, 1.0, 0.0},
 
9601
      {0.0, 0.0, 1.0}};
 
9602
      
 
9603
      // Loop possible derivatives.
 
9604
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
9605
      {
 
9606
        // Resetting dmats values to compute next derivative.
 
9607
        for (unsigned int t = 0; t < 3; t++)
 
9608
        {
 
9609
          for (unsigned int u = 0; u < 3; u++)
 
9610
          {
 
9611
            dmats[t][u] = 0.0;
 
9612
            if (t == u)
 
9613
            {
 
9614
            dmats[t][u] = 1.0;
 
9615
            }
 
9616
            
 
9617
          }// end loop over 'u'
 
9618
        }// end loop over 't'
 
9619
        
 
9620
        // Looping derivative order to generate dmats.
 
9621
        for (unsigned int s = 0; s < n; s++)
 
9622
        {
 
9623
          // Updating dmats_old with new values and resetting dmats.
 
9624
          for (unsigned int t = 0; t < 3; t++)
 
9625
          {
 
9626
            for (unsigned int u = 0; u < 3; u++)
 
9627
            {
 
9628
              dmats_old[t][u] = dmats[t][u];
 
9629
              dmats[t][u] = 0.0;
 
9630
            }// end loop over 'u'
 
9631
          }// end loop over 't'
 
9632
          
 
9633
          // Update dmats using an inner product.
 
9634
          if (combinations_t[r][s] == 0)
 
9635
          {
 
9636
          for (unsigned int t = 0; t < 3; t++)
 
9637
          {
 
9638
            for (unsigned int u = 0; u < 3; u++)
 
9639
            {
 
9640
              for (unsigned int tu = 0; tu < 3; tu++)
 
9641
              {
 
9642
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
9643
              }// end loop over 'tu'
 
9644
            }// end loop over 'u'
 
9645
          }// end loop over 't'
 
9646
          }
 
9647
          
 
9648
          if (combinations_t[r][s] == 1)
 
9649
          {
 
9650
          for (unsigned int t = 0; t < 3; t++)
 
9651
          {
 
9652
            for (unsigned int u = 0; u < 3; u++)
 
9653
            {
 
9654
              for (unsigned int tu = 0; tu < 3; tu++)
 
9655
              {
 
9656
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
9657
              }// end loop over 'tu'
 
9658
            }// end loop over 'u'
 
9659
          }// end loop over 't'
 
9660
          }
 
9661
          
 
9662
        }// end loop over 's'
 
9663
        for (unsigned int s = 0; s < 3; s++)
 
9664
        {
 
9665
          for (unsigned int t = 0; t < 3; t++)
 
9666
          {
 
9667
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
9668
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
9669
          }// end loop over 't'
 
9670
        }// end loop over 's'
 
9671
        
 
9672
        // Using contravariant Piola transform to map values back to the physical element.
 
9673
        const double tmp_ref0 = derivatives[r];
 
9674
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
9675
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
9676
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
9677
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
9678
      }// end loop over 'r'
 
9679
      
 
9680
      // Transform derivatives back to physical element
 
9681
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
9682
      {
 
9683
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
9684
        {
 
9685
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[s];
 
9686
          values[3*num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
9687
          values[4*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
9688
        }// end loop over 's'
 
9689
      }// end loop over 'r'
 
9690
      
 
9691
      // Delete pointer to array of derivatives on FIAT element
 
9692
      delete [] derivatives;
 
9693
      
 
9694
      // Delete pointer to array of reference derivatives on physical element.
 
9695
      delete [] derivatives_p;
 
9696
      
 
9697
      // Delete pointer to array of combinations of derivatives and transform
 
9698
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
9699
      {
 
9700
        delete [] combinations_t[r];
 
9701
      }// end loop over 'r'
 
9702
      delete [] combinations_t;
 
9703
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
9704
      {
 
9705
        delete [] combinations_g[r];
 
9706
      }// end loop over 'r'
 
9707
      delete [] combinations_g;
 
9708
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
9709
      {
 
9710
        delete [] transform[r];
 
9711
      }// end loop over 'r'
 
9712
      delete [] transform;
 
9713
        break;
 
9714
      }
 
9715
    case 12:
 
9716
      {
 
9717
        
 
9718
      // Array of basisvalues
 
9719
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
9720
      
 
9721
      // Declare helper variables
 
9722
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
9723
      
 
9724
      // Compute basisvalues
 
9725
      basisvalues[0] = 1.0;
 
9726
      basisvalues[1] = tmp0;
 
9727
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
9728
      basisvalues[0] *= std::sqrt(0.5);
 
9729
      basisvalues[2] *= std::sqrt(1.0);
 
9730
      basisvalues[1] *= std::sqrt(3.0);
 
9731
      
 
9732
      // Table(s) of coefficients
 
9733
      static const double coefficients0[3] = \
 
9734
      {-0.47140452, -0.28867513, 0.16666667};
 
9735
      
 
9736
      static const double coefficients1[3] = \
 
9737
      {-0.47140452, 0.8660254, 0.16666667};
 
9738
      
 
9739
      // Tables of derivatives of the polynomial base (transpose).
 
9740
      static const double dmats0[3][3] = \
 
9741
      {{0.0, 0.0, 0.0},
 
9742
      {4.8989795, 0.0, 0.0},
 
9743
      {0.0, 0.0, 0.0}};
 
9744
      
 
9745
      static const double dmats1[3][3] = \
 
9746
      {{0.0, 0.0, 0.0},
 
9747
      {2.4494897, 0.0, 0.0},
 
9748
      {4.2426407, 0.0, 0.0}};
 
9749
      
 
9750
      // Compute reference derivatives.
 
9751
      // Declare pointer to array of derivatives on FIAT element.
 
9752
      double *derivatives = new double[2*num_derivatives_t];
 
9753
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
9754
      {
 
9755
        derivatives[r] = 0.0;
 
9756
      }// end loop over 'r'
 
9757
      
 
9758
      // Declare pointer to array of reference derivatives on physical element.
 
9759
      double *derivatives_p = new double[3*num_derivatives_t];
 
9760
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
9761
      {
 
9762
        derivatives_p[r] = 0.0;
 
9763
      }// end loop over 'r'
 
9764
      
 
9765
      // Declare derivative matrix (of polynomial basis).
 
9766
      double dmats[3][3] = \
 
9767
      {{1.0, 0.0, 0.0},
 
9768
      {0.0, 1.0, 0.0},
 
9769
      {0.0, 0.0, 1.0}};
 
9770
      
 
9771
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
9772
      double dmats_old[3][3] = \
 
9773
      {{1.0, 0.0, 0.0},
 
9774
      {0.0, 1.0, 0.0},
 
9775
      {0.0, 0.0, 1.0}};
 
9776
      
 
9777
      // Loop possible derivatives.
 
9778
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
9779
      {
 
9780
        // Resetting dmats values to compute next derivative.
 
9781
        for (unsigned int t = 0; t < 3; t++)
 
9782
        {
 
9783
          for (unsigned int u = 0; u < 3; u++)
 
9784
          {
 
9785
            dmats[t][u] = 0.0;
 
9786
            if (t == u)
 
9787
            {
 
9788
            dmats[t][u] = 1.0;
 
9789
            }
 
9790
            
 
9791
          }// end loop over 'u'
 
9792
        }// end loop over 't'
 
9793
        
 
9794
        // Looping derivative order to generate dmats.
 
9795
        for (unsigned int s = 0; s < n; s++)
 
9796
        {
 
9797
          // Updating dmats_old with new values and resetting dmats.
 
9798
          for (unsigned int t = 0; t < 3; t++)
 
9799
          {
 
9800
            for (unsigned int u = 0; u < 3; u++)
 
9801
            {
 
9802
              dmats_old[t][u] = dmats[t][u];
 
9803
              dmats[t][u] = 0.0;
 
9804
            }// end loop over 'u'
 
9805
          }// end loop over 't'
 
9806
          
 
9807
          // Update dmats using an inner product.
 
9808
          if (combinations_t[r][s] == 0)
 
9809
          {
 
9810
          for (unsigned int t = 0; t < 3; t++)
 
9811
          {
 
9812
            for (unsigned int u = 0; u < 3; u++)
 
9813
            {
 
9814
              for (unsigned int tu = 0; tu < 3; tu++)
 
9815
              {
 
9816
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
9817
              }// end loop over 'tu'
 
9818
            }// end loop over 'u'
 
9819
          }// end loop over 't'
 
9820
          }
 
9821
          
 
9822
          if (combinations_t[r][s] == 1)
 
9823
          {
 
9824
          for (unsigned int t = 0; t < 3; t++)
 
9825
          {
 
9826
            for (unsigned int u = 0; u < 3; u++)
 
9827
            {
 
9828
              for (unsigned int tu = 0; tu < 3; tu++)
 
9829
              {
 
9830
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
9831
              }// end loop over 'tu'
 
9832
            }// end loop over 'u'
 
9833
          }// end loop over 't'
 
9834
          }
 
9835
          
 
9836
        }// end loop over 's'
 
9837
        for (unsigned int s = 0; s < 3; s++)
 
9838
        {
 
9839
          for (unsigned int t = 0; t < 3; t++)
 
9840
          {
 
9841
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
9842
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
9843
          }// end loop over 't'
 
9844
        }// end loop over 's'
 
9845
        
 
9846
        // Using contravariant Piola transform to map values back to the physical element.
 
9847
        const double tmp_ref0 = derivatives[r];
 
9848
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
9849
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
9850
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
9851
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
9852
      }// end loop over 'r'
 
9853
      
 
9854
      // Transform derivatives back to physical element
 
9855
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
9856
      {
 
9857
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
9858
        {
 
9859
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[s];
 
9860
          values[3*num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
9861
          values[4*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
9862
        }// end loop over 's'
 
9863
      }// end loop over 'r'
 
9864
      
 
9865
      // Delete pointer to array of derivatives on FIAT element
 
9866
      delete [] derivatives;
 
9867
      
 
9868
      // Delete pointer to array of reference derivatives on physical element.
 
9869
      delete [] derivatives_p;
 
9870
      
 
9871
      // Delete pointer to array of combinations of derivatives and transform
 
9872
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
9873
      {
 
9874
        delete [] combinations_t[r];
 
9875
      }// end loop over 'r'
 
9876
      delete [] combinations_t;
 
9877
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
9878
      {
 
9879
        delete [] combinations_g[r];
 
9880
      }// end loop over 'r'
 
9881
      delete [] combinations_g;
 
9882
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
9883
      {
 
9884
        delete [] transform[r];
 
9885
      }// end loop over 'r'
 
9886
      delete [] transform;
 
9887
        break;
 
9888
      }
 
9889
    case 13:
 
9890
      {
 
9891
        
 
9892
      // Array of basisvalues
 
9893
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
9894
      
 
9895
      // Declare helper variables
 
9896
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
9897
      
 
9898
      // Compute basisvalues
 
9899
      basisvalues[0] = 1.0;
 
9900
      basisvalues[1] = tmp0;
 
9901
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
9902
      basisvalues[0] *= std::sqrt(0.5);
 
9903
      basisvalues[2] *= std::sqrt(1.0);
 
9904
      basisvalues[1] *= std::sqrt(3.0);
 
9905
      
 
9906
      // Table(s) of coefficients
 
9907
      static const double coefficients0[3] = \
 
9908
      {0.94280904, 0.57735027, -0.33333333};
 
9909
      
 
9910
      static const double coefficients1[3] = \
 
9911
      {-0.47140452, -0.8660254, 0.16666667};
 
9912
      
 
9913
      // Tables of derivatives of the polynomial base (transpose).
 
9914
      static const double dmats0[3][3] = \
 
9915
      {{0.0, 0.0, 0.0},
 
9916
      {4.8989795, 0.0, 0.0},
 
9917
      {0.0, 0.0, 0.0}};
 
9918
      
 
9919
      static const double dmats1[3][3] = \
 
9920
      {{0.0, 0.0, 0.0},
 
9921
      {2.4494897, 0.0, 0.0},
 
9922
      {4.2426407, 0.0, 0.0}};
 
9923
      
 
9924
      // Compute reference derivatives.
 
9925
      // Declare pointer to array of derivatives on FIAT element.
 
9926
      double *derivatives = new double[2*num_derivatives_t];
 
9927
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
9928
      {
 
9929
        derivatives[r] = 0.0;
 
9930
      }// end loop over 'r'
 
9931
      
 
9932
      // Declare pointer to array of reference derivatives on physical element.
 
9933
      double *derivatives_p = new double[3*num_derivatives_t];
 
9934
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
9935
      {
 
9936
        derivatives_p[r] = 0.0;
 
9937
      }// end loop over 'r'
 
9938
      
 
9939
      // Declare derivative matrix (of polynomial basis).
 
9940
      double dmats[3][3] = \
 
9941
      {{1.0, 0.0, 0.0},
 
9942
      {0.0, 1.0, 0.0},
 
9943
      {0.0, 0.0, 1.0}};
 
9944
      
 
9945
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
9946
      double dmats_old[3][3] = \
 
9947
      {{1.0, 0.0, 0.0},
 
9948
      {0.0, 1.0, 0.0},
 
9949
      {0.0, 0.0, 1.0}};
 
9950
      
 
9951
      // Loop possible derivatives.
 
9952
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
9953
      {
 
9954
        // Resetting dmats values to compute next derivative.
 
9955
        for (unsigned int t = 0; t < 3; t++)
 
9956
        {
 
9957
          for (unsigned int u = 0; u < 3; u++)
 
9958
          {
 
9959
            dmats[t][u] = 0.0;
 
9960
            if (t == u)
 
9961
            {
 
9962
            dmats[t][u] = 1.0;
 
9963
            }
 
9964
            
 
9965
          }// end loop over 'u'
 
9966
        }// end loop over 't'
 
9967
        
 
9968
        // Looping derivative order to generate dmats.
 
9969
        for (unsigned int s = 0; s < n; s++)
 
9970
        {
 
9971
          // Updating dmats_old with new values and resetting dmats.
 
9972
          for (unsigned int t = 0; t < 3; t++)
 
9973
          {
 
9974
            for (unsigned int u = 0; u < 3; u++)
 
9975
            {
 
9976
              dmats_old[t][u] = dmats[t][u];
 
9977
              dmats[t][u] = 0.0;
 
9978
            }// end loop over 'u'
 
9979
          }// end loop over 't'
 
9980
          
 
9981
          // Update dmats using an inner product.
 
9982
          if (combinations_t[r][s] == 0)
 
9983
          {
 
9984
          for (unsigned int t = 0; t < 3; t++)
 
9985
          {
 
9986
            for (unsigned int u = 0; u < 3; u++)
 
9987
            {
 
9988
              for (unsigned int tu = 0; tu < 3; tu++)
 
9989
              {
 
9990
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
9991
              }// end loop over 'tu'
 
9992
            }// end loop over 'u'
 
9993
          }// end loop over 't'
 
9994
          }
 
9995
          
 
9996
          if (combinations_t[r][s] == 1)
 
9997
          {
 
9998
          for (unsigned int t = 0; t < 3; t++)
 
9999
          {
 
10000
            for (unsigned int u = 0; u < 3; u++)
 
10001
            {
 
10002
              for (unsigned int tu = 0; tu < 3; tu++)
 
10003
              {
 
10004
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
10005
              }// end loop over 'tu'
 
10006
            }// end loop over 'u'
 
10007
          }// end loop over 't'
 
10008
          }
 
10009
          
 
10010
        }// end loop over 's'
 
10011
        for (unsigned int s = 0; s < 3; s++)
 
10012
        {
 
10013
          for (unsigned int t = 0; t < 3; t++)
 
10014
          {
 
10015
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
10016
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
10017
          }// end loop over 't'
 
10018
        }// end loop over 's'
 
10019
        
 
10020
        // Using contravariant Piola transform to map values back to the physical element.
 
10021
        const double tmp_ref0 = derivatives[r];
 
10022
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
10023
        derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
 
10024
        derivatives_p[num_derivatives_t + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
 
10025
        derivatives_p[2*num_derivatives_t + r] = (1.0/detJ)*(J[4]*tmp_ref0 + J[5]*tmp_ref1);
 
10026
      }// end loop over 'r'
 
10027
      
 
10028
      // Transform derivatives back to physical element
 
10029
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
10030
      {
 
10031
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
10032
        {
 
10033
          values[2*num_derivatives_g + r] += transform[r][s]*derivatives_p[s];
 
10034
          values[3*num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
10035
          values[4*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
10036
        }// end loop over 's'
 
10037
      }// end loop over 'r'
 
10038
      
 
10039
      // Delete pointer to array of derivatives on FIAT element
 
10040
      delete [] derivatives;
 
10041
      
 
10042
      // Delete pointer to array of reference derivatives on physical element.
 
10043
      delete [] derivatives_p;
 
10044
      
 
10045
      // Delete pointer to array of combinations of derivatives and transform
 
10046
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
10047
      {
 
10048
        delete [] combinations_t[r];
 
10049
      }// end loop over 'r'
 
10050
      delete [] combinations_t;
 
10051
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
10052
      {
 
10053
        delete [] combinations_g[r];
 
10054
      }// end loop over 'r'
 
10055
      delete [] combinations_g;
 
10056
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
10057
      {
 
10058
        delete [] transform[r];
 
10059
      }// end loop over 'r'
 
10060
      delete [] transform;
 
10061
        break;
 
10062
      }
 
10063
    case 14:
 
10064
      {
 
10065
        
 
10066
      // Array of basisvalues
 
10067
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
10068
      
 
10069
      // Declare helper variables
 
10070
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
10071
      
 
10072
      // Compute basisvalues
 
10073
      basisvalues[0] = 1.0;
 
10074
      basisvalues[1] = tmp0;
 
10075
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
10076
      basisvalues[0] *= std::sqrt(0.5);
 
10077
      basisvalues[2] *= std::sqrt(1.0);
 
10078
      basisvalues[1] *= std::sqrt(3.0);
 
10079
      
 
10080
      // Table(s) of coefficients
 
10081
      static const double coefficients0[3] = \
 
10082
      {-0.47140452, 0.0, -0.33333333};
 
10083
      
 
10084
      static const double coefficients1[3] = \
 
10085
      {0.47140452, 0.28867513, -0.16666667};
 
10086
      
 
10087
      // Tables of derivatives of the polynomial base (transpose).
 
10088
      static const double dmats0[3][3] = \
 
10089
      {{0.0, 0.0, 0.0},
 
10090
      {4.8989795, 0.0, 0.0},
 
10091
      {0.0, 0.0, 0.0}};
 
10092
      
 
10093
      static const double dmats1[3][3] = \
 
10094
      {{0.0, 0.0, 0.0},
 
10095
      {2.4494897, 0.0, 0.0},
 
10096
      {4.2426407, 0.0, 0.0}};
 
10097
      
 
10098
      // Compute reference derivatives.
 
10099
      // Declare pointer to array of derivatives on FIAT element.
 
10100
      double *derivatives = new double[2*num_derivatives_t];
 
10101
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
10102
      {
 
10103
        derivatives[r] = 0.0;
 
10104
      }// end loop over 'r'
 
10105
      
 
10106
      // Declare pointer to array of reference derivatives on physical element.
 
10107
      double *derivatives_p = new double[3*num_derivatives_t];
 
10108
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
10109
      {
 
10110
        derivatives_p[r] = 0.0;
 
10111
      }// end loop over 'r'
 
10112
      
 
10113
      // Declare derivative matrix (of polynomial basis).
 
10114
      double dmats[3][3] = \
 
10115
      {{1.0, 0.0, 0.0},
 
10116
      {0.0, 1.0, 0.0},
 
10117
      {0.0, 0.0, 1.0}};
 
10118
      
 
10119
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
10120
      double dmats_old[3][3] = \
 
10121
      {{1.0, 0.0, 0.0},
 
10122
      {0.0, 1.0, 0.0},
 
10123
      {0.0, 0.0, 1.0}};
 
10124
      
 
10125
      // Loop possible derivatives.
 
10126
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
10127
      {
 
10128
        // Resetting dmats values to compute next derivative.
 
10129
        for (unsigned int t = 0; t < 3; t++)
 
10130
        {
 
10131
          for (unsigned int u = 0; u < 3; u++)
 
10132
          {
 
10133
            dmats[t][u] = 0.0;
 
10134
            if (t == u)
 
10135
            {
 
10136
            dmats[t][u] = 1.0;
 
10137
            }
 
10138
            
 
10139
          }// end loop over 'u'
 
10140
        }// end loop over 't'
 
10141
        
 
10142
        // Looping derivative order to generate dmats.
 
10143
        for (unsigned int s = 0; s < n; s++)
 
10144
        {
 
10145
          // Updating dmats_old with new values and resetting dmats.
 
10146
          for (unsigned int t = 0; t < 3; t++)
 
10147
          {
 
10148
            for (unsigned int u = 0; u < 3; u++)
 
10149
            {
 
10150
              dmats_old[t][u] = dmats[t][u];
 
10151
              dmats[t][u] = 0.0;
 
10152
            }// end loop over 'u'
 
10153
          }// end loop over 't'
 
10154
          
 
10155
          // Update dmats using an inner product.
 
10156
          if (combinations_t[r][s] == 0)
 
10157
          {
 
10158
          for (unsigned int t = 0; t < 3; t++)
 
10159
          {
 
10160
            for (unsigned int u = 0; u < 3; u++)
 
10161
            {
 
10162
              for (unsigned int tu = 0; tu < 3; tu++)
 
10163
              {
 
10164
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
10165
              }// end loop over 'tu'
 
10166
            }// end loop over 'u'
 
10167
          }// end loop over 't'
 
10168
          }
 
10169
          
 
10170
          if (combinations_t[r][s] == 1)
 
10171
          {
 
10172
          for (unsigned int t = 0; t < 3; t++)
 
10173
          {
 
10174
            for (unsigned int u = 0; u < 3; u++)
 
10175
            {
 
10176
              for (unsigned int tu = 0; tu < 3; tu++)
 
10177
              {
 
10178
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
10179
              }// end loop over 'tu'
 
10180
            }// end loop over 'u'
 
10181
          }// end loop over 't'
 
10182
          }
 
10183
          
 
10184
        }// end loop over 's'
 
10185
        for (unsigned int s = 0; s < 3; s++)
 
10186
        {
 
10187
          for (unsigned int t = 0; t < 3; t++)
 
10188
          {
 
10189
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
10190
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
10191
          }// end loop over 't'
 
10192
        }// end loop over 's'
 
10193
        
 
10194
        // Using covariant Piola transform to map values back to the physical element
 
10195
        const double tmp_ref0 = derivatives[r];
 
10196
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
10197
        derivatives_p[r] = (K[0]*tmp_ref0 + K[3]*tmp_ref1);
 
10198
        derivatives_p[num_derivatives_t + r] = (K[1]*tmp_ref0 + K[4]*tmp_ref1);
 
10199
        derivatives_p[2*num_derivatives_t + r] = (K[2]*tmp_ref0 + K[5]*tmp_ref1);
 
10200
      }// end loop over 'r'
 
10201
      
 
10202
      // Transform derivatives back to physical element
 
10203
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
10204
      {
 
10205
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
10206
        {
 
10207
          values[4*num_derivatives_g + r] += transform[r][s]*derivatives_p[s];
 
10208
          values[5*num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
10209
          values[6*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
10210
        }// end loop over 's'
 
10211
      }// end loop over 'r'
 
10212
      
 
10213
      // Delete pointer to array of derivatives on FIAT element
 
10214
      delete [] derivatives;
 
10215
      
 
10216
      // Delete pointer to array of reference derivatives on physical element.
 
10217
      delete [] derivatives_p;
 
10218
      
 
10219
      // Delete pointer to array of combinations of derivatives and transform
 
10220
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
10221
      {
 
10222
        delete [] combinations_t[r];
 
10223
      }// end loop over 'r'
 
10224
      delete [] combinations_t;
 
10225
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
10226
      {
 
10227
        delete [] combinations_g[r];
 
10228
      }// end loop over 'r'
 
10229
      delete [] combinations_g;
 
10230
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
10231
      {
 
10232
        delete [] transform[r];
 
10233
      }// end loop over 'r'
 
10234
      delete [] transform;
 
10235
        break;
 
10236
      }
 
10237
    case 15:
 
10238
      {
 
10239
        
 
10240
      // Array of basisvalues
 
10241
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
10242
      
 
10243
      // Declare helper variables
 
10244
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
10245
      
 
10246
      // Compute basisvalues
 
10247
      basisvalues[0] = 1.0;
 
10248
      basisvalues[1] = tmp0;
 
10249
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
10250
      basisvalues[0] *= std::sqrt(0.5);
 
10251
      basisvalues[2] *= std::sqrt(1.0);
 
10252
      basisvalues[1] *= std::sqrt(3.0);
 
10253
      
 
10254
      // Table(s) of coefficients
 
10255
      static const double coefficients0[3] = \
 
10256
      {0.47140452, 0.0, 0.33333333};
 
10257
      
 
10258
      static const double coefficients1[3] = \
 
10259
      {0.94280904, -0.28867513, 0.16666667};
 
10260
      
 
10261
      // Tables of derivatives of the polynomial base (transpose).
 
10262
      static const double dmats0[3][3] = \
 
10263
      {{0.0, 0.0, 0.0},
 
10264
      {4.8989795, 0.0, 0.0},
 
10265
      {0.0, 0.0, 0.0}};
 
10266
      
 
10267
      static const double dmats1[3][3] = \
 
10268
      {{0.0, 0.0, 0.0},
 
10269
      {2.4494897, 0.0, 0.0},
 
10270
      {4.2426407, 0.0, 0.0}};
 
10271
      
 
10272
      // Compute reference derivatives.
 
10273
      // Declare pointer to array of derivatives on FIAT element.
 
10274
      double *derivatives = new double[2*num_derivatives_t];
 
10275
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
10276
      {
 
10277
        derivatives[r] = 0.0;
 
10278
      }// end loop over 'r'
 
10279
      
 
10280
      // Declare pointer to array of reference derivatives on physical element.
 
10281
      double *derivatives_p = new double[3*num_derivatives_t];
 
10282
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
10283
      {
 
10284
        derivatives_p[r] = 0.0;
 
10285
      }// end loop over 'r'
 
10286
      
 
10287
      // Declare derivative matrix (of polynomial basis).
 
10288
      double dmats[3][3] = \
 
10289
      {{1.0, 0.0, 0.0},
 
10290
      {0.0, 1.0, 0.0},
 
10291
      {0.0, 0.0, 1.0}};
 
10292
      
 
10293
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
10294
      double dmats_old[3][3] = \
 
10295
      {{1.0, 0.0, 0.0},
 
10296
      {0.0, 1.0, 0.0},
 
10297
      {0.0, 0.0, 1.0}};
 
10298
      
 
10299
      // Loop possible derivatives.
 
10300
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
10301
      {
 
10302
        // Resetting dmats values to compute next derivative.
 
10303
        for (unsigned int t = 0; t < 3; t++)
 
10304
        {
 
10305
          for (unsigned int u = 0; u < 3; u++)
 
10306
          {
 
10307
            dmats[t][u] = 0.0;
 
10308
            if (t == u)
 
10309
            {
 
10310
            dmats[t][u] = 1.0;
 
10311
            }
 
10312
            
 
10313
          }// end loop over 'u'
 
10314
        }// end loop over 't'
 
10315
        
 
10316
        // Looping derivative order to generate dmats.
 
10317
        for (unsigned int s = 0; s < n; s++)
 
10318
        {
 
10319
          // Updating dmats_old with new values and resetting dmats.
 
10320
          for (unsigned int t = 0; t < 3; t++)
 
10321
          {
 
10322
            for (unsigned int u = 0; u < 3; u++)
 
10323
            {
 
10324
              dmats_old[t][u] = dmats[t][u];
 
10325
              dmats[t][u] = 0.0;
 
10326
            }// end loop over 'u'
 
10327
          }// end loop over 't'
 
10328
          
 
10329
          // Update dmats using an inner product.
 
10330
          if (combinations_t[r][s] == 0)
 
10331
          {
 
10332
          for (unsigned int t = 0; t < 3; t++)
 
10333
          {
 
10334
            for (unsigned int u = 0; u < 3; u++)
 
10335
            {
 
10336
              for (unsigned int tu = 0; tu < 3; tu++)
 
10337
              {
 
10338
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
10339
              }// end loop over 'tu'
 
10340
            }// end loop over 'u'
 
10341
          }// end loop over 't'
 
10342
          }
 
10343
          
 
10344
          if (combinations_t[r][s] == 1)
 
10345
          {
 
10346
          for (unsigned int t = 0; t < 3; t++)
 
10347
          {
 
10348
            for (unsigned int u = 0; u < 3; u++)
 
10349
            {
 
10350
              for (unsigned int tu = 0; tu < 3; tu++)
 
10351
              {
 
10352
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
10353
              }// end loop over 'tu'
 
10354
            }// end loop over 'u'
 
10355
          }// end loop over 't'
 
10356
          }
 
10357
          
 
10358
        }// end loop over 's'
 
10359
        for (unsigned int s = 0; s < 3; s++)
 
10360
        {
 
10361
          for (unsigned int t = 0; t < 3; t++)
 
10362
          {
 
10363
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
10364
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
10365
          }// end loop over 't'
 
10366
        }// end loop over 's'
 
10367
        
 
10368
        // Using covariant Piola transform to map values back to the physical element
 
10369
        const double tmp_ref0 = derivatives[r];
 
10370
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
10371
        derivatives_p[r] = (K[0]*tmp_ref0 + K[3]*tmp_ref1);
 
10372
        derivatives_p[num_derivatives_t + r] = (K[1]*tmp_ref0 + K[4]*tmp_ref1);
 
10373
        derivatives_p[2*num_derivatives_t + r] = (K[2]*tmp_ref0 + K[5]*tmp_ref1);
 
10374
      }// end loop over 'r'
 
10375
      
 
10376
      // Transform derivatives back to physical element
 
10377
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
10378
      {
 
10379
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
10380
        {
 
10381
          values[4*num_derivatives_g + r] += transform[r][s]*derivatives_p[s];
 
10382
          values[5*num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
10383
          values[6*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
10384
        }// end loop over 's'
 
10385
      }// end loop over 'r'
 
10386
      
 
10387
      // Delete pointer to array of derivatives on FIAT element
 
10388
      delete [] derivatives;
 
10389
      
 
10390
      // Delete pointer to array of reference derivatives on physical element.
 
10391
      delete [] derivatives_p;
 
10392
      
 
10393
      // Delete pointer to array of combinations of derivatives and transform
 
10394
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
10395
      {
 
10396
        delete [] combinations_t[r];
 
10397
      }// end loop over 'r'
 
10398
      delete [] combinations_t;
 
10399
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
10400
      {
 
10401
        delete [] combinations_g[r];
 
10402
      }// end loop over 'r'
 
10403
      delete [] combinations_g;
 
10404
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
10405
      {
 
10406
        delete [] transform[r];
 
10407
      }// end loop over 'r'
 
10408
      delete [] transform;
 
10409
        break;
 
10410
      }
 
10411
    case 16:
 
10412
      {
 
10413
        
 
10414
      // Array of basisvalues
 
10415
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
10416
      
 
10417
      // Declare helper variables
 
10418
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
10419
      
 
10420
      // Compute basisvalues
 
10421
      basisvalues[0] = 1.0;
 
10422
      basisvalues[1] = tmp0;
 
10423
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
10424
      basisvalues[0] *= std::sqrt(0.5);
 
10425
      basisvalues[2] *= std::sqrt(1.0);
 
10426
      basisvalues[1] *= std::sqrt(3.0);
 
10427
      
 
10428
      // Table(s) of coefficients
 
10429
      static const double coefficients0[3] = \
 
10430
      {0.94280904, 0.0, -0.33333333};
 
10431
      
 
10432
      static const double coefficients1[3] = \
 
10433
      {0.47140452, 0.28867513, -0.16666667};
 
10434
      
 
10435
      // Tables of derivatives of the polynomial base (transpose).
 
10436
      static const double dmats0[3][3] = \
 
10437
      {{0.0, 0.0, 0.0},
 
10438
      {4.8989795, 0.0, 0.0},
 
10439
      {0.0, 0.0, 0.0}};
 
10440
      
 
10441
      static const double dmats1[3][3] = \
 
10442
      {{0.0, 0.0, 0.0},
 
10443
      {2.4494897, 0.0, 0.0},
 
10444
      {4.2426407, 0.0, 0.0}};
 
10445
      
 
10446
      // Compute reference derivatives.
 
10447
      // Declare pointer to array of derivatives on FIAT element.
 
10448
      double *derivatives = new double[2*num_derivatives_t];
 
10449
      for (unsigned int r = 0; r < 2*num_derivatives_t; r++)
 
10450
      {
 
10451
        derivatives[r] = 0.0;
 
10452
      }// end loop over 'r'
 
10453
      
 
10454
      // Declare pointer to array of reference derivatives on physical element.
 
10455
      double *derivatives_p = new double[3*num_derivatives_t];
 
10456
      for (unsigned int r = 0; r < 3*num_derivatives_t; r++)
 
10457
      {
 
10458
        derivatives_p[r] = 0.0;
 
10459
      }// end loop over 'r'
 
10460
      
 
10461
      // Declare derivative matrix (of polynomial basis).
 
10462
      double dmats[3][3] = \
 
10463
      {{1.0, 0.0, 0.0},
 
10464
      {0.0, 1.0, 0.0},
 
10465
      {0.0, 0.0, 1.0}};
 
10466
      
 
10467
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
10468
      double dmats_old[3][3] = \
 
10469
      {{1.0, 0.0, 0.0},
 
10470
      {0.0, 1.0, 0.0},
 
10471
      {0.0, 0.0, 1.0}};
 
10472
      
 
10473
      // Loop possible derivatives.
 
10474
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
10475
      {
 
10476
        // Resetting dmats values to compute next derivative.
 
10477
        for (unsigned int t = 0; t < 3; t++)
 
10478
        {
 
10479
          for (unsigned int u = 0; u < 3; u++)
 
10480
          {
 
10481
            dmats[t][u] = 0.0;
 
10482
            if (t == u)
 
10483
            {
 
10484
            dmats[t][u] = 1.0;
 
10485
            }
 
10486
            
 
10487
          }// end loop over 'u'
 
10488
        }// end loop over 't'
 
10489
        
 
10490
        // Looping derivative order to generate dmats.
 
10491
        for (unsigned int s = 0; s < n; s++)
 
10492
        {
 
10493
          // Updating dmats_old with new values and resetting dmats.
 
10494
          for (unsigned int t = 0; t < 3; t++)
 
10495
          {
 
10496
            for (unsigned int u = 0; u < 3; u++)
 
10497
            {
 
10498
              dmats_old[t][u] = dmats[t][u];
 
10499
              dmats[t][u] = 0.0;
 
10500
            }// end loop over 'u'
 
10501
          }// end loop over 't'
 
10502
          
 
10503
          // Update dmats using an inner product.
 
10504
          if (combinations_t[r][s] == 0)
 
10505
          {
 
10506
          for (unsigned int t = 0; t < 3; t++)
 
10507
          {
 
10508
            for (unsigned int u = 0; u < 3; u++)
 
10509
            {
 
10510
              for (unsigned int tu = 0; tu < 3; tu++)
 
10511
              {
 
10512
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
10513
              }// end loop over 'tu'
 
10514
            }// end loop over 'u'
 
10515
          }// end loop over 't'
 
10516
          }
 
10517
          
 
10518
          if (combinations_t[r][s] == 1)
 
10519
          {
 
10520
          for (unsigned int t = 0; t < 3; t++)
 
10521
          {
 
10522
            for (unsigned int u = 0; u < 3; u++)
 
10523
            {
 
10524
              for (unsigned int tu = 0; tu < 3; tu++)
 
10525
              {
 
10526
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
10527
              }// end loop over 'tu'
 
10528
            }// end loop over 'u'
 
10529
          }// end loop over 't'
 
10530
          }
 
10531
          
 
10532
        }// end loop over 's'
 
10533
        for (unsigned int s = 0; s < 3; s++)
 
10534
        {
 
10535
          for (unsigned int t = 0; t < 3; t++)
 
10536
          {
 
10537
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
10538
            derivatives[num_derivatives_t + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
 
10539
          }// end loop over 't'
 
10540
        }// end loop over 's'
 
10541
        
 
10542
        // Using covariant Piola transform to map values back to the physical element
 
10543
        const double tmp_ref0 = derivatives[r];
 
10544
        const double tmp_ref1 = derivatives[num_derivatives_t + r];
 
10545
        derivatives_p[r] = (K[0]*tmp_ref0 + K[3]*tmp_ref1);
 
10546
        derivatives_p[num_derivatives_t + r] = (K[1]*tmp_ref0 + K[4]*tmp_ref1);
 
10547
        derivatives_p[2*num_derivatives_t + r] = (K[2]*tmp_ref0 + K[5]*tmp_ref1);
 
10548
      }// end loop over 'r'
 
10549
      
 
10550
      // Transform derivatives back to physical element
 
10551
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
10552
      {
 
10553
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
10554
        {
 
10555
          values[4*num_derivatives_g + r] += transform[r][s]*derivatives_p[s];
 
10556
          values[5*num_derivatives_g + r] += transform[r][s]*derivatives_p[num_derivatives_t + s];
 
10557
          values[6*num_derivatives_g + r] += transform[r][s]*derivatives_p[2*num_derivatives_t + s];
 
10558
        }// end loop over 's'
 
10559
      }// end loop over 'r'
 
10560
      
 
10561
      // Delete pointer to array of derivatives on FIAT element
 
10562
      delete [] derivatives;
 
10563
      
 
10564
      // Delete pointer to array of reference derivatives on physical element.
 
10565
      delete [] derivatives_p;
 
10566
      
 
10567
      // Delete pointer to array of combinations of derivatives and transform
 
10568
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
10569
      {
 
10570
        delete [] combinations_t[r];
 
10571
      }// end loop over 'r'
 
10572
      delete [] combinations_t;
 
10573
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
10574
      {
 
10575
        delete [] combinations_g[r];
 
10576
      }// end loop over 'r'
 
10577
      delete [] combinations_g;
 
10578
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
10579
      {
 
10580
        delete [] transform[r];
 
10581
      }// end loop over 'r'
 
10582
      delete [] transform;
 
10583
        break;
 
10584
      }
 
10585
    case 17:
 
10586
      {
 
10587
        
 
10588
      // Array of basisvalues
 
10589
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
10590
      
 
10591
      // Declare helper variables
 
10592
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
10593
      
 
10594
      // Compute basisvalues
 
10595
      basisvalues[0] = 1.0;
 
10596
      basisvalues[1] = tmp0;
 
10597
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
10598
      basisvalues[0] *= std::sqrt(0.5);
 
10599
      basisvalues[2] *= std::sqrt(1.0);
 
10600
      basisvalues[1] *= std::sqrt(3.0);
 
10601
      
 
10602
      // Table(s) of coefficients
 
10603
      static const double coefficients0[3] = \
 
10604
      {0.47140452, -0.28867513, -0.16666667};
 
10605
      
 
10606
      // Tables of derivatives of the polynomial base (transpose).
 
10607
      static const double dmats0[3][3] = \
 
10608
      {{0.0, 0.0, 0.0},
 
10609
      {4.8989795, 0.0, 0.0},
 
10610
      {0.0, 0.0, 0.0}};
 
10611
      
 
10612
      static const double dmats1[3][3] = \
 
10613
      {{0.0, 0.0, 0.0},
 
10614
      {2.4494897, 0.0, 0.0},
 
10615
      {4.2426407, 0.0, 0.0}};
 
10616
      
 
10617
      // Compute reference derivatives.
 
10618
      // Declare pointer to array of derivatives on FIAT element.
 
10619
      double *derivatives = new double[num_derivatives_t];
 
10620
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
10621
      {
 
10622
        derivatives[r] = 0.0;
 
10623
      }// end loop over 'r'
 
10624
      
 
10625
      // Declare derivative matrix (of polynomial basis).
 
10626
      double dmats[3][3] = \
 
10627
      {{1.0, 0.0, 0.0},
 
10628
      {0.0, 1.0, 0.0},
 
10629
      {0.0, 0.0, 1.0}};
 
10630
      
 
10631
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
10632
      double dmats_old[3][3] = \
 
10633
      {{1.0, 0.0, 0.0},
 
10634
      {0.0, 1.0, 0.0},
 
10635
      {0.0, 0.0, 1.0}};
 
10636
      
 
10637
      // Loop possible derivatives.
 
10638
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
10639
      {
 
10640
        // Resetting dmats values to compute next derivative.
 
10641
        for (unsigned int t = 0; t < 3; t++)
 
10642
        {
 
10643
          for (unsigned int u = 0; u < 3; u++)
 
10644
          {
 
10645
            dmats[t][u] = 0.0;
 
10646
            if (t == u)
 
10647
            {
 
10648
            dmats[t][u] = 1.0;
 
10649
            }
 
10650
            
 
10651
          }// end loop over 'u'
 
10652
        }// end loop over 't'
 
10653
        
 
10654
        // Looping derivative order to generate dmats.
 
10655
        for (unsigned int s = 0; s < n; s++)
 
10656
        {
 
10657
          // Updating dmats_old with new values and resetting dmats.
 
10658
          for (unsigned int t = 0; t < 3; t++)
 
10659
          {
 
10660
            for (unsigned int u = 0; u < 3; u++)
 
10661
            {
 
10662
              dmats_old[t][u] = dmats[t][u];
 
10663
              dmats[t][u] = 0.0;
 
10664
            }// end loop over 'u'
 
10665
          }// end loop over 't'
 
10666
          
 
10667
          // Update dmats using an inner product.
 
10668
          if (combinations_t[r][s] == 0)
 
10669
          {
 
10670
          for (unsigned int t = 0; t < 3; t++)
 
10671
          {
 
10672
            for (unsigned int u = 0; u < 3; u++)
 
10673
            {
 
10674
              for (unsigned int tu = 0; tu < 3; tu++)
 
10675
              {
 
10676
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
10677
              }// end loop over 'tu'
 
10678
            }// end loop over 'u'
 
10679
          }// end loop over 't'
 
10680
          }
 
10681
          
 
10682
          if (combinations_t[r][s] == 1)
 
10683
          {
 
10684
          for (unsigned int t = 0; t < 3; t++)
 
10685
          {
 
10686
            for (unsigned int u = 0; u < 3; u++)
 
10687
            {
 
10688
              for (unsigned int tu = 0; tu < 3; tu++)
 
10689
              {
 
10690
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
10691
              }// end loop over 'tu'
 
10692
            }// end loop over 'u'
 
10693
          }// end loop over 't'
 
10694
          }
 
10695
          
 
10696
        }// end loop over 's'
 
10697
        for (unsigned int s = 0; s < 3; s++)
 
10698
        {
 
10699
          for (unsigned int t = 0; t < 3; t++)
 
10700
          {
 
10701
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
10702
          }// end loop over 't'
 
10703
        }// end loop over 's'
 
10704
      }// end loop over 'r'
 
10705
      
 
10706
      // Transform derivatives back to physical element
 
10707
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
10708
      {
 
10709
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
10710
        {
 
10711
          values[6*num_derivatives_g + r] += transform[r][s]*derivatives[s];
 
10712
        }// end loop over 's'
 
10713
      }// end loop over 'r'
 
10714
      
 
10715
      // Delete pointer to array of derivatives on FIAT element
 
10716
      delete [] derivatives;
 
10717
      
 
10718
      // Delete pointer to array of combinations of derivatives and transform
 
10719
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
10720
      {
 
10721
        delete [] combinations_t[r];
 
10722
      }// end loop over 'r'
 
10723
      delete [] combinations_t;
 
10724
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
10725
      {
 
10726
        delete [] combinations_g[r];
 
10727
      }// end loop over 'r'
 
10728
      delete [] combinations_g;
 
10729
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
10730
      {
 
10731
        delete [] transform[r];
 
10732
      }// end loop over 'r'
 
10733
      delete [] transform;
 
10734
        break;
 
10735
      }
 
10736
    case 18:
 
10737
      {
 
10738
        
 
10739
      // Array of basisvalues
 
10740
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
10741
      
 
10742
      // Declare helper variables
 
10743
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
10744
      
 
10745
      // Compute basisvalues
 
10746
      basisvalues[0] = 1.0;
 
10747
      basisvalues[1] = tmp0;
 
10748
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
10749
      basisvalues[0] *= std::sqrt(0.5);
 
10750
      basisvalues[2] *= std::sqrt(1.0);
 
10751
      basisvalues[1] *= std::sqrt(3.0);
 
10752
      
 
10753
      // Table(s) of coefficients
 
10754
      static const double coefficients0[3] = \
 
10755
      {0.47140452, 0.28867513, -0.16666667};
 
10756
      
 
10757
      // Tables of derivatives of the polynomial base (transpose).
 
10758
      static const double dmats0[3][3] = \
 
10759
      {{0.0, 0.0, 0.0},
 
10760
      {4.8989795, 0.0, 0.0},
 
10761
      {0.0, 0.0, 0.0}};
 
10762
      
 
10763
      static const double dmats1[3][3] = \
 
10764
      {{0.0, 0.0, 0.0},
 
10765
      {2.4494897, 0.0, 0.0},
 
10766
      {4.2426407, 0.0, 0.0}};
 
10767
      
 
10768
      // Compute reference derivatives.
 
10769
      // Declare pointer to array of derivatives on FIAT element.
 
10770
      double *derivatives = new double[num_derivatives_t];
 
10771
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
10772
      {
 
10773
        derivatives[r] = 0.0;
 
10774
      }// end loop over 'r'
 
10775
      
 
10776
      // Declare derivative matrix (of polynomial basis).
 
10777
      double dmats[3][3] = \
 
10778
      {{1.0, 0.0, 0.0},
 
10779
      {0.0, 1.0, 0.0},
 
10780
      {0.0, 0.0, 1.0}};
 
10781
      
 
10782
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
10783
      double dmats_old[3][3] = \
 
10784
      {{1.0, 0.0, 0.0},
 
10785
      {0.0, 1.0, 0.0},
 
10786
      {0.0, 0.0, 1.0}};
 
10787
      
 
10788
      // Loop possible derivatives.
 
10789
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
10790
      {
 
10791
        // Resetting dmats values to compute next derivative.
 
10792
        for (unsigned int t = 0; t < 3; t++)
 
10793
        {
 
10794
          for (unsigned int u = 0; u < 3; u++)
 
10795
          {
 
10796
            dmats[t][u] = 0.0;
 
10797
            if (t == u)
 
10798
            {
 
10799
            dmats[t][u] = 1.0;
 
10800
            }
 
10801
            
 
10802
          }// end loop over 'u'
 
10803
        }// end loop over 't'
 
10804
        
 
10805
        // Looping derivative order to generate dmats.
 
10806
        for (unsigned int s = 0; s < n; s++)
 
10807
        {
 
10808
          // Updating dmats_old with new values and resetting dmats.
 
10809
          for (unsigned int t = 0; t < 3; t++)
 
10810
          {
 
10811
            for (unsigned int u = 0; u < 3; u++)
 
10812
            {
 
10813
              dmats_old[t][u] = dmats[t][u];
 
10814
              dmats[t][u] = 0.0;
 
10815
            }// end loop over 'u'
 
10816
          }// end loop over 't'
 
10817
          
 
10818
          // Update dmats using an inner product.
 
10819
          if (combinations_t[r][s] == 0)
 
10820
          {
 
10821
          for (unsigned int t = 0; t < 3; t++)
 
10822
          {
 
10823
            for (unsigned int u = 0; u < 3; u++)
 
10824
            {
 
10825
              for (unsigned int tu = 0; tu < 3; tu++)
 
10826
              {
 
10827
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
10828
              }// end loop over 'tu'
 
10829
            }// end loop over 'u'
 
10830
          }// end loop over 't'
 
10831
          }
 
10832
          
 
10833
          if (combinations_t[r][s] == 1)
 
10834
          {
 
10835
          for (unsigned int t = 0; t < 3; t++)
 
10836
          {
 
10837
            for (unsigned int u = 0; u < 3; u++)
 
10838
            {
 
10839
              for (unsigned int tu = 0; tu < 3; tu++)
 
10840
              {
 
10841
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
10842
              }// end loop over 'tu'
 
10843
            }// end loop over 'u'
 
10844
          }// end loop over 't'
 
10845
          }
 
10846
          
 
10847
        }// end loop over 's'
 
10848
        for (unsigned int s = 0; s < 3; s++)
 
10849
        {
 
10850
          for (unsigned int t = 0; t < 3; t++)
 
10851
          {
 
10852
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
10853
          }// end loop over 't'
 
10854
        }// end loop over 's'
 
10855
      }// end loop over 'r'
 
10856
      
 
10857
      // Transform derivatives back to physical element
 
10858
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
10859
      {
 
10860
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
10861
        {
 
10862
          values[6*num_derivatives_g + r] += transform[r][s]*derivatives[s];
 
10863
        }// end loop over 's'
 
10864
      }// end loop over 'r'
 
10865
      
 
10866
      // Delete pointer to array of derivatives on FIAT element
 
10867
      delete [] derivatives;
 
10868
      
 
10869
      // Delete pointer to array of combinations of derivatives and transform
 
10870
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
10871
      {
 
10872
        delete [] combinations_t[r];
 
10873
      }// end loop over 'r'
 
10874
      delete [] combinations_t;
 
10875
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
10876
      {
 
10877
        delete [] combinations_g[r];
 
10878
      }// end loop over 'r'
 
10879
      delete [] combinations_g;
 
10880
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
10881
      {
 
10882
        delete [] transform[r];
 
10883
      }// end loop over 'r'
 
10884
      delete [] transform;
 
10885
        break;
 
10886
      }
 
10887
    case 19:
 
10888
      {
 
10889
        
 
10890
      // Array of basisvalues
 
10891
      double basisvalues[3] = {0.0, 0.0, 0.0};
 
10892
      
 
10893
      // Declare helper variables
 
10894
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
 
10895
      
 
10896
      // Compute basisvalues
 
10897
      basisvalues[0] = 1.0;
 
10898
      basisvalues[1] = tmp0;
 
10899
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
 
10900
      basisvalues[0] *= std::sqrt(0.5);
 
10901
      basisvalues[2] *= std::sqrt(1.0);
 
10902
      basisvalues[1] *= std::sqrt(3.0);
 
10903
      
 
10904
      // Table(s) of coefficients
 
10905
      static const double coefficients0[3] = \
 
10906
      {0.47140452, 0.0, 0.33333333};
 
10907
      
 
10908
      // Tables of derivatives of the polynomial base (transpose).
 
10909
      static const double dmats0[3][3] = \
 
10910
      {{0.0, 0.0, 0.0},
 
10911
      {4.8989795, 0.0, 0.0},
 
10912
      {0.0, 0.0, 0.0}};
 
10913
      
 
10914
      static const double dmats1[3][3] = \
 
10915
      {{0.0, 0.0, 0.0},
 
10916
      {2.4494897, 0.0, 0.0},
 
10917
      {4.2426407, 0.0, 0.0}};
 
10918
      
 
10919
      // Compute reference derivatives.
 
10920
      // Declare pointer to array of derivatives on FIAT element.
 
10921
      double *derivatives = new double[num_derivatives_t];
 
10922
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
10923
      {
 
10924
        derivatives[r] = 0.0;
 
10925
      }// end loop over 'r'
 
10926
      
 
10927
      // Declare derivative matrix (of polynomial basis).
 
10928
      double dmats[3][3] = \
 
10929
      {{1.0, 0.0, 0.0},
 
10930
      {0.0, 1.0, 0.0},
 
10931
      {0.0, 0.0, 1.0}};
 
10932
      
 
10933
      // Declare (auxiliary) derivative matrix (of polynomial basis).
 
10934
      double dmats_old[3][3] = \
 
10935
      {{1.0, 0.0, 0.0},
 
10936
      {0.0, 1.0, 0.0},
 
10937
      {0.0, 0.0, 1.0}};
 
10938
      
 
10939
      // Loop possible derivatives.
 
10940
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
10941
      {
 
10942
        // Resetting dmats values to compute next derivative.
 
10943
        for (unsigned int t = 0; t < 3; t++)
 
10944
        {
 
10945
          for (unsigned int u = 0; u < 3; u++)
 
10946
          {
 
10947
            dmats[t][u] = 0.0;
 
10948
            if (t == u)
 
10949
            {
 
10950
            dmats[t][u] = 1.0;
 
10951
            }
 
10952
            
 
10953
          }// end loop over 'u'
 
10954
        }// end loop over 't'
 
10955
        
 
10956
        // Looping derivative order to generate dmats.
 
10957
        for (unsigned int s = 0; s < n; s++)
 
10958
        {
 
10959
          // Updating dmats_old with new values and resetting dmats.
 
10960
          for (unsigned int t = 0; t < 3; t++)
 
10961
          {
 
10962
            for (unsigned int u = 0; u < 3; u++)
 
10963
            {
 
10964
              dmats_old[t][u] = dmats[t][u];
 
10965
              dmats[t][u] = 0.0;
 
10966
            }// end loop over 'u'
 
10967
          }// end loop over 't'
 
10968
          
 
10969
          // Update dmats using an inner product.
 
10970
          if (combinations_t[r][s] == 0)
 
10971
          {
 
10972
          for (unsigned int t = 0; t < 3; t++)
 
10973
          {
 
10974
            for (unsigned int u = 0; u < 3; u++)
 
10975
            {
 
10976
              for (unsigned int tu = 0; tu < 3; tu++)
 
10977
              {
 
10978
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
 
10979
              }// end loop over 'tu'
 
10980
            }// end loop over 'u'
 
10981
          }// end loop over 't'
 
10982
          }
 
10983
          
 
10984
          if (combinations_t[r][s] == 1)
 
10985
          {
 
10986
          for (unsigned int t = 0; t < 3; t++)
 
10987
          {
 
10988
            for (unsigned int u = 0; u < 3; u++)
 
10989
            {
 
10990
              for (unsigned int tu = 0; tu < 3; tu++)
 
10991
              {
 
10992
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
 
10993
              }// end loop over 'tu'
 
10994
            }// end loop over 'u'
 
10995
          }// end loop over 't'
 
10996
          }
 
10997
          
 
10998
        }// end loop over 's'
 
10999
        for (unsigned int s = 0; s < 3; s++)
 
11000
        {
 
11001
          for (unsigned int t = 0; t < 3; t++)
 
11002
          {
 
11003
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
 
11004
          }// end loop over 't'
 
11005
        }// end loop over 's'
 
11006
      }// end loop over 'r'
 
11007
      
 
11008
      // Transform derivatives back to physical element
 
11009
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
11010
      {
 
11011
        for (unsigned int s = 0; s < num_derivatives_t; s++)
 
11012
        {
 
11013
          values[6*num_derivatives_g + r] += transform[r][s]*derivatives[s];
 
11014
        }// end loop over 's'
 
11015
      }// end loop over 'r'
 
11016
      
 
11017
      // Delete pointer to array of derivatives on FIAT element
 
11018
      delete [] derivatives;
 
11019
      
 
11020
      // Delete pointer to array of combinations of derivatives and transform
 
11021
      for (unsigned int r = 0; r < num_derivatives_t; r++)
 
11022
      {
 
11023
        delete [] combinations_t[r];
 
11024
      }// end loop over 'r'
 
11025
      delete [] combinations_t;
 
11026
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
11027
      {
 
11028
        delete [] combinations_g[r];
 
11029
      }// end loop over 'r'
 
11030
      delete [] combinations_g;
 
11031
      for (unsigned int r = 0; r < num_derivatives_g; r++)
 
11032
      {
 
11033
        delete [] transform[r];
 
11034
      }// end loop over 'r'
 
11035
      delete [] transform;
 
11036
        break;
 
11037
      }
 
11038
    }
 
11039
    
 
11040
  }
 
11041
 
 
11042
  /// Evaluate order n derivatives of all basis functions at given point x in cell
 
11043
  virtual void evaluate_basis_derivatives_all(std::size_t n,
 
11044
                                              double* values,
 
11045
                                              const double* x,
 
11046
                                              const double* vertex_coordinates,
 
11047
                                              int cell_orientation) const
 
11048
  {
 
11049
    // Compute number of derivatives.
 
11050
    unsigned int num_derivatives_g = 1;
 
11051
    for (unsigned int r = 0; r < n; r++)
 
11052
    {
 
11053
      num_derivatives_g *= 3;
 
11054
    }// end loop over 'r'
 
11055
    
 
11056
    // Helper variable to hold values of a single dof.
 
11057
    double *dof_values = new double[10*num_derivatives_g];
 
11058
    for (unsigned int r = 0; r < 10*num_derivatives_g; r++)
 
11059
    {
 
11060
      dof_values[r] = 0.0;
 
11061
    }// end loop over 'r'
 
11062
    
 
11063
    // Loop dofs and call evaluate_basis_derivatives.
 
11064
    for (unsigned int r = 0; r < 20; r++)
 
11065
    {
 
11066
      evaluate_basis_derivatives(r, n, dof_values, x, vertex_coordinates, cell_orientation);
 
11067
      for (unsigned int s = 0; s < 10*num_derivatives_g; s++)
 
11068
      {
 
11069
        values[r*10*num_derivatives_g + s] = dof_values[s];
 
11070
      }// end loop over 's'
 
11071
    }// end loop over 'r'
 
11072
    
 
11073
    // Delete pointer.
 
11074
    delete [] dof_values;
 
11075
  }
 
11076
 
 
11077
  /// Evaluate linear functional for dof i on the function f
 
11078
  virtual double evaluate_dof(std::size_t i,
 
11079
                              const ufc::function& f,
 
11080
                              const double* vertex_coordinates,
 
11081
                              int cell_orientation,
 
11082
                              const ufc::cell& c) const
 
11083
  {
 
11084
    // Declare variables for result of evaluation
 
11085
    double vals[10];
 
11086
    
 
11087
    // Declare variable for physical coordinates
 
11088
    double y[3];
 
11089
    
 
11090
    double result;
 
11091
    // Compute Jacobian
 
11092
    double J[6];
 
11093
    compute_jacobian_triangle_3d(J, vertex_coordinates);
 
11094
    
 
11095
    
 
11096
    // Compute Jacobian inverse and determinant
 
11097
    double K[6];
 
11098
    double detJ;
 
11099
    compute_jacobian_inverse_triangle_3d(K, detJ, J);
 
11100
    
 
11101
    
 
11102
    
 
11103
    // Check orientation
 
11104
    if (cell_orientation == -1)
 
11105
      throw std::runtime_error("cell orientation must be defined (not -1)");
 
11106
    // (If cell_orientation == 1 = down, multiply det(J) by -1)
 
11107
    else if (cell_orientation == 1)
 
11108
      detJ *= -1;
 
11109
    switch (i)
 
11110
    {
 
11111
    case 0:
 
11112
      {
 
11113
        y[0] = 0.66666667*vertex_coordinates[3] + 0.33333333*vertex_coordinates[6];
 
11114
      y[1] = 0.66666667*vertex_coordinates[4] + 0.33333333*vertex_coordinates[7];
 
11115
      y[2] = 0.66666667*vertex_coordinates[5] + 0.33333333*vertex_coordinates[8];
 
11116
      f.evaluate(vals, y, c);
 
11117
      result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2])) + (detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
11118
      return result;
 
11119
        break;
 
11120
      }
 
11121
    case 1:
 
11122
      {
 
11123
        y[0] = 0.33333333*vertex_coordinates[3] + 0.66666667*vertex_coordinates[6];
 
11124
      y[1] = 0.33333333*vertex_coordinates[4] + 0.66666667*vertex_coordinates[7];
 
11125
      y[2] = 0.33333333*vertex_coordinates[5] + 0.66666667*vertex_coordinates[8];
 
11126
      f.evaluate(vals, y, c);
 
11127
      result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2])) + (detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
11128
      return result;
 
11129
        break;
 
11130
      }
 
11131
    case 2:
 
11132
      {
 
11133
        y[0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[6];
 
11134
      y[1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[7];
 
11135
      y[2] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[8];
 
11136
      f.evaluate(vals, y, c);
 
11137
      result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2]));
 
11138
      return result;
 
11139
        break;
 
11140
      }
 
11141
    case 3:
 
11142
      {
 
11143
        y[0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[6];
 
11144
      y[1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[7];
 
11145
      y[2] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[8];
 
11146
      f.evaluate(vals, y, c);
 
11147
      result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2]));
 
11148
      return result;
 
11149
        break;
 
11150
      }
 
11151
    case 4:
 
11152
      {
 
11153
        y[0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[3];
 
11154
      y[1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[4];
 
11155
      y[2] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[5];
 
11156
      f.evaluate(vals, y, c);
 
11157
      result = (-1.0)*(detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
11158
      return result;
 
11159
        break;
 
11160
      }
 
11161
    case 5:
 
11162
      {
 
11163
        y[0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[3];
 
11164
      y[1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[4];
 
11165
      y[2] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[5];
 
11166
      f.evaluate(vals, y, c);
 
11167
      result = (-1.0)*(detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
11168
      return result;
 
11169
        break;
 
11170
      }
 
11171
    case 6:
 
11172
      {
 
11173
        y[0] = 0.33333333*vertex_coordinates[0] + 0.33333333*vertex_coordinates[3] + 0.33333333*vertex_coordinates[6];
 
11174
      y[1] = 0.33333333*vertex_coordinates[1] + 0.33333333*vertex_coordinates[4] + 0.33333333*vertex_coordinates[7];
 
11175
      y[2] = 0.33333333*vertex_coordinates[2] + 0.33333333*vertex_coordinates[5] + 0.33333333*vertex_coordinates[8];
 
11176
      f.evaluate(vals, y, c);
 
11177
      result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2]));
 
11178
      return result;
 
11179
        break;
 
11180
      }
 
11181
    case 7:
 
11182
      {
 
11183
        y[0] = 0.33333333*vertex_coordinates[0] + 0.33333333*vertex_coordinates[3] + 0.33333333*vertex_coordinates[6];
 
11184
      y[1] = 0.33333333*vertex_coordinates[1] + 0.33333333*vertex_coordinates[4] + 0.33333333*vertex_coordinates[7];
 
11185
      y[2] = 0.33333333*vertex_coordinates[2] + 0.33333333*vertex_coordinates[5] + 0.33333333*vertex_coordinates[8];
 
11186
      f.evaluate(vals, y, c);
 
11187
      result = (detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
11188
      return result;
 
11189
        break;
 
11190
      }
 
11191
    case 8:
 
11192
      {
 
11193
        y[0] = 0.66666667*vertex_coordinates[3] + 0.33333333*vertex_coordinates[6];
 
11194
      y[1] = 0.66666667*vertex_coordinates[4] + 0.33333333*vertex_coordinates[7];
 
11195
      y[2] = 0.66666667*vertex_coordinates[5] + 0.33333333*vertex_coordinates[8];
 
11196
      f.evaluate(vals, y, c);
 
11197
      result = (detJ*(K[0]*vals[3] + K[1]*vals[4] + K[2]*vals[5])) + (detJ*(K[3]*vals[3] + K[4]*vals[4] + K[5]*vals[5]));
 
11198
      return result;
 
11199
        break;
 
11200
      }
 
11201
    case 9:
 
11202
      {
 
11203
        y[0] = 0.33333333*vertex_coordinates[3] + 0.66666667*vertex_coordinates[6];
 
11204
      y[1] = 0.33333333*vertex_coordinates[4] + 0.66666667*vertex_coordinates[7];
 
11205
      y[2] = 0.33333333*vertex_coordinates[5] + 0.66666667*vertex_coordinates[8];
 
11206
      f.evaluate(vals, y, c);
 
11207
      result = (detJ*(K[0]*vals[3] + K[1]*vals[4] + K[2]*vals[5])) + (detJ*(K[3]*vals[3] + K[4]*vals[4] + K[5]*vals[5]));
 
11208
      return result;
 
11209
        break;
 
11210
      }
 
11211
    case 10:
 
11212
      {
 
11213
        y[0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[6];
 
11214
      y[1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[7];
 
11215
      y[2] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[8];
 
11216
      f.evaluate(vals, y, c);
 
11217
      result = (detJ*(K[0]*vals[3] + K[1]*vals[4] + K[2]*vals[5]));
 
11218
      return result;
 
11219
        break;
 
11220
      }
 
11221
    case 11:
 
11222
      {
 
11223
        y[0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[6];
 
11224
      y[1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[7];
 
11225
      y[2] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[8];
 
11226
      f.evaluate(vals, y, c);
 
11227
      result = (detJ*(K[0]*vals[3] + K[1]*vals[4] + K[2]*vals[5]));
 
11228
      return result;
 
11229
        break;
 
11230
      }
 
11231
    case 12:
 
11232
      {
 
11233
        y[0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[3];
 
11234
      y[1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[4];
 
11235
      y[2] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[5];
 
11236
      f.evaluate(vals, y, c);
 
11237
      result = (-1.0)*(detJ*(K[3]*vals[3] + K[4]*vals[4] + K[5]*vals[5]));
 
11238
      return result;
 
11239
        break;
 
11240
      }
 
11241
    case 13:
 
11242
      {
 
11243
        y[0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[3];
 
11244
      y[1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[4];
 
11245
      y[2] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[5];
 
11246
      f.evaluate(vals, y, c);
 
11247
      result = (-1.0)*(detJ*(K[3]*vals[3] + K[4]*vals[4] + K[5]*vals[5]));
 
11248
      return result;
 
11249
        break;
 
11250
      }
 
11251
    case 14:
 
11252
      {
 
11253
        y[0] = 0.5*vertex_coordinates[3] + 0.5*vertex_coordinates[6];
 
11254
      y[1] = 0.5*vertex_coordinates[4] + 0.5*vertex_coordinates[7];
 
11255
      y[2] = 0.5*vertex_coordinates[5] + 0.5*vertex_coordinates[8];
 
11256
      f.evaluate(vals, y, c);
 
11257
      result = (-1.0)*(J[0]*vals[6] + J[2]*vals[7] + J[4]*vals[8]) + (J[1]*vals[6] + J[3]*vals[7] + J[5]*vals[8]);
 
11258
      return result;
 
11259
        break;
 
11260
      }
 
11261
    case 15:
 
11262
      {
 
11263
        y[0] = 0.5*vertex_coordinates[0] + 0.5*vertex_coordinates[6];
 
11264
      y[1] = 0.5*vertex_coordinates[1] + 0.5*vertex_coordinates[7];
 
11265
      y[2] = 0.5*vertex_coordinates[2] + 0.5*vertex_coordinates[8];
 
11266
      f.evaluate(vals, y, c);
 
11267
      result = (J[1]*vals[6] + J[3]*vals[7] + J[5]*vals[8]);
 
11268
      return result;
 
11269
        break;
 
11270
      }
 
11271
    case 16:
 
11272
      {
 
11273
        y[0] = 0.5*vertex_coordinates[0] + 0.5*vertex_coordinates[3];
 
11274
      y[1] = 0.5*vertex_coordinates[1] + 0.5*vertex_coordinates[4];
 
11275
      y[2] = 0.5*vertex_coordinates[2] + 0.5*vertex_coordinates[5];
 
11276
      f.evaluate(vals, y, c);
 
11277
      result = (J[0]*vals[6] + J[2]*vals[7] + J[4]*vals[8]);
 
11278
      return result;
 
11279
        break;
 
11280
      }
 
11281
    case 17:
 
11282
      {
 
11283
        y[0] = vertex_coordinates[0];
 
11284
      y[1] = vertex_coordinates[1];
 
11285
      y[2] = vertex_coordinates[2];
 
11286
      f.evaluate(vals, y, c);
 
11287
      return vals[9];
 
11288
        break;
 
11289
      }
 
11290
    case 18:
 
11291
      {
 
11292
        y[0] = vertex_coordinates[3];
 
11293
      y[1] = vertex_coordinates[4];
 
11294
      y[2] = vertex_coordinates[5];
 
11295
      f.evaluate(vals, y, c);
 
11296
      return vals[9];
 
11297
        break;
 
11298
      }
 
11299
    case 19:
 
11300
      {
 
11301
        y[0] = vertex_coordinates[6];
 
11302
      y[1] = vertex_coordinates[7];
 
11303
      y[2] = vertex_coordinates[8];
 
11304
      f.evaluate(vals, y, c);
 
11305
      return vals[9];
 
11306
        break;
 
11307
      }
 
11308
    }
 
11309
    
 
11310
    return 0.0;
 
11311
  }
 
11312
 
 
11313
  /// Evaluate linear functionals for all dofs on the function f
 
11314
  virtual void evaluate_dofs(double* values,
 
11315
                             const ufc::function& f,
 
11316
                             const double* vertex_coordinates,
 
11317
                             int cell_orientation,
 
11318
                             const ufc::cell& c) const
 
11319
  {
 
11320
    // Declare variables for result of evaluation
 
11321
    double vals[10];
 
11322
    
 
11323
    // Declare variable for physical coordinates
 
11324
    double y[3];
 
11325
    
 
11326
    double result;
 
11327
    // Compute Jacobian
 
11328
    double J[6];
 
11329
    compute_jacobian_triangle_3d(J, vertex_coordinates);
 
11330
    
 
11331
    
 
11332
    // Compute Jacobian inverse and determinant
 
11333
    double K[6];
 
11334
    double detJ;
 
11335
    compute_jacobian_inverse_triangle_3d(K, detJ, J);
 
11336
    
 
11337
    
 
11338
    
 
11339
    // Check orientation
 
11340
    if (cell_orientation == -1)
 
11341
      throw std::runtime_error("cell orientation must be defined (not -1)");
 
11342
    // (If cell_orientation == 1 = down, multiply det(J) by -1)
 
11343
    else if (cell_orientation == 1)
 
11344
      detJ *= -1;
 
11345
    y[0] = 0.66666667*vertex_coordinates[3] + 0.33333333*vertex_coordinates[6];
 
11346
    y[1] = 0.66666667*vertex_coordinates[4] + 0.33333333*vertex_coordinates[7];
 
11347
    y[2] = 0.66666667*vertex_coordinates[5] + 0.33333333*vertex_coordinates[8];
 
11348
    f.evaluate(vals, y, c);
 
11349
    result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2])) + (detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
11350
    values[0] = result;
 
11351
    y[0] = 0.33333333*vertex_coordinates[3] + 0.66666667*vertex_coordinates[6];
 
11352
    y[1] = 0.33333333*vertex_coordinates[4] + 0.66666667*vertex_coordinates[7];
 
11353
    y[2] = 0.33333333*vertex_coordinates[5] + 0.66666667*vertex_coordinates[8];
 
11354
    f.evaluate(vals, y, c);
 
11355
    result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2])) + (detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
11356
    values[1] = result;
 
11357
    y[0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[6];
 
11358
    y[1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[7];
 
11359
    y[2] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[8];
 
11360
    f.evaluate(vals, y, c);
 
11361
    result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2]));
 
11362
    values[2] = result;
 
11363
    y[0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[6];
 
11364
    y[1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[7];
 
11365
    y[2] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[8];
 
11366
    f.evaluate(vals, y, c);
 
11367
    result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2]));
 
11368
    values[3] = result;
 
11369
    y[0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[3];
 
11370
    y[1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[4];
 
11371
    y[2] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[5];
 
11372
    f.evaluate(vals, y, c);
 
11373
    result = (-1.0)*(detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
11374
    values[4] = result;
 
11375
    y[0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[3];
 
11376
    y[1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[4];
 
11377
    y[2] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[5];
 
11378
    f.evaluate(vals, y, c);
 
11379
    result = (-1.0)*(detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
11380
    values[5] = result;
 
11381
    y[0] = 0.33333333*vertex_coordinates[0] + 0.33333333*vertex_coordinates[3] + 0.33333333*vertex_coordinates[6];
 
11382
    y[1] = 0.33333333*vertex_coordinates[1] + 0.33333333*vertex_coordinates[4] + 0.33333333*vertex_coordinates[7];
 
11383
    y[2] = 0.33333333*vertex_coordinates[2] + 0.33333333*vertex_coordinates[5] + 0.33333333*vertex_coordinates[8];
 
11384
    f.evaluate(vals, y, c);
 
11385
    result = (detJ*(K[0]*vals[0] + K[1]*vals[1] + K[2]*vals[2]));
 
11386
    values[6] = result;
 
11387
    y[0] = 0.33333333*vertex_coordinates[0] + 0.33333333*vertex_coordinates[3] + 0.33333333*vertex_coordinates[6];
 
11388
    y[1] = 0.33333333*vertex_coordinates[1] + 0.33333333*vertex_coordinates[4] + 0.33333333*vertex_coordinates[7];
 
11389
    y[2] = 0.33333333*vertex_coordinates[2] + 0.33333333*vertex_coordinates[5] + 0.33333333*vertex_coordinates[8];
 
11390
    f.evaluate(vals, y, c);
 
11391
    result = (detJ*(K[3]*vals[0] + K[4]*vals[1] + K[5]*vals[2]));
 
11392
    values[7] = result;
 
11393
    y[0] = 0.66666667*vertex_coordinates[3] + 0.33333333*vertex_coordinates[6];
 
11394
    y[1] = 0.66666667*vertex_coordinates[4] + 0.33333333*vertex_coordinates[7];
 
11395
    y[2] = 0.66666667*vertex_coordinates[5] + 0.33333333*vertex_coordinates[8];
 
11396
    f.evaluate(vals, y, c);
 
11397
    result = (detJ*(K[0]*vals[3] + K[1]*vals[4] + K[2]*vals[5])) + (detJ*(K[3]*vals[3] + K[4]*vals[4] + K[5]*vals[5]));
 
11398
    values[8] = result;
 
11399
    y[0] = 0.33333333*vertex_coordinates[3] + 0.66666667*vertex_coordinates[6];
 
11400
    y[1] = 0.33333333*vertex_coordinates[4] + 0.66666667*vertex_coordinates[7];
 
11401
    y[2] = 0.33333333*vertex_coordinates[5] + 0.66666667*vertex_coordinates[8];
 
11402
    f.evaluate(vals, y, c);
 
11403
    result = (detJ*(K[0]*vals[3] + K[1]*vals[4] + K[2]*vals[5])) + (detJ*(K[3]*vals[3] + K[4]*vals[4] + K[5]*vals[5]));
 
11404
    values[9] = result;
 
11405
    y[0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[6];
 
11406
    y[1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[7];
 
11407
    y[2] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[8];
 
11408
    f.evaluate(vals, y, c);
 
11409
    result = (detJ*(K[0]*vals[3] + K[1]*vals[4] + K[2]*vals[5]));
 
11410
    values[10] = result;
 
11411
    y[0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[6];
 
11412
    y[1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[7];
 
11413
    y[2] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[8];
 
11414
    f.evaluate(vals, y, c);
 
11415
    result = (detJ*(K[0]*vals[3] + K[1]*vals[4] + K[2]*vals[5]));
 
11416
    values[11] = result;
 
11417
    y[0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[3];
 
11418
    y[1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[4];
 
11419
    y[2] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[5];
 
11420
    f.evaluate(vals, y, c);
 
11421
    result = (-1.0)*(detJ*(K[3]*vals[3] + K[4]*vals[4] + K[5]*vals[5]));
 
11422
    values[12] = result;
 
11423
    y[0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[3];
 
11424
    y[1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[4];
 
11425
    y[2] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[5];
 
11426
    f.evaluate(vals, y, c);
 
11427
    result = (-1.0)*(detJ*(K[3]*vals[3] + K[4]*vals[4] + K[5]*vals[5]));
 
11428
    values[13] = result;
 
11429
    y[0] = 0.5*vertex_coordinates[3] + 0.5*vertex_coordinates[6];
 
11430
    y[1] = 0.5*vertex_coordinates[4] + 0.5*vertex_coordinates[7];
 
11431
    y[2] = 0.5*vertex_coordinates[5] + 0.5*vertex_coordinates[8];
 
11432
    f.evaluate(vals, y, c);
 
11433
    result = (-1.0)*(J[0]*vals[6] + J[2]*vals[7] + J[4]*vals[8]) + (J[1]*vals[6] + J[3]*vals[7] + J[5]*vals[8]);
 
11434
    values[14] = result;
 
11435
    y[0] = 0.5*vertex_coordinates[0] + 0.5*vertex_coordinates[6];
 
11436
    y[1] = 0.5*vertex_coordinates[1] + 0.5*vertex_coordinates[7];
 
11437
    y[2] = 0.5*vertex_coordinates[2] + 0.5*vertex_coordinates[8];
 
11438
    f.evaluate(vals, y, c);
 
11439
    result = (J[1]*vals[6] + J[3]*vals[7] + J[5]*vals[8]);
 
11440
    values[15] = result;
 
11441
    y[0] = 0.5*vertex_coordinates[0] + 0.5*vertex_coordinates[3];
 
11442
    y[1] = 0.5*vertex_coordinates[1] + 0.5*vertex_coordinates[4];
 
11443
    y[2] = 0.5*vertex_coordinates[2] + 0.5*vertex_coordinates[5];
 
11444
    f.evaluate(vals, y, c);
 
11445
    result = (J[0]*vals[6] + J[2]*vals[7] + J[4]*vals[8]);
 
11446
    values[16] = result;
 
11447
    y[0] = vertex_coordinates[0];
 
11448
    y[1] = vertex_coordinates[1];
 
11449
    y[2] = vertex_coordinates[2];
 
11450
    f.evaluate(vals, y, c);
 
11451
    values[17] = vals[9];
 
11452
    y[0] = vertex_coordinates[3];
 
11453
    y[1] = vertex_coordinates[4];
 
11454
    y[2] = vertex_coordinates[5];
 
11455
    f.evaluate(vals, y, c);
 
11456
    values[18] = vals[9];
 
11457
    y[0] = vertex_coordinates[6];
 
11458
    y[1] = vertex_coordinates[7];
 
11459
    y[2] = vertex_coordinates[8];
 
11460
    f.evaluate(vals, y, c);
 
11461
    values[19] = vals[9];
 
11462
  }
 
11463
 
 
11464
  /// Interpolate vertex values from dof values
 
11465
  virtual void interpolate_vertex_values(double* vertex_values,
 
11466
                                         const double* dof_values,
 
11467
                                         const double* vertex_coordinates,
 
11468
                                         int cell_orientation,
 
11469
                                         const ufc::cell& c) const
 
11470
  {
 
11471
    // Compute Jacobian
 
11472
    double J[6];
 
11473
    compute_jacobian_triangle_3d(J, vertex_coordinates);
 
11474
    
 
11475
    
 
11476
    // Compute Jacobian inverse and determinant
 
11477
    double K[6];
 
11478
    double detJ;
 
11479
    compute_jacobian_inverse_triangle_3d(K, detJ, J);
 
11480
    
 
11481
    
 
11482
    
 
11483
    // Check orientation
 
11484
    if (cell_orientation == -1)
 
11485
      throw std::runtime_error("cell orientation must be defined (not -1)");
 
11486
    // (If cell_orientation == 1 = down, multiply det(J) by -1)
 
11487
    else if (cell_orientation == 1)
 
11488
      detJ *= -1;
 
11489
    
 
11490
    // Evaluate function and change variables
 
11491
    vertex_values[0] = dof_values[2]*(1.0/detJ)*J[0]*2.0 + dof_values[3]*((1.0/detJ)*(J[0]*(-1.0))) + dof_values[4]*((1.0/detJ)*(J[1]*(-2.0))) + dof_values[5]*(1.0/detJ)*J[1];
 
11492
    vertex_values[7] = dof_values[0]*(1.0/detJ)*J[0]*2.0 + dof_values[1]*((1.0/detJ)*(J[0]*(-1.0))) + dof_values[4]*((1.0/detJ)*(J[0]*(-1.0) + J[1])) + dof_values[5]*((1.0/detJ)*(J[0]*2.0 + J[1]*(-2.0)));
 
11493
    vertex_values[14] = dof_values[0]*((1.0/detJ)*(J[1]*(-1.0))) + dof_values[1]*(1.0/detJ)*J[1]*2.0 + dof_values[2]*((1.0/detJ)*(J[0]*(-1.0) + J[1])) + dof_values[3]*((1.0/detJ)*(J[0]*2.0 + J[1]*(-2.0)));
 
11494
    vertex_values[1] = dof_values[2]*(1.0/detJ)*J[2]*2.0 + dof_values[3]*((1.0/detJ)*(J[2]*(-1.0))) + dof_values[4]*((1.0/detJ)*(J[3]*(-2.0))) + dof_values[5]*(1.0/detJ)*J[3];
 
11495
    vertex_values[8] = dof_values[0]*(1.0/detJ)*J[2]*2.0 + dof_values[1]*((1.0/detJ)*(J[2]*(-1.0))) + dof_values[4]*((1.0/detJ)*(J[2]*(-1.0) + J[3])) + dof_values[5]*((1.0/detJ)*(J[2]*2.0 + J[3]*(-2.0)));
 
11496
    vertex_values[15] = dof_values[0]*((1.0/detJ)*(J[3]*(-1.0))) + dof_values[1]*(1.0/detJ)*J[3]*2.0 + dof_values[2]*((1.0/detJ)*(J[2]*(-1.0) + J[3])) + dof_values[3]*((1.0/detJ)*(J[2]*2.0 + J[3]*(-2.0)));
 
11497
    // Evaluate function and change variables
 
11498
    vertex_values[2] = dof_values[10]*(1.0/detJ)*J[0]*2.0 + dof_values[11]*((1.0/detJ)*(J[0]*(-1.0))) + dof_values[12]*((1.0/detJ)*(J[1]*(-2.0))) + dof_values[13]*(1.0/detJ)*J[1];
 
11499
    vertex_values[9] = dof_values[8]*(1.0/detJ)*J[0]*2.0 + dof_values[9]*((1.0/detJ)*(J[0]*(-1.0))) + dof_values[12]*((1.0/detJ)*(J[0]*(-1.0) + J[1])) + dof_values[13]*((1.0/detJ)*(J[0]*2.0 + J[1]*(-2.0)));
 
11500
    vertex_values[16] = dof_values[8]*((1.0/detJ)*(J[1]*(-1.0))) + dof_values[9]*(1.0/detJ)*J[1]*2.0 + dof_values[10]*((1.0/detJ)*(J[0]*(-1.0) + J[1])) + dof_values[11]*((1.0/detJ)*(J[0]*2.0 + J[1]*(-2.0)));
 
11501
    vertex_values[3] = dof_values[10]*(1.0/detJ)*J[2]*2.0 + dof_values[11]*((1.0/detJ)*(J[2]*(-1.0))) + dof_values[12]*((1.0/detJ)*(J[3]*(-2.0))) + dof_values[13]*(1.0/detJ)*J[3];
 
11502
    vertex_values[10] = dof_values[8]*(1.0/detJ)*J[2]*2.0 + dof_values[9]*((1.0/detJ)*(J[2]*(-1.0))) + dof_values[12]*((1.0/detJ)*(J[2]*(-1.0) + J[3])) + dof_values[13]*((1.0/detJ)*(J[2]*2.0 + J[3]*(-2.0)));
 
11503
    vertex_values[17] = dof_values[8]*((1.0/detJ)*(J[3]*(-1.0))) + dof_values[9]*(1.0/detJ)*J[3]*2.0 + dof_values[10]*((1.0/detJ)*(J[2]*(-1.0) + J[3])) + dof_values[11]*((1.0/detJ)*(J[2]*2.0 + J[3]*(-2.0)));
 
11504
    // Evaluate function and change variables
 
11505
    vertex_values[4] = dof_values[15]*K[3] + dof_values[16]*K[0];
 
11506
    vertex_values[11] = dof_values[14]*K[3] + dof_values[16]*(K[0] + K[3]);
 
11507
    vertex_values[18] = dof_values[14]*(K[0]*(-1.0)) + dof_values[15]*(K[0] + K[3]);
 
11508
    vertex_values[5] = dof_values[15]*K[4] + dof_values[16]*K[1];
 
11509
    vertex_values[12] = dof_values[14]*K[4] + dof_values[16]*(K[1] + K[4]);
 
11510
    vertex_values[19] = dof_values[14]*(K[1]*(-1.0)) + dof_values[15]*(K[1] + K[4]);
 
11511
    // Evaluate function and change variables
 
11512
    vertex_values[6] = dof_values[17];
 
11513
    vertex_values[13] = dof_values[18];
 
11514
    vertex_values[20] = dof_values[19];
 
11515
  }
 
11516
 
 
11517
  /// Map coordinate xhat from reference cell to coordinate x in cell
 
11518
  virtual void map_from_reference_cell(double* x,
 
11519
                                       const double* xhat,
 
11520
                                       const ufc::cell& c) const
 
11521
  {
 
11522
    std::cerr << "*** FFC warning: " << "map_from_reference_cell not yet implemented." << std::endl;
 
11523
  }
 
11524
 
 
11525
  /// Map from coordinate x in cell to coordinate xhat in reference cell
 
11526
  virtual void map_to_reference_cell(double* xhat,
 
11527
                                     const double* x,
 
11528
                                     const ufc::cell& c) const
 
11529
  {
 
11530
    std::cerr << "*** FFC warning: " << "map_to_reference_cell not yet implemented." << std::endl;
 
11531
  }
 
11532
 
 
11533
  /// Return the number of sub elements (for a mixed element)
 
11534
  virtual std::size_t num_sub_elements() const
 
11535
  {
 
11536
    return 4;
 
11537
  }
 
11538
 
 
11539
  /// Create a new finite element for sub element i (for a mixed element)
 
11540
  virtual ufc::finite_element* create_sub_element(std::size_t i) const
 
11541
  {
 
11542
    switch (i)
 
11543
    {
 
11544
    case 0:
 
11545
      {
 
11546
        return new x_element9_finite_element_0();
 
11547
        break;
 
11548
      }
 
11549
    case 1:
 
11550
      {
 
11551
        return new x_element9_finite_element_1();
 
11552
        break;
 
11553
      }
 
11554
    case 2:
 
11555
      {
 
11556
        return new x_element9_finite_element_2();
 
11557
        break;
 
11558
      }
 
11559
    case 3:
 
11560
      {
 
11561
        return new x_element9_finite_element_3();
 
11562
        break;
 
11563
      }
 
11564
    }
 
11565
    
 
11566
    return 0;
 
11567
  }
 
11568
 
 
11569
  /// Create a new class instance
 
11570
  virtual ufc::finite_element* create() const
 
11571
  {
 
11572
    return new x_element9_finite_element_4();
 
11573
  }
 
11574
 
 
11575
};
 
11576
 
 
11577
/// This class defines the interface for a local-to-global mapping of
 
11578
/// degrees of freedom (dofs).
 
11579
 
 
11580
class x_element9_dofmap_0: public ufc::dofmap
 
11581
{
 
11582
public:
 
11583
 
 
11584
  /// Constructor
 
11585
  x_element9_dofmap_0() : ufc::dofmap()
 
11586
  {
 
11587
    // Do nothing
 
11588
  }
 
11589
 
 
11590
  /// Destructor
 
11591
  virtual ~x_element9_dofmap_0()
 
11592
  {
 
11593
    // Do nothing
 
11594
  }
 
11595
 
 
11596
  /// Return a string identifying the dofmap
 
11597
  virtual const char* signature() const
 
11598
  {
 
11599
    return "FFC dofmap for FiniteElement('Raviart-Thomas', Domain(Cell('triangle', 3), 'triangle_multiverse', 3, 2), 2, None)";
 
11600
  }
 
11601
 
 
11602
  /// Return true iff mesh entities of topological dimension d are needed
 
11603
  virtual bool needs_mesh_entities(std::size_t d) const
 
11604
  {
 
11605
    switch (d)
 
11606
    {
 
11607
    case 0:
 
11608
      {
 
11609
        return false;
 
11610
        break;
 
11611
      }
 
11612
    case 1:
 
11613
      {
 
11614
        return true;
 
11615
        break;
 
11616
      }
 
11617
    case 2:
 
11618
      {
 
11619
        return true;
 
11620
        break;
 
11621
      }
 
11622
    }
 
11623
    
 
11624
    return false;
 
11625
  }
 
11626
 
 
11627
  /// Return the topological dimension of the associated cell shape
 
11628
  virtual std::size_t topological_dimension() const
 
11629
  {
 
11630
    return 2;
 
11631
  }
 
11632
 
 
11633
  /// Return the geometric dimension of the associated cell shape
 
11634
  virtual std::size_t geometric_dimension() const
 
11635
  {
 
11636
    return 3;
 
11637
  }
 
11638
 
 
11639
  /// Return the dimension of the global finite element function space
 
11640
  virtual std::size_t global_dimension(const std::vector<std::size_t>&
 
11641
                                       num_global_entities) const
 
11642
  {
 
11643
    return 2*num_global_entities[1] + 2*num_global_entities[2];
 
11644
  }
 
11645
 
 
11646
  /// Return the dimension of the local finite element function space for a cell
 
11647
  virtual std::size_t local_dimension(const ufc::cell& c) const
 
11648
  {
 
11649
    return 8;
 
11650
  }
 
11651
 
 
11652
  /// Return the maximum dimension of the local finite element function space
 
11653
  virtual std::size_t max_local_dimension() const
 
11654
  {
 
11655
    return 8;
 
11656
  }
 
11657
 
 
11658
  /// Return the number of dofs on each cell facet
 
11659
  virtual std::size_t num_facet_dofs() const
 
11660
  {
 
11661
    return 2;
 
11662
  }
 
11663
 
 
11664
  /// Return the number of dofs associated with each cell entity of dimension d
 
11665
  virtual std::size_t num_entity_dofs(std::size_t d) const
 
11666
  {
 
11667
    switch (d)
 
11668
    {
 
11669
    case 0:
 
11670
      {
 
11671
        return 0;
 
11672
        break;
 
11673
      }
 
11674
    case 1:
 
11675
      {
 
11676
        return 2;
 
11677
        break;
 
11678
      }
 
11679
    case 2:
 
11680
      {
 
11681
        return 2;
 
11682
        break;
 
11683
      }
 
11684
    }
 
11685
    
 
11686
    return 0;
 
11687
  }
 
11688
 
 
11689
  /// Tabulate the local-to-global mapping of dofs on a cell
 
11690
  virtual void tabulate_dofs(std::size_t* dofs,
 
11691
                             const std::vector<std::size_t>& num_global_entities,
 
11692
                             const ufc::cell& c) const
 
11693
  {
 
11694
    unsigned int offset = 0;
 
11695
    dofs[0] = offset + 2*c.entity_indices[1][0];
 
11696
    dofs[1] = offset + 2*c.entity_indices[1][0] + 1;
 
11697
    dofs[2] = offset + 2*c.entity_indices[1][1];
 
11698
    dofs[3] = offset + 2*c.entity_indices[1][1] + 1;
 
11699
    dofs[4] = offset + 2*c.entity_indices[1][2];
 
11700
    dofs[5] = offset + 2*c.entity_indices[1][2] + 1;
 
11701
    offset += 2*num_global_entities[1];
 
11702
    dofs[6] = offset + 2*c.entity_indices[2][0];
 
11703
    dofs[7] = offset + 2*c.entity_indices[2][0] + 1;
 
11704
    offset += 2*num_global_entities[2];
 
11705
  }
 
11706
 
 
11707
  /// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
11708
  virtual void tabulate_facet_dofs(std::size_t* dofs,
 
11709
                                   std::size_t facet) const
 
11710
  {
 
11711
    switch (facet)
 
11712
    {
 
11713
    case 0:
 
11714
      {
 
11715
        dofs[0] = 0;
 
11716
      dofs[1] = 1;
 
11717
        break;
 
11718
      }
 
11719
    case 1:
 
11720
      {
 
11721
        dofs[0] = 2;
 
11722
      dofs[1] = 3;
 
11723
        break;
 
11724
      }
 
11725
    case 2:
 
11726
      {
 
11727
        dofs[0] = 4;
 
11728
      dofs[1] = 5;
 
11729
        break;
 
11730
      }
 
11731
    }
 
11732
    
 
11733
  }
 
11734
 
 
11735
  /// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
11736
  virtual void tabulate_entity_dofs(std::size_t* dofs,
 
11737
                                    std::size_t d, std::size_t i) const
 
11738
  {
 
11739
    if (d > 2)
 
11740
    {
 
11741
    std::cerr << "*** FFC warning: " << "d is larger than dimension (2)" << std::endl;
 
11742
    }
 
11743
    
 
11744
    switch (d)
 
11745
    {
 
11746
    case 0:
 
11747
      {
 
11748
        
 
11749
        break;
 
11750
      }
 
11751
    case 1:
 
11752
      {
 
11753
        if (i > 2)
 
11754
      {
 
11755
      std::cerr << "*** FFC warning: " << "i is larger than number of entities (2)" << std::endl;
 
11756
      }
 
11757
      
 
11758
      switch (i)
 
11759
      {
 
11760
      case 0:
 
11761
        {
 
11762
          dofs[0] = 0;
 
11763
        dofs[1] = 1;
 
11764
          break;
 
11765
        }
 
11766
      case 1:
 
11767
        {
 
11768
          dofs[0] = 2;
 
11769
        dofs[1] = 3;
 
11770
          break;
 
11771
        }
 
11772
      case 2:
 
11773
        {
 
11774
          dofs[0] = 4;
 
11775
        dofs[1] = 5;
 
11776
          break;
 
11777
        }
 
11778
      }
 
11779
      
 
11780
        break;
 
11781
      }
 
11782
    case 2:
 
11783
      {
 
11784
        if (i > 0)
 
11785
      {
 
11786
      std::cerr << "*** FFC warning: " << "i is larger than number of entities (0)" << std::endl;
 
11787
      }
 
11788
      
 
11789
      dofs[0] = 6;
 
11790
      dofs[1] = 7;
 
11791
        break;
 
11792
      }
 
11793
    }
 
11794
    
 
11795
  }
 
11796
 
 
11797
  /// Tabulate the coordinates of all dofs on a cell
 
11798
  virtual void tabulate_coordinates(double** dof_coordinates,
 
11799
                                    const double* vertex_coordinates) const
 
11800
  {
 
11801
    dof_coordinates[0][0] = 0.66666667*vertex_coordinates[3] + 0.33333333*vertex_coordinates[6];
 
11802
    dof_coordinates[0][1] = 0.66666667*vertex_coordinates[4] + 0.33333333*vertex_coordinates[7];
 
11803
    dof_coordinates[0][2] = 0.66666667*vertex_coordinates[5] + 0.33333333*vertex_coordinates[8];
 
11804
    dof_coordinates[1][0] = 0.33333333*vertex_coordinates[3] + 0.66666667*vertex_coordinates[6];
 
11805
    dof_coordinates[1][1] = 0.33333333*vertex_coordinates[4] + 0.66666667*vertex_coordinates[7];
 
11806
    dof_coordinates[1][2] = 0.33333333*vertex_coordinates[5] + 0.66666667*vertex_coordinates[8];
 
11807
    dof_coordinates[2][0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[6];
 
11808
    dof_coordinates[2][1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[7];
 
11809
    dof_coordinates[2][2] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[8];
 
11810
    dof_coordinates[3][0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[6];
 
11811
    dof_coordinates[3][1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[7];
 
11812
    dof_coordinates[3][2] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[8];
 
11813
    dof_coordinates[4][0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[3];
 
11814
    dof_coordinates[4][1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[4];
 
11815
    dof_coordinates[4][2] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[5];
 
11816
    dof_coordinates[5][0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[3];
 
11817
    dof_coordinates[5][1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[4];
 
11818
    dof_coordinates[5][2] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[5];
 
11819
    dof_coordinates[6][0] = 0.33333333*vertex_coordinates[0] + 0.33333333*vertex_coordinates[3] + 0.33333333*vertex_coordinates[6];
 
11820
    dof_coordinates[6][1] = 0.33333333*vertex_coordinates[1] + 0.33333333*vertex_coordinates[4] + 0.33333333*vertex_coordinates[7];
 
11821
    dof_coordinates[6][2] = 0.33333333*vertex_coordinates[2] + 0.33333333*vertex_coordinates[5] + 0.33333333*vertex_coordinates[8];
 
11822
    dof_coordinates[7][0] = 0.33333333*vertex_coordinates[0] + 0.33333333*vertex_coordinates[3] + 0.33333333*vertex_coordinates[6];
 
11823
    dof_coordinates[7][1] = 0.33333333*vertex_coordinates[1] + 0.33333333*vertex_coordinates[4] + 0.33333333*vertex_coordinates[7];
 
11824
    dof_coordinates[7][2] = 0.33333333*vertex_coordinates[2] + 0.33333333*vertex_coordinates[5] + 0.33333333*vertex_coordinates[8];
 
11825
  }
 
11826
 
 
11827
  /// Return the number of sub dofmaps (for a mixed element)
 
11828
  virtual std::size_t num_sub_dofmaps() const
 
11829
  {
 
11830
    return 0;
 
11831
  }
 
11832
 
 
11833
  /// Create a new dofmap for sub dofmap i (for a mixed element)
 
11834
  virtual ufc::dofmap* create_sub_dofmap(std::size_t i) const
 
11835
  {
 
11836
    return 0;
 
11837
  }
 
11838
 
 
11839
  /// Create a new class instance
 
11840
  virtual ufc::dofmap* create() const
 
11841
  {
 
11842
    return new x_element9_dofmap_0();
 
11843
  }
 
11844
 
 
11845
};
 
11846
 
 
11847
/// This class defines the interface for a local-to-global mapping of
 
11848
/// degrees of freedom (dofs).
 
11849
 
 
11850
class x_element9_dofmap_1: public ufc::dofmap
 
11851
{
 
11852
public:
 
11853
 
 
11854
  /// Constructor
 
11855
  x_element9_dofmap_1() : ufc::dofmap()
 
11856
  {
 
11857
    // Do nothing
 
11858
  }
 
11859
 
 
11860
  /// Destructor
 
11861
  virtual ~x_element9_dofmap_1()
 
11862
  {
 
11863
    // Do nothing
 
11864
  }
 
11865
 
 
11866
  /// Return a string identifying the dofmap
 
11867
  virtual const char* signature() const
 
11868
  {
 
11869
    return "FFC dofmap for FiniteElement('Brezzi-Douglas-Marini', Domain(Cell('triangle', 3), 'triangle_multiverse', 3, 2), 1, None)";
 
11870
  }
 
11871
 
 
11872
  /// Return true iff mesh entities of topological dimension d are needed
 
11873
  virtual bool needs_mesh_entities(std::size_t d) const
 
11874
  {
 
11875
    switch (d)
 
11876
    {
 
11877
    case 0:
 
11878
      {
 
11879
        return false;
 
11880
        break;
 
11881
      }
 
11882
    case 1:
 
11883
      {
 
11884
        return true;
 
11885
        break;
 
11886
      }
 
11887
    case 2:
 
11888
      {
 
11889
        return false;
 
11890
        break;
 
11891
      }
 
11892
    }
 
11893
    
 
11894
    return false;
 
11895
  }
 
11896
 
 
11897
  /// Return the topological dimension of the associated cell shape
 
11898
  virtual std::size_t topological_dimension() const
 
11899
  {
 
11900
    return 2;
 
11901
  }
 
11902
 
 
11903
  /// Return the geometric dimension of the associated cell shape
 
11904
  virtual std::size_t geometric_dimension() const
 
11905
  {
 
11906
    return 3;
 
11907
  }
 
11908
 
 
11909
  /// Return the dimension of the global finite element function space
 
11910
  virtual std::size_t global_dimension(const std::vector<std::size_t>&
 
11911
                                       num_global_entities) const
 
11912
  {
 
11913
    return 2*num_global_entities[1];
 
11914
  }
 
11915
 
 
11916
  /// Return the dimension of the local finite element function space for a cell
 
11917
  virtual std::size_t local_dimension(const ufc::cell& c) const
 
11918
  {
 
11919
    return 6;
 
11920
  }
 
11921
 
 
11922
  /// Return the maximum dimension of the local finite element function space
 
11923
  virtual std::size_t max_local_dimension() const
 
11924
  {
 
11925
    return 6;
 
11926
  }
 
11927
 
 
11928
  /// Return the number of dofs on each cell facet
 
11929
  virtual std::size_t num_facet_dofs() const
 
11930
  {
 
11931
    return 2;
 
11932
  }
 
11933
 
 
11934
  /// Return the number of dofs associated with each cell entity of dimension d
 
11935
  virtual std::size_t num_entity_dofs(std::size_t d) const
 
11936
  {
 
11937
    switch (d)
 
11938
    {
 
11939
    case 0:
 
11940
      {
 
11941
        return 0;
 
11942
        break;
 
11943
      }
 
11944
    case 1:
 
11945
      {
 
11946
        return 2;
 
11947
        break;
 
11948
      }
 
11949
    case 2:
 
11950
      {
 
11951
        return 0;
 
11952
        break;
 
11953
      }
 
11954
    }
 
11955
    
 
11956
    return 0;
 
11957
  }
 
11958
 
 
11959
  /// Tabulate the local-to-global mapping of dofs on a cell
 
11960
  virtual void tabulate_dofs(std::size_t* dofs,
 
11961
                             const std::vector<std::size_t>& num_global_entities,
 
11962
                             const ufc::cell& c) const
 
11963
  {
 
11964
    dofs[0] = 2*c.entity_indices[1][0];
 
11965
    dofs[1] = 2*c.entity_indices[1][0] + 1;
 
11966
    dofs[2] = 2*c.entity_indices[1][1];
 
11967
    dofs[3] = 2*c.entity_indices[1][1] + 1;
 
11968
    dofs[4] = 2*c.entity_indices[1][2];
 
11969
    dofs[5] = 2*c.entity_indices[1][2] + 1;
 
11970
  }
 
11971
 
 
11972
  /// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
11973
  virtual void tabulate_facet_dofs(std::size_t* dofs,
 
11974
                                   std::size_t facet) const
 
11975
  {
 
11976
    switch (facet)
 
11977
    {
 
11978
    case 0:
 
11979
      {
 
11980
        dofs[0] = 0;
 
11981
      dofs[1] = 1;
 
11982
        break;
 
11983
      }
 
11984
    case 1:
 
11985
      {
 
11986
        dofs[0] = 2;
 
11987
      dofs[1] = 3;
 
11988
        break;
 
11989
      }
 
11990
    case 2:
 
11991
      {
 
11992
        dofs[0] = 4;
 
11993
      dofs[1] = 5;
 
11994
        break;
 
11995
      }
 
11996
    }
 
11997
    
 
11998
  }
 
11999
 
 
12000
  /// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
12001
  virtual void tabulate_entity_dofs(std::size_t* dofs,
 
12002
                                    std::size_t d, std::size_t i) const
 
12003
  {
 
12004
    if (d > 2)
 
12005
    {
 
12006
    std::cerr << "*** FFC warning: " << "d is larger than dimension (2)" << std::endl;
 
12007
    }
 
12008
    
 
12009
    switch (d)
 
12010
    {
 
12011
    case 0:
 
12012
      {
 
12013
        
 
12014
        break;
 
12015
      }
 
12016
    case 1:
 
12017
      {
 
12018
        if (i > 2)
 
12019
      {
 
12020
      std::cerr << "*** FFC warning: " << "i is larger than number of entities (2)" << std::endl;
 
12021
      }
 
12022
      
 
12023
      switch (i)
 
12024
      {
 
12025
      case 0:
 
12026
        {
 
12027
          dofs[0] = 0;
 
12028
        dofs[1] = 1;
 
12029
          break;
 
12030
        }
 
12031
      case 1:
 
12032
        {
 
12033
          dofs[0] = 2;
 
12034
        dofs[1] = 3;
 
12035
          break;
 
12036
        }
 
12037
      case 2:
 
12038
        {
 
12039
          dofs[0] = 4;
 
12040
        dofs[1] = 5;
 
12041
          break;
 
12042
        }
 
12043
      }
 
12044
      
 
12045
        break;
 
12046
      }
 
12047
    case 2:
 
12048
      {
 
12049
        
 
12050
        break;
 
12051
      }
 
12052
    }
 
12053
    
 
12054
  }
 
12055
 
 
12056
  /// Tabulate the coordinates of all dofs on a cell
 
12057
  virtual void tabulate_coordinates(double** dof_coordinates,
 
12058
                                    const double* vertex_coordinates) const
 
12059
  {
 
12060
    dof_coordinates[0][0] = 0.66666667*vertex_coordinates[3] + 0.33333333*vertex_coordinates[6];
 
12061
    dof_coordinates[0][1] = 0.66666667*vertex_coordinates[4] + 0.33333333*vertex_coordinates[7];
 
12062
    dof_coordinates[0][2] = 0.66666667*vertex_coordinates[5] + 0.33333333*vertex_coordinates[8];
 
12063
    dof_coordinates[1][0] = 0.33333333*vertex_coordinates[3] + 0.66666667*vertex_coordinates[6];
 
12064
    dof_coordinates[1][1] = 0.33333333*vertex_coordinates[4] + 0.66666667*vertex_coordinates[7];
 
12065
    dof_coordinates[1][2] = 0.33333333*vertex_coordinates[5] + 0.66666667*vertex_coordinates[8];
 
12066
    dof_coordinates[2][0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[6];
 
12067
    dof_coordinates[2][1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[7];
 
12068
    dof_coordinates[2][2] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[8];
 
12069
    dof_coordinates[3][0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[6];
 
12070
    dof_coordinates[3][1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[7];
 
12071
    dof_coordinates[3][2] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[8];
 
12072
    dof_coordinates[4][0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[3];
 
12073
    dof_coordinates[4][1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[4];
 
12074
    dof_coordinates[4][2] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[5];
 
12075
    dof_coordinates[5][0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[3];
 
12076
    dof_coordinates[5][1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[4];
 
12077
    dof_coordinates[5][2] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[5];
 
12078
  }
 
12079
 
 
12080
  /// Return the number of sub dofmaps (for a mixed element)
 
12081
  virtual std::size_t num_sub_dofmaps() const
 
12082
  {
 
12083
    return 0;
 
12084
  }
 
12085
 
 
12086
  /// Create a new dofmap for sub dofmap i (for a mixed element)
 
12087
  virtual ufc::dofmap* create_sub_dofmap(std::size_t i) const
 
12088
  {
 
12089
    return 0;
 
12090
  }
 
12091
 
 
12092
  /// Create a new class instance
 
12093
  virtual ufc::dofmap* create() const
 
12094
  {
 
12095
    return new x_element9_dofmap_1();
 
12096
  }
 
12097
 
 
12098
};
 
12099
 
 
12100
/// This class defines the interface for a local-to-global mapping of
 
12101
/// degrees of freedom (dofs).
 
12102
 
 
12103
class x_element9_dofmap_2: public ufc::dofmap
 
12104
{
 
12105
public:
 
12106
 
 
12107
  /// Constructor
 
12108
  x_element9_dofmap_2() : ufc::dofmap()
 
12109
  {
 
12110
    // Do nothing
 
12111
  }
 
12112
 
 
12113
  /// Destructor
 
12114
  virtual ~x_element9_dofmap_2()
 
12115
  {
 
12116
    // Do nothing
 
12117
  }
 
12118
 
 
12119
  /// Return a string identifying the dofmap
 
12120
  virtual const char* signature() const
 
12121
  {
 
12122
    return "FFC dofmap for FiniteElement('Nedelec 1st kind H(curl)', Domain(Cell('triangle', 3), 'triangle_multiverse', 3, 2), 1, None)";
 
12123
  }
 
12124
 
 
12125
  /// Return true iff mesh entities of topological dimension d are needed
 
12126
  virtual bool needs_mesh_entities(std::size_t d) const
 
12127
  {
 
12128
    switch (d)
 
12129
    {
 
12130
    case 0:
 
12131
      {
 
12132
        return false;
 
12133
        break;
 
12134
      }
 
12135
    case 1:
 
12136
      {
 
12137
        return true;
 
12138
        break;
 
12139
      }
 
12140
    case 2:
 
12141
      {
 
12142
        return false;
 
12143
        break;
 
12144
      }
 
12145
    }
 
12146
    
 
12147
    return false;
 
12148
  }
 
12149
 
 
12150
  /// Return the topological dimension of the associated cell shape
 
12151
  virtual std::size_t topological_dimension() const
 
12152
  {
 
12153
    return 2;
 
12154
  }
 
12155
 
 
12156
  /// Return the geometric dimension of the associated cell shape
 
12157
  virtual std::size_t geometric_dimension() const
 
12158
  {
 
12159
    return 3;
 
12160
  }
 
12161
 
 
12162
  /// Return the dimension of the global finite element function space
 
12163
  virtual std::size_t global_dimension(const std::vector<std::size_t>&
 
12164
                                       num_global_entities) const
 
12165
  {
 
12166
    return num_global_entities[1];
 
12167
  }
 
12168
 
 
12169
  /// Return the dimension of the local finite element function space for a cell
 
12170
  virtual std::size_t local_dimension(const ufc::cell& c) const
 
12171
  {
 
12172
    return 3;
 
12173
  }
 
12174
 
 
12175
  /// Return the maximum dimension of the local finite element function space
 
12176
  virtual std::size_t max_local_dimension() const
 
12177
  {
 
12178
    return 3;
 
12179
  }
 
12180
 
 
12181
  /// Return the number of dofs on each cell facet
 
12182
  virtual std::size_t num_facet_dofs() const
 
12183
  {
 
12184
    return 1;
 
12185
  }
 
12186
 
 
12187
  /// Return the number of dofs associated with each cell entity of dimension d
 
12188
  virtual std::size_t num_entity_dofs(std::size_t d) const
 
12189
  {
 
12190
    switch (d)
 
12191
    {
 
12192
    case 0:
 
12193
      {
 
12194
        return 0;
 
12195
        break;
 
12196
      }
 
12197
    case 1:
 
12198
      {
 
12199
        return 1;
 
12200
        break;
 
12201
      }
 
12202
    case 2:
 
12203
      {
 
12204
        return 0;
 
12205
        break;
 
12206
      }
 
12207
    }
 
12208
    
 
12209
    return 0;
 
12210
  }
 
12211
 
 
12212
  /// Tabulate the local-to-global mapping of dofs on a cell
 
12213
  virtual void tabulate_dofs(std::size_t* dofs,
 
12214
                             const std::vector<std::size_t>& num_global_entities,
 
12215
                             const ufc::cell& c) const
 
12216
  {
 
12217
    dofs[0] = c.entity_indices[1][0];
 
12218
    dofs[1] = c.entity_indices[1][1];
 
12219
    dofs[2] = c.entity_indices[1][2];
 
12220
  }
 
12221
 
 
12222
  /// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
12223
  virtual void tabulate_facet_dofs(std::size_t* dofs,
 
12224
                                   std::size_t facet) const
 
12225
  {
 
12226
    switch (facet)
 
12227
    {
 
12228
    case 0:
 
12229
      {
 
12230
        dofs[0] = 0;
 
12231
        break;
 
12232
      }
 
12233
    case 1:
 
12234
      {
 
12235
        dofs[0] = 1;
 
12236
        break;
 
12237
      }
 
12238
    case 2:
 
12239
      {
 
12240
        dofs[0] = 2;
 
12241
        break;
 
12242
      }
 
12243
    }
 
12244
    
 
12245
  }
 
12246
 
 
12247
  /// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
12248
  virtual void tabulate_entity_dofs(std::size_t* dofs,
 
12249
                                    std::size_t d, std::size_t i) const
 
12250
  {
 
12251
    if (d > 2)
 
12252
    {
 
12253
    std::cerr << "*** FFC warning: " << "d is larger than dimension (2)" << std::endl;
 
12254
    }
 
12255
    
 
12256
    switch (d)
 
12257
    {
 
12258
    case 0:
 
12259
      {
 
12260
        
 
12261
        break;
 
12262
      }
 
12263
    case 1:
 
12264
      {
 
12265
        if (i > 2)
 
12266
      {
 
12267
      std::cerr << "*** FFC warning: " << "i is larger than number of entities (2)" << std::endl;
 
12268
      }
 
12269
      
 
12270
      switch (i)
 
12271
      {
 
12272
      case 0:
 
12273
        {
 
12274
          dofs[0] = 0;
 
12275
          break;
 
12276
        }
 
12277
      case 1:
 
12278
        {
 
12279
          dofs[0] = 1;
 
12280
          break;
 
12281
        }
 
12282
      case 2:
 
12283
        {
 
12284
          dofs[0] = 2;
 
12285
          break;
 
12286
        }
 
12287
      }
 
12288
      
 
12289
        break;
 
12290
      }
 
12291
    case 2:
 
12292
      {
 
12293
        
 
12294
        break;
 
12295
      }
 
12296
    }
 
12297
    
 
12298
  }
 
12299
 
 
12300
  /// Tabulate the coordinates of all dofs on a cell
 
12301
  virtual void tabulate_coordinates(double** dof_coordinates,
 
12302
                                    const double* vertex_coordinates) const
 
12303
  {
 
12304
    dof_coordinates[0][0] = 0.5*vertex_coordinates[3] + 0.5*vertex_coordinates[6];
 
12305
    dof_coordinates[0][1] = 0.5*vertex_coordinates[4] + 0.5*vertex_coordinates[7];
 
12306
    dof_coordinates[0][2] = 0.5*vertex_coordinates[5] + 0.5*vertex_coordinates[8];
 
12307
    dof_coordinates[1][0] = 0.5*vertex_coordinates[0] + 0.5*vertex_coordinates[6];
 
12308
    dof_coordinates[1][1] = 0.5*vertex_coordinates[1] + 0.5*vertex_coordinates[7];
 
12309
    dof_coordinates[1][2] = 0.5*vertex_coordinates[2] + 0.5*vertex_coordinates[8];
 
12310
    dof_coordinates[2][0] = 0.5*vertex_coordinates[0] + 0.5*vertex_coordinates[3];
 
12311
    dof_coordinates[2][1] = 0.5*vertex_coordinates[1] + 0.5*vertex_coordinates[4];
 
12312
    dof_coordinates[2][2] = 0.5*vertex_coordinates[2] + 0.5*vertex_coordinates[5];
 
12313
  }
 
12314
 
 
12315
  /// Return the number of sub dofmaps (for a mixed element)
 
12316
  virtual std::size_t num_sub_dofmaps() const
 
12317
  {
 
12318
    return 0;
 
12319
  }
 
12320
 
 
12321
  /// Create a new dofmap for sub dofmap i (for a mixed element)
 
12322
  virtual ufc::dofmap* create_sub_dofmap(std::size_t i) const
 
12323
  {
 
12324
    return 0;
 
12325
  }
 
12326
 
 
12327
  /// Create a new class instance
 
12328
  virtual ufc::dofmap* create() const
 
12329
  {
 
12330
    return new x_element9_dofmap_2();
 
12331
  }
 
12332
 
 
12333
};
 
12334
 
 
12335
/// This class defines the interface for a local-to-global mapping of
 
12336
/// degrees of freedom (dofs).
 
12337
 
 
12338
class x_element9_dofmap_3: public ufc::dofmap
 
12339
{
 
12340
public:
 
12341
 
 
12342
  /// Constructor
 
12343
  x_element9_dofmap_3() : ufc::dofmap()
 
12344
  {
 
12345
    // Do nothing
 
12346
  }
 
12347
 
 
12348
  /// Destructor
 
12349
  virtual ~x_element9_dofmap_3()
 
12350
  {
 
12351
    // Do nothing
 
12352
  }
 
12353
 
 
12354
  /// Return a string identifying the dofmap
 
12355
  virtual const char* signature() const
 
12356
  {
 
12357
    return "FFC dofmap for FiniteElement('Discontinuous Lagrange', Domain(Cell('triangle', 3), 'triangle_multiverse', 3, 2), 1, None)";
 
12358
  }
 
12359
 
 
12360
  /// Return true iff mesh entities of topological dimension d are needed
 
12361
  virtual bool needs_mesh_entities(std::size_t d) const
 
12362
  {
 
12363
    switch (d)
 
12364
    {
 
12365
    case 0:
 
12366
      {
 
12367
        return false;
 
12368
        break;
 
12369
      }
 
12370
    case 1:
 
12371
      {
 
12372
        return false;
 
12373
        break;
 
12374
      }
 
12375
    case 2:
 
12376
      {
 
12377
        return true;
 
12378
        break;
 
12379
      }
 
12380
    }
 
12381
    
 
12382
    return false;
 
12383
  }
 
12384
 
 
12385
  /// Return the topological dimension of the associated cell shape
 
12386
  virtual std::size_t topological_dimension() const
 
12387
  {
 
12388
    return 2;
 
12389
  }
 
12390
 
 
12391
  /// Return the geometric dimension of the associated cell shape
 
12392
  virtual std::size_t geometric_dimension() const
 
12393
  {
 
12394
    return 3;
 
12395
  }
 
12396
 
 
12397
  /// Return the dimension of the global finite element function space
 
12398
  virtual std::size_t global_dimension(const std::vector<std::size_t>&
 
12399
                                       num_global_entities) const
 
12400
  {
 
12401
    return 3*num_global_entities[2];
 
12402
  }
 
12403
 
 
12404
  /// Return the dimension of the local finite element function space for a cell
 
12405
  virtual std::size_t local_dimension(const ufc::cell& c) const
 
12406
  {
 
12407
    return 3;
 
12408
  }
 
12409
 
 
12410
  /// Return the maximum dimension of the local finite element function space
 
12411
  virtual std::size_t max_local_dimension() const
 
12412
  {
 
12413
    return 3;
 
12414
  }
 
12415
 
 
12416
  /// Return the number of dofs on each cell facet
 
12417
  virtual std::size_t num_facet_dofs() const
 
12418
  {
 
12419
    return 0;
 
12420
  }
 
12421
 
 
12422
  /// Return the number of dofs associated with each cell entity of dimension d
 
12423
  virtual std::size_t num_entity_dofs(std::size_t d) const
 
12424
  {
 
12425
    switch (d)
 
12426
    {
 
12427
    case 0:
 
12428
      {
 
12429
        return 0;
 
12430
        break;
 
12431
      }
 
12432
    case 1:
 
12433
      {
 
12434
        return 0;
 
12435
        break;
 
12436
      }
 
12437
    case 2:
 
12438
      {
 
12439
        return 3;
 
12440
        break;
 
12441
      }
 
12442
    }
 
12443
    
 
12444
    return 0;
 
12445
  }
 
12446
 
 
12447
  /// Tabulate the local-to-global mapping of dofs on a cell
 
12448
  virtual void tabulate_dofs(std::size_t* dofs,
 
12449
                             const std::vector<std::size_t>& num_global_entities,
 
12450
                             const ufc::cell& c) const
 
12451
  {
 
12452
    dofs[0] = 3*c.entity_indices[2][0];
 
12453
    dofs[1] = 3*c.entity_indices[2][0] + 1;
 
12454
    dofs[2] = 3*c.entity_indices[2][0] + 2;
 
12455
  }
 
12456
 
 
12457
  /// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
12458
  virtual void tabulate_facet_dofs(std::size_t* dofs,
 
12459
                                   std::size_t facet) const
 
12460
  {
 
12461
    switch (facet)
 
12462
    {
 
12463
    case 0:
 
12464
      {
 
12465
        
 
12466
        break;
 
12467
      }
 
12468
    case 1:
 
12469
      {
 
12470
        
 
12471
        break;
 
12472
      }
 
12473
    case 2:
 
12474
      {
 
12475
        
 
12476
        break;
 
12477
      }
 
12478
    }
 
12479
    
 
12480
  }
 
12481
 
 
12482
  /// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
12483
  virtual void tabulate_entity_dofs(std::size_t* dofs,
 
12484
                                    std::size_t d, std::size_t i) const
 
12485
  {
 
12486
    if (d > 2)
 
12487
    {
 
12488
    std::cerr << "*** FFC warning: " << "d is larger than dimension (2)" << std::endl;
 
12489
    }
 
12490
    
 
12491
    switch (d)
 
12492
    {
 
12493
    case 0:
 
12494
      {
 
12495
        
 
12496
        break;
 
12497
      }
 
12498
    case 1:
 
12499
      {
 
12500
        
 
12501
        break;
 
12502
      }
 
12503
    case 2:
 
12504
      {
 
12505
        if (i > 0)
 
12506
      {
 
12507
      std::cerr << "*** FFC warning: " << "i is larger than number of entities (0)" << std::endl;
 
12508
      }
 
12509
      
 
12510
      dofs[0] = 0;
 
12511
      dofs[1] = 1;
 
12512
      dofs[2] = 2;
 
12513
        break;
 
12514
      }
 
12515
    }
 
12516
    
 
12517
  }
 
12518
 
 
12519
  /// Tabulate the coordinates of all dofs on a cell
 
12520
  virtual void tabulate_coordinates(double** dof_coordinates,
 
12521
                                    const double* vertex_coordinates) const
 
12522
  {
 
12523
    dof_coordinates[0][0] = vertex_coordinates[0];
 
12524
    dof_coordinates[0][1] = vertex_coordinates[1];
 
12525
    dof_coordinates[0][2] = vertex_coordinates[2];
 
12526
    dof_coordinates[1][0] = vertex_coordinates[3];
 
12527
    dof_coordinates[1][1] = vertex_coordinates[4];
 
12528
    dof_coordinates[1][2] = vertex_coordinates[5];
 
12529
    dof_coordinates[2][0] = vertex_coordinates[6];
 
12530
    dof_coordinates[2][1] = vertex_coordinates[7];
 
12531
    dof_coordinates[2][2] = vertex_coordinates[8];
 
12532
  }
 
12533
 
 
12534
  /// Return the number of sub dofmaps (for a mixed element)
 
12535
  virtual std::size_t num_sub_dofmaps() const
 
12536
  {
 
12537
    return 0;
 
12538
  }
 
12539
 
 
12540
  /// Create a new dofmap for sub dofmap i (for a mixed element)
 
12541
  virtual ufc::dofmap* create_sub_dofmap(std::size_t i) const
 
12542
  {
 
12543
    return 0;
 
12544
  }
 
12545
 
 
12546
  /// Create a new class instance
 
12547
  virtual ufc::dofmap* create() const
 
12548
  {
 
12549
    return new x_element9_dofmap_3();
 
12550
  }
 
12551
 
 
12552
};
 
12553
 
 
12554
/// This class defines the interface for a local-to-global mapping of
 
12555
/// degrees of freedom (dofs).
 
12556
 
 
12557
class x_element9_dofmap_4: public ufc::dofmap
 
12558
{
 
12559
public:
 
12560
 
 
12561
  /// Constructor
 
12562
  x_element9_dofmap_4() : ufc::dofmap()
 
12563
  {
 
12564
    // Do nothing
 
12565
  }
 
12566
 
 
12567
  /// Destructor
 
12568
  virtual ~x_element9_dofmap_4()
 
12569
  {
 
12570
    // Do nothing
 
12571
  }
 
12572
 
 
12573
  /// Return a string identifying the dofmap
 
12574
  virtual const char* signature() const
 
12575
  {
 
12576
    return "FFC dofmap for MixedElement(*[FiniteElement('Raviart-Thomas', Domain(Cell('triangle', 3), 'triangle_multiverse', 3, 2), 2, None), FiniteElement('Brezzi-Douglas-Marini', Domain(Cell('triangle', 3), 'triangle_multiverse', 3, 2), 1, None), FiniteElement('Nedelec 1st kind H(curl)', Domain(Cell('triangle', 3), 'triangle_multiverse', 3, 2), 1, None), FiniteElement('Discontinuous Lagrange', Domain(Cell('triangle', 3), 'triangle_multiverse', 3, 2), 1, None)], **{'value_shape': (10,) })";
 
12577
  }
 
12578
 
 
12579
  /// Return true iff mesh entities of topological dimension d are needed
 
12580
  virtual bool needs_mesh_entities(std::size_t d) const
 
12581
  {
 
12582
    switch (d)
 
12583
    {
 
12584
    case 0:
 
12585
      {
 
12586
        return false;
 
12587
        break;
 
12588
      }
 
12589
    case 1:
 
12590
      {
 
12591
        return true;
 
12592
        break;
 
12593
      }
 
12594
    case 2:
 
12595
      {
 
12596
        return true;
 
12597
        break;
 
12598
      }
 
12599
    }
 
12600
    
 
12601
    return false;
 
12602
  }
 
12603
 
 
12604
  /// Return the topological dimension of the associated cell shape
 
12605
  virtual std::size_t topological_dimension() const
 
12606
  {
 
12607
    return 2;
 
12608
  }
 
12609
 
 
12610
  /// Return the geometric dimension of the associated cell shape
 
12611
  virtual std::size_t geometric_dimension() const
 
12612
  {
 
12613
    return 3;
 
12614
  }
 
12615
 
 
12616
  /// Return the dimension of the global finite element function space
 
12617
  virtual std::size_t global_dimension(const std::vector<std::size_t>&
 
12618
                                       num_global_entities) const
 
12619
  {
 
12620
    return 5*num_global_entities[1] + 5*num_global_entities[2];
 
12621
  }
 
12622
 
 
12623
  /// Return the dimension of the local finite element function space for a cell
 
12624
  virtual std::size_t local_dimension(const ufc::cell& c) const
 
12625
  {
 
12626
    return 20;
 
12627
  }
 
12628
 
 
12629
  /// Return the maximum dimension of the local finite element function space
 
12630
  virtual std::size_t max_local_dimension() const
 
12631
  {
 
12632
    return 20;
 
12633
  }
 
12634
 
 
12635
  /// Return the number of dofs on each cell facet
 
12636
  virtual std::size_t num_facet_dofs() const
 
12637
  {
 
12638
    return 5;
 
12639
  }
 
12640
 
 
12641
  /// Return the number of dofs associated with each cell entity of dimension d
 
12642
  virtual std::size_t num_entity_dofs(std::size_t d) const
 
12643
  {
 
12644
    switch (d)
 
12645
    {
 
12646
    case 0:
 
12647
      {
 
12648
        return 0;
 
12649
        break;
 
12650
      }
 
12651
    case 1:
 
12652
      {
 
12653
        return 5;
 
12654
        break;
 
12655
      }
 
12656
    case 2:
 
12657
      {
 
12658
        return 5;
 
12659
        break;
 
12660
      }
 
12661
    }
 
12662
    
 
12663
    return 0;
 
12664
  }
 
12665
 
 
12666
  /// Tabulate the local-to-global mapping of dofs on a cell
 
12667
  virtual void tabulate_dofs(std::size_t* dofs,
 
12668
                             const std::vector<std::size_t>& num_global_entities,
 
12669
                             const ufc::cell& c) const
 
12670
  {
 
12671
    unsigned int offset = 0;
 
12672
    dofs[0] = offset + 2*c.entity_indices[1][0];
 
12673
    dofs[1] = offset + 2*c.entity_indices[1][0] + 1;
 
12674
    dofs[2] = offset + 2*c.entity_indices[1][1];
 
12675
    dofs[3] = offset + 2*c.entity_indices[1][1] + 1;
 
12676
    dofs[4] = offset + 2*c.entity_indices[1][2];
 
12677
    dofs[5] = offset + 2*c.entity_indices[1][2] + 1;
 
12678
    offset += 2*num_global_entities[1];
 
12679
    dofs[6] = offset + 2*c.entity_indices[2][0];
 
12680
    dofs[7] = offset + 2*c.entity_indices[2][0] + 1;
 
12681
    offset += 2*num_global_entities[2];
 
12682
    dofs[8] = offset + 2*c.entity_indices[1][0];
 
12683
    dofs[9] = offset + 2*c.entity_indices[1][0] + 1;
 
12684
    dofs[10] = offset + 2*c.entity_indices[1][1];
 
12685
    dofs[11] = offset + 2*c.entity_indices[1][1] + 1;
 
12686
    dofs[12] = offset + 2*c.entity_indices[1][2];
 
12687
    dofs[13] = offset + 2*c.entity_indices[1][2] + 1;
 
12688
    offset += 2*num_global_entities[1];
 
12689
    dofs[14] = offset + c.entity_indices[1][0];
 
12690
    dofs[15] = offset + c.entity_indices[1][1];
 
12691
    dofs[16] = offset + c.entity_indices[1][2];
 
12692
    offset += num_global_entities[1];
 
12693
    dofs[17] = offset + 3*c.entity_indices[2][0];
 
12694
    dofs[18] = offset + 3*c.entity_indices[2][0] + 1;
 
12695
    dofs[19] = offset + 3*c.entity_indices[2][0] + 2;
 
12696
    offset += 3*num_global_entities[2];
 
12697
  }
 
12698
 
 
12699
  /// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
12700
  virtual void tabulate_facet_dofs(std::size_t* dofs,
 
12701
                                   std::size_t facet) const
 
12702
  {
 
12703
    switch (facet)
 
12704
    {
 
12705
    case 0:
 
12706
      {
 
12707
        dofs[0] = 0;
 
12708
      dofs[1] = 1;
 
12709
      dofs[2] = 8;
 
12710
      dofs[3] = 9;
 
12711
      dofs[4] = 14;
 
12712
        break;
 
12713
      }
 
12714
    case 1:
 
12715
      {
 
12716
        dofs[0] = 2;
 
12717
      dofs[1] = 3;
 
12718
      dofs[2] = 10;
 
12719
      dofs[3] = 11;
 
12720
      dofs[4] = 15;
 
12721
        break;
 
12722
      }
 
12723
    case 2:
 
12724
      {
 
12725
        dofs[0] = 4;
 
12726
      dofs[1] = 5;
 
12727
      dofs[2] = 12;
 
12728
      dofs[3] = 13;
 
12729
      dofs[4] = 16;
 
12730
        break;
 
12731
      }
 
12732
    }
 
12733
    
 
12734
  }
 
12735
 
 
12736
  /// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
12737
  virtual void tabulate_entity_dofs(std::size_t* dofs,
 
12738
                                    std::size_t d, std::size_t i) const
 
12739
  {
 
12740
    if (d > 2)
 
12741
    {
 
12742
    std::cerr << "*** FFC warning: " << "d is larger than dimension (2)" << std::endl;
 
12743
    }
 
12744
    
 
12745
    switch (d)
 
12746
    {
 
12747
    case 0:
 
12748
      {
 
12749
        
 
12750
        break;
 
12751
      }
 
12752
    case 1:
 
12753
      {
 
12754
        if (i > 2)
 
12755
      {
 
12756
      std::cerr << "*** FFC warning: " << "i is larger than number of entities (2)" << std::endl;
 
12757
      }
 
12758
      
 
12759
      switch (i)
 
12760
      {
 
12761
      case 0:
 
12762
        {
 
12763
          dofs[0] = 0;
 
12764
        dofs[1] = 1;
 
12765
        dofs[2] = 8;
 
12766
        dofs[3] = 9;
 
12767
        dofs[4] = 14;
 
12768
          break;
 
12769
        }
 
12770
      case 1:
 
12771
        {
 
12772
          dofs[0] = 2;
 
12773
        dofs[1] = 3;
 
12774
        dofs[2] = 10;
 
12775
        dofs[3] = 11;
 
12776
        dofs[4] = 15;
 
12777
          break;
 
12778
        }
 
12779
      case 2:
 
12780
        {
 
12781
          dofs[0] = 4;
 
12782
        dofs[1] = 5;
 
12783
        dofs[2] = 12;
 
12784
        dofs[3] = 13;
 
12785
        dofs[4] = 16;
 
12786
          break;
 
12787
        }
 
12788
      }
 
12789
      
 
12790
        break;
 
12791
      }
 
12792
    case 2:
 
12793
      {
 
12794
        if (i > 0)
 
12795
      {
 
12796
      std::cerr << "*** FFC warning: " << "i is larger than number of entities (0)" << std::endl;
 
12797
      }
 
12798
      
 
12799
      dofs[0] = 6;
 
12800
      dofs[1] = 7;
 
12801
      dofs[2] = 17;
 
12802
      dofs[3] = 18;
 
12803
      dofs[4] = 19;
 
12804
        break;
 
12805
      }
 
12806
    }
 
12807
    
 
12808
  }
 
12809
 
 
12810
  /// Tabulate the coordinates of all dofs on a cell
 
12811
  virtual void tabulate_coordinates(double** dof_coordinates,
 
12812
                                    const double* vertex_coordinates) const
 
12813
  {
 
12814
    dof_coordinates[0][0] = 0.66666667*vertex_coordinates[3] + 0.33333333*vertex_coordinates[6];
 
12815
    dof_coordinates[0][1] = 0.66666667*vertex_coordinates[4] + 0.33333333*vertex_coordinates[7];
 
12816
    dof_coordinates[0][2] = 0.66666667*vertex_coordinates[5] + 0.33333333*vertex_coordinates[8];
 
12817
    dof_coordinates[1][0] = 0.33333333*vertex_coordinates[3] + 0.66666667*vertex_coordinates[6];
 
12818
    dof_coordinates[1][1] = 0.33333333*vertex_coordinates[4] + 0.66666667*vertex_coordinates[7];
 
12819
    dof_coordinates[1][2] = 0.33333333*vertex_coordinates[5] + 0.66666667*vertex_coordinates[8];
 
12820
    dof_coordinates[2][0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[6];
 
12821
    dof_coordinates[2][1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[7];
 
12822
    dof_coordinates[2][2] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[8];
 
12823
    dof_coordinates[3][0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[6];
 
12824
    dof_coordinates[3][1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[7];
 
12825
    dof_coordinates[3][2] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[8];
 
12826
    dof_coordinates[4][0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[3];
 
12827
    dof_coordinates[4][1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[4];
 
12828
    dof_coordinates[4][2] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[5];
 
12829
    dof_coordinates[5][0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[3];
 
12830
    dof_coordinates[5][1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[4];
 
12831
    dof_coordinates[5][2] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[5];
 
12832
    dof_coordinates[6][0] = 0.33333333*vertex_coordinates[0] + 0.33333333*vertex_coordinates[3] + 0.33333333*vertex_coordinates[6];
 
12833
    dof_coordinates[6][1] = 0.33333333*vertex_coordinates[1] + 0.33333333*vertex_coordinates[4] + 0.33333333*vertex_coordinates[7];
 
12834
    dof_coordinates[6][2] = 0.33333333*vertex_coordinates[2] + 0.33333333*vertex_coordinates[5] + 0.33333333*vertex_coordinates[8];
 
12835
    dof_coordinates[7][0] = 0.33333333*vertex_coordinates[0] + 0.33333333*vertex_coordinates[3] + 0.33333333*vertex_coordinates[6];
 
12836
    dof_coordinates[7][1] = 0.33333333*vertex_coordinates[1] + 0.33333333*vertex_coordinates[4] + 0.33333333*vertex_coordinates[7];
 
12837
    dof_coordinates[7][2] = 0.33333333*vertex_coordinates[2] + 0.33333333*vertex_coordinates[5] + 0.33333333*vertex_coordinates[8];
 
12838
    dof_coordinates[8][0] = 0.66666667*vertex_coordinates[3] + 0.33333333*vertex_coordinates[6];
 
12839
    dof_coordinates[8][1] = 0.66666667*vertex_coordinates[4] + 0.33333333*vertex_coordinates[7];
 
12840
    dof_coordinates[8][2] = 0.66666667*vertex_coordinates[5] + 0.33333333*vertex_coordinates[8];
 
12841
    dof_coordinates[9][0] = 0.33333333*vertex_coordinates[3] + 0.66666667*vertex_coordinates[6];
 
12842
    dof_coordinates[9][1] = 0.33333333*vertex_coordinates[4] + 0.66666667*vertex_coordinates[7];
 
12843
    dof_coordinates[9][2] = 0.33333333*vertex_coordinates[5] + 0.66666667*vertex_coordinates[8];
 
12844
    dof_coordinates[10][0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[6];
 
12845
    dof_coordinates[10][1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[7];
 
12846
    dof_coordinates[10][2] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[8];
 
12847
    dof_coordinates[11][0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[6];
 
12848
    dof_coordinates[11][1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[7];
 
12849
    dof_coordinates[11][2] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[8];
 
12850
    dof_coordinates[12][0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[3];
 
12851
    dof_coordinates[12][1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[4];
 
12852
    dof_coordinates[12][2] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[5];
 
12853
    dof_coordinates[13][0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[3];
 
12854
    dof_coordinates[13][1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[4];
 
12855
    dof_coordinates[13][2] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[5];
 
12856
    dof_coordinates[14][0] = 0.5*vertex_coordinates[3] + 0.5*vertex_coordinates[6];
 
12857
    dof_coordinates[14][1] = 0.5*vertex_coordinates[4] + 0.5*vertex_coordinates[7];
 
12858
    dof_coordinates[14][2] = 0.5*vertex_coordinates[5] + 0.5*vertex_coordinates[8];
 
12859
    dof_coordinates[15][0] = 0.5*vertex_coordinates[0] + 0.5*vertex_coordinates[6];
 
12860
    dof_coordinates[15][1] = 0.5*vertex_coordinates[1] + 0.5*vertex_coordinates[7];
 
12861
    dof_coordinates[15][2] = 0.5*vertex_coordinates[2] + 0.5*vertex_coordinates[8];
 
12862
    dof_coordinates[16][0] = 0.5*vertex_coordinates[0] + 0.5*vertex_coordinates[3];
 
12863
    dof_coordinates[16][1] = 0.5*vertex_coordinates[1] + 0.5*vertex_coordinates[4];
 
12864
    dof_coordinates[16][2] = 0.5*vertex_coordinates[2] + 0.5*vertex_coordinates[5];
 
12865
    dof_coordinates[17][0] = vertex_coordinates[0];
 
12866
    dof_coordinates[17][1] = vertex_coordinates[1];
 
12867
    dof_coordinates[17][2] = vertex_coordinates[2];
 
12868
    dof_coordinates[18][0] = vertex_coordinates[3];
 
12869
    dof_coordinates[18][1] = vertex_coordinates[4];
 
12870
    dof_coordinates[18][2] = vertex_coordinates[5];
 
12871
    dof_coordinates[19][0] = vertex_coordinates[6];
 
12872
    dof_coordinates[19][1] = vertex_coordinates[7];
 
12873
    dof_coordinates[19][2] = vertex_coordinates[8];
 
12874
  }
 
12875
 
 
12876
  /// Return the number of sub dofmaps (for a mixed element)
 
12877
  virtual std::size_t num_sub_dofmaps() const
 
12878
  {
 
12879
    return 4;
 
12880
  }
 
12881
 
 
12882
  /// Create a new dofmap for sub dofmap i (for a mixed element)
 
12883
  virtual ufc::dofmap* create_sub_dofmap(std::size_t i) const
 
12884
  {
 
12885
    switch (i)
 
12886
    {
 
12887
    case 0:
 
12888
      {
 
12889
        return new x_element9_dofmap_0();
 
12890
        break;
 
12891
      }
 
12892
    case 1:
 
12893
      {
 
12894
        return new x_element9_dofmap_1();
 
12895
        break;
 
12896
      }
 
12897
    case 2:
 
12898
      {
 
12899
        return new x_element9_dofmap_2();
 
12900
        break;
 
12901
      }
 
12902
    case 3:
 
12903
      {
 
12904
        return new x_element9_dofmap_3();
 
12905
        break;
 
12906
      }
 
12907
    }
 
12908
    
 
12909
    return 0;
 
12910
  }
 
12911
 
 
12912
  /// Create a new class instance
 
12913
  virtual ufc::dofmap* create() const
 
12914
  {
 
12915
    return new x_element9_dofmap_4();
 
12916
  }
 
12917
 
 
12918
};
 
12919
 
 
12920
#endif