~njansson/dolfin/hpc

« back to all changes in this revision

Viewing changes to include/dolfin/elements/ffc_23.h

  • Committer: Niclas Jansson
  • Date: 2011-06-10 14:33:43 UTC
  • Revision ID: njansson@csc.kth.se-20110610143343-d21p4am8rghiojfm
Added rudimentary header to binary files

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// This code conforms with the UFC specification version 1.0
 
2
// and was automatically generated by FFC version 0.5.0.
 
3
 
 
4
#ifndef __FFC_23_H
 
5
#define __FFC_23_H
 
6
 
 
7
#include <cmath>
 
8
#include <stdexcept>
 
9
#include <ufc.h>
 
10
 
 
11
/// This class defines the interface for a finite element.
 
12
 
 
13
class ffc_23_finite_element_0_0: public ufc::finite_element
 
14
{
 
15
public:
 
16
 
 
17
  /// Constructor
 
18
  ffc_23_finite_element_0_0() : ufc::finite_element()
 
19
  {
 
20
    // Do nothing
 
21
  }
 
22
 
 
23
  /// Destructor
 
24
  virtual ~ffc_23_finite_element_0_0()
 
25
  {
 
26
    // Do nothing
 
27
  }
 
28
 
 
29
  /// Return a string identifying the finite element
 
30
  virtual const char* signature() const
 
31
  {
 
32
    return "Discontinuous Lagrange finite element of degree 2 on a tetrahedron";
 
33
  }
 
34
 
 
35
  /// Return the cell shape
 
36
  virtual ufc::shape cell_shape() const
 
37
  {
 
38
    return ufc::tetrahedron;
 
39
  }
 
40
 
 
41
  /// Return the dimension of the finite element function space
 
42
  virtual unsigned int space_dimension() const
 
43
  {
 
44
    return 10;
 
45
  }
 
46
 
 
47
  /// Return the rank of the value space
 
48
  virtual unsigned int value_rank() const
 
49
  {
 
50
    return 0;
 
51
  }
 
52
 
 
53
  /// Return the dimension of the value space for axis i
 
54
  virtual unsigned int value_dimension(unsigned int i) const
 
55
  {
 
56
    return 1;
 
57
  }
 
58
 
 
59
  /// Evaluate basis function i at given point in cell
 
60
  virtual void evaluate_basis(unsigned int i,
 
61
                              double* values,
 
62
                              const double* coordinates,
 
63
                              const ufc::cell& c) const
 
64
  {
 
65
    throw std::runtime_error("// Function evaluate_basis not generated (compiled with -fno-evaluate_basis)");
 
66
  }
 
67
 
 
68
  /// Evaluate all basis functions at given point in cell
 
69
  virtual void evaluate_basis_all(double* values,
 
70
                                  const double* coordinates,
 
71
                                  const ufc::cell& c) const
 
72
  {
 
73
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
74
  }
 
75
 
 
76
  /// Evaluate order n derivatives of basis function i at given point in cell
 
77
  virtual void evaluate_basis_derivatives(unsigned int i,
 
78
                                          unsigned int n,
 
79
                                          double* values,
 
80
                                          const double* coordinates,
 
81
                                          const ufc::cell& c) const
 
82
  {
 
83
    throw std::runtime_error("// Function evaluate_basis_derivatives not generated (compiled with -fno-evaluate_basis_derivatives)");
 
84
  }
 
85
 
 
86
  /// Evaluate order n derivatives of all basis functions at given point in cell
 
87
  virtual void evaluate_basis_derivatives_all(unsigned int n,
 
88
                                              double* values,
 
89
                                              const double* coordinates,
 
90
                                              const ufc::cell& c) const
 
91
  {
 
92
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
93
  }
 
94
 
 
95
  /// Evaluate linear functional for dof i on the function f
 
96
  virtual double evaluate_dof(unsigned int i,
 
97
                              const ufc::function& f,
 
98
                              const ufc::cell& c) const
 
99
  {
 
100
    // The reference points, direction and weights:
 
101
    const static double X[10][1][3] = {{{0, 0, 0}}, {{0.5, 0, 0}}, {{1, 0, 0}}, {{0, 0.5, 0}}, {{0.5, 0.5, 0}}, {{0, 1, 0}}, {{0, 0, 0.5}}, {{0.5, 0, 0.5}}, {{0, 0.5, 0.5}}, {{0, 0, 1}}};
 
102
    const static double W[10][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
 
103
    const static double D[10][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
 
104
    
 
105
    const double * const * x = c.coordinates;
 
106
    double result = 0.0;
 
107
    // Iterate over the points:
 
108
    // Evaluate basis functions for affine mapping
 
109
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
 
110
    const double w1 = X[i][0][0];
 
111
    const double w2 = X[i][0][1];
 
112
    const double w3 = X[i][0][2];
 
113
    
 
114
    // Compute affine mapping y = F(X)
 
115
    double y[3];
 
116
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
 
117
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
 
118
    y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
 
119
    
 
120
    // Evaluate function at physical points
 
121
    double values[1];
 
122
    f.evaluate(values, y, c);
 
123
    
 
124
    // Map function values using appropriate mapping
 
125
    // Affine map: Do nothing
 
126
    
 
127
    // Note that we do not map the weights (yet).
 
128
    
 
129
    // Take directional components
 
130
    for(int k = 0; k < 1; k++)
 
131
      result += values[k]*D[i][0][k];
 
132
    // Multiply by weights 
 
133
    result *= W[i][0];
 
134
    
 
135
    return result;
 
136
  }
 
137
 
 
138
  /// Evaluate linear functionals for all dofs on the function f
 
139
  virtual void evaluate_dofs(double* values,
 
140
                             const ufc::function& f,
 
141
                             const ufc::cell& c) const
 
142
  {
 
143
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
144
  }
 
145
 
 
146
  /// Interpolate vertex values from dof values
 
147
  virtual void interpolate_vertex_values(double* vertex_values,
 
148
                                         const double* dof_values,
 
149
                                         const ufc::cell& c) const
 
150
  {
 
151
    // Evaluate at vertices and use affine mapping
 
152
    vertex_values[0] = dof_values[0];
 
153
    vertex_values[1] = dof_values[2];
 
154
    vertex_values[2] = dof_values[5];
 
155
    vertex_values[3] = dof_values[9];
 
156
  }
 
157
 
 
158
  /// Return the number of sub elements (for a mixed element)
 
159
  virtual unsigned int num_sub_elements() const
 
160
  {
 
161
    return 1;
 
162
  }
 
163
 
 
164
  /// Create a new finite element for sub element i (for a mixed element)
 
165
  virtual ufc::finite_element* create_sub_element(unsigned int i) const
 
166
  {
 
167
    return new ffc_23_finite_element_0_0();
 
168
  }
 
169
 
 
170
};
 
171
 
 
172
/// This class defines the interface for a finite element.
 
173
 
 
174
class ffc_23_finite_element_0_1: public ufc::finite_element
 
175
{
 
176
public:
 
177
 
 
178
  /// Constructor
 
179
  ffc_23_finite_element_0_1() : ufc::finite_element()
 
180
  {
 
181
    // Do nothing
 
182
  }
 
183
 
 
184
  /// Destructor
 
185
  virtual ~ffc_23_finite_element_0_1()
 
186
  {
 
187
    // Do nothing
 
188
  }
 
189
 
 
190
  /// Return a string identifying the finite element
 
191
  virtual const char* signature() const
 
192
  {
 
193
    return "Discontinuous Lagrange finite element of degree 2 on a tetrahedron";
 
194
  }
 
195
 
 
196
  /// Return the cell shape
 
197
  virtual ufc::shape cell_shape() const
 
198
  {
 
199
    return ufc::tetrahedron;
 
200
  }
 
201
 
 
202
  /// Return the dimension of the finite element function space
 
203
  virtual unsigned int space_dimension() const
 
204
  {
 
205
    return 10;
 
206
  }
 
207
 
 
208
  /// Return the rank of the value space
 
209
  virtual unsigned int value_rank() const
 
210
  {
 
211
    return 0;
 
212
  }
 
213
 
 
214
  /// Return the dimension of the value space for axis i
 
215
  virtual unsigned int value_dimension(unsigned int i) const
 
216
  {
 
217
    return 1;
 
218
  }
 
219
 
 
220
  /// Evaluate basis function i at given point in cell
 
221
  virtual void evaluate_basis(unsigned int i,
 
222
                              double* values,
 
223
                              const double* coordinates,
 
224
                              const ufc::cell& c) const
 
225
  {
 
226
    throw std::runtime_error("// Function evaluate_basis not generated (compiled with -fno-evaluate_basis)");
 
227
  }
 
228
 
 
229
  /// Evaluate all basis functions at given point in cell
 
230
  virtual void evaluate_basis_all(double* values,
 
231
                                  const double* coordinates,
 
232
                                  const ufc::cell& c) const
 
233
  {
 
234
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
235
  }
 
236
 
 
237
  /// Evaluate order n derivatives of basis function i at given point in cell
 
238
  virtual void evaluate_basis_derivatives(unsigned int i,
 
239
                                          unsigned int n,
 
240
                                          double* values,
 
241
                                          const double* coordinates,
 
242
                                          const ufc::cell& c) const
 
243
  {
 
244
    throw std::runtime_error("// Function evaluate_basis_derivatives not generated (compiled with -fno-evaluate_basis_derivatives)");
 
245
  }
 
246
 
 
247
  /// Evaluate order n derivatives of all basis functions at given point in cell
 
248
  virtual void evaluate_basis_derivatives_all(unsigned int n,
 
249
                                              double* values,
 
250
                                              const double* coordinates,
 
251
                                              const ufc::cell& c) const
 
252
  {
 
253
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
254
  }
 
255
 
 
256
  /// Evaluate linear functional for dof i on the function f
 
257
  virtual double evaluate_dof(unsigned int i,
 
258
                              const ufc::function& f,
 
259
                              const ufc::cell& c) const
 
260
  {
 
261
    // The reference points, direction and weights:
 
262
    const static double X[10][1][3] = {{{0, 0, 0}}, {{0.5, 0, 0}}, {{1, 0, 0}}, {{0, 0.5, 0}}, {{0.5, 0.5, 0}}, {{0, 1, 0}}, {{0, 0, 0.5}}, {{0.5, 0, 0.5}}, {{0, 0.5, 0.5}}, {{0, 0, 1}}};
 
263
    const static double W[10][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
 
264
    const static double D[10][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
 
265
    
 
266
    const double * const * x = c.coordinates;
 
267
    double result = 0.0;
 
268
    // Iterate over the points:
 
269
    // Evaluate basis functions for affine mapping
 
270
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
 
271
    const double w1 = X[i][0][0];
 
272
    const double w2 = X[i][0][1];
 
273
    const double w3 = X[i][0][2];
 
274
    
 
275
    // Compute affine mapping y = F(X)
 
276
    double y[3];
 
277
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
 
278
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
 
279
    y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
 
280
    
 
281
    // Evaluate function at physical points
 
282
    double values[1];
 
283
    f.evaluate(values, y, c);
 
284
    
 
285
    // Map function values using appropriate mapping
 
286
    // Affine map: Do nothing
 
287
    
 
288
    // Note that we do not map the weights (yet).
 
289
    
 
290
    // Take directional components
 
291
    for(int k = 0; k < 1; k++)
 
292
      result += values[k]*D[i][0][k];
 
293
    // Multiply by weights 
 
294
    result *= W[i][0];
 
295
    
 
296
    return result;
 
297
  }
 
298
 
 
299
  /// Evaluate linear functionals for all dofs on the function f
 
300
  virtual void evaluate_dofs(double* values,
 
301
                             const ufc::function& f,
 
302
                             const ufc::cell& c) const
 
303
  {
 
304
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
305
  }
 
306
 
 
307
  /// Interpolate vertex values from dof values
 
308
  virtual void interpolate_vertex_values(double* vertex_values,
 
309
                                         const double* dof_values,
 
310
                                         const ufc::cell& c) const
 
311
  {
 
312
    // Evaluate at vertices and use affine mapping
 
313
    vertex_values[0] = dof_values[0];
 
314
    vertex_values[1] = dof_values[2];
 
315
    vertex_values[2] = dof_values[5];
 
316
    vertex_values[3] = dof_values[9];
 
317
  }
 
318
 
 
319
  /// Return the number of sub elements (for a mixed element)
 
320
  virtual unsigned int num_sub_elements() const
 
321
  {
 
322
    return 1;
 
323
  }
 
324
 
 
325
  /// Create a new finite element for sub element i (for a mixed element)
 
326
  virtual ufc::finite_element* create_sub_element(unsigned int i) const
 
327
  {
 
328
    return new ffc_23_finite_element_0_1();
 
329
  }
 
330
 
 
331
};
 
332
 
 
333
/// This class defines the interface for a finite element.
 
334
 
 
335
class ffc_23_finite_element_0_2: public ufc::finite_element
 
336
{
 
337
public:
 
338
 
 
339
  /// Constructor
 
340
  ffc_23_finite_element_0_2() : ufc::finite_element()
 
341
  {
 
342
    // Do nothing
 
343
  }
 
344
 
 
345
  /// Destructor
 
346
  virtual ~ffc_23_finite_element_0_2()
 
347
  {
 
348
    // Do nothing
 
349
  }
 
350
 
 
351
  /// Return a string identifying the finite element
 
352
  virtual const char* signature() const
 
353
  {
 
354
    return "Discontinuous Lagrange finite element of degree 2 on a tetrahedron";
 
355
  }
 
356
 
 
357
  /// Return the cell shape
 
358
  virtual ufc::shape cell_shape() const
 
359
  {
 
360
    return ufc::tetrahedron;
 
361
  }
 
362
 
 
363
  /// Return the dimension of the finite element function space
 
364
  virtual unsigned int space_dimension() const
 
365
  {
 
366
    return 10;
 
367
  }
 
368
 
 
369
  /// Return the rank of the value space
 
370
  virtual unsigned int value_rank() const
 
371
  {
 
372
    return 0;
 
373
  }
 
374
 
 
375
  /// Return the dimension of the value space for axis i
 
376
  virtual unsigned int value_dimension(unsigned int i) const
 
377
  {
 
378
    return 1;
 
379
  }
 
380
 
 
381
  /// Evaluate basis function i at given point in cell
 
382
  virtual void evaluate_basis(unsigned int i,
 
383
                              double* values,
 
384
                              const double* coordinates,
 
385
                              const ufc::cell& c) const
 
386
  {
 
387
    throw std::runtime_error("// Function evaluate_basis not generated (compiled with -fno-evaluate_basis)");
 
388
  }
 
389
 
 
390
  /// Evaluate all basis functions at given point in cell
 
391
  virtual void evaluate_basis_all(double* values,
 
392
                                  const double* coordinates,
 
393
                                  const ufc::cell& c) const
 
394
  {
 
395
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
396
  }
 
397
 
 
398
  /// Evaluate order n derivatives of basis function i at given point in cell
 
399
  virtual void evaluate_basis_derivatives(unsigned int i,
 
400
                                          unsigned int n,
 
401
                                          double* values,
 
402
                                          const double* coordinates,
 
403
                                          const ufc::cell& c) const
 
404
  {
 
405
    throw std::runtime_error("// Function evaluate_basis_derivatives not generated (compiled with -fno-evaluate_basis_derivatives)");
 
406
  }
 
407
 
 
408
  /// Evaluate order n derivatives of all basis functions at given point in cell
 
409
  virtual void evaluate_basis_derivatives_all(unsigned int n,
 
410
                                              double* values,
 
411
                                              const double* coordinates,
 
412
                                              const ufc::cell& c) const
 
413
  {
 
414
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
415
  }
 
416
 
 
417
  /// Evaluate linear functional for dof i on the function f
 
418
  virtual double evaluate_dof(unsigned int i,
 
419
                              const ufc::function& f,
 
420
                              const ufc::cell& c) const
 
421
  {
 
422
    // The reference points, direction and weights:
 
423
    const static double X[10][1][3] = {{{0, 0, 0}}, {{0.5, 0, 0}}, {{1, 0, 0}}, {{0, 0.5, 0}}, {{0.5, 0.5, 0}}, {{0, 1, 0}}, {{0, 0, 0.5}}, {{0.5, 0, 0.5}}, {{0, 0.5, 0.5}}, {{0, 0, 1}}};
 
424
    const static double W[10][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
 
425
    const static double D[10][1][1] = {{{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}, {{1}}};
 
426
    
 
427
    const double * const * x = c.coordinates;
 
428
    double result = 0.0;
 
429
    // Iterate over the points:
 
430
    // Evaluate basis functions for affine mapping
 
431
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
 
432
    const double w1 = X[i][0][0];
 
433
    const double w2 = X[i][0][1];
 
434
    const double w3 = X[i][0][2];
 
435
    
 
436
    // Compute affine mapping y = F(X)
 
437
    double y[3];
 
438
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
 
439
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
 
440
    y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
 
441
    
 
442
    // Evaluate function at physical points
 
443
    double values[1];
 
444
    f.evaluate(values, y, c);
 
445
    
 
446
    // Map function values using appropriate mapping
 
447
    // Affine map: Do nothing
 
448
    
 
449
    // Note that we do not map the weights (yet).
 
450
    
 
451
    // Take directional components
 
452
    for(int k = 0; k < 1; k++)
 
453
      result += values[k]*D[i][0][k];
 
454
    // Multiply by weights 
 
455
    result *= W[i][0];
 
456
    
 
457
    return result;
 
458
  }
 
459
 
 
460
  /// Evaluate linear functionals for all dofs on the function f
 
461
  virtual void evaluate_dofs(double* values,
 
462
                             const ufc::function& f,
 
463
                             const ufc::cell& c) const
 
464
  {
 
465
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
466
  }
 
467
 
 
468
  /// Interpolate vertex values from dof values
 
469
  virtual void interpolate_vertex_values(double* vertex_values,
 
470
                                         const double* dof_values,
 
471
                                         const ufc::cell& c) const
 
472
  {
 
473
    // Evaluate at vertices and use affine mapping
 
474
    vertex_values[0] = dof_values[0];
 
475
    vertex_values[1] = dof_values[2];
 
476
    vertex_values[2] = dof_values[5];
 
477
    vertex_values[3] = dof_values[9];
 
478
  }
 
479
 
 
480
  /// Return the number of sub elements (for a mixed element)
 
481
  virtual unsigned int num_sub_elements() const
 
482
  {
 
483
    return 1;
 
484
  }
 
485
 
 
486
  /// Create a new finite element for sub element i (for a mixed element)
 
487
  virtual ufc::finite_element* create_sub_element(unsigned int i) const
 
488
  {
 
489
    return new ffc_23_finite_element_0_2();
 
490
  }
 
491
 
 
492
};
 
493
 
 
494
/// This class defines the interface for a finite element.
 
495
 
 
496
class ffc_23_finite_element_0: public ufc::finite_element
 
497
{
 
498
public:
 
499
 
 
500
  /// Constructor
 
501
  ffc_23_finite_element_0() : ufc::finite_element()
 
502
  {
 
503
    // Do nothing
 
504
  }
 
505
 
 
506
  /// Destructor
 
507
  virtual ~ffc_23_finite_element_0()
 
508
  {
 
509
    // Do nothing
 
510
  }
 
511
 
 
512
  /// Return a string identifying the finite element
 
513
  virtual const char* signature() const
 
514
  {
 
515
    return "Mixed finite element: [Discontinuous Lagrange finite element of degree 2 on a tetrahedron, Discontinuous Lagrange finite element of degree 2 on a tetrahedron, Discontinuous Lagrange finite element of degree 2 on a tetrahedron]";
 
516
  }
 
517
 
 
518
  /// Return the cell shape
 
519
  virtual ufc::shape cell_shape() const
 
520
  {
 
521
    return ufc::tetrahedron;
 
522
  }
 
523
 
 
524
  /// Return the dimension of the finite element function space
 
525
  virtual unsigned int space_dimension() const
 
526
  {
 
527
    return 30;
 
528
  }
 
529
 
 
530
  /// Return the rank of the value space
 
531
  virtual unsigned int value_rank() const
 
532
  {
 
533
    return 1;
 
534
  }
 
535
 
 
536
  /// Return the dimension of the value space for axis i
 
537
  virtual unsigned int value_dimension(unsigned int i) const
 
538
  {
 
539
    return 3;
 
540
  }
 
541
 
 
542
  /// Evaluate basis function i at given point in cell
 
543
  virtual void evaluate_basis(unsigned int i,
 
544
                              double* values,
 
545
                              const double* coordinates,
 
546
                              const ufc::cell& c) const
 
547
  {
 
548
    throw std::runtime_error("// Function evaluate_basis not generated (compiled with -fno-evaluate_basis)");
 
549
  }
 
550
 
 
551
  /// Evaluate all basis functions at given point in cell
 
552
  virtual void evaluate_basis_all(double* values,
 
553
                                  const double* coordinates,
 
554
                                  const ufc::cell& c) const
 
555
  {
 
556
    throw std::runtime_error("The vectorised version of evaluate_basis() is not yet implemented.");
 
557
  }
 
558
 
 
559
  /// Evaluate order n derivatives of basis function i at given point in cell
 
560
  virtual void evaluate_basis_derivatives(unsigned int i,
 
561
                                          unsigned int n,
 
562
                                          double* values,
 
563
                                          const double* coordinates,
 
564
                                          const ufc::cell& c) const
 
565
  {
 
566
    throw std::runtime_error("// Function evaluate_basis_derivatives not generated (compiled with -fno-evaluate_basis_derivatives)");
 
567
  }
 
568
 
 
569
  /// Evaluate order n derivatives of all basis functions at given point in cell
 
570
  virtual void evaluate_basis_derivatives_all(unsigned int n,
 
571
                                              double* values,
 
572
                                              const double* coordinates,
 
573
                                              const ufc::cell& c) const
 
574
  {
 
575
    throw std::runtime_error("The vectorised version of evaluate_basis_derivatives() is not yet implemented.");
 
576
  }
 
577
 
 
578
  /// Evaluate linear functional for dof i on the function f
 
579
  virtual double evaluate_dof(unsigned int i,
 
580
                              const ufc::function& f,
 
581
                              const ufc::cell& c) const
 
582
  {
 
583
    // The reference points, direction and weights:
 
584
    const static double X[30][1][3] = {{{0, 0, 0}}, {{0.5, 0, 0}}, {{1, 0, 0}}, {{0, 0.5, 0}}, {{0.5, 0.5, 0}}, {{0, 1, 0}}, {{0, 0, 0.5}}, {{0.5, 0, 0.5}}, {{0, 0.5, 0.5}}, {{0, 0, 1}}, {{0, 0, 0}}, {{0.5, 0, 0}}, {{1, 0, 0}}, {{0, 0.5, 0}}, {{0.5, 0.5, 0}}, {{0, 1, 0}}, {{0, 0, 0.5}}, {{0.5, 0, 0.5}}, {{0, 0.5, 0.5}}, {{0, 0, 1}}, {{0, 0, 0}}, {{0.5, 0, 0}}, {{1, 0, 0}}, {{0, 0.5, 0}}, {{0.5, 0.5, 0}}, {{0, 1, 0}}, {{0, 0, 0.5}}, {{0.5, 0, 0.5}}, {{0, 0.5, 0.5}}, {{0, 0, 1}}};
 
585
    const static double W[30][1] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};
 
586
    const static double D[30][1][3] = {{{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{1, 0, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 1, 0}}, {{0, 0, 1}}, {{0, 0, 1}}, {{0, 0, 1}}, {{0, 0, 1}}, {{0, 0, 1}}, {{0, 0, 1}}, {{0, 0, 1}}, {{0, 0, 1}}, {{0, 0, 1}}, {{0, 0, 1}}};
 
587
    
 
588
    const double * const * x = c.coordinates;
 
589
    double result = 0.0;
 
590
    // Iterate over the points:
 
591
    // Evaluate basis functions for affine mapping
 
592
    const double w0 = 1.0 - X[i][0][0] - X[i][0][1] - X[i][0][2];
 
593
    const double w1 = X[i][0][0];
 
594
    const double w2 = X[i][0][1];
 
595
    const double w3 = X[i][0][2];
 
596
    
 
597
    // Compute affine mapping y = F(X)
 
598
    double y[3];
 
599
    y[0] = w0*x[0][0] + w1*x[1][0] + w2*x[2][0] + w3*x[3][0];
 
600
    y[1] = w0*x[0][1] + w1*x[1][1] + w2*x[2][1] + w3*x[3][1];
 
601
    y[2] = w0*x[0][2] + w1*x[1][2] + w2*x[2][2] + w3*x[3][2];
 
602
    
 
603
    // Evaluate function at physical points
 
604
    double values[3];
 
605
    f.evaluate(values, y, c);
 
606
    
 
607
    // Map function values using appropriate mapping
 
608
    // Affine map: Do nothing
 
609
    
 
610
    // Note that we do not map the weights (yet).
 
611
    
 
612
    // Take directional components
 
613
    for(int k = 0; k < 3; k++)
 
614
      result += values[k]*D[i][0][k];
 
615
    // Multiply by weights 
 
616
    result *= W[i][0];
 
617
    
 
618
    return result;
 
619
  }
 
620
 
 
621
  /// Evaluate linear functionals for all dofs on the function f
 
622
  virtual void evaluate_dofs(double* values,
 
623
                             const ufc::function& f,
 
624
                             const ufc::cell& c) const
 
625
  {
 
626
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
627
  }
 
628
 
 
629
  /// Interpolate vertex values from dof values
 
630
  virtual void interpolate_vertex_values(double* vertex_values,
 
631
                                         const double* dof_values,
 
632
                                         const ufc::cell& c) const
 
633
  {
 
634
    // Evaluate at vertices and use affine mapping
 
635
    vertex_values[0] = dof_values[0];
 
636
    vertex_values[3] = dof_values[2];
 
637
    vertex_values[6] = dof_values[5];
 
638
    vertex_values[9] = dof_values[9];
 
639
    // Evaluate at vertices and use affine mapping
 
640
    vertex_values[1] = dof_values[10];
 
641
    vertex_values[4] = dof_values[12];
 
642
    vertex_values[7] = dof_values[15];
 
643
    vertex_values[10] = dof_values[19];
 
644
    // Evaluate at vertices and use affine mapping
 
645
    vertex_values[2] = dof_values[20];
 
646
    vertex_values[5] = dof_values[22];
 
647
    vertex_values[8] = dof_values[25];
 
648
    vertex_values[11] = dof_values[29];
 
649
  }
 
650
 
 
651
  /// Return the number of sub elements (for a mixed element)
 
652
  virtual unsigned int num_sub_elements() const
 
653
  {
 
654
    return 3;
 
655
  }
 
656
 
 
657
  /// Create a new finite element for sub element i (for a mixed element)
 
658
  virtual ufc::finite_element* create_sub_element(unsigned int i) const
 
659
  {
 
660
    switch ( i )
 
661
    {
 
662
    case 0:
 
663
      return new ffc_23_finite_element_0_0();
 
664
      break;
 
665
    case 1:
 
666
      return new ffc_23_finite_element_0_1();
 
667
      break;
 
668
    case 2:
 
669
      return new ffc_23_finite_element_0_2();
 
670
      break;
 
671
    }
 
672
    return 0;
 
673
  }
 
674
 
 
675
};
 
676
 
 
677
/// This class defines the interface for a local-to-global mapping of
 
678
/// degrees of freedom (dofs).
 
679
 
 
680
class ffc_23_dof_map_0_0: public ufc::dof_map
 
681
{
 
682
private:
 
683
 
 
684
  unsigned int __global_dimension;
 
685
 
 
686
public:
 
687
 
 
688
  /// Constructor
 
689
  ffc_23_dof_map_0_0() : ufc::dof_map()
 
690
  {
 
691
    __global_dimension = 0;
 
692
  }
 
693
 
 
694
  /// Destructor
 
695
  virtual ~ffc_23_dof_map_0_0()
 
696
  {
 
697
    // Do nothing
 
698
  }
 
699
 
 
700
  /// Return a string identifying the dof map
 
701
  virtual const char* signature() const
 
702
  {
 
703
    return "FFC dof map for Discontinuous Lagrange finite element of degree 2 on a tetrahedron";
 
704
  }
 
705
 
 
706
  /// Return true iff mesh entities of topological dimension d are needed
 
707
  virtual bool needs_mesh_entities(unsigned int d) const
 
708
  {
 
709
    switch ( d )
 
710
    {
 
711
    case 0:
 
712
      return false;
 
713
      break;
 
714
    case 1:
 
715
      return false;
 
716
      break;
 
717
    case 2:
 
718
      return false;
 
719
      break;
 
720
    case 3:
 
721
      return true;
 
722
      break;
 
723
    }
 
724
    return false;
 
725
  }
 
726
 
 
727
  /// Initialize dof map for mesh (return true iff init_cell() is needed)
 
728
  virtual bool init_mesh(const ufc::mesh& m)
 
729
  {
 
730
    __global_dimension = 10*m.num_entities[3];
 
731
    return false;
 
732
  }
 
733
 
 
734
  /// Initialize dof map for given cell
 
735
  virtual void init_cell(const ufc::mesh& m,
 
736
                         const ufc::cell& c)
 
737
  {
 
738
    // Do nothing
 
739
  }
 
740
 
 
741
  /// Finish initialization of dof map for cells
 
742
  virtual void init_cell_finalize()
 
743
  {
 
744
    // Do nothing
 
745
  }
 
746
 
 
747
  /// Return the dimension of the global finite element function space
 
748
  virtual unsigned int global_dimension() const
 
749
  {
 
750
    return __global_dimension;
 
751
  }
 
752
 
 
753
  /// Return the dimension of the local finite element function space
 
754
  virtual unsigned int local_dimension() const
 
755
  {
 
756
    return 10;
 
757
  }
 
758
 
 
759
  // Return the geometric dimension of the coordinates this dof map provides
 
760
  virtual unsigned int geometric_dimension() const
 
761
  {
 
762
    return 3;
 
763
  }
 
764
 
 
765
  /// Return the number of dofs on each cell facet
 
766
  virtual unsigned int num_facet_dofs() const
 
767
  {
 
768
    return 0;
 
769
  }
 
770
 
 
771
  /// Return the number of dofs associated with each cell entity of dimension d
 
772
  virtual unsigned int num_entity_dofs(unsigned int d) const
 
773
  {
 
774
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
775
  }
 
776
 
 
777
  /// Tabulate the local-to-global mapping of dofs on a cell
 
778
  virtual void tabulate_dofs(unsigned int* dofs,
 
779
                             const ufc::mesh& m,
 
780
                             const ufc::cell& c) const
 
781
  {
 
782
    dofs[0] = 10*c.entity_indices[3][0];
 
783
    dofs[1] = 10*c.entity_indices[3][0] + 1;
 
784
    dofs[2] = 10*c.entity_indices[3][0] + 2;
 
785
    dofs[3] = 10*c.entity_indices[3][0] + 3;
 
786
    dofs[4] = 10*c.entity_indices[3][0] + 4;
 
787
    dofs[5] = 10*c.entity_indices[3][0] + 5;
 
788
    dofs[6] = 10*c.entity_indices[3][0] + 6;
 
789
    dofs[7] = 10*c.entity_indices[3][0] + 7;
 
790
    dofs[8] = 10*c.entity_indices[3][0] + 8;
 
791
    dofs[9] = 10*c.entity_indices[3][0] + 9;
 
792
  }
 
793
 
 
794
  /// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
795
  virtual void tabulate_facet_dofs(unsigned int* dofs,
 
796
                                   unsigned int facet) const
 
797
  {
 
798
    switch ( facet )
 
799
    {
 
800
    case 0:
 
801
      
 
802
      break;
 
803
    case 1:
 
804
      
 
805
      break;
 
806
    case 2:
 
807
      
 
808
      break;
 
809
    case 3:
 
810
      
 
811
      break;
 
812
    }
 
813
  }
 
814
 
 
815
  /// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
816
  virtual void tabulate_entity_dofs(unsigned int* dofs,
 
817
                                    unsigned int d, unsigned int i) const
 
818
  {
 
819
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
820
  }
 
821
 
 
822
  /// Tabulate the coordinates of all dofs on a cell
 
823
  virtual void tabulate_coordinates(double** coordinates,
 
824
                                    const ufc::cell& c) const
 
825
  {
 
826
    const double * const * x = c.coordinates;
 
827
    coordinates[0][0] = x[0][0];
 
828
    coordinates[0][1] = x[0][1];
 
829
    coordinates[0][2] = x[0][2];
 
830
    coordinates[1][0] = 0.5*x[0][0] + 0.5*x[1][0];
 
831
    coordinates[1][1] = 0.5*x[0][1] + 0.5*x[1][1];
 
832
    coordinates[1][2] = 0.5*x[0][2] + 0.5*x[1][2];
 
833
    coordinates[2][0] = x[1][0];
 
834
    coordinates[2][1] = x[1][1];
 
835
    coordinates[2][2] = x[1][2];
 
836
    coordinates[3][0] = 0.5*x[0][0] + 0.5*x[2][0];
 
837
    coordinates[3][1] = 0.5*x[0][1] + 0.5*x[2][1];
 
838
    coordinates[3][2] = 0.5*x[0][2] + 0.5*x[2][2];
 
839
    coordinates[4][0] = 0.5*x[1][0] + 0.5*x[2][0];
 
840
    coordinates[4][1] = 0.5*x[1][1] + 0.5*x[2][1];
 
841
    coordinates[4][2] = 0.5*x[1][2] + 0.5*x[2][2];
 
842
    coordinates[5][0] = x[2][0];
 
843
    coordinates[5][1] = x[2][1];
 
844
    coordinates[5][2] = x[2][2];
 
845
    coordinates[6][0] = 0.5*x[0][0] + 0.5*x[3][0];
 
846
    coordinates[6][1] = 0.5*x[0][1] + 0.5*x[3][1];
 
847
    coordinates[6][2] = 0.5*x[0][2] + 0.5*x[3][2];
 
848
    coordinates[7][0] = 0.5*x[1][0] + 0.5*x[3][0];
 
849
    coordinates[7][1] = 0.5*x[1][1] + 0.5*x[3][1];
 
850
    coordinates[7][2] = 0.5*x[1][2] + 0.5*x[3][2];
 
851
    coordinates[8][0] = 0.5*x[2][0] + 0.5*x[3][0];
 
852
    coordinates[8][1] = 0.5*x[2][1] + 0.5*x[3][1];
 
853
    coordinates[8][2] = 0.5*x[2][2] + 0.5*x[3][2];
 
854
    coordinates[9][0] = x[3][0];
 
855
    coordinates[9][1] = x[3][1];
 
856
    coordinates[9][2] = x[3][2];
 
857
  }
 
858
 
 
859
  /// Return the number of sub dof maps (for a mixed element)
 
860
  virtual unsigned int num_sub_dof_maps() const
 
861
  {
 
862
    return 1;
 
863
  }
 
864
 
 
865
  /// Create a new dof_map for sub dof map i (for a mixed element)
 
866
  virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
 
867
  {
 
868
    return new ffc_23_dof_map_0_0();
 
869
  }
 
870
 
 
871
};
 
872
 
 
873
/// This class defines the interface for a local-to-global mapping of
 
874
/// degrees of freedom (dofs).
 
875
 
 
876
class ffc_23_dof_map_0_1: public ufc::dof_map
 
877
{
 
878
private:
 
879
 
 
880
  unsigned int __global_dimension;
 
881
 
 
882
public:
 
883
 
 
884
  /// Constructor
 
885
  ffc_23_dof_map_0_1() : ufc::dof_map()
 
886
  {
 
887
    __global_dimension = 0;
 
888
  }
 
889
 
 
890
  /// Destructor
 
891
  virtual ~ffc_23_dof_map_0_1()
 
892
  {
 
893
    // Do nothing
 
894
  }
 
895
 
 
896
  /// Return a string identifying the dof map
 
897
  virtual const char* signature() const
 
898
  {
 
899
    return "FFC dof map for Discontinuous Lagrange finite element of degree 2 on a tetrahedron";
 
900
  }
 
901
 
 
902
  /// Return true iff mesh entities of topological dimension d are needed
 
903
  virtual bool needs_mesh_entities(unsigned int d) const
 
904
  {
 
905
    switch ( d )
 
906
    {
 
907
    case 0:
 
908
      return false;
 
909
      break;
 
910
    case 1:
 
911
      return false;
 
912
      break;
 
913
    case 2:
 
914
      return false;
 
915
      break;
 
916
    case 3:
 
917
      return true;
 
918
      break;
 
919
    }
 
920
    return false;
 
921
  }
 
922
 
 
923
  /// Initialize dof map for mesh (return true iff init_cell() is needed)
 
924
  virtual bool init_mesh(const ufc::mesh& m)
 
925
  {
 
926
    __global_dimension = 10*m.num_entities[3];
 
927
    return false;
 
928
  }
 
929
 
 
930
  /// Initialize dof map for given cell
 
931
  virtual void init_cell(const ufc::mesh& m,
 
932
                         const ufc::cell& c)
 
933
  {
 
934
    // Do nothing
 
935
  }
 
936
 
 
937
  /// Finish initialization of dof map for cells
 
938
  virtual void init_cell_finalize()
 
939
  {
 
940
    // Do nothing
 
941
  }
 
942
 
 
943
  /// Return the dimension of the global finite element function space
 
944
  virtual unsigned int global_dimension() const
 
945
  {
 
946
    return __global_dimension;
 
947
  }
 
948
 
 
949
  /// Return the dimension of the local finite element function space
 
950
  virtual unsigned int local_dimension() const
 
951
  {
 
952
    return 10;
 
953
  }
 
954
 
 
955
  // Return the geometric dimension of the coordinates this dof map provides
 
956
  virtual unsigned int geometric_dimension() const
 
957
  {
 
958
    return 3;
 
959
  }
 
960
 
 
961
  /// Return the number of dofs on each cell facet
 
962
  virtual unsigned int num_facet_dofs() const
 
963
  {
 
964
    return 0;
 
965
  }
 
966
 
 
967
  /// Return the number of dofs associated with each cell entity of dimension d
 
968
  virtual unsigned int num_entity_dofs(unsigned int d) const
 
969
  {
 
970
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
971
  }
 
972
 
 
973
  /// Tabulate the local-to-global mapping of dofs on a cell
 
974
  virtual void tabulate_dofs(unsigned int* dofs,
 
975
                             const ufc::mesh& m,
 
976
                             const ufc::cell& c) const
 
977
  {
 
978
    dofs[0] = 10*c.entity_indices[3][0];
 
979
    dofs[1] = 10*c.entity_indices[3][0] + 1;
 
980
    dofs[2] = 10*c.entity_indices[3][0] + 2;
 
981
    dofs[3] = 10*c.entity_indices[3][0] + 3;
 
982
    dofs[4] = 10*c.entity_indices[3][0] + 4;
 
983
    dofs[5] = 10*c.entity_indices[3][0] + 5;
 
984
    dofs[6] = 10*c.entity_indices[3][0] + 6;
 
985
    dofs[7] = 10*c.entity_indices[3][0] + 7;
 
986
    dofs[8] = 10*c.entity_indices[3][0] + 8;
 
987
    dofs[9] = 10*c.entity_indices[3][0] + 9;
 
988
  }
 
989
 
 
990
  /// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
991
  virtual void tabulate_facet_dofs(unsigned int* dofs,
 
992
                                   unsigned int facet) const
 
993
  {
 
994
    switch ( facet )
 
995
    {
 
996
    case 0:
 
997
      
 
998
      break;
 
999
    case 1:
 
1000
      
 
1001
      break;
 
1002
    case 2:
 
1003
      
 
1004
      break;
 
1005
    case 3:
 
1006
      
 
1007
      break;
 
1008
    }
 
1009
  }
 
1010
 
 
1011
  /// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
1012
  virtual void tabulate_entity_dofs(unsigned int* dofs,
 
1013
                                    unsigned int d, unsigned int i) const
 
1014
  {
 
1015
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
1016
  }
 
1017
 
 
1018
  /// Tabulate the coordinates of all dofs on a cell
 
1019
  virtual void tabulate_coordinates(double** coordinates,
 
1020
                                    const ufc::cell& c) const
 
1021
  {
 
1022
    const double * const * x = c.coordinates;
 
1023
    coordinates[0][0] = x[0][0];
 
1024
    coordinates[0][1] = x[0][1];
 
1025
    coordinates[0][2] = x[0][2];
 
1026
    coordinates[1][0] = 0.5*x[0][0] + 0.5*x[1][0];
 
1027
    coordinates[1][1] = 0.5*x[0][1] + 0.5*x[1][1];
 
1028
    coordinates[1][2] = 0.5*x[0][2] + 0.5*x[1][2];
 
1029
    coordinates[2][0] = x[1][0];
 
1030
    coordinates[2][1] = x[1][1];
 
1031
    coordinates[2][2] = x[1][2];
 
1032
    coordinates[3][0] = 0.5*x[0][0] + 0.5*x[2][0];
 
1033
    coordinates[3][1] = 0.5*x[0][1] + 0.5*x[2][1];
 
1034
    coordinates[3][2] = 0.5*x[0][2] + 0.5*x[2][2];
 
1035
    coordinates[4][0] = 0.5*x[1][0] + 0.5*x[2][0];
 
1036
    coordinates[4][1] = 0.5*x[1][1] + 0.5*x[2][1];
 
1037
    coordinates[4][2] = 0.5*x[1][2] + 0.5*x[2][2];
 
1038
    coordinates[5][0] = x[2][0];
 
1039
    coordinates[5][1] = x[2][1];
 
1040
    coordinates[5][2] = x[2][2];
 
1041
    coordinates[6][0] = 0.5*x[0][0] + 0.5*x[3][0];
 
1042
    coordinates[6][1] = 0.5*x[0][1] + 0.5*x[3][1];
 
1043
    coordinates[6][2] = 0.5*x[0][2] + 0.5*x[3][2];
 
1044
    coordinates[7][0] = 0.5*x[1][0] + 0.5*x[3][0];
 
1045
    coordinates[7][1] = 0.5*x[1][1] + 0.5*x[3][1];
 
1046
    coordinates[7][2] = 0.5*x[1][2] + 0.5*x[3][2];
 
1047
    coordinates[8][0] = 0.5*x[2][0] + 0.5*x[3][0];
 
1048
    coordinates[8][1] = 0.5*x[2][1] + 0.5*x[3][1];
 
1049
    coordinates[8][2] = 0.5*x[2][2] + 0.5*x[3][2];
 
1050
    coordinates[9][0] = x[3][0];
 
1051
    coordinates[9][1] = x[3][1];
 
1052
    coordinates[9][2] = x[3][2];
 
1053
  }
 
1054
 
 
1055
  /// Return the number of sub dof maps (for a mixed element)
 
1056
  virtual unsigned int num_sub_dof_maps() const
 
1057
  {
 
1058
    return 1;
 
1059
  }
 
1060
 
 
1061
  /// Create a new dof_map for sub dof map i (for a mixed element)
 
1062
  virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
 
1063
  {
 
1064
    return new ffc_23_dof_map_0_1();
 
1065
  }
 
1066
 
 
1067
};
 
1068
 
 
1069
/// This class defines the interface for a local-to-global mapping of
 
1070
/// degrees of freedom (dofs).
 
1071
 
 
1072
class ffc_23_dof_map_0_2: public ufc::dof_map
 
1073
{
 
1074
private:
 
1075
 
 
1076
  unsigned int __global_dimension;
 
1077
 
 
1078
public:
 
1079
 
 
1080
  /// Constructor
 
1081
  ffc_23_dof_map_0_2() : ufc::dof_map()
 
1082
  {
 
1083
    __global_dimension = 0;
 
1084
  }
 
1085
 
 
1086
  /// Destructor
 
1087
  virtual ~ffc_23_dof_map_0_2()
 
1088
  {
 
1089
    // Do nothing
 
1090
  }
 
1091
 
 
1092
  /// Return a string identifying the dof map
 
1093
  virtual const char* signature() const
 
1094
  {
 
1095
    return "FFC dof map for Discontinuous Lagrange finite element of degree 2 on a tetrahedron";
 
1096
  }
 
1097
 
 
1098
  /// Return true iff mesh entities of topological dimension d are needed
 
1099
  virtual bool needs_mesh_entities(unsigned int d) const
 
1100
  {
 
1101
    switch ( d )
 
1102
    {
 
1103
    case 0:
 
1104
      return false;
 
1105
      break;
 
1106
    case 1:
 
1107
      return false;
 
1108
      break;
 
1109
    case 2:
 
1110
      return false;
 
1111
      break;
 
1112
    case 3:
 
1113
      return true;
 
1114
      break;
 
1115
    }
 
1116
    return false;
 
1117
  }
 
1118
 
 
1119
  /// Initialize dof map for mesh (return true iff init_cell() is needed)
 
1120
  virtual bool init_mesh(const ufc::mesh& m)
 
1121
  {
 
1122
    __global_dimension = 10*m.num_entities[3];
 
1123
    return false;
 
1124
  }
 
1125
 
 
1126
  /// Initialize dof map for given cell
 
1127
  virtual void init_cell(const ufc::mesh& m,
 
1128
                         const ufc::cell& c)
 
1129
  {
 
1130
    // Do nothing
 
1131
  }
 
1132
 
 
1133
  /// Finish initialization of dof map for cells
 
1134
  virtual void init_cell_finalize()
 
1135
  {
 
1136
    // Do nothing
 
1137
  }
 
1138
 
 
1139
  /// Return the dimension of the global finite element function space
 
1140
  virtual unsigned int global_dimension() const
 
1141
  {
 
1142
    return __global_dimension;
 
1143
  }
 
1144
 
 
1145
  /// Return the dimension of the local finite element function space
 
1146
  virtual unsigned int local_dimension() const
 
1147
  {
 
1148
    return 10;
 
1149
  }
 
1150
 
 
1151
  // Return the geometric dimension of the coordinates this dof map provides
 
1152
  virtual unsigned int geometric_dimension() const
 
1153
  {
 
1154
    return 3;
 
1155
  }
 
1156
 
 
1157
  /// Return the number of dofs on each cell facet
 
1158
  virtual unsigned int num_facet_dofs() const
 
1159
  {
 
1160
    return 0;
 
1161
  }
 
1162
 
 
1163
  /// Return the number of dofs associated with each cell entity of dimension d
 
1164
  virtual unsigned int num_entity_dofs(unsigned int d) const
 
1165
  {
 
1166
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
1167
  }
 
1168
 
 
1169
  /// Tabulate the local-to-global mapping of dofs on a cell
 
1170
  virtual void tabulate_dofs(unsigned int* dofs,
 
1171
                             const ufc::mesh& m,
 
1172
                             const ufc::cell& c) const
 
1173
  {
 
1174
    dofs[0] = 10*c.entity_indices[3][0];
 
1175
    dofs[1] = 10*c.entity_indices[3][0] + 1;
 
1176
    dofs[2] = 10*c.entity_indices[3][0] + 2;
 
1177
    dofs[3] = 10*c.entity_indices[3][0] + 3;
 
1178
    dofs[4] = 10*c.entity_indices[3][0] + 4;
 
1179
    dofs[5] = 10*c.entity_indices[3][0] + 5;
 
1180
    dofs[6] = 10*c.entity_indices[3][0] + 6;
 
1181
    dofs[7] = 10*c.entity_indices[3][0] + 7;
 
1182
    dofs[8] = 10*c.entity_indices[3][0] + 8;
 
1183
    dofs[9] = 10*c.entity_indices[3][0] + 9;
 
1184
  }
 
1185
 
 
1186
  /// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
1187
  virtual void tabulate_facet_dofs(unsigned int* dofs,
 
1188
                                   unsigned int facet) const
 
1189
  {
 
1190
    switch ( facet )
 
1191
    {
 
1192
    case 0:
 
1193
      
 
1194
      break;
 
1195
    case 1:
 
1196
      
 
1197
      break;
 
1198
    case 2:
 
1199
      
 
1200
      break;
 
1201
    case 3:
 
1202
      
 
1203
      break;
 
1204
    }
 
1205
  }
 
1206
 
 
1207
  /// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
1208
  virtual void tabulate_entity_dofs(unsigned int* dofs,
 
1209
                                    unsigned int d, unsigned int i) const
 
1210
  {
 
1211
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
1212
  }
 
1213
 
 
1214
  /// Tabulate the coordinates of all dofs on a cell
 
1215
  virtual void tabulate_coordinates(double** coordinates,
 
1216
                                    const ufc::cell& c) const
 
1217
  {
 
1218
    const double * const * x = c.coordinates;
 
1219
    coordinates[0][0] = x[0][0];
 
1220
    coordinates[0][1] = x[0][1];
 
1221
    coordinates[0][2] = x[0][2];
 
1222
    coordinates[1][0] = 0.5*x[0][0] + 0.5*x[1][0];
 
1223
    coordinates[1][1] = 0.5*x[0][1] + 0.5*x[1][1];
 
1224
    coordinates[1][2] = 0.5*x[0][2] + 0.5*x[1][2];
 
1225
    coordinates[2][0] = x[1][0];
 
1226
    coordinates[2][1] = x[1][1];
 
1227
    coordinates[2][2] = x[1][2];
 
1228
    coordinates[3][0] = 0.5*x[0][0] + 0.5*x[2][0];
 
1229
    coordinates[3][1] = 0.5*x[0][1] + 0.5*x[2][1];
 
1230
    coordinates[3][2] = 0.5*x[0][2] + 0.5*x[2][2];
 
1231
    coordinates[4][0] = 0.5*x[1][0] + 0.5*x[2][0];
 
1232
    coordinates[4][1] = 0.5*x[1][1] + 0.5*x[2][1];
 
1233
    coordinates[4][2] = 0.5*x[1][2] + 0.5*x[2][2];
 
1234
    coordinates[5][0] = x[2][0];
 
1235
    coordinates[5][1] = x[2][1];
 
1236
    coordinates[5][2] = x[2][2];
 
1237
    coordinates[6][0] = 0.5*x[0][0] + 0.5*x[3][0];
 
1238
    coordinates[6][1] = 0.5*x[0][1] + 0.5*x[3][1];
 
1239
    coordinates[6][2] = 0.5*x[0][2] + 0.5*x[3][2];
 
1240
    coordinates[7][0] = 0.5*x[1][0] + 0.5*x[3][0];
 
1241
    coordinates[7][1] = 0.5*x[1][1] + 0.5*x[3][1];
 
1242
    coordinates[7][2] = 0.5*x[1][2] + 0.5*x[3][2];
 
1243
    coordinates[8][0] = 0.5*x[2][0] + 0.5*x[3][0];
 
1244
    coordinates[8][1] = 0.5*x[2][1] + 0.5*x[3][1];
 
1245
    coordinates[8][2] = 0.5*x[2][2] + 0.5*x[3][2];
 
1246
    coordinates[9][0] = x[3][0];
 
1247
    coordinates[9][1] = x[3][1];
 
1248
    coordinates[9][2] = x[3][2];
 
1249
  }
 
1250
 
 
1251
  /// Return the number of sub dof maps (for a mixed element)
 
1252
  virtual unsigned int num_sub_dof_maps() const
 
1253
  {
 
1254
    return 1;
 
1255
  }
 
1256
 
 
1257
  /// Create a new dof_map for sub dof map i (for a mixed element)
 
1258
  virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
 
1259
  {
 
1260
    return new ffc_23_dof_map_0_2();
 
1261
  }
 
1262
 
 
1263
};
 
1264
 
 
1265
/// This class defines the interface for a local-to-global mapping of
 
1266
/// degrees of freedom (dofs).
 
1267
 
 
1268
class ffc_23_dof_map_0: public ufc::dof_map
 
1269
{
 
1270
private:
 
1271
 
 
1272
  unsigned int __global_dimension;
 
1273
 
 
1274
public:
 
1275
 
 
1276
  /// Constructor
 
1277
  ffc_23_dof_map_0() : ufc::dof_map()
 
1278
  {
 
1279
    __global_dimension = 0;
 
1280
  }
 
1281
 
 
1282
  /// Destructor
 
1283
  virtual ~ffc_23_dof_map_0()
 
1284
  {
 
1285
    // Do nothing
 
1286
  }
 
1287
 
 
1288
  /// Return a string identifying the dof map
 
1289
  virtual const char* signature() const
 
1290
  {
 
1291
    return "FFC dof map for Mixed finite element: [Discontinuous Lagrange finite element of degree 2 on a tetrahedron, Discontinuous Lagrange finite element of degree 2 on a tetrahedron, Discontinuous Lagrange finite element of degree 2 on a tetrahedron]";
 
1292
  }
 
1293
 
 
1294
  /// Return true iff mesh entities of topological dimension d are needed
 
1295
  virtual bool needs_mesh_entities(unsigned int d) const
 
1296
  {
 
1297
    switch ( d )
 
1298
    {
 
1299
    case 0:
 
1300
      return false;
 
1301
      break;
 
1302
    case 1:
 
1303
      return false;
 
1304
      break;
 
1305
    case 2:
 
1306
      return false;
 
1307
      break;
 
1308
    case 3:
 
1309
      return true;
 
1310
      break;
 
1311
    }
 
1312
    return false;
 
1313
  }
 
1314
 
 
1315
  /// Initialize dof map for mesh (return true iff init_cell() is needed)
 
1316
  virtual bool init_mesh(const ufc::mesh& m)
 
1317
  {
 
1318
    __global_dimension = 30*m.num_entities[3];
 
1319
    return false;
 
1320
  }
 
1321
 
 
1322
  /// Initialize dof map for given cell
 
1323
  virtual void init_cell(const ufc::mesh& m,
 
1324
                         const ufc::cell& c)
 
1325
  {
 
1326
    // Do nothing
 
1327
  }
 
1328
 
 
1329
  /// Finish initialization of dof map for cells
 
1330
  virtual void init_cell_finalize()
 
1331
  {
 
1332
    // Do nothing
 
1333
  }
 
1334
 
 
1335
  /// Return the dimension of the global finite element function space
 
1336
  virtual unsigned int global_dimension() const
 
1337
  {
 
1338
    return __global_dimension;
 
1339
  }
 
1340
 
 
1341
  /// Return the dimension of the local finite element function space
 
1342
  virtual unsigned int local_dimension() const
 
1343
  {
 
1344
    return 30;
 
1345
  }
 
1346
 
 
1347
  // Return the geometric dimension of the coordinates this dof map provides
 
1348
  virtual unsigned int geometric_dimension() const
 
1349
  {
 
1350
    return 3;
 
1351
  }
 
1352
 
 
1353
  /// Return the number of dofs on each cell facet
 
1354
  virtual unsigned int num_facet_dofs() const
 
1355
  {
 
1356
    return 0;
 
1357
  }
 
1358
 
 
1359
  /// Return the number of dofs associated with each cell entity of dimension d
 
1360
  virtual unsigned int num_entity_dofs(unsigned int d) const
 
1361
  {
 
1362
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
1363
  }
 
1364
 
 
1365
  /// Tabulate the local-to-global mapping of dofs on a cell
 
1366
  virtual void tabulate_dofs(unsigned int* dofs,
 
1367
                             const ufc::mesh& m,
 
1368
                             const ufc::cell& c) const
 
1369
  {
 
1370
    dofs[0] = 10*c.entity_indices[3][0];
 
1371
    dofs[1] = 10*c.entity_indices[3][0] + 1;
 
1372
    dofs[2] = 10*c.entity_indices[3][0] + 2;
 
1373
    dofs[3] = 10*c.entity_indices[3][0] + 3;
 
1374
    dofs[4] = 10*c.entity_indices[3][0] + 4;
 
1375
    dofs[5] = 10*c.entity_indices[3][0] + 5;
 
1376
    dofs[6] = 10*c.entity_indices[3][0] + 6;
 
1377
    dofs[7] = 10*c.entity_indices[3][0] + 7;
 
1378
    dofs[8] = 10*c.entity_indices[3][0] + 8;
 
1379
    dofs[9] = 10*c.entity_indices[3][0] + 9;
 
1380
    unsigned int offset = 10*m.num_entities[3];
 
1381
    dofs[10] = offset + 10*c.entity_indices[3][0];
 
1382
    dofs[11] = offset + 10*c.entity_indices[3][0] + 1;
 
1383
    dofs[12] = offset + 10*c.entity_indices[3][0] + 2;
 
1384
    dofs[13] = offset + 10*c.entity_indices[3][0] + 3;
 
1385
    dofs[14] = offset + 10*c.entity_indices[3][0] + 4;
 
1386
    dofs[15] = offset + 10*c.entity_indices[3][0] + 5;
 
1387
    dofs[16] = offset + 10*c.entity_indices[3][0] + 6;
 
1388
    dofs[17] = offset + 10*c.entity_indices[3][0] + 7;
 
1389
    dofs[18] = offset + 10*c.entity_indices[3][0] + 8;
 
1390
    dofs[19] = offset + 10*c.entity_indices[3][0] + 9;
 
1391
    offset = offset + 10*m.num_entities[3];
 
1392
    dofs[20] = offset + 10*c.entity_indices[3][0];
 
1393
    dofs[21] = offset + 10*c.entity_indices[3][0] + 1;
 
1394
    dofs[22] = offset + 10*c.entity_indices[3][0] + 2;
 
1395
    dofs[23] = offset + 10*c.entity_indices[3][0] + 3;
 
1396
    dofs[24] = offset + 10*c.entity_indices[3][0] + 4;
 
1397
    dofs[25] = offset + 10*c.entity_indices[3][0] + 5;
 
1398
    dofs[26] = offset + 10*c.entity_indices[3][0] + 6;
 
1399
    dofs[27] = offset + 10*c.entity_indices[3][0] + 7;
 
1400
    dofs[28] = offset + 10*c.entity_indices[3][0] + 8;
 
1401
    dofs[29] = offset + 10*c.entity_indices[3][0] + 9;
 
1402
  }
 
1403
 
 
1404
  /// Tabulate the local-to-local mapping from facet dofs to cell dofs
 
1405
  virtual void tabulate_facet_dofs(unsigned int* dofs,
 
1406
                                   unsigned int facet) const
 
1407
  {
 
1408
    switch ( facet )
 
1409
    {
 
1410
    case 0:
 
1411
      
 
1412
      break;
 
1413
    case 1:
 
1414
      
 
1415
      break;
 
1416
    case 2:
 
1417
      
 
1418
      break;
 
1419
    case 3:
 
1420
      
 
1421
      break;
 
1422
    }
 
1423
  }
 
1424
 
 
1425
  /// Tabulate the local-to-local mapping of dofs on entity (d, i)
 
1426
  virtual void tabulate_entity_dofs(unsigned int* dofs,
 
1427
                                    unsigned int d, unsigned int i) const
 
1428
  {
 
1429
    throw std::runtime_error("Not implemented (introduced in UFC v1.1).");
 
1430
  }
 
1431
 
 
1432
  /// Tabulate the coordinates of all dofs on a cell
 
1433
  virtual void tabulate_coordinates(double** coordinates,
 
1434
                                    const ufc::cell& c) const
 
1435
  {
 
1436
    const double * const * x = c.coordinates;
 
1437
    coordinates[0][0] = x[0][0];
 
1438
    coordinates[0][1] = x[0][1];
 
1439
    coordinates[0][2] = x[0][2];
 
1440
    coordinates[1][0] = 0.5*x[0][0] + 0.5*x[1][0];
 
1441
    coordinates[1][1] = 0.5*x[0][1] + 0.5*x[1][1];
 
1442
    coordinates[1][2] = 0.5*x[0][2] + 0.5*x[1][2];
 
1443
    coordinates[2][0] = x[1][0];
 
1444
    coordinates[2][1] = x[1][1];
 
1445
    coordinates[2][2] = x[1][2];
 
1446
    coordinates[3][0] = 0.5*x[0][0] + 0.5*x[2][0];
 
1447
    coordinates[3][1] = 0.5*x[0][1] + 0.5*x[2][1];
 
1448
    coordinates[3][2] = 0.5*x[0][2] + 0.5*x[2][2];
 
1449
    coordinates[4][0] = 0.5*x[1][0] + 0.5*x[2][0];
 
1450
    coordinates[4][1] = 0.5*x[1][1] + 0.5*x[2][1];
 
1451
    coordinates[4][2] = 0.5*x[1][2] + 0.5*x[2][2];
 
1452
    coordinates[5][0] = x[2][0];
 
1453
    coordinates[5][1] = x[2][1];
 
1454
    coordinates[5][2] = x[2][2];
 
1455
    coordinates[6][0] = 0.5*x[0][0] + 0.5*x[3][0];
 
1456
    coordinates[6][1] = 0.5*x[0][1] + 0.5*x[3][1];
 
1457
    coordinates[6][2] = 0.5*x[0][2] + 0.5*x[3][2];
 
1458
    coordinates[7][0] = 0.5*x[1][0] + 0.5*x[3][0];
 
1459
    coordinates[7][1] = 0.5*x[1][1] + 0.5*x[3][1];
 
1460
    coordinates[7][2] = 0.5*x[1][2] + 0.5*x[3][2];
 
1461
    coordinates[8][0] = 0.5*x[2][0] + 0.5*x[3][0];
 
1462
    coordinates[8][1] = 0.5*x[2][1] + 0.5*x[3][1];
 
1463
    coordinates[8][2] = 0.5*x[2][2] + 0.5*x[3][2];
 
1464
    coordinates[9][0] = x[3][0];
 
1465
    coordinates[9][1] = x[3][1];
 
1466
    coordinates[9][2] = x[3][2];
 
1467
    coordinates[10][0] = x[0][0];
 
1468
    coordinates[10][1] = x[0][1];
 
1469
    coordinates[10][2] = x[0][2];
 
1470
    coordinates[11][0] = 0.5*x[0][0] + 0.5*x[1][0];
 
1471
    coordinates[11][1] = 0.5*x[0][1] + 0.5*x[1][1];
 
1472
    coordinates[11][2] = 0.5*x[0][2] + 0.5*x[1][2];
 
1473
    coordinates[12][0] = x[1][0];
 
1474
    coordinates[12][1] = x[1][1];
 
1475
    coordinates[12][2] = x[1][2];
 
1476
    coordinates[13][0] = 0.5*x[0][0] + 0.5*x[2][0];
 
1477
    coordinates[13][1] = 0.5*x[0][1] + 0.5*x[2][1];
 
1478
    coordinates[13][2] = 0.5*x[0][2] + 0.5*x[2][2];
 
1479
    coordinates[14][0] = 0.5*x[1][0] + 0.5*x[2][0];
 
1480
    coordinates[14][1] = 0.5*x[1][1] + 0.5*x[2][1];
 
1481
    coordinates[14][2] = 0.5*x[1][2] + 0.5*x[2][2];
 
1482
    coordinates[15][0] = x[2][0];
 
1483
    coordinates[15][1] = x[2][1];
 
1484
    coordinates[15][2] = x[2][2];
 
1485
    coordinates[16][0] = 0.5*x[0][0] + 0.5*x[3][0];
 
1486
    coordinates[16][1] = 0.5*x[0][1] + 0.5*x[3][1];
 
1487
    coordinates[16][2] = 0.5*x[0][2] + 0.5*x[3][2];
 
1488
    coordinates[17][0] = 0.5*x[1][0] + 0.5*x[3][0];
 
1489
    coordinates[17][1] = 0.5*x[1][1] + 0.5*x[3][1];
 
1490
    coordinates[17][2] = 0.5*x[1][2] + 0.5*x[3][2];
 
1491
    coordinates[18][0] = 0.5*x[2][0] + 0.5*x[3][0];
 
1492
    coordinates[18][1] = 0.5*x[2][1] + 0.5*x[3][1];
 
1493
    coordinates[18][2] = 0.5*x[2][2] + 0.5*x[3][2];
 
1494
    coordinates[19][0] = x[3][0];
 
1495
    coordinates[19][1] = x[3][1];
 
1496
    coordinates[19][2] = x[3][2];
 
1497
    coordinates[20][0] = x[0][0];
 
1498
    coordinates[20][1] = x[0][1];
 
1499
    coordinates[20][2] = x[0][2];
 
1500
    coordinates[21][0] = 0.5*x[0][0] + 0.5*x[1][0];
 
1501
    coordinates[21][1] = 0.5*x[0][1] + 0.5*x[1][1];
 
1502
    coordinates[21][2] = 0.5*x[0][2] + 0.5*x[1][2];
 
1503
    coordinates[22][0] = x[1][0];
 
1504
    coordinates[22][1] = x[1][1];
 
1505
    coordinates[22][2] = x[1][2];
 
1506
    coordinates[23][0] = 0.5*x[0][0] + 0.5*x[2][0];
 
1507
    coordinates[23][1] = 0.5*x[0][1] + 0.5*x[2][1];
 
1508
    coordinates[23][2] = 0.5*x[0][2] + 0.5*x[2][2];
 
1509
    coordinates[24][0] = 0.5*x[1][0] + 0.5*x[2][0];
 
1510
    coordinates[24][1] = 0.5*x[1][1] + 0.5*x[2][1];
 
1511
    coordinates[24][2] = 0.5*x[1][2] + 0.5*x[2][2];
 
1512
    coordinates[25][0] = x[2][0];
 
1513
    coordinates[25][1] = x[2][1];
 
1514
    coordinates[25][2] = x[2][2];
 
1515
    coordinates[26][0] = 0.5*x[0][0] + 0.5*x[3][0];
 
1516
    coordinates[26][1] = 0.5*x[0][1] + 0.5*x[3][1];
 
1517
    coordinates[26][2] = 0.5*x[0][2] + 0.5*x[3][2];
 
1518
    coordinates[27][0] = 0.5*x[1][0] + 0.5*x[3][0];
 
1519
    coordinates[27][1] = 0.5*x[1][1] + 0.5*x[3][1];
 
1520
    coordinates[27][2] = 0.5*x[1][2] + 0.5*x[3][2];
 
1521
    coordinates[28][0] = 0.5*x[2][0] + 0.5*x[3][0];
 
1522
    coordinates[28][1] = 0.5*x[2][1] + 0.5*x[3][1];
 
1523
    coordinates[28][2] = 0.5*x[2][2] + 0.5*x[3][2];
 
1524
    coordinates[29][0] = x[3][0];
 
1525
    coordinates[29][1] = x[3][1];
 
1526
    coordinates[29][2] = x[3][2];
 
1527
  }
 
1528
 
 
1529
  /// Return the number of sub dof maps (for a mixed element)
 
1530
  virtual unsigned int num_sub_dof_maps() const
 
1531
  {
 
1532
    return 3;
 
1533
  }
 
1534
 
 
1535
  /// Create a new dof_map for sub dof map i (for a mixed element)
 
1536
  virtual ufc::dof_map* create_sub_dof_map(unsigned int i) const
 
1537
  {
 
1538
    switch ( i )
 
1539
    {
 
1540
    case 0:
 
1541
      return new ffc_23_dof_map_0_0();
 
1542
      break;
 
1543
    case 1:
 
1544
      return new ffc_23_dof_map_0_1();
 
1545
      break;
 
1546
    case 2:
 
1547
      return new ffc_23_dof_map_0_2();
 
1548
      break;
 
1549
    }
 
1550
    return 0;
 
1551
  }
 
1552
 
 
1553
};
 
1554
 
 
1555
#endif