~johan-hake/dolfin/general-rk-solver

« back to all changes in this revision

Viewing changes to bench/fem/multicore/cpp/NavierStokes.h

  • Committer: Johan Hake
  • Date: 2013-03-27 15:18:08 UTC
  • mfrom: (7352.1.227 working)
  • Revision ID: hake.dev@gmail.com-20130327151808-b73d4pueq1n432hg
Merge with trunk

Show diffs side-by-side

added added

removed removed

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