~chaffra/ffc/main-old

1675.1.99 by Martin Sandve Alnaes
Update references with 2.1.0+ version of ufc.
1
// This code conforms with the UFC specification version 2.1.0+
1675.1.97 by Anders Logg
Updated references for new version number
2
// and was automatically generated by FFC version 1.1.0+.
1672.1.3 by Marie E. Rognes
Update references.
3
// 
4
// This code was generated with the following parameters:
5
// 
6
//   cache_dir:                      ''
7
//   convert_exceptions_to_warnings: True
8
//   cpp_optimize:                   False
9
//   cpp_optimize_flags:             '-O2'
10
//   epsilon:                        1e-14
11
//   error_control:                  False
12
//   form_postfix:                   True
13
//   format:                         'ufc'
14
//   log_level:                      20
15
//   log_prefix:                     ''
16
//   optimize:                       False
17
//   output_dir:                     '.'
18
//   precision:                      '8'
19
//   quadrature_degree:              'auto'
20
//   quadrature_rule:                'auto'
21
//   representation:                 'quadrature'
22
//   split:                          False
23
//   swig_binary:                    'swig'
24
//   swig_path:                      ''
25
26
#ifndef __HEAT_H
27
#define __HEAT_H
28
29
#include <cmath>
30
#include <stdexcept>
31
#include <fstream>
32
#include <ufc.h>
33
34
/// This class defines the interface for a finite element.
35
36
class heat_finite_element_0: public ufc::finite_element
37
{
38
public:
39
40
  /// Constructor
41
  heat_finite_element_0() : ufc::finite_element()
42
  {
43
    // Do nothing
44
  }
45
46
  /// Destructor
47
  virtual ~heat_finite_element_0()
48
  {
49
    // Do nothing
50
  }
51
52
  /// Return a string identifying the finite element
53
  virtual const char* signature() const
54
  {
1675.1.129 by Martin Sandve Alnaes
Update references to match ufl multidomain changes.
55
    return "FiniteElement('Real', Domain(Cell('triangle', 2), 'triangle_multiverse', 2, 2), 0, None)";
1672.1.3 by Marie E. Rognes
Update references.
56
  }
57
58
  /// Return the cell shape
59
  virtual ufc::shape cell_shape() const
60
  {
61
    return ufc::triangle;
62
  }
63
64
  /// Return the topological dimension of the cell shape
1675.1.101 by Garth N. Wells
size_t updates for tests
65
  virtual std::size_t topological_dimension() const
1672.1.3 by Marie E. Rognes
Update references.
66
  {
67
    return 2;
68
  }
69
70
  /// Return the geometric dimension of the cell shape
1675.1.101 by Garth N. Wells
size_t updates for tests
71
  virtual std::size_t geometric_dimension() const
1672.1.3 by Marie E. Rognes
Update references.
72
  {
73
    return 2;
74
  }
75
76
  /// Return the dimension of the finite element function space
1675.1.101 by Garth N. Wells
size_t updates for tests
77
  virtual std::size_t space_dimension() const
1672.1.3 by Marie E. Rognes
Update references.
78
  {
79
    return 1;
80
  }
81
82
  /// Return the rank of the value space
1675.1.101 by Garth N. Wells
size_t updates for tests
83
  virtual std::size_t value_rank() const
1672.1.3 by Marie E. Rognes
Update references.
84
  {
85
    return 0;
86
  }
87
88
  /// Return the dimension of the value space for axis i
1675.1.101 by Garth N. Wells
size_t updates for tests
89
  virtual std::size_t value_dimension(std::size_t i) const
1672.1.3 by Marie E. Rognes
Update references.
90
  {
91
    return 1;
92
  }
93
94
  /// Evaluate basis function i at given point in cell
1675.1.101 by Garth N. Wells
size_t updates for tests
95
  virtual void evaluate_basis(std::size_t i,
1672.1.3 by Marie E. Rognes
Update references.
96
                              double* values,
97
                              const double* coordinates,
98
                              const ufc::cell& c) const
99
  {
100
    // Extract vertex coordinates
101
    
102
    // Compute Jacobian of affine map from reference cell
103
    
104
    // Compute determinant of Jacobian
105
    
106
    // Compute inverse of Jacobian
107
    
108
    // Compute constants
109
    
110
    // Get coordinates and map to the reference (FIAT) element
111
    
112
    // Reset values.
113
    *values = 0.0;
114
    
115
    // Array of basisvalues.
116
    double basisvalues[1] = {0.0};
117
    
118
    // Declare helper variables.
119
    
120
    // Compute basisvalues.
121
    basisvalues[0] = 1.0;
122
    
123
    // Table(s) of coefficients.
124
    static const double coefficients0[1] = \
125
    {1.0};
126
    
127
    // Compute value(s).
128
    for (unsigned int r = 0; r < 1; r++)
129
    {
130
      *values += coefficients0[r]*basisvalues[r];
131
    }// end loop over 'r'
132
  }
133
134
  /// Evaluate all basis functions at given point in cell
135
  virtual void evaluate_basis_all(double* values,
136
                                  const double* coordinates,
137
                                  const ufc::cell& c) const
138
  {
139
    // Element is constant, calling evaluate_basis.
140
    evaluate_basis(0, values, coordinates, c);
141
  }
142
143
  /// Evaluate order n derivatives of basis function i at given point in cell
1675.1.101 by Garth N. Wells
size_t updates for tests
144
  virtual void evaluate_basis_derivatives(std::size_t i,
145
                                          std::size_t n,
1672.1.3 by Marie E. Rognes
Update references.
146
                                          double* values,
147
                                          const double* coordinates,
148
                                          const ufc::cell& c) const
149
  {
150
    // Extract vertex coordinates
151
    const double * const * x = c.coordinates;
152
    
153
    // Compute Jacobian of affine map from reference cell
154
    const double J_00 = x[1][0] - x[0][0];
155
    const double J_01 = x[2][0] - x[0][0];
156
    const double J_10 = x[1][1] - x[0][1];
157
    const double J_11 = x[2][1] - x[0][1];
158
    
159
    // Compute determinant of Jacobian
1675.17.30 by Marie E. Rognes
Update references after changing some doubles to const double.
160
    const double detJ = J_00*J_11 - J_01*J_10;
1672.1.3 by Marie E. Rognes
Update references.
161
    
162
    // Compute inverse of Jacobian
163
    const double K_00 =  J_11 / detJ;
164
    const double K_01 = -J_01 / detJ;
165
    const double K_10 = -J_10 / detJ;
166
    const double K_11 =  J_00 / detJ;
167
    
168
    // Compute constants
169
    
170
    // Get coordinates and map to the reference (FIAT) element
171
    
172
    // Compute number of derivatives.
173
    unsigned int num_derivatives = 1;
174
    for (unsigned int r = 0; r < n; r++)
175
    {
176
      num_derivatives *= 2;
177
    }// end loop over 'r'
178
    
179
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
180
    unsigned int **combinations = new unsigned int *[num_derivatives];
181
    for (unsigned int row = 0; row < num_derivatives; row++)
182
    {
183
      combinations[row] = new unsigned int [n];
184
      for (unsigned int col = 0; col < n; col++)
185
        combinations[row][col] = 0;
186
    }
187
    
188
    // Generate combinations of derivatives
189
    for (unsigned int row = 1; row < num_derivatives; row++)
190
    {
191
      for (unsigned int num = 0; num < row; num++)
192
      {
193
        for (unsigned int col = n-1; col+1 > 0; col--)
194
        {
195
          if (combinations[row][col] + 1 > 1)
196
            combinations[row][col] = 0;
197
          else
198
          {
199
            combinations[row][col] += 1;
200
            break;
201
          }
202
        }
203
      }
204
    }
205
    
206
    // Compute inverse of Jacobian
207
    const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}};
208
    
209
    // Declare transformation matrix
210
    // Declare pointer to two dimensional array and initialise
211
    double **transform = new double *[num_derivatives];
212
    
213
    for (unsigned int j = 0; j < num_derivatives; j++)
214
    {
215
      transform[j] = new double [num_derivatives];
216
      for (unsigned int k = 0; k < num_derivatives; k++)
217
        transform[j][k] = 1;
218
    }
219
    
220
    // Construct transformation matrix
221
    for (unsigned int row = 0; row < num_derivatives; row++)
222
    {
223
      for (unsigned int col = 0; col < num_derivatives; col++)
224
      {
225
        for (unsigned int k = 0; k < n; k++)
226
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
227
      }
228
    }
229
    
230
    // Reset values. Assuming that values is always an array.
231
    for (unsigned int r = 0; r < num_derivatives; r++)
232
    {
233
      values[r] = 0.0;
234
    }// end loop over 'r'
235
    
236
    
237
    // Array of basisvalues.
238
    double basisvalues[1] = {0.0};
239
    
240
    // Declare helper variables.
241
    
242
    // Compute basisvalues.
243
    basisvalues[0] = 1.0;
244
    
245
    // Table(s) of coefficients.
246
    static const double coefficients0[1] = \
247
    {1.0};
248
    
249
    // Tables of derivatives of the polynomial base (transpose).
250
    static const double dmats0[1][1] = \
251
    {{0.0}};
252
    
253
    static const double dmats1[1][1] = \
254
    {{0.0}};
255
    
256
    // Compute reference derivatives.
257
    // Declare pointer to array of derivatives on FIAT element.
258
    double *derivatives = new double[num_derivatives];
259
    for (unsigned int r = 0; r < num_derivatives; r++)
260
    {
261
      derivatives[r] = 0.0;
262
    }// end loop over 'r'
263
    
264
    // Declare derivative matrix (of polynomial basis).
265
    double dmats[1][1] = \
266
    {{1.0}};
267
    
268
    // Declare (auxiliary) derivative matrix (of polynomial basis).
269
    double dmats_old[1][1] = \
270
    {{1.0}};
271
    
272
    // Loop possible derivatives.
273
    for (unsigned int r = 0; r < num_derivatives; r++)
274
    {
275
      // Resetting dmats values to compute next derivative.
276
      for (unsigned int t = 0; t < 1; t++)
277
      {
278
        for (unsigned int u = 0; u < 1; u++)
279
        {
280
          dmats[t][u] = 0.0;
281
          if (t == u)
282
          {
283
          dmats[t][u] = 1.0;
284
          }
285
          
286
        }// end loop over 'u'
287
      }// end loop over 't'
288
      
289
      // Looping derivative order to generate dmats.
290
      for (unsigned int s = 0; s < n; s++)
291
      {
292
        // Updating dmats_old with new values and resetting dmats.
293
        for (unsigned int t = 0; t < 1; t++)
294
        {
295
          for (unsigned int u = 0; u < 1; u++)
296
          {
297
            dmats_old[t][u] = dmats[t][u];
298
            dmats[t][u] = 0.0;
299
          }// end loop over 'u'
300
        }// end loop over 't'
301
        
302
        // Update dmats using an inner product.
303
        if (combinations[r][s] == 0)
304
        {
305
        for (unsigned int t = 0; t < 1; t++)
306
        {
307
          for (unsigned int u = 0; u < 1; u++)
308
          {
309
            for (unsigned int tu = 0; tu < 1; tu++)
310
            {
311
              dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
312
            }// end loop over 'tu'
313
          }// end loop over 'u'
314
        }// end loop over 't'
315
        }
316
        
317
        if (combinations[r][s] == 1)
318
        {
319
        for (unsigned int t = 0; t < 1; t++)
320
        {
321
          for (unsigned int u = 0; u < 1; u++)
322
          {
323
            for (unsigned int tu = 0; tu < 1; tu++)
324
            {
325
              dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
326
            }// end loop over 'tu'
327
          }// end loop over 'u'
328
        }// end loop over 't'
329
        }
330
        
331
      }// end loop over 's'
332
      for (unsigned int s = 0; s < 1; s++)
333
      {
334
        for (unsigned int t = 0; t < 1; t++)
335
        {
336
          derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
337
        }// end loop over 't'
338
      }// end loop over 's'
339
    }// end loop over 'r'
340
    
341
    // Transform derivatives back to physical element
342
    for (unsigned int r = 0; r < num_derivatives; r++)
343
    {
344
      for (unsigned int s = 0; s < num_derivatives; s++)
345
      {
346
        values[r] += transform[r][s]*derivatives[s];
347
      }// end loop over 's'
348
    }// end loop over 'r'
349
    
350
    // Delete pointer to array of derivatives on FIAT element
351
    delete [] derivatives;
352
    
353
    // Delete pointer to array of combinations of derivatives and transform
354
    for (unsigned int r = 0; r < num_derivatives; r++)
355
    {
356
      delete [] combinations[r];
357
    }// end loop over 'r'
358
    delete [] combinations;
359
    for (unsigned int r = 0; r < num_derivatives; r++)
360
    {
361
      delete [] transform[r];
362
    }// end loop over 'r'
363
    delete [] transform;
364
  }
365
366
  /// Evaluate order n derivatives of all basis functions at given point in cell
1675.1.101 by Garth N. Wells
size_t updates for tests
367
  virtual void evaluate_basis_derivatives_all(std::size_t n,
1672.1.3 by Marie E. Rognes
Update references.
368
                                              double* values,
369
                                              const double* coordinates,
370
                                              const ufc::cell& c) const
371
  {
372
    // Element is constant, calling evaluate_basis_derivatives.
373
    evaluate_basis_derivatives(0, n, values, coordinates, c);
374
  }
375
376
  /// Evaluate linear functional for dof i on the function f
1675.1.101 by Garth N. Wells
size_t updates for tests
377
  virtual double evaluate_dof(std::size_t i,
1672.1.3 by Marie E. Rognes
Update references.
378
                              const ufc::function& f,
379
                              const ufc::cell& c) const
380
  {
381
    // Declare variables for result of evaluation.
382
    double vals[1];
383
    
384
    // Declare variable for physical coordinates.
385
    double y[2];
386
    const double * const * x = c.coordinates;
387
    switch (i)
388
    {
389
    case 0:
390
      {
391
        y[0] = 0.33333333*x[0][0] + 0.33333333*x[1][0] + 0.33333333*x[2][0];
392
      y[1] = 0.33333333*x[0][1] + 0.33333333*x[1][1] + 0.33333333*x[2][1];
393
      f.evaluate(vals, y, c);
394
      return vals[0];
395
        break;
396
      }
397
    }
398
    
399
    return 0.0;
400
  }
401
402
  /// Evaluate linear functionals for all dofs on the function f
403
  virtual void evaluate_dofs(double* values,
404
                             const ufc::function& f,
405
                             const ufc::cell& c) const
406
  {
407
    // Declare variables for result of evaluation.
408
    double vals[1];
409
    
410
    // Declare variable for physical coordinates.
411
    double y[2];
412
    const double * const * x = c.coordinates;
413
    y[0] = 0.33333333*x[0][0] + 0.33333333*x[1][0] + 0.33333333*x[2][0];
414
    y[1] = 0.33333333*x[0][1] + 0.33333333*x[1][1] + 0.33333333*x[2][1];
415
    f.evaluate(vals, y, c);
416
    values[0] = vals[0];
417
  }
418
419
  /// Interpolate vertex values from dof values
420
  virtual void interpolate_vertex_values(double* vertex_values,
421
                                         const double* dof_values,
422
                                         const ufc::cell& c) const
423
  {
424
    // Evaluate function and change variables
425
    vertex_values[0] = dof_values[0];
426
    vertex_values[1] = dof_values[0];
427
    vertex_values[2] = dof_values[0];
428
  }
429
430
  /// Map coordinate xhat from reference cell to coordinate x in cell
431
  virtual void map_from_reference_cell(double* x,
432
                                       const double* xhat,
433
                                       const ufc::cell& c) const
434
  {
435
    std::cerr << "*** FFC warning: " << "map_from_reference_cell not yet implemented (introduced in UFC 2.0)." << std::endl;
436
  }
437
438
  /// Map from coordinate x in cell to coordinate xhat in reference cell
439
  virtual void map_to_reference_cell(double* xhat,
440
                                     const double* x,
441
                                     const ufc::cell& c) const
442
  {
443
    std::cerr << "*** FFC warning: " << "map_to_reference_cell not yet implemented (introduced in UFC 2.0)." << std::endl;
444
  }
445
446
  /// Return the number of sub elements (for a mixed element)
1675.1.101 by Garth N. Wells
size_t updates for tests
447
  virtual std::size_t num_sub_elements() const
1672.1.3 by Marie E. Rognes
Update references.
448
  {
449
    return 0;
450
  }
451
452
  /// Create a new finite element for sub element i (for a mixed element)
1675.1.101 by Garth N. Wells
size_t updates for tests
453
  virtual ufc::finite_element* create_sub_element(std::size_t i) const
1672.1.3 by Marie E. Rognes
Update references.
454
  {
455
    return 0;
456
  }
457
458
  /// Create a new class instance
459
  virtual ufc::finite_element* create() const
460
  {
461
    return new heat_finite_element_0();
462
  }
463
464
};
465
466
/// This class defines the interface for a finite element.
467
468
class heat_finite_element_1: public ufc::finite_element
469
{
470
public:
471
472
  /// Constructor
473
  heat_finite_element_1() : ufc::finite_element()
474
  {
475
    // Do nothing
476
  }
477
478
  /// Destructor
479
  virtual ~heat_finite_element_1()
480
  {
481
    // Do nothing
482
  }
483
484
  /// Return a string identifying the finite element
485
  virtual const char* signature() const
486
  {
1675.1.129 by Martin Sandve Alnaes
Update references to match ufl multidomain changes.
487
    return "FiniteElement('Lagrange', Domain(Cell('triangle', 2), 'triangle_multiverse', 2, 2), 1, None)";
1672.1.3 by Marie E. Rognes
Update references.
488
  }
489
490
  /// Return the cell shape
491
  virtual ufc::shape cell_shape() const
492
  {
493
    return ufc::triangle;
494
  }
495
496
  /// Return the topological dimension of the cell shape
1675.1.101 by Garth N. Wells
size_t updates for tests
497
  virtual std::size_t topological_dimension() const
1672.1.3 by Marie E. Rognes
Update references.
498
  {
499
    return 2;
500
  }
501
502
  /// Return the geometric dimension of the cell shape
1675.1.101 by Garth N. Wells
size_t updates for tests
503
  virtual std::size_t geometric_dimension() const
1672.1.3 by Marie E. Rognes
Update references.
504
  {
505
    return 2;
506
  }
507
508
  /// Return the dimension of the finite element function space
1675.1.101 by Garth N. Wells
size_t updates for tests
509
  virtual std::size_t space_dimension() const
1672.1.3 by Marie E. Rognes
Update references.
510
  {
511
    return 3;
512
  }
513
514
  /// Return the rank of the value space
1675.1.101 by Garth N. Wells
size_t updates for tests
515
  virtual std::size_t value_rank() const
1672.1.3 by Marie E. Rognes
Update references.
516
  {
517
    return 0;
518
  }
519
520
  /// Return the dimension of the value space for axis i
1675.1.101 by Garth N. Wells
size_t updates for tests
521
  virtual std::size_t value_dimension(std::size_t i) const
1672.1.3 by Marie E. Rognes
Update references.
522
  {
523
    return 1;
524
  }
525
526
  /// Evaluate basis function i at given point in cell
1675.1.101 by Garth N. Wells
size_t updates for tests
527
  virtual void evaluate_basis(std::size_t i,
1672.1.3 by Marie E. Rognes
Update references.
528
                              double* values,
529
                              const double* coordinates,
530
                              const ufc::cell& c) const
531
  {
532
    // Extract vertex coordinates
533
    const double * const * x = c.coordinates;
534
    
535
    // Compute Jacobian of affine map from reference cell
536
    const double J_00 = x[1][0] - x[0][0];
537
    const double J_01 = x[2][0] - x[0][0];
538
    const double J_10 = x[1][1] - x[0][1];
539
    const double J_11 = x[2][1] - x[0][1];
540
    
541
    // Compute determinant of Jacobian
1675.17.30 by Marie E. Rognes
Update references after changing some doubles to const double.
542
    const double detJ = J_00*J_11 - J_01*J_10;
1672.1.3 by Marie E. Rognes
Update references.
543
    
544
    // Compute inverse of Jacobian
545
    
546
    // Compute constants
547
    const double C0 = x[1][0] + x[2][0];
548
    const double C1 = x[1][1] + x[2][1];
549
    
550
    // Get coordinates and map to the reference (FIAT) element
551
    double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ;
552
    double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ;
553
    
554
    // Reset values.
555
    *values = 0.0;
556
    switch (i)
557
    {
558
    case 0:
559
      {
560
        
561
      // Array of basisvalues.
562
      double basisvalues[3] = {0.0, 0.0, 0.0};
563
      
564
      // Declare helper variables.
565
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
566
      
567
      // Compute basisvalues.
568
      basisvalues[0] = 1.0;
569
      basisvalues[1] = tmp0;
1675.2.6 by Marie E. Rognes
Update references after change in evaluate_basis* code.
570
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
571
      basisvalues[0] *= std::sqrt(0.5);
572
      basisvalues[2] *= std::sqrt(1.0);
573
      basisvalues[1] *= std::sqrt(3.0);
1672.1.3 by Marie E. Rognes
Update references.
574
      
575
      // Table(s) of coefficients.
576
      static const double coefficients0[3] = \
577
      {0.47140452, -0.28867513, -0.16666667};
578
      
579
      // Compute value(s).
580
      for (unsigned int r = 0; r < 3; r++)
581
      {
582
        *values += coefficients0[r]*basisvalues[r];
583
      }// end loop over 'r'
584
        break;
585
      }
586
    case 1:
587
      {
588
        
589
      // Array of basisvalues.
590
      double basisvalues[3] = {0.0, 0.0, 0.0};
591
      
592
      // Declare helper variables.
593
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
594
      
595
      // Compute basisvalues.
596
      basisvalues[0] = 1.0;
597
      basisvalues[1] = tmp0;
1675.2.6 by Marie E. Rognes
Update references after change in evaluate_basis* code.
598
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
599
      basisvalues[0] *= std::sqrt(0.5);
600
      basisvalues[2] *= std::sqrt(1.0);
601
      basisvalues[1] *= std::sqrt(3.0);
1672.1.3 by Marie E. Rognes
Update references.
602
      
603
      // Table(s) of coefficients.
604
      static const double coefficients0[3] = \
605
      {0.47140452, 0.28867513, -0.16666667};
606
      
607
      // Compute value(s).
608
      for (unsigned int r = 0; r < 3; r++)
609
      {
610
        *values += coefficients0[r]*basisvalues[r];
611
      }// end loop over 'r'
612
        break;
613
      }
614
    case 2:
615
      {
616
        
617
      // Array of basisvalues.
618
      double basisvalues[3] = {0.0, 0.0, 0.0};
619
      
620
      // Declare helper variables.
621
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
622
      
623
      // Compute basisvalues.
624
      basisvalues[0] = 1.0;
625
      basisvalues[1] = tmp0;
1675.2.6 by Marie E. Rognes
Update references after change in evaluate_basis* code.
626
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
627
      basisvalues[0] *= std::sqrt(0.5);
628
      basisvalues[2] *= std::sqrt(1.0);
629
      basisvalues[1] *= std::sqrt(3.0);
1672.1.3 by Marie E. Rognes
Update references.
630
      
631
      // Table(s) of coefficients.
632
      static const double coefficients0[3] = \
633
      {0.47140452, 0.0, 0.33333333};
634
      
635
      // Compute value(s).
636
      for (unsigned int r = 0; r < 3; r++)
637
      {
638
        *values += coefficients0[r]*basisvalues[r];
639
      }// end loop over 'r'
640
        break;
641
      }
642
    }
643
    
644
  }
645
646
  /// Evaluate all basis functions at given point in cell
647
  virtual void evaluate_basis_all(double* values,
648
                                  const double* coordinates,
649
                                  const ufc::cell& c) const
650
  {
651
    // Helper variable to hold values of a single dof.
652
    double dof_values = 0.0;
653
    
654
    // Loop dofs and call evaluate_basis.
655
    for (unsigned int r = 0; r < 3; r++)
656
    {
657
      evaluate_basis(r, &dof_values, coordinates, c);
658
      values[r] = dof_values;
659
    }// end loop over 'r'
660
  }
661
662
  /// Evaluate order n derivatives of basis function i at given point in cell
1675.1.101 by Garth N. Wells
size_t updates for tests
663
  virtual void evaluate_basis_derivatives(std::size_t i,
664
                                          std::size_t n,
1672.1.3 by Marie E. Rognes
Update references.
665
                                          double* values,
666
                                          const double* coordinates,
667
                                          const ufc::cell& c) const
668
  {
669
    // Extract vertex coordinates
670
    const double * const * x = c.coordinates;
671
    
672
    // Compute Jacobian of affine map from reference cell
673
    const double J_00 = x[1][0] - x[0][0];
674
    const double J_01 = x[2][0] - x[0][0];
675
    const double J_10 = x[1][1] - x[0][1];
676
    const double J_11 = x[2][1] - x[0][1];
677
    
678
    // Compute determinant of Jacobian
1675.17.30 by Marie E. Rognes
Update references after changing some doubles to const double.
679
    const double detJ = J_00*J_11 - J_01*J_10;
1672.1.3 by Marie E. Rognes
Update references.
680
    
681
    // Compute inverse of Jacobian
682
    const double K_00 =  J_11 / detJ;
683
    const double K_01 = -J_01 / detJ;
684
    const double K_10 = -J_10 / detJ;
685
    const double K_11 =  J_00 / detJ;
686
    
687
    // Compute constants
688
    const double C0 = x[1][0] + x[2][0];
689
    const double C1 = x[1][1] + x[2][1];
690
    
691
    // Get coordinates and map to the reference (FIAT) element
692
    double X = (J_01*(C1 - 2.0*coordinates[1]) + J_11*(2.0*coordinates[0] - C0)) / detJ;
693
    double Y = (J_00*(2.0*coordinates[1] - C1) + J_10*(C0 - 2.0*coordinates[0])) / detJ;
694
    
695
    // Compute number of derivatives.
696
    unsigned int num_derivatives = 1;
697
    for (unsigned int r = 0; r < n; r++)
698
    {
699
      num_derivatives *= 2;
700
    }// end loop over 'r'
701
    
702
    // Declare pointer to two dimensional array that holds combinations of derivatives and initialise
703
    unsigned int **combinations = new unsigned int *[num_derivatives];
704
    for (unsigned int row = 0; row < num_derivatives; row++)
705
    {
706
      combinations[row] = new unsigned int [n];
707
      for (unsigned int col = 0; col < n; col++)
708
        combinations[row][col] = 0;
709
    }
710
    
711
    // Generate combinations of derivatives
712
    for (unsigned int row = 1; row < num_derivatives; row++)
713
    {
714
      for (unsigned int num = 0; num < row; num++)
715
      {
716
        for (unsigned int col = n-1; col+1 > 0; col--)
717
        {
718
          if (combinations[row][col] + 1 > 1)
719
            combinations[row][col] = 0;
720
          else
721
          {
722
            combinations[row][col] += 1;
723
            break;
724
          }
725
        }
726
      }
727
    }
728
    
729
    // Compute inverse of Jacobian
730
    const double Jinv[2][2] = {{K_00, K_01}, {K_10, K_11}};
731
    
732
    // Declare transformation matrix
733
    // Declare pointer to two dimensional array and initialise
734
    double **transform = new double *[num_derivatives];
735
    
736
    for (unsigned int j = 0; j < num_derivatives; j++)
737
    {
738
      transform[j] = new double [num_derivatives];
739
      for (unsigned int k = 0; k < num_derivatives; k++)
740
        transform[j][k] = 1;
741
    }
742
    
743
    // Construct transformation matrix
744
    for (unsigned int row = 0; row < num_derivatives; row++)
745
    {
746
      for (unsigned int col = 0; col < num_derivatives; col++)
747
      {
748
        for (unsigned int k = 0; k < n; k++)
749
          transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
750
      }
751
    }
752
    
753
    // Reset values. Assuming that values is always an array.
754
    for (unsigned int r = 0; r < num_derivatives; r++)
755
    {
756
      values[r] = 0.0;
757
    }// end loop over 'r'
758
    
759
    switch (i)
760
    {
761
    case 0:
762
      {
763
        
764
      // Array of basisvalues.
765
      double basisvalues[3] = {0.0, 0.0, 0.0};
766
      
767
      // Declare helper variables.
768
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
769
      
770
      // Compute basisvalues.
771
      basisvalues[0] = 1.0;
772
      basisvalues[1] = tmp0;
1675.2.6 by Marie E. Rognes
Update references after change in evaluate_basis* code.
773
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
774
      basisvalues[0] *= std::sqrt(0.5);
775
      basisvalues[2] *= std::sqrt(1.0);
776
      basisvalues[1] *= std::sqrt(3.0);
1672.1.3 by Marie E. Rognes
Update references.
777
      
778
      // Table(s) of coefficients.
779
      static const double coefficients0[3] = \
780
      {0.47140452, -0.28867513, -0.16666667};
781
      
782
      // Tables of derivatives of the polynomial base (transpose).
783
      static const double dmats0[3][3] = \
784
      {{0.0, 0.0, 0.0},
785
      {4.8989795, 0.0, 0.0},
786
      {0.0, 0.0, 0.0}};
787
      
788
      static const double dmats1[3][3] = \
789
      {{0.0, 0.0, 0.0},
790
      {2.4494897, 0.0, 0.0},
791
      {4.2426407, 0.0, 0.0}};
792
      
793
      // Compute reference derivatives.
794
      // Declare pointer to array of derivatives on FIAT element.
795
      double *derivatives = new double[num_derivatives];
796
      for (unsigned int r = 0; r < num_derivatives; r++)
797
      {
798
        derivatives[r] = 0.0;
799
      }// end loop over 'r'
800
      
801
      // Declare derivative matrix (of polynomial basis).
802
      double dmats[3][3] = \
803
      {{1.0, 0.0, 0.0},
804
      {0.0, 1.0, 0.0},
805
      {0.0, 0.0, 1.0}};
806
      
807
      // Declare (auxiliary) derivative matrix (of polynomial basis).
808
      double dmats_old[3][3] = \
809
      {{1.0, 0.0, 0.0},
810
      {0.0, 1.0, 0.0},
811
      {0.0, 0.0, 1.0}};
812
      
813
      // Loop possible derivatives.
814
      for (unsigned int r = 0; r < num_derivatives; r++)
815
      {
816
        // Resetting dmats values to compute next derivative.
817
        for (unsigned int t = 0; t < 3; t++)
818
        {
819
          for (unsigned int u = 0; u < 3; u++)
820
          {
821
            dmats[t][u] = 0.0;
822
            if (t == u)
823
            {
824
            dmats[t][u] = 1.0;
825
            }
826
            
827
          }// end loop over 'u'
828
        }// end loop over 't'
829
        
830
        // Looping derivative order to generate dmats.
831
        for (unsigned int s = 0; s < n; s++)
832
        {
833
          // Updating dmats_old with new values and resetting dmats.
834
          for (unsigned int t = 0; t < 3; t++)
835
          {
836
            for (unsigned int u = 0; u < 3; u++)
837
            {
838
              dmats_old[t][u] = dmats[t][u];
839
              dmats[t][u] = 0.0;
840
            }// end loop over 'u'
841
          }// end loop over 't'
842
          
843
          // Update dmats using an inner product.
844
          if (combinations[r][s] == 0)
845
          {
846
          for (unsigned int t = 0; t < 3; t++)
847
          {
848
            for (unsigned int u = 0; u < 3; u++)
849
            {
850
              for (unsigned int tu = 0; tu < 3; tu++)
851
              {
852
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
853
              }// end loop over 'tu'
854
            }// end loop over 'u'
855
          }// end loop over 't'
856
          }
857
          
858
          if (combinations[r][s] == 1)
859
          {
860
          for (unsigned int t = 0; t < 3; t++)
861
          {
862
            for (unsigned int u = 0; u < 3; u++)
863
            {
864
              for (unsigned int tu = 0; tu < 3; tu++)
865
              {
866
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
867
              }// end loop over 'tu'
868
            }// end loop over 'u'
869
          }// end loop over 't'
870
          }
871
          
872
        }// end loop over 's'
873
        for (unsigned int s = 0; s < 3; s++)
874
        {
875
          for (unsigned int t = 0; t < 3; t++)
876
          {
877
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
878
          }// end loop over 't'
879
        }// end loop over 's'
880
      }// end loop over 'r'
881
      
882
      // Transform derivatives back to physical element
883
      for (unsigned int r = 0; r < num_derivatives; r++)
884
      {
885
        for (unsigned int s = 0; s < num_derivatives; s++)
886
        {
887
          values[r] += transform[r][s]*derivatives[s];
888
        }// end loop over 's'
889
      }// end loop over 'r'
890
      
891
      // Delete pointer to array of derivatives on FIAT element
892
      delete [] derivatives;
893
      
894
      // Delete pointer to array of combinations of derivatives and transform
895
      for (unsigned int r = 0; r < num_derivatives; r++)
896
      {
897
        delete [] combinations[r];
898
      }// end loop over 'r'
899
      delete [] combinations;
900
      for (unsigned int r = 0; r < num_derivatives; r++)
901
      {
902
        delete [] transform[r];
903
      }// end loop over 'r'
904
      delete [] transform;
905
        break;
906
      }
907
    case 1:
908
      {
909
        
910
      // Array of basisvalues.
911
      double basisvalues[3] = {0.0, 0.0, 0.0};
912
      
913
      // Declare helper variables.
914
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
915
      
916
      // Compute basisvalues.
917
      basisvalues[0] = 1.0;
918
      basisvalues[1] = tmp0;
1675.2.6 by Marie E. Rognes
Update references after change in evaluate_basis* code.
919
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
920
      basisvalues[0] *= std::sqrt(0.5);
921
      basisvalues[2] *= std::sqrt(1.0);
922
      basisvalues[1] *= std::sqrt(3.0);
1672.1.3 by Marie E. Rognes
Update references.
923
      
924
      // Table(s) of coefficients.
925
      static const double coefficients0[3] = \
926
      {0.47140452, 0.28867513, -0.16666667};
927
      
928
      // Tables of derivatives of the polynomial base (transpose).
929
      static const double dmats0[3][3] = \
930
      {{0.0, 0.0, 0.0},
931
      {4.8989795, 0.0, 0.0},
932
      {0.0, 0.0, 0.0}};
933
      
934
      static const double dmats1[3][3] = \
935
      {{0.0, 0.0, 0.0},
936
      {2.4494897, 0.0, 0.0},
937
      {4.2426407, 0.0, 0.0}};
938
      
939
      // Compute reference derivatives.
940
      // Declare pointer to array of derivatives on FIAT element.
941
      double *derivatives = new double[num_derivatives];
942
      for (unsigned int r = 0; r < num_derivatives; r++)
943
      {
944
        derivatives[r] = 0.0;
945
      }// end loop over 'r'
946
      
947
      // Declare derivative matrix (of polynomial basis).
948
      double dmats[3][3] = \
949
      {{1.0, 0.0, 0.0},
950
      {0.0, 1.0, 0.0},
951
      {0.0, 0.0, 1.0}};
952
      
953
      // Declare (auxiliary) derivative matrix (of polynomial basis).
954
      double dmats_old[3][3] = \
955
      {{1.0, 0.0, 0.0},
956
      {0.0, 1.0, 0.0},
957
      {0.0, 0.0, 1.0}};
958
      
959
      // Loop possible derivatives.
960
      for (unsigned int r = 0; r < num_derivatives; r++)
961
      {
962
        // Resetting dmats values to compute next derivative.
963
        for (unsigned int t = 0; t < 3; t++)
964
        {
965
          for (unsigned int u = 0; u < 3; u++)
966
          {
967
            dmats[t][u] = 0.0;
968
            if (t == u)
969
            {
970
            dmats[t][u] = 1.0;
971
            }
972
            
973
          }// end loop over 'u'
974
        }// end loop over 't'
975
        
976
        // Looping derivative order to generate dmats.
977
        for (unsigned int s = 0; s < n; s++)
978
        {
979
          // Updating dmats_old with new values and resetting dmats.
980
          for (unsigned int t = 0; t < 3; t++)
981
          {
982
            for (unsigned int u = 0; u < 3; u++)
983
            {
984
              dmats_old[t][u] = dmats[t][u];
985
              dmats[t][u] = 0.0;
986
            }// end loop over 'u'
987
          }// end loop over 't'
988
          
989
          // Update dmats using an inner product.
990
          if (combinations[r][s] == 0)
991
          {
992
          for (unsigned int t = 0; t < 3; t++)
993
          {
994
            for (unsigned int u = 0; u < 3; u++)
995
            {
996
              for (unsigned int tu = 0; tu < 3; tu++)
997
              {
998
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
999
              }// end loop over 'tu'
1000
            }// end loop over 'u'
1001
          }// end loop over 't'
1002
          }
1003
          
1004
          if (combinations[r][s] == 1)
1005
          {
1006
          for (unsigned int t = 0; t < 3; t++)
1007
          {
1008
            for (unsigned int u = 0; u < 3; u++)
1009
            {
1010
              for (unsigned int tu = 0; tu < 3; tu++)
1011
              {
1012
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
1013
              }// end loop over 'tu'
1014
            }// end loop over 'u'
1015
          }// end loop over 't'
1016
          }
1017
          
1018
        }// end loop over 's'
1019
        for (unsigned int s = 0; s < 3; s++)
1020
        {
1021
          for (unsigned int t = 0; t < 3; t++)
1022
          {
1023
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
1024
          }// end loop over 't'
1025
        }// end loop over 's'
1026
      }// end loop over 'r'
1027
      
1028
      // Transform derivatives back to physical element
1029
      for (unsigned int r = 0; r < num_derivatives; r++)
1030
      {
1031
        for (unsigned int s = 0; s < num_derivatives; s++)
1032
        {
1033
          values[r] += transform[r][s]*derivatives[s];
1034
        }// end loop over 's'
1035
      }// end loop over 'r'
1036
      
1037
      // Delete pointer to array of derivatives on FIAT element
1038
      delete [] derivatives;
1039
      
1040
      // Delete pointer to array of combinations of derivatives and transform
1041
      for (unsigned int r = 0; r < num_derivatives; r++)
1042
      {
1043
        delete [] combinations[r];
1044
      }// end loop over 'r'
1045
      delete [] combinations;
1046
      for (unsigned int r = 0; r < num_derivatives; r++)
1047
      {
1048
        delete [] transform[r];
1049
      }// end loop over 'r'
1050
      delete [] transform;
1051
        break;
1052
      }
1053
    case 2:
1054
      {
1055
        
1056
      // Array of basisvalues.
1057
      double basisvalues[3] = {0.0, 0.0, 0.0};
1058
      
1059
      // Declare helper variables.
1060
      double tmp0 = (1.0 + Y + 2.0*X)/2.0;
1061
      
1062
      // Compute basisvalues.
1063
      basisvalues[0] = 1.0;
1064
      basisvalues[1] = tmp0;
1675.2.6 by Marie E. Rognes
Update references after change in evaluate_basis* code.
1065
      basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
1066
      basisvalues[0] *= std::sqrt(0.5);
1067
      basisvalues[2] *= std::sqrt(1.0);
1068
      basisvalues[1] *= std::sqrt(3.0);
1672.1.3 by Marie E. Rognes
Update references.
1069
      
1070
      // Table(s) of coefficients.
1071
      static const double coefficients0[3] = \
1072
      {0.47140452, 0.0, 0.33333333};
1073
      
1074
      // Tables of derivatives of the polynomial base (transpose).
1075
      static const double dmats0[3][3] = \
1076
      {{0.0, 0.0, 0.0},
1077
      {4.8989795, 0.0, 0.0},
1078
      {0.0, 0.0, 0.0}};
1079
      
1080
      static const double dmats1[3][3] = \
1081
      {{0.0, 0.0, 0.0},
1082
      {2.4494897, 0.0, 0.0},
1083
      {4.2426407, 0.0, 0.0}};
1084
      
1085
      // Compute reference derivatives.
1086
      // Declare pointer to array of derivatives on FIAT element.
1087
      double *derivatives = new double[num_derivatives];
1088
      for (unsigned int r = 0; r < num_derivatives; r++)
1089
      {
1090
        derivatives[r] = 0.0;
1091
      }// end loop over 'r'
1092
      
1093
      // Declare derivative matrix (of polynomial basis).
1094
      double dmats[3][3] = \
1095
      {{1.0, 0.0, 0.0},
1096
      {0.0, 1.0, 0.0},
1097
      {0.0, 0.0, 1.0}};
1098
      
1099
      // Declare (auxiliary) derivative matrix (of polynomial basis).
1100
      double dmats_old[3][3] = \
1101
      {{1.0, 0.0, 0.0},
1102
      {0.0, 1.0, 0.0},
1103
      {0.0, 0.0, 1.0}};
1104
      
1105
      // Loop possible derivatives.
1106
      for (unsigned int r = 0; r < num_derivatives; r++)
1107
      {
1108
        // Resetting dmats values to compute next derivative.
1109
        for (unsigned int t = 0; t < 3; t++)
1110
        {
1111
          for (unsigned int u = 0; u < 3; u++)
1112
          {
1113
            dmats[t][u] = 0.0;
1114
            if (t == u)
1115
            {
1116
            dmats[t][u] = 1.0;
1117
            }
1118
            
1119
          }// end loop over 'u'
1120
        }// end loop over 't'
1121
        
1122
        // Looping derivative order to generate dmats.
1123
        for (unsigned int s = 0; s < n; s++)
1124
        {
1125
          // Updating dmats_old with new values and resetting dmats.
1126
          for (unsigned int t = 0; t < 3; t++)
1127
          {
1128
            for (unsigned int u = 0; u < 3; u++)
1129
            {
1130
              dmats_old[t][u] = dmats[t][u];
1131
              dmats[t][u] = 0.0;
1132
            }// end loop over 'u'
1133
          }// end loop over 't'
1134
          
1135
          // Update dmats using an inner product.
1136
          if (combinations[r][s] == 0)
1137
          {
1138
          for (unsigned int t = 0; t < 3; t++)
1139
          {
1140
            for (unsigned int u = 0; u < 3; u++)
1141
            {
1142
              for (unsigned int tu = 0; tu < 3; tu++)
1143
              {
1144
                dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
1145
              }// end loop over 'tu'
1146
            }// end loop over 'u'
1147
          }// end loop over 't'
1148
          }
1149
          
1150
          if (combinations[r][s] == 1)
1151
          {
1152
          for (unsigned int t = 0; t < 3; t++)
1153
          {
1154
            for (unsigned int u = 0; u < 3; u++)
1155
            {
1156
              for (unsigned int tu = 0; tu < 3; tu++)
1157
              {
1158
                dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
1159
              }// end loop over 'tu'
1160
            }// end loop over 'u'
1161
          }// end loop over 't'
1162
          }
1163
          
1164
        }// end loop over 's'
1165
        for (unsigned int s = 0; s < 3; s++)
1166
        {
1167
          for (unsigned int t = 0; t < 3; t++)
1168
          {
1169
            derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
1170
          }// end loop over 't'
1171
        }// end loop over 's'
1172
      }// end loop over 'r'
1173
      
1174
      // Transform derivatives back to physical element
1175
      for (unsigned int r = 0; r < num_derivatives; r++)
1176
      {
1177
        for (unsigned int s = 0; s < num_derivatives; s++)
1178
        {
1179
          values[r] += transform[r][s]*derivatives[s];
1180
        }// end loop over 's'
1181
      }// end loop over 'r'
1182
      
1183
      // Delete pointer to array of derivatives on FIAT element
1184
      delete [] derivatives;
1185
      
1186
      // Delete pointer to array of combinations of derivatives and transform
1187
      for (unsigned int r = 0; r < num_derivatives; r++)
1188
      {
1189
        delete [] combinations[r];
1190
      }// end loop over 'r'
1191
      delete [] combinations;
1192
      for (unsigned int r = 0; r < num_derivatives; r++)
1193
      {
1194
        delete [] transform[r];
1195
      }// end loop over 'r'
1196
      delete [] transform;
1197
        break;
1198
      }
1199
    }
1200
    
1201
  }
1202
1203
  /// Evaluate order n derivatives of all basis functions at given point in cell
1675.1.101 by Garth N. Wells
size_t updates for tests
1204
  virtual void evaluate_basis_derivatives_all(std::size_t n,
1672.1.3 by Marie E. Rognes
Update references.
1205
                                              double* values,
1206
                                              const double* coordinates,
1207
                                              const ufc::cell& c) const
1208
  {
1209
    // Compute number of derivatives.
1210
    unsigned int num_derivatives = 1;
1211
    for (unsigned int r = 0; r < n; r++)
1212
    {
1213
      num_derivatives *= 2;
1214
    }// end loop over 'r'
1215
    
1216
    // Helper variable to hold values of a single dof.
1217
    double *dof_values = new double[num_derivatives];
1218
    for (unsigned int r = 0; r < num_derivatives; r++)
1219
    {
1220
      dof_values[r] = 0.0;
1221
    }// end loop over 'r'
1222
    
1223
    // Loop dofs and call evaluate_basis_derivatives.
1224
    for (unsigned int r = 0; r < 3; r++)
1225
    {
1226
      evaluate_basis_derivatives(r, n, dof_values, coordinates, c);
1227
      for (unsigned int s = 0; s < num_derivatives; s++)
1228
      {
1229
        values[r*num_derivatives + s] = dof_values[s];
1230
      }// end loop over 's'
1231
    }// end loop over 'r'
1232
    
1233
    // Delete pointer.
1234
    delete [] dof_values;
1235
  }
1236
1237
  /// Evaluate linear functional for dof i on the function f
1675.1.101 by Garth N. Wells
size_t updates for tests
1238
  virtual double evaluate_dof(std::size_t i,
1672.1.3 by Marie E. Rognes
Update references.
1239
                              const ufc::function& f,
1240
                              const ufc::cell& c) const
1241
  {
1242
    // Declare variables for result of evaluation.
1243
    double vals[1];
1244
    
1245
    // Declare variable for physical coordinates.
1246
    double y[2];
1247
    const double * const * x = c.coordinates;
1248
    switch (i)
1249
    {
1250
    case 0:
1251
      {
1252
        y[0] = x[0][0];
1253
      y[1] = x[0][1];
1254
      f.evaluate(vals, y, c);
1255
      return vals[0];
1256
        break;
1257
      }
1258
    case 1:
1259
      {
1260
        y[0] = x[1][0];
1261
      y[1] = x[1][1];
1262
      f.evaluate(vals, y, c);
1263
      return vals[0];
1264
        break;
1265
      }
1266
    case 2:
1267
      {
1268
        y[0] = x[2][0];
1269
      y[1] = x[2][1];
1270
      f.evaluate(vals, y, c);
1271
      return vals[0];
1272
        break;
1273
      }
1274
    }
1275
    
1276
    return 0.0;
1277
  }
1278
1279
  /// Evaluate linear functionals for all dofs on the function f
1280
  virtual void evaluate_dofs(double* values,
1281
                             const ufc::function& f,
1282
                             const ufc::cell& c) const
1283
  {
1284
    // Declare variables for result of evaluation.
1285
    double vals[1];
1286
    
1287
    // Declare variable for physical coordinates.
1288
    double y[2];
1289
    const double * const * x = c.coordinates;
1290
    y[0] = x[0][0];
1291
    y[1] = x[0][1];
1292
    f.evaluate(vals, y, c);
1293
    values[0] = vals[0];
1294
    y[0] = x[1][0];
1295
    y[1] = x[1][1];
1296
    f.evaluate(vals, y, c);
1297
    values[1] = vals[0];
1298
    y[0] = x[2][0];
1299
    y[1] = x[2][1];
1300
    f.evaluate(vals, y, c);
1301
    values[2] = vals[0];
1302
  }
1303
1304
  /// Interpolate vertex values from dof values
1305
  virtual void interpolate_vertex_values(double* vertex_values,
1306
                                         const double* dof_values,
1307
                                         const ufc::cell& c) const
1308
  {
1309
    // Evaluate function and change variables
1310
    vertex_values[0] = dof_values[0];
1311
    vertex_values[1] = dof_values[1];
1312
    vertex_values[2] = dof_values[2];
1313
  }
1314
1315
  /// Map coordinate xhat from reference cell to coordinate x in cell
1316
  virtual void map_from_reference_cell(double* x,
1317
                                       const double* xhat,
1318
                                       const ufc::cell& c) const
1319
  {
1320
    std::cerr << "*** FFC warning: " << "map_from_reference_cell not yet implemented (introduced in UFC 2.0)." << std::endl;
1321
  }
1322
1323
  /// Map from coordinate x in cell to coordinate xhat in reference cell
1324
  virtual void map_to_reference_cell(double* xhat,
1325
                                     const double* x,
1326
                                     const ufc::cell& c) const
1327
  {
1328
    std::cerr << "*** FFC warning: " << "map_to_reference_cell not yet implemented (introduced in UFC 2.0)." << std::endl;
1329
  }
1330
1331
  /// Return the number of sub elements (for a mixed element)
1675.1.101 by Garth N. Wells
size_t updates for tests
1332
  virtual std::size_t num_sub_elements() const
1672.1.3 by Marie E. Rognes
Update references.
1333
  {
1334
    return 0;
1335
  }
1336
1337
  /// Create a new finite element for sub element i (for a mixed element)
1675.1.101 by Garth N. Wells
size_t updates for tests
1338
  virtual ufc::finite_element* create_sub_element(std::size_t i) const
1672.1.3 by Marie E. Rognes
Update references.
1339
  {
1340
    return 0;
1341
  }
1342
1343
  /// Create a new class instance
1344
  virtual ufc::finite_element* create() const
1345
  {
1346
    return new heat_finite_element_1();
1347
  }
1348
1349
};
1350
1351
/// This class defines the interface for a local-to-global mapping of
1352
/// degrees of freedom (dofs).
1353
1354
class heat_dofmap_0: public ufc::dofmap
1355
{
1356
public:
1357
1358
  /// Constructor
1359
  heat_dofmap_0() : ufc::dofmap()
1360
  {
1675.1.105 by Martin Sandve Alnaes
Update references.
1361
    // Do nothing
1672.1.3 by Marie E. Rognes
Update references.
1362
  }
1363
1364
  /// Destructor
1365
  virtual ~heat_dofmap_0()
1366
  {
1367
    // Do nothing
1368
  }
1369
1370
  /// Return a string identifying the dofmap
1371
  virtual const char* signature() const
1372
  {
1675.1.129 by Martin Sandve Alnaes
Update references to match ufl multidomain changes.
1373
    return "FFC dofmap for FiniteElement('Real', Domain(Cell('triangle', 2), 'triangle_multiverse', 2, 2), 0, None)";
1672.1.3 by Marie E. Rognes
Update references.
1374
  }
1375
1376
  /// Return true iff mesh entities of topological dimension d are needed
1675.1.101 by Garth N. Wells
size_t updates for tests
1377
  virtual bool needs_mesh_entities(std::size_t d) const
1672.1.3 by Marie E. Rognes
Update references.
1378
  {
1379
    switch (d)
1380
    {
1381
    case 0:
1382
      {
1383
        return false;
1384
        break;
1385
      }
1386
    case 1:
1387
      {
1388
        return false;
1389
        break;
1390
      }
1391
    case 2:
1392
      {
1675.1.22 by Marie E. Rognes
Update references after change DG0 -> Real for Constant.
1393
        return false;
1672.1.3 by Marie E. Rognes
Update references.
1394
        break;
1395
      }
1396
    }
1397
    
1398
    return false;
1399
  }
1400
1401
  /// Return the topological dimension of the associated cell shape
1675.1.101 by Garth N. Wells
size_t updates for tests
1402
  virtual std::size_t topological_dimension() const
1672.1.3 by Marie E. Rognes
Update references.
1403
  {
1404
    return 2;
1405
  }
1406
1407
  /// Return the geometric dimension of the associated cell shape
1675.1.101 by Garth N. Wells
size_t updates for tests
1408
  virtual std::size_t geometric_dimension() const
1672.1.3 by Marie E. Rognes
Update references.
1409
  {
1410
    return 2;
1411
  }
1412
1413
  /// Return the dimension of the global finite element function space
1675.1.105 by Martin Sandve Alnaes
Update references.
1414
  virtual std::size_t global_dimension(const std::vector<std::size_t>&
1415
                                       num_global_entities) const
1672.1.3 by Marie E. Rognes
Update references.
1416
  {
1675.1.105 by Martin Sandve Alnaes
Update references.
1417
    return 1;
1672.1.3 by Marie E. Rognes
Update references.
1418
  }
1419
1420
  /// Return the dimension of the local finite element function space for a cell
1675.1.101 by Garth N. Wells
size_t updates for tests
1421
  virtual std::size_t local_dimension(const ufc::cell& c) const
1672.1.3 by Marie E. Rognes
Update references.
1422
  {
1423
    return 1;
1424
  }
1425
1426
  /// Return the maximum dimension of the local finite element function space
1675.1.101 by Garth N. Wells
size_t updates for tests
1427
  virtual std::size_t max_local_dimension() const
1672.1.3 by Marie E. Rognes
Update references.
1428
  {
1429
    return 1;
1430
  }
1431
1432
  /// Return the number of dofs on each cell facet
1675.1.101 by Garth N. Wells
size_t updates for tests
1433
  virtual std::size_t num_facet_dofs() const
1672.1.3 by Marie E. Rognes
Update references.
1434
  {
1435
    return 0;
1436
  }
1437
1438
  /// Return the number of dofs associated with each cell entity of dimension d
1675.1.101 by Garth N. Wells
size_t updates for tests
1439
  virtual std::size_t num_entity_dofs(std::size_t d) const
1672.1.3 by Marie E. Rognes
Update references.
1440
  {
1441
    switch (d)
1442
    {
1443
    case 0:
1444
      {
1445
        return 0;
1446
        break;
1447
      }
1448
    case 1:
1449
      {
1450
        return 0;
1451
        break;
1452
      }
1453
    case 2:
1454
      {
1455
        return 1;
1456
        break;
1457
      }
1458
    }
1459
    
1460
    return 0;
1461
  }
1462
1463
  /// Tabulate the local-to-global mapping of dofs on a cell
1675.1.101 by Garth N. Wells
size_t updates for tests
1464
  virtual void tabulate_dofs(std::size_t* dofs,
1675.1.105 by Martin Sandve Alnaes
Update references.
1465
                             const std::vector<std::size_t>& num_global_entities,
1672.1.3 by Marie E. Rognes
Update references.
1466
                             const ufc::cell& c) const
1467
  {
1675.1.22 by Marie E. Rognes
Update references after change DG0 -> Real for Constant.
1468
    dofs[0] = 0;
1672.1.3 by Marie E. Rognes
Update references.
1469
  }
1470
1471
  /// Tabulate the local-to-local mapping from facet dofs to cell dofs
1675.1.101 by Garth N. Wells
size_t updates for tests
1472
  virtual void tabulate_facet_dofs(std::size_t* dofs,
1473
                                   std::size_t facet) const
1672.1.3 by Marie E. Rognes
Update references.
1474
  {
1475
    switch (facet)
1476
    {
1477
    case 0:
1478
      {
1479
        
1480
        break;
1481
      }
1482
    case 1:
1483
      {
1484
        
1485
        break;
1486
      }
1487
    case 2:
1488
      {
1489
        
1490
        break;
1491
      }
1492
    }
1493
    
1494
  }
1495
1496
  /// Tabulate the local-to-local mapping of dofs on entity (d, i)
1675.1.101 by Garth N. Wells
size_t updates for tests
1497
  virtual void tabulate_entity_dofs(std::size_t* dofs,
1498
                                    std::size_t d, std::size_t i) const
1672.1.3 by Marie E. Rognes
Update references.
1499
  {
1500
    if (d > 2)
1501
    {
1502
    std::cerr << "*** FFC warning: " << "d is larger than dimension (2)" << std::endl;
1503
    }
1504
    
1505
    switch (d)
1506
    {
1507
    case 0:
1508
      {
1509
        
1510
        break;
1511
      }
1512
    case 1:
1513
      {
1514
        
1515
        break;
1516
      }
1517
    case 2:
1518
      {
1519
        if (i > 0)
1520
      {
1521
      std::cerr << "*** FFC warning: " << "i is larger than number of entities (0)" << std::endl;
1522
      }
1523
      
1524
      dofs[0] = 0;
1525
        break;
1526
      }
1527
    }
1528
    
1529
  }
1530
1531
  /// Tabulate the coordinates of all dofs on a cell
1532
  virtual void tabulate_coordinates(double** coordinates,
1533
                                    const ufc::cell& c) const
1534
  {
1535
    const double * const * x = c.coordinates;
1536
    
1537
    coordinates[0][0] = 0.33333333*x[0][0] + 0.33333333*x[1][0] + 0.33333333*x[2][0];
1538
    coordinates[0][1] = 0.33333333*x[0][1] + 0.33333333*x[1][1] + 0.33333333*x[2][1];
1539
  }
1540
1541
  /// Return the number of sub dofmaps (for a mixed element)
1675.1.101 by Garth N. Wells
size_t updates for tests
1542
  virtual std::size_t num_sub_dofmaps() const
1672.1.3 by Marie E. Rognes
Update references.
1543
  {
1544
    return 0;
1545
  }
1546
1547
  /// Create a new dofmap for sub dofmap i (for a mixed element)
1675.1.101 by Garth N. Wells
size_t updates for tests
1548
  virtual ufc::dofmap* create_sub_dofmap(std::size_t i) const
1672.1.3 by Marie E. Rognes
Update references.
1549
  {
1550
    return 0;
1551
  }
1552
1553
  /// Create a new class instance
1554
  virtual ufc::dofmap* create() const
1555
  {
1556
    return new heat_dofmap_0();
1557
  }
1558
1559
};
1560
1561
/// This class defines the interface for a local-to-global mapping of
1562
/// degrees of freedom (dofs).
1563
1564
class heat_dofmap_1: public ufc::dofmap
1565
{
1566
public:
1567
1568
  /// Constructor
1569
  heat_dofmap_1() : ufc::dofmap()
1570
  {
1675.1.105 by Martin Sandve Alnaes
Update references.
1571
    // Do nothing
1672.1.3 by Marie E. Rognes
Update references.
1572
  }
1573
1574
  /// Destructor
1575
  virtual ~heat_dofmap_1()
1576
  {
1577
    // Do nothing
1578
  }
1579
1580
  /// Return a string identifying the dofmap
1581
  virtual const char* signature() const
1582
  {
1675.1.129 by Martin Sandve Alnaes
Update references to match ufl multidomain changes.
1583
    return "FFC dofmap for FiniteElement('Lagrange', Domain(Cell('triangle', 2), 'triangle_multiverse', 2, 2), 1, None)";
1672.1.3 by Marie E. Rognes
Update references.
1584
  }
1585
1586
  /// Return true iff mesh entities of topological dimension d are needed
1675.1.101 by Garth N. Wells
size_t updates for tests
1587
  virtual bool needs_mesh_entities(std::size_t d) const
1672.1.3 by Marie E. Rognes
Update references.
1588
  {
1589
    switch (d)
1590
    {
1591
    case 0:
1592
      {
1593
        return true;
1594
        break;
1595
      }
1596
    case 1:
1597
      {
1598
        return false;
1599
        break;
1600
      }
1601
    case 2:
1602
      {
1603
        return false;
1604
        break;
1605
      }
1606
    }
1607
    
1608
    return false;
1609
  }
1610
1611
  /// Return the topological dimension of the associated cell shape
1675.1.101 by Garth N. Wells
size_t updates for tests
1612
  virtual std::size_t topological_dimension() const
1672.1.3 by Marie E. Rognes
Update references.
1613
  {
1614
    return 2;
1615
  }
1616
1617
  /// Return the geometric dimension of the associated cell shape
1675.1.101 by Garth N. Wells
size_t updates for tests
1618
  virtual std::size_t geometric_dimension() const
1672.1.3 by Marie E. Rognes
Update references.
1619
  {
1620
    return 2;
1621
  }
1622
1623
  /// Return the dimension of the global finite element function space
1675.1.105 by Martin Sandve Alnaes
Update references.
1624
  virtual std::size_t global_dimension(const std::vector<std::size_t>&
1625
                                       num_global_entities) const
1672.1.3 by Marie E. Rognes
Update references.
1626
  {
1675.1.105 by Martin Sandve Alnaes
Update references.
1627
    return num_global_entities[0];
1672.1.3 by Marie E. Rognes
Update references.
1628
  }
1629
1630
  /// Return the dimension of the local finite element function space for a cell
1675.1.101 by Garth N. Wells
size_t updates for tests
1631
  virtual std::size_t local_dimension(const ufc::cell& c) const
1672.1.3 by Marie E. Rognes
Update references.
1632
  {
1633
    return 3;
1634
  }
1635
1636
  /// Return the maximum dimension of the local finite element function space
1675.1.101 by Garth N. Wells
size_t updates for tests
1637
  virtual std::size_t max_local_dimension() const
1672.1.3 by Marie E. Rognes
Update references.
1638
  {
1639
    return 3;
1640
  }
1641
1642
  /// Return the number of dofs on each cell facet
1675.1.101 by Garth N. Wells
size_t updates for tests
1643
  virtual std::size_t num_facet_dofs() const
1672.1.3 by Marie E. Rognes
Update references.
1644
  {
1645
    return 2;
1646
  }
1647
1648
  /// Return the number of dofs associated with each cell entity of dimension d
1675.1.101 by Garth N. Wells
size_t updates for tests
1649
  virtual std::size_t num_entity_dofs(std::size_t d) const
1672.1.3 by Marie E. Rognes
Update references.
1650
  {
1651
    switch (d)
1652
    {
1653
    case 0:
1654
      {
1655
        return 1;
1656
        break;
1657
      }
1658
    case 1:
1659
      {
1660
        return 0;
1661
        break;
1662
      }
1663
    case 2:
1664
      {
1665
        return 0;
1666
        break;
1667
      }
1668
    }
1669
    
1670
    return 0;
1671
  }
1672
1673
  /// Tabulate the local-to-global mapping of dofs on a cell
1675.1.101 by Garth N. Wells
size_t updates for tests
1674
  virtual void tabulate_dofs(std::size_t* dofs,
1675.1.105 by Martin Sandve Alnaes
Update references.
1675
                             const std::vector<std::size_t>& num_global_entities,
1672.1.3 by Marie E. Rognes
Update references.
1676
                             const ufc::cell& c) const
1677
  {
1678
    dofs[0] = c.entity_indices[0][0];
1679
    dofs[1] = c.entity_indices[0][1];
1680
    dofs[2] = c.entity_indices[0][2];
1681
  }
1682
1683
  /// Tabulate the local-to-local mapping from facet dofs to cell dofs
1675.1.101 by Garth N. Wells
size_t updates for tests
1684
  virtual void tabulate_facet_dofs(std::size_t* dofs,
1685
                                   std::size_t facet) const
1672.1.3 by Marie E. Rognes
Update references.
1686
  {
1687
    switch (facet)
1688
    {
1689
    case 0:
1690
      {
1691
        dofs[0] = 1;
1692
      dofs[1] = 2;
1693
        break;
1694
      }
1695
    case 1:
1696
      {
1697
        dofs[0] = 0;
1698
      dofs[1] = 2;
1699
        break;
1700
      }
1701
    case 2:
1702
      {
1703
        dofs[0] = 0;
1704
      dofs[1] = 1;
1705
        break;
1706
      }
1707
    }
1708
    
1709
  }
1710
1711
  /// Tabulate the local-to-local mapping of dofs on entity (d, i)
1675.1.101 by Garth N. Wells
size_t updates for tests
1712
  virtual void tabulate_entity_dofs(std::size_t* dofs,
1713
                                    std::size_t d, std::size_t i) const
1672.1.3 by Marie E. Rognes
Update references.
1714
  {
1715
    if (d > 2)
1716
    {
1717
    std::cerr << "*** FFC warning: " << "d is larger than dimension (2)" << std::endl;
1718
    }
1719
    
1720
    switch (d)
1721
    {
1722
    case 0:
1723
      {
1724
        if (i > 2)
1725
      {
1726
      std::cerr << "*** FFC warning: " << "i is larger than number of entities (2)" << std::endl;
1727
      }
1728
      
1729
      switch (i)
1730
      {
1731
      case 0:
1732
        {
1733
          dofs[0] = 0;
1734
          break;
1735
        }
1736
      case 1:
1737
        {
1738
          dofs[0] = 1;
1739
          break;
1740
        }
1741
      case 2:
1742
        {
1743
          dofs[0] = 2;
1744
          break;
1745
        }
1746
      }
1747
      
1748
        break;
1749
      }
1750
    case 1:
1751
      {
1752
        
1753
        break;
1754
      }
1755
    case 2:
1756
      {
1757
        
1758
        break;
1759
      }
1760
    }
1761
    
1762
  }
1763
1764
  /// Tabulate the coordinates of all dofs on a cell
1765
  virtual void tabulate_coordinates(double** coordinates,
1766
                                    const ufc::cell& c) const
1767
  {
1768
    const double * const * x = c.coordinates;
1769
    
1770
    coordinates[0][0] = x[0][0];
1771
    coordinates[0][1] = x[0][1];
1772
    coordinates[1][0] = x[1][0];
1773
    coordinates[1][1] = x[1][1];
1774
    coordinates[2][0] = x[2][0];
1775
    coordinates[2][1] = x[2][1];
1776
  }
1777
1778
  /// Return the number of sub dofmaps (for a mixed element)
1675.1.101 by Garth N. Wells
size_t updates for tests
1779
  virtual std::size_t num_sub_dofmaps() const
1672.1.3 by Marie E. Rognes
Update references.
1780
  {
1781
    return 0;
1782
  }
1783
1784
  /// Create a new dofmap for sub dofmap i (for a mixed element)
1675.1.101 by Garth N. Wells
size_t updates for tests
1785
  virtual ufc::dofmap* create_sub_dofmap(std::size_t i) const
1672.1.3 by Marie E. Rognes
Update references.
1786
  {
1787
    return 0;
1788
  }
1789
1790
  /// Create a new class instance
1791
  virtual ufc::dofmap* create() const
1792
  {
1793
    return new heat_dofmap_1();
1794
  }
1795
1796
};
1797
1798
/// This class defines the interface for the tabulation of the cell
1799
/// tensor corresponding to the local contribution to a form from
1800
/// the integral over a cell.
1801
1802
class heat_cell_integral_0_0: public ufc::cell_integral
1803
{
1804
public:
1805
1806
  /// Constructor
1807
  heat_cell_integral_0_0() : ufc::cell_integral()
1808
  {
1809
    // Do nothing
1810
  }
1811
1812
  /// Destructor
1813
  virtual ~heat_cell_integral_0_0()
1814
  {
1815
    // Do nothing
1816
  }
1817
1818
  /// Tabulate the tensor for the contribution from a local cell
1819
  virtual void tabulate_tensor(double* A,
1820
                               const double * const * w,
1821
                               const ufc::cell& c) const
1822
  {
1823
    // Extract vertex coordinates
1824
    const double * const * x = c.coordinates;
1825
    
1826
    // Compute Jacobian of affine map from reference cell
1827
    const double J_00 = x[1][0] - x[0][0];
1828
    const double J_01 = x[2][0] - x[0][0];
1829
    const double J_10 = x[1][1] - x[0][1];
1830
    const double J_11 = x[2][1] - x[0][1];
1831
    
1832
    // Compute determinant of Jacobian
1675.17.30 by Marie E. Rognes
Update references after changing some doubles to const double.
1833
    const double detJ = J_00*J_11 - J_01*J_10;
1672.1.3 by Marie E. Rognes
Update references.
1834
    
1835
    // Compute inverse of Jacobian
1836
    const double K_00 =  J_11 / detJ;
1837
    const double K_01 = -J_01 / detJ;
1838
    const double K_10 = -J_10 / detJ;
1839
    const double K_11 =  J_00 / detJ;
1840
    
1841
    // Set scale factor
1842
    const double det = std::abs(detJ);
1843
    
1675.17.74 by Marie E. Rognes
Update references after changes in comments
1844
    // Cell volume.
1672.1.3 by Marie E. Rognes
Update references.
1845
    
1675.17.74 by Marie E. Rognes
Update references after changes in comments
1846
    // Compute circumradius of triangle in 2D.
1672.1.3 by Marie E. Rognes
Update references.
1847
    
1848
    
1675.1.43 by Kristian B. Ølgaard
Update references due to new 'facet area comment' present in the header files.
1849
    // Facet Area.
1850
    
1672.1.3 by Marie E. Rognes
Update references.
1851
    // Array of quadrature weights.
1852
    static const double W3[3] = {0.16666667, 0.16666667, 0.16666667};
1853
    // Quadrature points on the UFC reference element: (0.16666667, 0.16666667), (0.16666667, 0.66666667), (0.66666667, 0.16666667)
1854
    
1855
    // Value of basis functions at quadrature points.
1856
    static const double FE0[3][3] = \
1857
    {{0.66666667, 0.16666667, 0.16666667},
1858
    {0.16666667, 0.16666667, 0.66666667},
1859
    {0.16666667, 0.66666667, 0.16666667}};
1860
    
1861
    static const double FE0_D01[3][3] = \
1862
    {{-1.0, 0.0, 1.0},
1863
    {-1.0, 0.0, 1.0},
1864
    {-1.0, 0.0, 1.0}};
1865
    
1866
    static const double FE0_D10[3][3] = \
1867
    {{-1.0, 1.0, 0.0},
1868
    {-1.0, 1.0, 0.0},
1869
    {-1.0, 1.0, 0.0}};
1870
    
1871
    // Reset values in the element tensor.
1872
    for (unsigned int r = 0; r < 9; r++)
1873
    {
1874
      A[r] = 0.0;
1875
    }// end loop over 'r'
1876
    
1877
    // Compute element tensor using UFL quadrature representation
1878
    // Optimisations: ('eliminate zeros', False), ('ignore ones', False), ('ignore zero tables', False), ('optimisation', False), ('remove zero terms', False)
1879
    
1880
    // Loop quadrature points for integral.
1881
    // Number of operations to compute element tensor for following IP loop = 612
1882
    for (unsigned int ip = 0; ip < 3; ip++)
1883
    {
1884
      
1885
      // Coefficient declarations.
1886
      double F0 = 0.0;
1887
      
1888
      // Total number of operations to compute function values = 6
1889
      for (unsigned int r = 0; r < 3; r++)
1890
      {
1891
        F0 += FE0[ip][r]*w[0][r];
1892
      }// end loop over 'r'
1893
      
1894
      // Number of operations for primary indices: 198
1895
      for (unsigned int j = 0; j < 3; j++)
1896
      {
1897
        for (unsigned int k = 0; k < 3; k++)
1898
        {
1899
          // Number of operations to compute entry: 22
1900
          A[j*3 + k] += (FE0[ip][j]*FE0[ip][k] + ((((K_00*FE0_D10[ip][j] + K_10*FE0_D01[ip][j]))*((K_00*FE0_D10[ip][k] + K_10*FE0_D01[ip][k])) + ((K_01*FE0_D10[ip][j] + K_11*FE0_D01[ip][j]))*((K_01*FE0_D10[ip][k] + K_11*FE0_D01[ip][k]))))*F0*w[1][0])*W3[ip]*det;
1901
        }// end loop over 'k'
1902
      }// end loop over 'j'
1903
    }// end loop over 'ip'
1904
  }
1905
1906
  /// Tabulate the tensor for the contribution from a local cell
1907
  /// using the specified reference cell quadrature points/weights
1908
  virtual void tabulate_tensor(double* A,
1909
                               const double * const * w,
1910
                               const ufc::cell& c,
1675.1.101 by Garth N. Wells
size_t updates for tests
1911
                               std::size_t num_quadrature_points,
1672.1.3 by Marie E. Rognes
Update references.
1912
                               const double * const * quadrature_points,
1913
                               const double* quadrature_weights) const
1914
  {
1915
    std::cerr << "*** FFC warning: " << "Quadrature version of tabulate_tensor not yet implemented (introduced in UFC 2.0)." << std::endl;
1916
  }
1917
1918
};
1919
1920
/// This class defines the interface for the tabulation of the cell
1921
/// tensor corresponding to the local contribution to a form from
1922
/// the integral over a cell.
1923
1924
class heat_cell_integral_1_0: public ufc::cell_integral
1925
{
1926
public:
1927
1928
  /// Constructor
1929
  heat_cell_integral_1_0() : ufc::cell_integral()
1930
  {
1931
    // Do nothing
1932
  }
1933
1934
  /// Destructor
1935
  virtual ~heat_cell_integral_1_0()
1936
  {
1937
    // Do nothing
1938
  }
1939
1940
  /// Tabulate the tensor for the contribution from a local cell
1941
  virtual void tabulate_tensor(double* A,
1942
                               const double * const * w,
1943
                               const ufc::cell& c) const
1944
  {
1945
    // Extract vertex coordinates
1946
    const double * const * x = c.coordinates;
1947
    
1948
    // Compute Jacobian of affine map from reference cell
1949
    const double J_00 = x[1][0] - x[0][0];
1950
    const double J_01 = x[2][0] - x[0][0];
1951
    const double J_10 = x[1][1] - x[0][1];
1952
    const double J_11 = x[2][1] - x[0][1];
1953
    
1954
    // Compute determinant of Jacobian
1675.17.30 by Marie E. Rognes
Update references after changing some doubles to const double.
1955
    const double detJ = J_00*J_11 - J_01*J_10;
1672.1.3 by Marie E. Rognes
Update references.
1956
    
1957
    // Compute inverse of Jacobian
1958
    
1959
    // Set scale factor
1960
    const double det = std::abs(detJ);
1961
    
1675.17.74 by Marie E. Rognes
Update references after changes in comments
1962
    // Cell volume.
1672.1.3 by Marie E. Rognes
Update references.
1963
    
1675.17.74 by Marie E. Rognes
Update references after changes in comments
1964
    // Compute circumradius of triangle in 2D.
1672.1.3 by Marie E. Rognes
Update references.
1965
    
1966
    
1675.1.43 by Kristian B. Ølgaard
Update references due to new 'facet area comment' present in the header files.
1967
    // Facet Area.
1968
    
1672.1.3 by Marie E. Rognes
Update references.
1969
    // Array of quadrature weights.
1970
    static const double W3[3] = {0.16666667, 0.16666667, 0.16666667};
1971
    // Quadrature points on the UFC reference element: (0.16666667, 0.16666667), (0.16666667, 0.66666667), (0.66666667, 0.16666667)
1972
    
1973
    // Value of basis functions at quadrature points.
1974
    static const double FE0[3][3] = \
1975
    {{0.66666667, 0.16666667, 0.16666667},
1976
    {0.16666667, 0.16666667, 0.66666667},
1977
    {0.16666667, 0.66666667, 0.16666667}};
1978
    
1979
    // Reset values in the element tensor.
1980
    for (unsigned int r = 0; r < 3; r++)
1981
    {
1982
      A[r] = 0.0;
1983
    }// end loop over 'r'
1984
    
1985
    // Compute element tensor using UFL quadrature representation
1986
    // Optimisations: ('eliminate zeros', False), ('ignore ones', False), ('ignore zero tables', False), ('optimisation', False), ('remove zero terms', False)
1987
    
1988
    // Loop quadrature points for integral.
1989
    // Number of operations to compute element tensor for following IP loop = 99
1990
    for (unsigned int ip = 0; ip < 3; ip++)
1991
    {
1992
      
1993
      // Coefficient declarations.
1994
      double F0 = 0.0;
1995
      double F1 = 0.0;
1996
      
1997
      // Total number of operations to compute function values = 12
1998
      for (unsigned int r = 0; r < 3; r++)
1999
      {
2000
        F0 += FE0[ip][r]*w[0][r];
2001
        F1 += FE0[ip][r]*w[1][r];
2002
      }// end loop over 'r'
2003
      
2004
      // Number of operations for primary indices: 21
2005
      for (unsigned int j = 0; j < 3; j++)
2006
      {
2007
        // Number of operations to compute entry: 7
2008
        A[j] += (FE0[ip][j]*F0 + FE0[ip][j]*F1*w[2][0])*W3[ip]*det;
2009
      }// end loop over 'j'
2010
    }// end loop over 'ip'
2011
  }
2012
2013
  /// Tabulate the tensor for the contribution from a local cell
2014
  /// using the specified reference cell quadrature points/weights
2015
  virtual void tabulate_tensor(double* A,
2016
                               const double * const * w,
2017
                               const ufc::cell& c,
1675.1.101 by Garth N. Wells
size_t updates for tests
2018
                               std::size_t num_quadrature_points,
1672.1.3 by Marie E. Rognes
Update references.
2019
                               const double * const * quadrature_points,
2020
                               const double* quadrature_weights) const
2021
  {
2022
    std::cerr << "*** FFC warning: " << "Quadrature version of tabulate_tensor not yet implemented (introduced in UFC 2.0)." << std::endl;
2023
  }
2024
2025
};
2026
2027
/// This class defines the interface for the assembly of the global
2028
/// tensor corresponding to a form with r + n arguments, that is, a
2029
/// mapping
2030
///
2031
///     a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
2032
///
2033
/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
2034
/// global tensor A is defined by
2035
///
2036
///     A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
2037
///
2038
/// where each argument Vj represents the application to the
2039
/// sequence of basis functions of Vj and w1, w2, ..., wn are given
2040
/// fixed functions (coefficients).
2041
2042
class heat_form_0: public ufc::form
2043
{
2044
public:
2045
2046
  /// Constructor
2047
  heat_form_0() : ufc::form()
2048
  {
2049
    // Do nothing
2050
  }
2051
2052
  /// Destructor
2053
  virtual ~heat_form_0()
2054
  {
2055
    // Do nothing
2056
  }
2057
2058
  /// Return a string identifying the form
2059
  virtual const char* signature() const
2060
  {
1675.1.129 by Martin Sandve Alnaes
Update references to match ufl multidomain changes.
2061
    return "beabc8cbfdbde2305229a06a22fc65169df459942208b7edbad5638470484817dd7b24adf340e04be94824a800269900212bbcd0e8e41c86261007b33e4bb8d6";
1672.1.3 by Marie E. Rognes
Update references.
2062
  }
2063
2064
  /// Return the rank of the global tensor (r)
1675.1.101 by Garth N. Wells
size_t updates for tests
2065
  virtual std::size_t rank() const
1672.1.3 by Marie E. Rognes
Update references.
2066
  {
2067
    return 2;
2068
  }
2069
2070
  /// Return the number of coefficients (n)
1675.1.101 by Garth N. Wells
size_t updates for tests
2071
  virtual std::size_t num_coefficients() const
1672.1.3 by Marie E. Rognes
Update references.
2072
  {
2073
    return 2;
2074
  }
2075
2076
  /// Return the number of cell domains
1675.1.101 by Garth N. Wells
size_t updates for tests
2077
  virtual std::size_t num_cell_domains() const
1672.1.3 by Marie E. Rognes
Update references.
2078
  {
2079
    return 1;
2080
  }
2081
2082
  /// Return the number of exterior facet domains
1675.1.101 by Garth N. Wells
size_t updates for tests
2083
  virtual std::size_t num_exterior_facet_domains() const
1672.1.3 by Marie E. Rognes
Update references.
2084
  {
2085
    return 0;
2086
  }
2087
2088
  /// Return the number of interior facet domains
1675.1.101 by Garth N. Wells
size_t updates for tests
2089
  virtual std::size_t num_interior_facet_domains() const
1672.1.3 by Marie E. Rognes
Update references.
2090
  {
2091
    return 0;
2092
  }
2093
1675.1.131 by Martin Sandve Alnaes
Update reference files.
2094
  /// Return whether the form has any cell integrals
2095
  virtual bool has_cell_integrals() const
2096
  {
2097
    return true;
2098
  }
2099
2100
  /// Return whether the form has any exterior facet integrals
2101
  virtual bool has_exterior_facet_integrals() const
2102
  {
2103
    return false;
2104
  }
2105
2106
  /// Return whether the form has any interior facet integrals
2107
  virtual bool has_interior_facet_integrals() const
2108
  {
2109
    return false;
2110
  }
2111
1672.1.3 by Marie E. Rognes
Update references.
2112
  /// Create a new finite element for argument function i
1675.1.101 by Garth N. Wells
size_t updates for tests
2113
  virtual ufc::finite_element* create_finite_element(std::size_t i) const
1672.1.3 by Marie E. Rognes
Update references.
2114
  {
2115
    switch (i)
2116
    {
2117
    case 0:
2118
      {
2119
        return new heat_finite_element_1();
2120
        break;
2121
      }
2122
    case 1:
2123
      {
2124
        return new heat_finite_element_1();
2125
        break;
2126
      }
2127
    case 2:
2128
      {
2129
        return new heat_finite_element_1();
2130
        break;
2131
      }
2132
    case 3:
2133
      {
2134
        return new heat_finite_element_0();
2135
        break;
2136
      }
2137
    }
2138
    
2139
    return 0;
2140
  }
2141
2142
  /// Create a new dofmap for argument function i
1675.1.101 by Garth N. Wells
size_t updates for tests
2143
  virtual ufc::dofmap* create_dofmap(std::size_t i) const
1672.1.3 by Marie E. Rognes
Update references.
2144
  {
2145
    switch (i)
2146
    {
2147
    case 0:
2148
      {
2149
        return new heat_dofmap_1();
2150
        break;
2151
      }
2152
    case 1:
2153
      {
2154
        return new heat_dofmap_1();
2155
        break;
2156
      }
2157
    case 2:
2158
      {
2159
        return new heat_dofmap_1();
2160
        break;
2161
      }
2162
    case 3:
2163
      {
2164
        return new heat_dofmap_0();
2165
        break;
2166
      }
2167
    }
2168
    
2169
    return 0;
2170
  }
2171
2172
  /// Create a new cell integral on sub domain i
1675.1.101 by Garth N. Wells
size_t updates for tests
2173
  virtual ufc::cell_integral* create_cell_integral(std::size_t i) const
1672.1.3 by Marie E. Rognes
Update references.
2174
  {
2175
    switch (i)
2176
    {
2177
    case 0:
2178
      {
2179
        return new heat_cell_integral_0_0();
2180
        break;
2181
      }
2182
    }
2183
    
2184
    return 0;
2185
  }
2186
2187
  /// Create a new exterior facet integral on sub domain i
1675.1.101 by Garth N. Wells
size_t updates for tests
2188
  virtual ufc::exterior_facet_integral* create_exterior_facet_integral(std::size_t i) const
1672.1.3 by Marie E. Rognes
Update references.
2189
  {
2190
    return 0;
2191
  }
2192
2193
  /// Create a new interior facet integral on sub domain i
1675.1.101 by Garth N. Wells
size_t updates for tests
2194
  virtual ufc::interior_facet_integral* create_interior_facet_integral(std::size_t i) const
1672.1.3 by Marie E. Rognes
Update references.
2195
  {
2196
    return 0;
2197
  }
2198
1675.1.131 by Martin Sandve Alnaes
Update reference files.
2199
  /// Create a new cell integral on everywhere else
2200
  virtual ufc::cell_integral* create_default_cell_integral() const
2201
  {
2202
    return 0;
2203
  }
2204
2205
  /// Create a new exterior facet integral on everywhere else
2206
  virtual ufc::exterior_facet_integral* create_default_exterior_facet_integral() const
2207
  {
2208
    return 0;
2209
  }
2210
2211
  /// Create a new interior facet integral on everywhere else
2212
  virtual ufc::interior_facet_integral* create_default_interior_facet_integral() const
2213
  {
2214
    return 0;
2215
  }
2216
1672.1.3 by Marie E. Rognes
Update references.
2217
};
2218
2219
/// This class defines the interface for the assembly of the global
2220
/// tensor corresponding to a form with r + n arguments, that is, a
2221
/// mapping
2222
///
2223
///     a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
2224
///
2225
/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
2226
/// global tensor A is defined by
2227
///
2228
///     A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
2229
///
2230
/// where each argument Vj represents the application to the
2231
/// sequence of basis functions of Vj and w1, w2, ..., wn are given
2232
/// fixed functions (coefficients).
2233
2234
class heat_form_1: public ufc::form
2235
{
2236
public:
2237
2238
  /// Constructor
2239
  heat_form_1() : ufc::form()
2240
  {
2241
    // Do nothing
2242
  }
2243
2244
  /// Destructor
2245
  virtual ~heat_form_1()
2246
  {
2247
    // Do nothing
2248
  }
2249
2250
  /// Return a string identifying the form
2251
  virtual const char* signature() const
2252
  {
1675.1.129 by Martin Sandve Alnaes
Update references to match ufl multidomain changes.
2253
    return "b90e8813365e5fa06e1e0b75dbbe1a4a7729cc03a1dfd43caa3296bc2908db84d3aac4f9e1220007e11927ad07707d2e9266c2d8d4742a78eecc84fc6831ede1";
1672.1.3 by Marie E. Rognes
Update references.
2254
  }
2255
2256
  /// Return the rank of the global tensor (r)
1675.1.101 by Garth N. Wells
size_t updates for tests
2257
  virtual std::size_t rank() const
1672.1.3 by Marie E. Rognes
Update references.
2258
  {
2259
    return 1;
2260
  }
2261
2262
  /// Return the number of coefficients (n)
1675.1.101 by Garth N. Wells
size_t updates for tests
2263
  virtual std::size_t num_coefficients() const
1672.1.3 by Marie E. Rognes
Update references.
2264
  {
2265
    return 3;
2266
  }
2267
2268
  /// Return the number of cell domains
1675.1.101 by Garth N. Wells
size_t updates for tests
2269
  virtual std::size_t num_cell_domains() const
1672.1.3 by Marie E. Rognes
Update references.
2270
  {
2271
    return 1;
2272
  }
2273
2274
  /// Return the number of exterior facet domains
1675.1.101 by Garth N. Wells
size_t updates for tests
2275
  virtual std::size_t num_exterior_facet_domains() const
1672.1.3 by Marie E. Rognes
Update references.
2276
  {
2277
    return 0;
2278
  }
2279
2280
  /// Return the number of interior facet domains
1675.1.101 by Garth N. Wells
size_t updates for tests
2281
  virtual std::size_t num_interior_facet_domains() const
1672.1.3 by Marie E. Rognes
Update references.
2282
  {
2283
    return 0;
2284
  }
2285
1675.1.131 by Martin Sandve Alnaes
Update reference files.
2286
  /// Return whether the form has any cell integrals
2287
  virtual bool has_cell_integrals() const
2288
  {
2289
    return true;
2290
  }
2291
2292
  /// Return whether the form has any exterior facet integrals
2293
  virtual bool has_exterior_facet_integrals() const
2294
  {
2295
    return false;
2296
  }
2297
2298
  /// Return whether the form has any interior facet integrals
2299
  virtual bool has_interior_facet_integrals() const
2300
  {
2301
    return false;
2302
  }
2303
1672.1.3 by Marie E. Rognes
Update references.
2304
  /// Create a new finite element for argument function i
1675.1.101 by Garth N. Wells
size_t updates for tests
2305
  virtual ufc::finite_element* create_finite_element(std::size_t i) const
1672.1.3 by Marie E. Rognes
Update references.
2306
  {
2307
    switch (i)
2308
    {
2309
    case 0:
2310
      {
2311
        return new heat_finite_element_1();
2312
        break;
2313
      }
2314
    case 1:
2315
      {
2316
        return new heat_finite_element_1();
2317
        break;
2318
      }
2319
    case 2:
2320
      {
2321
        return new heat_finite_element_1();
2322
        break;
2323
      }
2324
    case 3:
2325
      {
2326
        return new heat_finite_element_0();
2327
        break;
2328
      }
2329
    }
2330
    
2331
    return 0;
2332
  }
2333
2334
  /// Create a new dofmap for argument function i
1675.1.101 by Garth N. Wells
size_t updates for tests
2335
  virtual ufc::dofmap* create_dofmap(std::size_t i) const
1672.1.3 by Marie E. Rognes
Update references.
2336
  {
2337
    switch (i)
2338
    {
2339
    case 0:
2340
      {
2341
        return new heat_dofmap_1();
2342
        break;
2343
      }
2344
    case 1:
2345
      {
2346
        return new heat_dofmap_1();
2347
        break;
2348
      }
2349
    case 2:
2350
      {
2351
        return new heat_dofmap_1();
2352
        break;
2353
      }
2354
    case 3:
2355
      {
2356
        return new heat_dofmap_0();
2357
        break;
2358
      }
2359
    }
2360
    
2361
    return 0;
2362
  }
2363
2364
  /// Create a new cell integral on sub domain i
1675.1.101 by Garth N. Wells
size_t updates for tests
2365
  virtual ufc::cell_integral* create_cell_integral(std::size_t i) const
1672.1.3 by Marie E. Rognes
Update references.
2366
  {
2367
    switch (i)
2368
    {
2369
    case 0:
2370
      {
2371
        return new heat_cell_integral_1_0();
2372
        break;
2373
      }
2374
    }
2375
    
2376
    return 0;
2377
  }
2378
2379
  /// Create a new exterior facet integral on sub domain i
1675.1.101 by Garth N. Wells
size_t updates for tests
2380
  virtual ufc::exterior_facet_integral* create_exterior_facet_integral(std::size_t i) const
1672.1.3 by Marie E. Rognes
Update references.
2381
  {
2382
    return 0;
2383
  }
2384
2385
  /// Create a new interior facet integral on sub domain i
1675.1.101 by Garth N. Wells
size_t updates for tests
2386
  virtual ufc::interior_facet_integral* create_interior_facet_integral(std::size_t i) const
1672.1.3 by Marie E. Rognes
Update references.
2387
  {
2388
    return 0;
2389
  }
2390
1675.1.131 by Martin Sandve Alnaes
Update reference files.
2391
  /// Create a new cell integral on everywhere else
2392
  virtual ufc::cell_integral* create_default_cell_integral() const
2393
  {
2394
    return 0;
2395
  }
2396
2397
  /// Create a new exterior facet integral on everywhere else
2398
  virtual ufc::exterior_facet_integral* create_default_exterior_facet_integral() const
2399
  {
2400
    return 0;
2401
  }
2402
2403
  /// Create a new interior facet integral on everywhere else
2404
  virtual ufc::interior_facet_integral* create_default_interior_facet_integral() const
2405
  {
2406
    return 0;
2407
  }
2408
1672.1.3 by Marie E. Rognes
Update references.
2409
};
2410
2411
#endif