1
// This code conforms with the UFC specification version 2.2.0
2
// and was automatically generated by FFC version 1.2.0.
4
// This code was generated with the following parameters:
7
// convert_exceptions_to_warnings: True
9
// cpp_optimize_flags: '-O2'
11
// error_control: False
19
// quadrature_degree: 'auto'
20
// quadrature_rule: 'auto'
21
// representation: 'quadrature'
23
// swig_binary: 'swig'
26
#ifndef __MIXEDPOISSON_H
27
#define __MIXEDPOISSON_H
34
/// This class defines the interface for a finite element.
36
class mixedpoisson_finite_element_0: public ufc::finite_element
41
mixedpoisson_finite_element_0() : ufc::finite_element()
47
virtual ~mixedpoisson_finite_element_0()
52
/// Return a string identifying the finite element
53
virtual const char* signature() const
55
return "FiniteElement('Brezzi-Douglas-Marini', Domain(Cell('triangle', 2), 'triangle_multiverse', 2, 2), 1, None)";
58
/// Return the cell shape
59
virtual ufc::shape cell_shape() const
64
/// Return the topological dimension of the cell shape
65
virtual std::size_t topological_dimension() const
70
/// Return the geometric dimension of the cell shape
71
virtual std::size_t geometric_dimension() const
76
/// Return the dimension of the finite element function space
77
virtual std::size_t space_dimension() const
82
/// Return the rank of the value space
83
virtual std::size_t value_rank() const
88
/// Return the dimension of the value space for axis i
89
virtual std::size_t value_dimension(std::size_t i) const
103
/// Evaluate basis function i at given point x in cell
104
virtual void evaluate_basis(std::size_t i,
107
const double* vertex_coordinates,
108
int cell_orientation) const
112
compute_jacobian_triangle_2d(J, vertex_coordinates);
114
// Compute Jacobian inverse and determinant
117
compute_jacobian_inverse_triangle_2d(K, detJ, J);
122
const double C0 = vertex_coordinates[2] + vertex_coordinates[4];
123
const double C1 = vertex_coordinates[3] + vertex_coordinates[5];
125
// Get coordinates and map to the reference (FIAT) element
126
double X = (J[1]*(C1 - 2.0*x[1]) + J[3]*(2.0*x[0] - C0)) / detJ;
127
double Y = (J[0]*(2.0*x[1] - C1) + J[2]*(C0 - 2.0*x[0])) / detJ;
137
// Array of basisvalues
138
double basisvalues[3] = {0.0, 0.0, 0.0};
140
// Declare helper variables
141
double tmp0 = (1.0 + Y + 2.0*X)/2.0;
143
// Compute basisvalues
144
basisvalues[0] = 1.0;
145
basisvalues[1] = tmp0;
146
basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
147
basisvalues[0] *= std::sqrt(0.5);
148
basisvalues[2] *= std::sqrt(1.0);
149
basisvalues[1] *= std::sqrt(3.0);
151
// Table(s) of coefficients
152
static const double coefficients0[3] = \
153
{0.94280904, 0.57735027, -0.33333333};
155
static const double coefficients1[3] = \
156
{-0.47140452, 0.0, -0.33333333};
159
for (unsigned int r = 0; r < 3; r++)
161
values[0] += coefficients0[r]*basisvalues[r];
162
values[1] += coefficients1[r]*basisvalues[r];
163
}// end loop over 'r'
165
// Using contravariant Piola transform to map values back to the physical element
166
const double tmp_ref0 = values[0];
167
const double tmp_ref1 = values[1];
168
values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
169
values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
175
// Array of basisvalues
176
double basisvalues[3] = {0.0, 0.0, 0.0};
178
// Declare helper variables
179
double tmp0 = (1.0 + Y + 2.0*X)/2.0;
181
// Compute basisvalues
182
basisvalues[0] = 1.0;
183
basisvalues[1] = tmp0;
184
basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
185
basisvalues[0] *= std::sqrt(0.5);
186
basisvalues[2] *= std::sqrt(1.0);
187
basisvalues[1] *= std::sqrt(3.0);
189
// Table(s) of coefficients
190
static const double coefficients0[3] = \
191
{-0.47140452, -0.28867513, 0.16666667};
193
static const double coefficients1[3] = \
194
{0.94280904, 0.0, 0.66666667};
197
for (unsigned int r = 0; r < 3; r++)
199
values[0] += coefficients0[r]*basisvalues[r];
200
values[1] += coefficients1[r]*basisvalues[r];
201
}// end loop over 'r'
203
// Using contravariant Piola transform to map values back to the physical element
204
const double tmp_ref0 = values[0];
205
const double tmp_ref1 = values[1];
206
values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
207
values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
213
// Array of basisvalues
214
double basisvalues[3] = {0.0, 0.0, 0.0};
216
// Declare helper variables
217
double tmp0 = (1.0 + Y + 2.0*X)/2.0;
219
// Compute basisvalues
220
basisvalues[0] = 1.0;
221
basisvalues[1] = tmp0;
222
basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
223
basisvalues[0] *= std::sqrt(0.5);
224
basisvalues[2] *= std::sqrt(1.0);
225
basisvalues[1] *= std::sqrt(3.0);
227
// Table(s) of coefficients
228
static const double coefficients0[3] = \
229
{0.47140452, -0.57735027, -0.66666667};
231
static const double coefficients1[3] = \
232
{0.47140452, 0.0, 0.33333333};
235
for (unsigned int r = 0; r < 3; r++)
237
values[0] += coefficients0[r]*basisvalues[r];
238
values[1] += coefficients1[r]*basisvalues[r];
239
}// end loop over 'r'
241
// Using contravariant Piola transform to map values back to the physical element
242
const double tmp_ref0 = values[0];
243
const double tmp_ref1 = values[1];
244
values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
245
values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
251
// Array of basisvalues
252
double basisvalues[3] = {0.0, 0.0, 0.0};
254
// Declare helper variables
255
double tmp0 = (1.0 + Y + 2.0*X)/2.0;
257
// Compute basisvalues
258
basisvalues[0] = 1.0;
259
basisvalues[1] = tmp0;
260
basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
261
basisvalues[0] *= std::sqrt(0.5);
262
basisvalues[2] *= std::sqrt(1.0);
263
basisvalues[1] *= std::sqrt(3.0);
265
// Table(s) of coefficients
266
static const double coefficients0[3] = \
267
{0.47140452, 0.28867513, 0.83333333};
269
static const double coefficients1[3] = \
270
{-0.94280904, 0.0, -0.66666667};
273
for (unsigned int r = 0; r < 3; r++)
275
values[0] += coefficients0[r]*basisvalues[r];
276
values[1] += coefficients1[r]*basisvalues[r];
277
}// end loop over 'r'
279
// Using contravariant Piola transform to map values back to the physical element
280
const double tmp_ref0 = values[0];
281
const double tmp_ref1 = values[1];
282
values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
283
values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
289
// Array of basisvalues
290
double basisvalues[3] = {0.0, 0.0, 0.0};
292
// Declare helper variables
293
double tmp0 = (1.0 + Y + 2.0*X)/2.0;
295
// Compute basisvalues
296
basisvalues[0] = 1.0;
297
basisvalues[1] = tmp0;
298
basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
299
basisvalues[0] *= std::sqrt(0.5);
300
basisvalues[2] *= std::sqrt(1.0);
301
basisvalues[1] *= std::sqrt(3.0);
303
// Table(s) of coefficients
304
static const double coefficients0[3] = \
305
{-0.47140452, -0.28867513, 0.16666667};
307
static const double coefficients1[3] = \
308
{-0.47140452, 0.8660254, 0.16666667};
311
for (unsigned int r = 0; r < 3; r++)
313
values[0] += coefficients0[r]*basisvalues[r];
314
values[1] += coefficients1[r]*basisvalues[r];
315
}// end loop over 'r'
317
// Using contravariant Piola transform to map values back to the physical element
318
const double tmp_ref0 = values[0];
319
const double tmp_ref1 = values[1];
320
values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
321
values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
327
// Array of basisvalues
328
double basisvalues[3] = {0.0, 0.0, 0.0};
330
// Declare helper variables
331
double tmp0 = (1.0 + Y + 2.0*X)/2.0;
333
// Compute basisvalues
334
basisvalues[0] = 1.0;
335
basisvalues[1] = tmp0;
336
basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
337
basisvalues[0] *= std::sqrt(0.5);
338
basisvalues[2] *= std::sqrt(1.0);
339
basisvalues[1] *= std::sqrt(3.0);
341
// Table(s) of coefficients
342
static const double coefficients0[3] = \
343
{0.94280904, 0.57735027, -0.33333333};
345
static const double coefficients1[3] = \
346
{-0.47140452, -0.8660254, 0.16666667};
349
for (unsigned int r = 0; r < 3; r++)
351
values[0] += coefficients0[r]*basisvalues[r];
352
values[1] += coefficients1[r]*basisvalues[r];
353
}// end loop over 'r'
355
// Using contravariant Piola transform to map values back to the physical element
356
const double tmp_ref0 = values[0];
357
const double tmp_ref1 = values[1];
358
values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
359
values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
366
/// Evaluate all basis functions at given point x in cell
367
virtual void evaluate_basis_all(double* values,
369
const double* vertex_coordinates,
370
int cell_orientation) const
372
// Helper variable to hold values of a single dof.
373
double dof_values[2] = {0.0, 0.0};
375
// Loop dofs and call evaluate_basis
376
for (unsigned int r = 0; r < 6; r++)
378
evaluate_basis(r, dof_values, x, vertex_coordinates, cell_orientation);
379
for (unsigned int s = 0; s < 2; s++)
381
values[r*2 + s] = dof_values[s];
382
}// end loop over 's'
383
}// end loop over 'r'
386
/// Evaluate order n derivatives of basis function i at given point x in cell
387
virtual void evaluate_basis_derivatives(std::size_t i,
391
const double* vertex_coordinates,
392
int cell_orientation) const
396
compute_jacobian_triangle_2d(J, vertex_coordinates);
398
// Compute Jacobian inverse and determinant
401
compute_jacobian_inverse_triangle_2d(K, detJ, J);
406
const double C0 = vertex_coordinates[2] + vertex_coordinates[4];
407
const double C1 = vertex_coordinates[3] + vertex_coordinates[5];
409
// Get coordinates and map to the reference (FIAT) element
410
double X = (J[1]*(C1 - 2.0*x[1]) + J[3]*(2.0*x[0] - C0)) / detJ;
411
double Y = (J[0]*(2.0*x[1] - C1) + J[2]*(C0 - 2.0*x[0])) / detJ;
413
// Compute number of derivatives.
414
unsigned int num_derivatives = 1;
415
for (unsigned int r = 0; r < n; r++)
417
num_derivatives *= 2;
418
}// end loop over 'r'
420
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
421
unsigned int **combinations = new unsigned int *[num_derivatives];
422
for (unsigned int row = 0; row < num_derivatives; row++)
424
combinations[row] = new unsigned int [n];
425
for (unsigned int col = 0; col < n; col++)
426
combinations[row][col] = 0;
429
// Generate combinations of derivatives
430
for (unsigned int row = 1; row < num_derivatives; row++)
432
for (unsigned int num = 0; num < row; num++)
434
for (unsigned int col = n-1; col+1 > 0; col--)
436
if (combinations[row][col] + 1 > 1)
437
combinations[row][col] = 0;
440
combinations[row][col] += 1;
447
// Compute inverse of Jacobian
448
const double Jinv[2][2] = {{K[0], K[1]}, {K[2], K[3]}};
450
// Declare transformation matrix
451
// Declare pointer to two dimensional array and initialise
452
double **transform = new double *[num_derivatives];
454
for (unsigned int j = 0; j < num_derivatives; j++)
456
transform[j] = new double [num_derivatives];
457
for (unsigned int k = 0; k < num_derivatives; k++)
461
// Construct transformation matrix
462
for (unsigned int row = 0; row < num_derivatives; row++)
464
for (unsigned int col = 0; col < num_derivatives; col++)
466
for (unsigned int k = 0; k < n; k++)
467
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
471
// Reset values. Assuming that values is always an array.
472
for (unsigned int r = 0; r < 2*num_derivatives; r++)
475
}// end loop over 'r'
482
// Array of basisvalues
483
double basisvalues[3] = {0.0, 0.0, 0.0};
485
// Declare helper variables
486
double tmp0 = (1.0 + Y + 2.0*X)/2.0;
488
// Compute basisvalues
489
basisvalues[0] = 1.0;
490
basisvalues[1] = tmp0;
491
basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
492
basisvalues[0] *= std::sqrt(0.5);
493
basisvalues[2] *= std::sqrt(1.0);
494
basisvalues[1] *= std::sqrt(3.0);
496
// Table(s) of coefficients
497
static const double coefficients0[3] = \
498
{0.94280904, 0.57735027, -0.33333333};
500
static const double coefficients1[3] = \
501
{-0.47140452, 0.0, -0.33333333};
503
// Tables of derivatives of the polynomial base (transpose).
504
static const double dmats0[3][3] = \
506
{4.8989795, 0.0, 0.0},
509
static const double dmats1[3][3] = \
511
{2.4494897, 0.0, 0.0},
512
{4.2426407, 0.0, 0.0}};
514
// Compute reference derivatives.
515
// Declare pointer to array of derivatives on FIAT element.
516
double *derivatives = new double[2*num_derivatives];
517
for (unsigned int r = 0; r < 2*num_derivatives; r++)
519
derivatives[r] = 0.0;
520
}// end loop over 'r'
522
// Declare pointer to array of reference derivatives on physical element.
523
double *derivatives_p = new double[2*num_derivatives];
524
for (unsigned int r = 0; r < 2*num_derivatives; r++)
526
derivatives_p[r] = 0.0;
527
}// end loop over 'r'
529
// Declare derivative matrix (of polynomial basis).
530
double dmats[3][3] = \
535
// Declare (auxiliary) derivative matrix (of polynomial basis).
536
double dmats_old[3][3] = \
541
// Loop possible derivatives.
542
for (unsigned int r = 0; r < num_derivatives; r++)
544
// Resetting dmats values to compute next derivative.
545
for (unsigned int t = 0; t < 3; t++)
547
for (unsigned int u = 0; u < 3; u++)
555
}// end loop over 'u'
556
}// end loop over 't'
558
// Looping derivative order to generate dmats.
559
for (unsigned int s = 0; s < n; s++)
561
// Updating dmats_old with new values and resetting dmats.
562
for (unsigned int t = 0; t < 3; t++)
564
for (unsigned int u = 0; u < 3; u++)
566
dmats_old[t][u] = dmats[t][u];
568
}// end loop over 'u'
569
}// end loop over 't'
571
// Update dmats using an inner product.
572
if (combinations[r][s] == 0)
574
for (unsigned int t = 0; t < 3; t++)
576
for (unsigned int u = 0; u < 3; u++)
578
for (unsigned int tu = 0; tu < 3; tu++)
580
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
581
}// end loop over 'tu'
582
}// end loop over 'u'
583
}// end loop over 't'
586
if (combinations[r][s] == 1)
588
for (unsigned int t = 0; t < 3; t++)
590
for (unsigned int u = 0; u < 3; u++)
592
for (unsigned int tu = 0; tu < 3; tu++)
594
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
595
}// end loop over 'tu'
596
}// end loop over 'u'
597
}// end loop over 't'
600
}// end loop over 's'
601
for (unsigned int s = 0; s < 3; s++)
603
for (unsigned int t = 0; t < 3; t++)
605
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
606
derivatives[num_derivatives + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
607
}// end loop over 't'
608
}// end loop over 's'
610
// Using contravariant Piola transform to map values back to the physical element.
611
const double tmp_ref0 = derivatives[r];
612
const double tmp_ref1 = derivatives[num_derivatives + r];
613
derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
614
derivatives_p[num_derivatives + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
615
}// end loop over 'r'
617
// Transform derivatives back to physical element
618
for (unsigned int r = 0; r < num_derivatives; r++)
620
for (unsigned int s = 0; s < num_derivatives; s++)
622
values[r] += transform[r][s]*derivatives_p[s];
623
values[num_derivatives + r] += transform[r][s]*derivatives_p[num_derivatives + s];
624
}// end loop over 's'
625
}// end loop over 'r'
627
// Delete pointer to array of derivatives on FIAT element
628
delete [] derivatives;
630
// Delete pointer to array of reference derivatives on physical element.
631
delete [] derivatives_p;
633
// Delete pointer to array of combinations of derivatives and transform
634
for (unsigned int r = 0; r < num_derivatives; r++)
636
delete [] combinations[r];
637
}// end loop over 'r'
638
delete [] combinations;
639
for (unsigned int r = 0; r < num_derivatives; r++)
641
delete [] transform[r];
642
}// end loop over 'r'
649
// Array of basisvalues
650
double basisvalues[3] = {0.0, 0.0, 0.0};
652
// Declare helper variables
653
double tmp0 = (1.0 + Y + 2.0*X)/2.0;
655
// Compute basisvalues
656
basisvalues[0] = 1.0;
657
basisvalues[1] = tmp0;
658
basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
659
basisvalues[0] *= std::sqrt(0.5);
660
basisvalues[2] *= std::sqrt(1.0);
661
basisvalues[1] *= std::sqrt(3.0);
663
// Table(s) of coefficients
664
static const double coefficients0[3] = \
665
{-0.47140452, -0.28867513, 0.16666667};
667
static const double coefficients1[3] = \
668
{0.94280904, 0.0, 0.66666667};
670
// Tables of derivatives of the polynomial base (transpose).
671
static const double dmats0[3][3] = \
673
{4.8989795, 0.0, 0.0},
676
static const double dmats1[3][3] = \
678
{2.4494897, 0.0, 0.0},
679
{4.2426407, 0.0, 0.0}};
681
// Compute reference derivatives.
682
// Declare pointer to array of derivatives on FIAT element.
683
double *derivatives = new double[2*num_derivatives];
684
for (unsigned int r = 0; r < 2*num_derivatives; r++)
686
derivatives[r] = 0.0;
687
}// end loop over 'r'
689
// Declare pointer to array of reference derivatives on physical element.
690
double *derivatives_p = new double[2*num_derivatives];
691
for (unsigned int r = 0; r < 2*num_derivatives; r++)
693
derivatives_p[r] = 0.0;
694
}// end loop over 'r'
696
// Declare derivative matrix (of polynomial basis).
697
double dmats[3][3] = \
702
// Declare (auxiliary) derivative matrix (of polynomial basis).
703
double dmats_old[3][3] = \
708
// Loop possible derivatives.
709
for (unsigned int r = 0; r < num_derivatives; r++)
711
// Resetting dmats values to compute next derivative.
712
for (unsigned int t = 0; t < 3; t++)
714
for (unsigned int u = 0; u < 3; u++)
722
}// end loop over 'u'
723
}// end loop over 't'
725
// Looping derivative order to generate dmats.
726
for (unsigned int s = 0; s < n; s++)
728
// Updating dmats_old with new values and resetting dmats.
729
for (unsigned int t = 0; t < 3; t++)
731
for (unsigned int u = 0; u < 3; u++)
733
dmats_old[t][u] = dmats[t][u];
735
}// end loop over 'u'
736
}// end loop over 't'
738
// Update dmats using an inner product.
739
if (combinations[r][s] == 0)
741
for (unsigned int t = 0; t < 3; t++)
743
for (unsigned int u = 0; u < 3; u++)
745
for (unsigned int tu = 0; tu < 3; tu++)
747
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
748
}// end loop over 'tu'
749
}// end loop over 'u'
750
}// end loop over 't'
753
if (combinations[r][s] == 1)
755
for (unsigned int t = 0; t < 3; t++)
757
for (unsigned int u = 0; u < 3; u++)
759
for (unsigned int tu = 0; tu < 3; tu++)
761
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
762
}// end loop over 'tu'
763
}// end loop over 'u'
764
}// end loop over 't'
767
}// end loop over 's'
768
for (unsigned int s = 0; s < 3; s++)
770
for (unsigned int t = 0; t < 3; t++)
772
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
773
derivatives[num_derivatives + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
774
}// end loop over 't'
775
}// end loop over 's'
777
// Using contravariant Piola transform to map values back to the physical element.
778
const double tmp_ref0 = derivatives[r];
779
const double tmp_ref1 = derivatives[num_derivatives + r];
780
derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
781
derivatives_p[num_derivatives + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
782
}// end loop over 'r'
784
// Transform derivatives back to physical element
785
for (unsigned int r = 0; r < num_derivatives; r++)
787
for (unsigned int s = 0; s < num_derivatives; s++)
789
values[r] += transform[r][s]*derivatives_p[s];
790
values[num_derivatives + r] += transform[r][s]*derivatives_p[num_derivatives + s];
791
}// end loop over 's'
792
}// end loop over 'r'
794
// Delete pointer to array of derivatives on FIAT element
795
delete [] derivatives;
797
// Delete pointer to array of reference derivatives on physical element.
798
delete [] derivatives_p;
800
// Delete pointer to array of combinations of derivatives and transform
801
for (unsigned int r = 0; r < num_derivatives; r++)
803
delete [] combinations[r];
804
}// end loop over 'r'
805
delete [] combinations;
806
for (unsigned int r = 0; r < num_derivatives; r++)
808
delete [] transform[r];
809
}// end loop over 'r'
816
// Array of basisvalues
817
double basisvalues[3] = {0.0, 0.0, 0.0};
819
// Declare helper variables
820
double tmp0 = (1.0 + Y + 2.0*X)/2.0;
822
// Compute basisvalues
823
basisvalues[0] = 1.0;
824
basisvalues[1] = tmp0;
825
basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
826
basisvalues[0] *= std::sqrt(0.5);
827
basisvalues[2] *= std::sqrt(1.0);
828
basisvalues[1] *= std::sqrt(3.0);
830
// Table(s) of coefficients
831
static const double coefficients0[3] = \
832
{0.47140452, -0.57735027, -0.66666667};
834
static const double coefficients1[3] = \
835
{0.47140452, 0.0, 0.33333333};
837
// Tables of derivatives of the polynomial base (transpose).
838
static const double dmats0[3][3] = \
840
{4.8989795, 0.0, 0.0},
843
static const double dmats1[3][3] = \
845
{2.4494897, 0.0, 0.0},
846
{4.2426407, 0.0, 0.0}};
848
// Compute reference derivatives.
849
// Declare pointer to array of derivatives on FIAT element.
850
double *derivatives = new double[2*num_derivatives];
851
for (unsigned int r = 0; r < 2*num_derivatives; r++)
853
derivatives[r] = 0.0;
854
}// end loop over 'r'
856
// Declare pointer to array of reference derivatives on physical element.
857
double *derivatives_p = new double[2*num_derivatives];
858
for (unsigned int r = 0; r < 2*num_derivatives; r++)
860
derivatives_p[r] = 0.0;
861
}// end loop over 'r'
863
// Declare derivative matrix (of polynomial basis).
864
double dmats[3][3] = \
869
// Declare (auxiliary) derivative matrix (of polynomial basis).
870
double dmats_old[3][3] = \
875
// Loop possible derivatives.
876
for (unsigned int r = 0; r < num_derivatives; r++)
878
// Resetting dmats values to compute next derivative.
879
for (unsigned int t = 0; t < 3; t++)
881
for (unsigned int u = 0; u < 3; u++)
889
}// end loop over 'u'
890
}// end loop over 't'
892
// Looping derivative order to generate dmats.
893
for (unsigned int s = 0; s < n; s++)
895
// Updating dmats_old with new values and resetting dmats.
896
for (unsigned int t = 0; t < 3; t++)
898
for (unsigned int u = 0; u < 3; u++)
900
dmats_old[t][u] = dmats[t][u];
902
}// end loop over 'u'
903
}// end loop over 't'
905
// Update dmats using an inner product.
906
if (combinations[r][s] == 0)
908
for (unsigned int t = 0; t < 3; t++)
910
for (unsigned int u = 0; u < 3; u++)
912
for (unsigned int tu = 0; tu < 3; tu++)
914
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
915
}// end loop over 'tu'
916
}// end loop over 'u'
917
}// end loop over 't'
920
if (combinations[r][s] == 1)
922
for (unsigned int t = 0; t < 3; t++)
924
for (unsigned int u = 0; u < 3; u++)
926
for (unsigned int tu = 0; tu < 3; tu++)
928
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
929
}// end loop over 'tu'
930
}// end loop over 'u'
931
}// end loop over 't'
934
}// end loop over 's'
935
for (unsigned int s = 0; s < 3; s++)
937
for (unsigned int t = 0; t < 3; t++)
939
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
940
derivatives[num_derivatives + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
941
}// end loop over 't'
942
}// end loop over 's'
944
// Using contravariant Piola transform to map values back to the physical element.
945
const double tmp_ref0 = derivatives[r];
946
const double tmp_ref1 = derivatives[num_derivatives + r];
947
derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
948
derivatives_p[num_derivatives + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
949
}// end loop over 'r'
951
// Transform derivatives back to physical element
952
for (unsigned int r = 0; r < num_derivatives; r++)
954
for (unsigned int s = 0; s < num_derivatives; s++)
956
values[r] += transform[r][s]*derivatives_p[s];
957
values[num_derivatives + r] += transform[r][s]*derivatives_p[num_derivatives + s];
958
}// end loop over 's'
959
}// end loop over 'r'
961
// Delete pointer to array of derivatives on FIAT element
962
delete [] derivatives;
964
// Delete pointer to array of reference derivatives on physical element.
965
delete [] derivatives_p;
967
// Delete pointer to array of combinations of derivatives and transform
968
for (unsigned int r = 0; r < num_derivatives; r++)
970
delete [] combinations[r];
971
}// end loop over 'r'
972
delete [] combinations;
973
for (unsigned int r = 0; r < num_derivatives; r++)
975
delete [] transform[r];
976
}// end loop over 'r'
983
// Array of basisvalues
984
double basisvalues[3] = {0.0, 0.0, 0.0};
986
// Declare helper variables
987
double tmp0 = (1.0 + Y + 2.0*X)/2.0;
989
// Compute basisvalues
990
basisvalues[0] = 1.0;
991
basisvalues[1] = tmp0;
992
basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
993
basisvalues[0] *= std::sqrt(0.5);
994
basisvalues[2] *= std::sqrt(1.0);
995
basisvalues[1] *= std::sqrt(3.0);
997
// Table(s) of coefficients
998
static const double coefficients0[3] = \
999
{0.47140452, 0.28867513, 0.83333333};
1001
static const double coefficients1[3] = \
1002
{-0.94280904, 0.0, -0.66666667};
1004
// Tables of derivatives of the polynomial base (transpose).
1005
static const double dmats0[3][3] = \
1007
{4.8989795, 0.0, 0.0},
1010
static const double dmats1[3][3] = \
1012
{2.4494897, 0.0, 0.0},
1013
{4.2426407, 0.0, 0.0}};
1015
// Compute reference derivatives.
1016
// Declare pointer to array of derivatives on FIAT element.
1017
double *derivatives = new double[2*num_derivatives];
1018
for (unsigned int r = 0; r < 2*num_derivatives; r++)
1020
derivatives[r] = 0.0;
1021
}// end loop over 'r'
1023
// Declare pointer to array of reference derivatives on physical element.
1024
double *derivatives_p = new double[2*num_derivatives];
1025
for (unsigned int r = 0; r < 2*num_derivatives; r++)
1027
derivatives_p[r] = 0.0;
1028
}// end loop over 'r'
1030
// Declare derivative matrix (of polynomial basis).
1031
double dmats[3][3] = \
1036
// Declare (auxiliary) derivative matrix (of polynomial basis).
1037
double dmats_old[3][3] = \
1042
// Loop possible derivatives.
1043
for (unsigned int r = 0; r < num_derivatives; r++)
1045
// Resetting dmats values to compute next derivative.
1046
for (unsigned int t = 0; t < 3; t++)
1048
for (unsigned int u = 0; u < 3; u++)
1056
}// end loop over 'u'
1057
}// end loop over 't'
1059
// Looping derivative order to generate dmats.
1060
for (unsigned int s = 0; s < n; s++)
1062
// Updating dmats_old with new values and resetting dmats.
1063
for (unsigned int t = 0; t < 3; t++)
1065
for (unsigned int u = 0; u < 3; u++)
1067
dmats_old[t][u] = dmats[t][u];
1069
}// end loop over 'u'
1070
}// end loop over 't'
1072
// Update dmats using an inner product.
1073
if (combinations[r][s] == 0)
1075
for (unsigned int t = 0; t < 3; t++)
1077
for (unsigned int u = 0; u < 3; u++)
1079
for (unsigned int tu = 0; tu < 3; tu++)
1081
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
1082
}// end loop over 'tu'
1083
}// end loop over 'u'
1084
}// end loop over 't'
1087
if (combinations[r][s] == 1)
1089
for (unsigned int t = 0; t < 3; t++)
1091
for (unsigned int u = 0; u < 3; u++)
1093
for (unsigned int tu = 0; tu < 3; tu++)
1095
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
1096
}// end loop over 'tu'
1097
}// end loop over 'u'
1098
}// end loop over 't'
1101
}// end loop over 's'
1102
for (unsigned int s = 0; s < 3; s++)
1104
for (unsigned int t = 0; t < 3; t++)
1106
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
1107
derivatives[num_derivatives + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
1108
}// end loop over 't'
1109
}// end loop over 's'
1111
// Using contravariant Piola transform to map values back to the physical element.
1112
const double tmp_ref0 = derivatives[r];
1113
const double tmp_ref1 = derivatives[num_derivatives + r];
1114
derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
1115
derivatives_p[num_derivatives + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
1116
}// end loop over 'r'
1118
// Transform derivatives back to physical element
1119
for (unsigned int r = 0; r < num_derivatives; r++)
1121
for (unsigned int s = 0; s < num_derivatives; s++)
1123
values[r] += transform[r][s]*derivatives_p[s];
1124
values[num_derivatives + r] += transform[r][s]*derivatives_p[num_derivatives + s];
1125
}// end loop over 's'
1126
}// end loop over 'r'
1128
// Delete pointer to array of derivatives on FIAT element
1129
delete [] derivatives;
1131
// Delete pointer to array of reference derivatives on physical element.
1132
delete [] derivatives_p;
1134
// Delete pointer to array of combinations of derivatives and transform
1135
for (unsigned int r = 0; r < num_derivatives; r++)
1137
delete [] combinations[r];
1138
}// end loop over 'r'
1139
delete [] combinations;
1140
for (unsigned int r = 0; r < num_derivatives; r++)
1142
delete [] transform[r];
1143
}// end loop over 'r'
1144
delete [] transform;
1150
// Array of basisvalues
1151
double basisvalues[3] = {0.0, 0.0, 0.0};
1153
// Declare helper variables
1154
double tmp0 = (1.0 + Y + 2.0*X)/2.0;
1156
// Compute basisvalues
1157
basisvalues[0] = 1.0;
1158
basisvalues[1] = tmp0;
1159
basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
1160
basisvalues[0] *= std::sqrt(0.5);
1161
basisvalues[2] *= std::sqrt(1.0);
1162
basisvalues[1] *= std::sqrt(3.0);
1164
// Table(s) of coefficients
1165
static const double coefficients0[3] = \
1166
{-0.47140452, -0.28867513, 0.16666667};
1168
static const double coefficients1[3] = \
1169
{-0.47140452, 0.8660254, 0.16666667};
1171
// Tables of derivatives of the polynomial base (transpose).
1172
static const double dmats0[3][3] = \
1174
{4.8989795, 0.0, 0.0},
1177
static const double dmats1[3][3] = \
1179
{2.4494897, 0.0, 0.0},
1180
{4.2426407, 0.0, 0.0}};
1182
// Compute reference derivatives.
1183
// Declare pointer to array of derivatives on FIAT element.
1184
double *derivatives = new double[2*num_derivatives];
1185
for (unsigned int r = 0; r < 2*num_derivatives; r++)
1187
derivatives[r] = 0.0;
1188
}// end loop over 'r'
1190
// Declare pointer to array of reference derivatives on physical element.
1191
double *derivatives_p = new double[2*num_derivatives];
1192
for (unsigned int r = 0; r < 2*num_derivatives; r++)
1194
derivatives_p[r] = 0.0;
1195
}// end loop over 'r'
1197
// Declare derivative matrix (of polynomial basis).
1198
double dmats[3][3] = \
1203
// Declare (auxiliary) derivative matrix (of polynomial basis).
1204
double dmats_old[3][3] = \
1209
// Loop possible derivatives.
1210
for (unsigned int r = 0; r < num_derivatives; r++)
1212
// Resetting dmats values to compute next derivative.
1213
for (unsigned int t = 0; t < 3; t++)
1215
for (unsigned int u = 0; u < 3; u++)
1223
}// end loop over 'u'
1224
}// end loop over 't'
1226
// Looping derivative order to generate dmats.
1227
for (unsigned int s = 0; s < n; s++)
1229
// Updating dmats_old with new values and resetting dmats.
1230
for (unsigned int t = 0; t < 3; t++)
1232
for (unsigned int u = 0; u < 3; u++)
1234
dmats_old[t][u] = dmats[t][u];
1236
}// end loop over 'u'
1237
}// end loop over 't'
1239
// Update dmats using an inner product.
1240
if (combinations[r][s] == 0)
1242
for (unsigned int t = 0; t < 3; t++)
1244
for (unsigned int u = 0; u < 3; u++)
1246
for (unsigned int tu = 0; tu < 3; tu++)
1248
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
1249
}// end loop over 'tu'
1250
}// end loop over 'u'
1251
}// end loop over 't'
1254
if (combinations[r][s] == 1)
1256
for (unsigned int t = 0; t < 3; t++)
1258
for (unsigned int u = 0; u < 3; u++)
1260
for (unsigned int tu = 0; tu < 3; tu++)
1262
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
1263
}// end loop over 'tu'
1264
}// end loop over 'u'
1265
}// end loop over 't'
1268
}// end loop over 's'
1269
for (unsigned int s = 0; s < 3; s++)
1271
for (unsigned int t = 0; t < 3; t++)
1273
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
1274
derivatives[num_derivatives + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
1275
}// end loop over 't'
1276
}// end loop over 's'
1278
// Using contravariant Piola transform to map values back to the physical element.
1279
const double tmp_ref0 = derivatives[r];
1280
const double tmp_ref1 = derivatives[num_derivatives + r];
1281
derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
1282
derivatives_p[num_derivatives + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
1283
}// end loop over 'r'
1285
// Transform derivatives back to physical element
1286
for (unsigned int r = 0; r < num_derivatives; r++)
1288
for (unsigned int s = 0; s < num_derivatives; s++)
1290
values[r] += transform[r][s]*derivatives_p[s];
1291
values[num_derivatives + r] += transform[r][s]*derivatives_p[num_derivatives + s];
1292
}// end loop over 's'
1293
}// end loop over 'r'
1295
// Delete pointer to array of derivatives on FIAT element
1296
delete [] derivatives;
1298
// Delete pointer to array of reference derivatives on physical element.
1299
delete [] derivatives_p;
1301
// Delete pointer to array of combinations of derivatives and transform
1302
for (unsigned int r = 0; r < num_derivatives; r++)
1304
delete [] combinations[r];
1305
}// end loop over 'r'
1306
delete [] combinations;
1307
for (unsigned int r = 0; r < num_derivatives; r++)
1309
delete [] transform[r];
1310
}// end loop over 'r'
1311
delete [] transform;
1317
// Array of basisvalues
1318
double basisvalues[3] = {0.0, 0.0, 0.0};
1320
// Declare helper variables
1321
double tmp0 = (1.0 + Y + 2.0*X)/2.0;
1323
// Compute basisvalues
1324
basisvalues[0] = 1.0;
1325
basisvalues[1] = tmp0;
1326
basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
1327
basisvalues[0] *= std::sqrt(0.5);
1328
basisvalues[2] *= std::sqrt(1.0);
1329
basisvalues[1] *= std::sqrt(3.0);
1331
// Table(s) of coefficients
1332
static const double coefficients0[3] = \
1333
{0.94280904, 0.57735027, -0.33333333};
1335
static const double coefficients1[3] = \
1336
{-0.47140452, -0.8660254, 0.16666667};
1338
// Tables of derivatives of the polynomial base (transpose).
1339
static const double dmats0[3][3] = \
1341
{4.8989795, 0.0, 0.0},
1344
static const double dmats1[3][3] = \
1346
{2.4494897, 0.0, 0.0},
1347
{4.2426407, 0.0, 0.0}};
1349
// Compute reference derivatives.
1350
// Declare pointer to array of derivatives on FIAT element.
1351
double *derivatives = new double[2*num_derivatives];
1352
for (unsigned int r = 0; r < 2*num_derivatives; r++)
1354
derivatives[r] = 0.0;
1355
}// end loop over 'r'
1357
// Declare pointer to array of reference derivatives on physical element.
1358
double *derivatives_p = new double[2*num_derivatives];
1359
for (unsigned int r = 0; r < 2*num_derivatives; r++)
1361
derivatives_p[r] = 0.0;
1362
}// end loop over 'r'
1364
// Declare derivative matrix (of polynomial basis).
1365
double dmats[3][3] = \
1370
// Declare (auxiliary) derivative matrix (of polynomial basis).
1371
double dmats_old[3][3] = \
1376
// Loop possible derivatives.
1377
for (unsigned int r = 0; r < num_derivatives; r++)
1379
// Resetting dmats values to compute next derivative.
1380
for (unsigned int t = 0; t < 3; t++)
1382
for (unsigned int u = 0; u < 3; u++)
1390
}// end loop over 'u'
1391
}// end loop over 't'
1393
// Looping derivative order to generate dmats.
1394
for (unsigned int s = 0; s < n; s++)
1396
// Updating dmats_old with new values and resetting dmats.
1397
for (unsigned int t = 0; t < 3; t++)
1399
for (unsigned int u = 0; u < 3; u++)
1401
dmats_old[t][u] = dmats[t][u];
1403
}// end loop over 'u'
1404
}// end loop over 't'
1406
// Update dmats using an inner product.
1407
if (combinations[r][s] == 0)
1409
for (unsigned int t = 0; t < 3; t++)
1411
for (unsigned int u = 0; u < 3; u++)
1413
for (unsigned int tu = 0; tu < 3; tu++)
1415
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
1416
}// end loop over 'tu'
1417
}// end loop over 'u'
1418
}// end loop over 't'
1421
if (combinations[r][s] == 1)
1423
for (unsigned int t = 0; t < 3; t++)
1425
for (unsigned int u = 0; u < 3; u++)
1427
for (unsigned int tu = 0; tu < 3; tu++)
1429
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
1430
}// end loop over 'tu'
1431
}// end loop over 'u'
1432
}// end loop over 't'
1435
}// end loop over 's'
1436
for (unsigned int s = 0; s < 3; s++)
1438
for (unsigned int t = 0; t < 3; t++)
1440
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
1441
derivatives[num_derivatives + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
1442
}// end loop over 't'
1443
}// end loop over 's'
1445
// Using contravariant Piola transform to map values back to the physical element.
1446
const double tmp_ref0 = derivatives[r];
1447
const double tmp_ref1 = derivatives[num_derivatives + r];
1448
derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
1449
derivatives_p[num_derivatives + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
1450
}// end loop over 'r'
1452
// Transform derivatives back to physical element
1453
for (unsigned int r = 0; r < num_derivatives; r++)
1455
for (unsigned int s = 0; s < num_derivatives; s++)
1457
values[r] += transform[r][s]*derivatives_p[s];
1458
values[num_derivatives + r] += transform[r][s]*derivatives_p[num_derivatives + s];
1459
}// end loop over 's'
1460
}// end loop over 'r'
1462
// Delete pointer to array of derivatives on FIAT element
1463
delete [] derivatives;
1465
// Delete pointer to array of reference derivatives on physical element.
1466
delete [] derivatives_p;
1468
// Delete pointer to array of combinations of derivatives and transform
1469
for (unsigned int r = 0; r < num_derivatives; r++)
1471
delete [] combinations[r];
1472
}// end loop over 'r'
1473
delete [] combinations;
1474
for (unsigned int r = 0; r < num_derivatives; r++)
1476
delete [] transform[r];
1477
}// end loop over 'r'
1478
delete [] transform;
1485
/// Evaluate order n derivatives of all basis functions at given point x in cell
1486
virtual void evaluate_basis_derivatives_all(std::size_t n,
1489
const double* vertex_coordinates,
1490
int cell_orientation) const
1492
// Compute number of derivatives.
1493
unsigned int num_derivatives = 1;
1494
for (unsigned int r = 0; r < n; r++)
1496
num_derivatives *= 2;
1497
}// end loop over 'r'
1499
// Helper variable to hold values of a single dof.
1500
double *dof_values = new double[2*num_derivatives];
1501
for (unsigned int r = 0; r < 2*num_derivatives; r++)
1503
dof_values[r] = 0.0;
1504
}// end loop over 'r'
1506
// Loop dofs and call evaluate_basis_derivatives.
1507
for (unsigned int r = 0; r < 6; r++)
1509
evaluate_basis_derivatives(r, n, dof_values, x, vertex_coordinates, cell_orientation);
1510
for (unsigned int s = 0; s < 2*num_derivatives; s++)
1512
values[r*2*num_derivatives + s] = dof_values[s];
1513
}// end loop over 's'
1514
}// end loop over 'r'
1517
delete [] dof_values;
1520
/// Evaluate linear functional for dof i on the function f
1521
virtual double evaluate_dof(std::size_t i,
1522
const ufc::function& f,
1523
const double* vertex_coordinates,
1524
int cell_orientation,
1525
const ufc::cell& c) const
1527
// Declare variables for result of evaluation
1530
// Declare variable for physical coordinates
1536
compute_jacobian_triangle_2d(J, vertex_coordinates);
1539
// Compute Jacobian inverse and determinant
1542
compute_jacobian_inverse_triangle_2d(K, detJ, J);
1549
y[0] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[4];
1550
y[1] = 0.66666667*vertex_coordinates[3] + 0.33333333*vertex_coordinates[5];
1551
f.evaluate(vals, y, c);
1552
result = (detJ*(K[0]*vals[0] + K[1]*vals[1])) + (detJ*(K[2]*vals[0] + K[3]*vals[1]));
1558
y[0] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[4];
1559
y[1] = 0.33333333*vertex_coordinates[3] + 0.66666667*vertex_coordinates[5];
1560
f.evaluate(vals, y, c);
1561
result = (detJ*(K[0]*vals[0] + K[1]*vals[1])) + (detJ*(K[2]*vals[0] + K[3]*vals[1]));
1567
y[0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[4];
1568
y[1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[5];
1569
f.evaluate(vals, y, c);
1570
result = (detJ*(K[0]*vals[0] + K[1]*vals[1]));
1576
y[0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[4];
1577
y[1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[5];
1578
f.evaluate(vals, y, c);
1579
result = (detJ*(K[0]*vals[0] + K[1]*vals[1]));
1585
y[0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[2];
1586
y[1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[3];
1587
f.evaluate(vals, y, c);
1588
result = (-1.0)*(detJ*(K[2]*vals[0] + K[3]*vals[1]));
1594
y[0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[2];
1595
y[1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[3];
1596
f.evaluate(vals, y, c);
1597
result = (-1.0)*(detJ*(K[2]*vals[0] + K[3]*vals[1]));
1606
/// Evaluate linear functionals for all dofs on the function f
1607
virtual void evaluate_dofs(double* values,
1608
const ufc::function& f,
1609
const double* vertex_coordinates,
1610
int cell_orientation,
1611
const ufc::cell& c) const
1613
// Declare variables for result of evaluation
1616
// Declare variable for physical coordinates
1622
compute_jacobian_triangle_2d(J, vertex_coordinates);
1625
// Compute Jacobian inverse and determinant
1628
compute_jacobian_inverse_triangle_2d(K, detJ, J);
1631
y[0] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[4];
1632
y[1] = 0.66666667*vertex_coordinates[3] + 0.33333333*vertex_coordinates[5];
1633
f.evaluate(vals, y, c);
1634
result = (detJ*(K[0]*vals[0] + K[1]*vals[1])) + (detJ*(K[2]*vals[0] + K[3]*vals[1]));
1636
y[0] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[4];
1637
y[1] = 0.33333333*vertex_coordinates[3] + 0.66666667*vertex_coordinates[5];
1638
f.evaluate(vals, y, c);
1639
result = (detJ*(K[0]*vals[0] + K[1]*vals[1])) + (detJ*(K[2]*vals[0] + K[3]*vals[1]));
1641
y[0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[4];
1642
y[1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[5];
1643
f.evaluate(vals, y, c);
1644
result = (detJ*(K[0]*vals[0] + K[1]*vals[1]));
1646
y[0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[4];
1647
y[1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[5];
1648
f.evaluate(vals, y, c);
1649
result = (detJ*(K[0]*vals[0] + K[1]*vals[1]));
1651
y[0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[2];
1652
y[1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[3];
1653
f.evaluate(vals, y, c);
1654
result = (-1.0)*(detJ*(K[2]*vals[0] + K[3]*vals[1]));
1656
y[0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[2];
1657
y[1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[3];
1658
f.evaluate(vals, y, c);
1659
result = (-1.0)*(detJ*(K[2]*vals[0] + K[3]*vals[1]));
1663
/// Interpolate vertex values from dof values
1664
virtual void interpolate_vertex_values(double* vertex_values,
1665
const double* dof_values,
1666
const double* vertex_coordinates,
1667
int cell_orientation,
1668
const ufc::cell& c) const
1672
compute_jacobian_triangle_2d(J, vertex_coordinates);
1675
// Compute Jacobian inverse and determinant
1678
compute_jacobian_inverse_triangle_2d(K, detJ, J);
1682
// Evaluate function and change variables
1683
vertex_values[0] = dof_values[2]*(1.0/detJ)*J[0]*2.0 + dof_values[3]*((1.0/detJ)*(J[0]*(-1.0))) + dof_values[4]*((1.0/detJ)*(J[1]*(-2.0))) + dof_values[5]*(1.0/detJ)*J[1];
1684
vertex_values[2] = dof_values[0]*(1.0/detJ)*J[0]*2.0 + dof_values[1]*((1.0/detJ)*(J[0]*(-1.0))) + dof_values[4]*((1.0/detJ)*(J[0]*(-1.0) + J[1])) + dof_values[5]*((1.0/detJ)*(J[0]*2.0 + J[1]*(-2.0)));
1685
vertex_values[4] = dof_values[0]*((1.0/detJ)*(J[1]*(-1.0))) + dof_values[1]*(1.0/detJ)*J[1]*2.0 + dof_values[2]*((1.0/detJ)*(J[0]*(-1.0) + J[1])) + dof_values[3]*((1.0/detJ)*(J[0]*2.0 + J[1]*(-2.0)));
1686
vertex_values[1] = dof_values[2]*(1.0/detJ)*J[2]*2.0 + dof_values[3]*((1.0/detJ)*(J[2]*(-1.0))) + dof_values[4]*((1.0/detJ)*(J[3]*(-2.0))) + dof_values[5]*(1.0/detJ)*J[3];
1687
vertex_values[3] = dof_values[0]*(1.0/detJ)*J[2]*2.0 + dof_values[1]*((1.0/detJ)*(J[2]*(-1.0))) + dof_values[4]*((1.0/detJ)*(J[2]*(-1.0) + J[3])) + dof_values[5]*((1.0/detJ)*(J[2]*2.0 + J[3]*(-2.0)));
1688
vertex_values[5] = dof_values[0]*((1.0/detJ)*(J[3]*(-1.0))) + dof_values[1]*(1.0/detJ)*J[3]*2.0 + dof_values[2]*((1.0/detJ)*(J[2]*(-1.0) + J[3])) + dof_values[3]*((1.0/detJ)*(J[2]*2.0 + J[3]*(-2.0)));
1691
/// Map coordinate xhat from reference cell to coordinate x in cell
1692
virtual void map_from_reference_cell(double* x,
1694
const ufc::cell& c) const
1696
std::cerr << "*** FFC warning: " << "map_from_reference_cell not yet implemented." << std::endl;
1699
/// Map from coordinate x in cell to coordinate xhat in reference cell
1700
virtual void map_to_reference_cell(double* xhat,
1702
const ufc::cell& c) const
1704
std::cerr << "*** FFC warning: " << "map_to_reference_cell not yet implemented." << std::endl;
1707
/// Return the number of sub elements (for a mixed element)
1708
virtual std::size_t num_sub_elements() const
1713
/// Create a new finite element for sub element i (for a mixed element)
1714
virtual ufc::finite_element* create_sub_element(std::size_t i) const
1719
/// Create a new class instance
1720
virtual ufc::finite_element* create() const
1722
return new mixedpoisson_finite_element_0();
1727
/// This class defines the interface for a finite element.
1729
class mixedpoisson_finite_element_1: public ufc::finite_element
1734
mixedpoisson_finite_element_1() : ufc::finite_element()
1740
virtual ~mixedpoisson_finite_element_1()
1745
/// Return a string identifying the finite element
1746
virtual const char* signature() const
1748
return "FiniteElement('Discontinuous Lagrange', Domain(Cell('triangle', 2), 'triangle_multiverse', 2, 2), 0, None)";
1751
/// Return the cell shape
1752
virtual ufc::shape cell_shape() const
1754
return ufc::triangle;
1757
/// Return the topological dimension of the cell shape
1758
virtual std::size_t topological_dimension() const
1763
/// Return the geometric dimension of the cell shape
1764
virtual std::size_t geometric_dimension() const
1769
/// Return the dimension of the finite element function space
1770
virtual std::size_t space_dimension() const
1775
/// Return the rank of the value space
1776
virtual std::size_t value_rank() const
1781
/// Return the dimension of the value space for axis i
1782
virtual std::size_t value_dimension(std::size_t i) const
1787
/// Evaluate basis function i at given point x in cell
1788
virtual void evaluate_basis(std::size_t i,
1791
const double* vertex_coordinates,
1792
int cell_orientation) const
1796
compute_jacobian_triangle_2d(J, vertex_coordinates);
1798
// Compute Jacobian inverse and determinant
1801
compute_jacobian_inverse_triangle_2d(K, detJ, J);
1804
// Compute constants
1806
// Get coordinates and map to the reference (FIAT) element
1811
// Array of basisvalues
1812
double basisvalues[1] = {0.0};
1814
// Declare helper variables
1816
// Compute basisvalues
1817
basisvalues[0] = 1.0;
1819
// Table(s) of coefficients
1820
static const double coefficients0[1] = \
1824
for (unsigned int r = 0; r < 1; r++)
1826
*values += coefficients0[r]*basisvalues[r];
1827
}// end loop over 'r'
1830
/// Evaluate all basis functions at given point x in cell
1831
virtual void evaluate_basis_all(double* values,
1833
const double* vertex_coordinates,
1834
int cell_orientation) const
1836
// Element is constant, calling evaluate_basis.
1837
evaluate_basis(0, values, x, vertex_coordinates, cell_orientation);
1840
/// Evaluate order n derivatives of basis function i at given point x in cell
1841
virtual void evaluate_basis_derivatives(std::size_t i,
1845
const double* vertex_coordinates,
1846
int cell_orientation) const
1850
compute_jacobian_triangle_2d(J, vertex_coordinates);
1852
// Compute Jacobian inverse and determinant
1855
compute_jacobian_inverse_triangle_2d(K, detJ, J);
1858
// Compute constants
1860
// Get coordinates and map to the reference (FIAT) element
1862
// Compute number of derivatives.
1863
unsigned int num_derivatives = 1;
1864
for (unsigned int r = 0; r < n; r++)
1866
num_derivatives *= 2;
1867
}// end loop over 'r'
1869
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
1870
unsigned int **combinations = new unsigned int *[num_derivatives];
1871
for (unsigned int row = 0; row < num_derivatives; row++)
1873
combinations[row] = new unsigned int [n];
1874
for (unsigned int col = 0; col < n; col++)
1875
combinations[row][col] = 0;
1878
// Generate combinations of derivatives
1879
for (unsigned int row = 1; row < num_derivatives; row++)
1881
for (unsigned int num = 0; num < row; num++)
1883
for (unsigned int col = n-1; col+1 > 0; col--)
1885
if (combinations[row][col] + 1 > 1)
1886
combinations[row][col] = 0;
1889
combinations[row][col] += 1;
1896
// Compute inverse of Jacobian
1897
const double Jinv[2][2] = {{K[0], K[1]}, {K[2], K[3]}};
1899
// Declare transformation matrix
1900
// Declare pointer to two dimensional array and initialise
1901
double **transform = new double *[num_derivatives];
1903
for (unsigned int j = 0; j < num_derivatives; j++)
1905
transform[j] = new double [num_derivatives];
1906
for (unsigned int k = 0; k < num_derivatives; k++)
1907
transform[j][k] = 1;
1910
// Construct transformation matrix
1911
for (unsigned int row = 0; row < num_derivatives; row++)
1913
for (unsigned int col = 0; col < num_derivatives; col++)
1915
for (unsigned int k = 0; k < n; k++)
1916
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
1920
// Reset values. Assuming that values is always an array.
1921
for (unsigned int r = 0; r < num_derivatives; r++)
1924
}// end loop over 'r'
1927
// Array of basisvalues
1928
double basisvalues[1] = {0.0};
1930
// Declare helper variables
1932
// Compute basisvalues
1933
basisvalues[0] = 1.0;
1935
// Table(s) of coefficients
1936
static const double coefficients0[1] = \
1939
// Tables of derivatives of the polynomial base (transpose).
1940
static const double dmats0[1][1] = \
1943
static const double dmats1[1][1] = \
1946
// Compute reference derivatives.
1947
// Declare pointer to array of derivatives on FIAT element.
1948
double *derivatives = new double[num_derivatives];
1949
for (unsigned int r = 0; r < num_derivatives; r++)
1951
derivatives[r] = 0.0;
1952
}// end loop over 'r'
1954
// Declare derivative matrix (of polynomial basis).
1955
double dmats[1][1] = \
1958
// Declare (auxiliary) derivative matrix (of polynomial basis).
1959
double dmats_old[1][1] = \
1962
// Loop possible derivatives.
1963
for (unsigned int r = 0; r < num_derivatives; r++)
1965
// Resetting dmats values to compute next derivative.
1966
for (unsigned int t = 0; t < 1; t++)
1968
for (unsigned int u = 0; u < 1; u++)
1976
}// end loop over 'u'
1977
}// end loop over 't'
1979
// Looping derivative order to generate dmats.
1980
for (unsigned int s = 0; s < n; s++)
1982
// Updating dmats_old with new values and resetting dmats.
1983
for (unsigned int t = 0; t < 1; t++)
1985
for (unsigned int u = 0; u < 1; u++)
1987
dmats_old[t][u] = dmats[t][u];
1989
}// end loop over 'u'
1990
}// end loop over 't'
1992
// Update dmats using an inner product.
1993
if (combinations[r][s] == 0)
1995
for (unsigned int t = 0; t < 1; t++)
1997
for (unsigned int u = 0; u < 1; u++)
1999
for (unsigned int tu = 0; tu < 1; tu++)
2001
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
2002
}// end loop over 'tu'
2003
}// end loop over 'u'
2004
}// end loop over 't'
2007
if (combinations[r][s] == 1)
2009
for (unsigned int t = 0; t < 1; t++)
2011
for (unsigned int u = 0; u < 1; u++)
2013
for (unsigned int tu = 0; tu < 1; tu++)
2015
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
2016
}// end loop over 'tu'
2017
}// end loop over 'u'
2018
}// end loop over 't'
2021
}// end loop over 's'
2022
for (unsigned int s = 0; s < 1; s++)
2024
for (unsigned int t = 0; t < 1; t++)
2026
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
2027
}// end loop over 't'
2028
}// end loop over 's'
2029
}// end loop over 'r'
2031
// Transform derivatives back to physical element
2032
for (unsigned int r = 0; r < num_derivatives; r++)
2034
for (unsigned int s = 0; s < num_derivatives; s++)
2036
values[r] += transform[r][s]*derivatives[s];
2037
}// end loop over 's'
2038
}// end loop over 'r'
2040
// Delete pointer to array of derivatives on FIAT element
2041
delete [] derivatives;
2043
// Delete pointer to array of combinations of derivatives and transform
2044
for (unsigned int r = 0; r < num_derivatives; r++)
2046
delete [] combinations[r];
2047
}// end loop over 'r'
2048
delete [] combinations;
2049
for (unsigned int r = 0; r < num_derivatives; r++)
2051
delete [] transform[r];
2052
}// end loop over 'r'
2053
delete [] transform;
2056
/// Evaluate order n derivatives of all basis functions at given point x in cell
2057
virtual void evaluate_basis_derivatives_all(std::size_t n,
2060
const double* vertex_coordinates,
2061
int cell_orientation) const
2063
// Element is constant, calling evaluate_basis_derivatives.
2064
evaluate_basis_derivatives(0, n, values, x, vertex_coordinates, cell_orientation);
2067
/// Evaluate linear functional for dof i on the function f
2068
virtual double evaluate_dof(std::size_t i,
2069
const ufc::function& f,
2070
const double* vertex_coordinates,
2071
int cell_orientation,
2072
const ufc::cell& c) const
2074
// Declare variables for result of evaluation
2077
// Declare variable for physical coordinates
2083
y[0] = 0.33333333*vertex_coordinates[0] + 0.33333333*vertex_coordinates[2] + 0.33333333*vertex_coordinates[4];
2084
y[1] = 0.33333333*vertex_coordinates[1] + 0.33333333*vertex_coordinates[3] + 0.33333333*vertex_coordinates[5];
2085
f.evaluate(vals, y, c);
2094
/// Evaluate linear functionals for all dofs on the function f
2095
virtual void evaluate_dofs(double* values,
2096
const ufc::function& f,
2097
const double* vertex_coordinates,
2098
int cell_orientation,
2099
const ufc::cell& c) const
2101
// Declare variables for result of evaluation
2104
// Declare variable for physical coordinates
2106
y[0] = 0.33333333*vertex_coordinates[0] + 0.33333333*vertex_coordinates[2] + 0.33333333*vertex_coordinates[4];
2107
y[1] = 0.33333333*vertex_coordinates[1] + 0.33333333*vertex_coordinates[3] + 0.33333333*vertex_coordinates[5];
2108
f.evaluate(vals, y, c);
2109
values[0] = vals[0];
2112
/// Interpolate vertex values from dof values
2113
virtual void interpolate_vertex_values(double* vertex_values,
2114
const double* dof_values,
2115
const double* vertex_coordinates,
2116
int cell_orientation,
2117
const ufc::cell& c) const
2119
// Evaluate function and change variables
2120
vertex_values[0] = dof_values[0];
2121
vertex_values[1] = dof_values[0];
2122
vertex_values[2] = dof_values[0];
2125
/// Map coordinate xhat from reference cell to coordinate x in cell
2126
virtual void map_from_reference_cell(double* x,
2128
const ufc::cell& c) const
2130
std::cerr << "*** FFC warning: " << "map_from_reference_cell not yet implemented." << std::endl;
2133
/// Map from coordinate x in cell to coordinate xhat in reference cell
2134
virtual void map_to_reference_cell(double* xhat,
2136
const ufc::cell& c) const
2138
std::cerr << "*** FFC warning: " << "map_to_reference_cell not yet implemented." << std::endl;
2141
/// Return the number of sub elements (for a mixed element)
2142
virtual std::size_t num_sub_elements() const
2147
/// Create a new finite element for sub element i (for a mixed element)
2148
virtual ufc::finite_element* create_sub_element(std::size_t i) const
2153
/// Create a new class instance
2154
virtual ufc::finite_element* create() const
2156
return new mixedpoisson_finite_element_1();
2161
/// This class defines the interface for a finite element.
2163
class mixedpoisson_finite_element_2: public ufc::finite_element
2168
mixedpoisson_finite_element_2() : ufc::finite_element()
2174
virtual ~mixedpoisson_finite_element_2()
2179
/// Return a string identifying the finite element
2180
virtual const char* signature() const
2182
return "MixedElement(*[FiniteElement('Brezzi-Douglas-Marini', Domain(Cell('triangle', 2), 'triangle_multiverse', 2, 2), 1, None), FiniteElement('Discontinuous Lagrange', Domain(Cell('triangle', 2), 'triangle_multiverse', 2, 2), 0, None)], **{'value_shape': (3,) })";
2185
/// Return the cell shape
2186
virtual ufc::shape cell_shape() const
2188
return ufc::triangle;
2191
/// Return the topological dimension of the cell shape
2192
virtual std::size_t topological_dimension() const
2197
/// Return the geometric dimension of the cell shape
2198
virtual std::size_t geometric_dimension() const
2203
/// Return the dimension of the finite element function space
2204
virtual std::size_t space_dimension() const
2209
/// Return the rank of the value space
2210
virtual std::size_t value_rank() const
2215
/// Return the dimension of the value space for axis i
2216
virtual std::size_t value_dimension(std::size_t i) const
2230
/// Evaluate basis function i at given point x in cell
2231
virtual void evaluate_basis(std::size_t i,
2234
const double* vertex_coordinates,
2235
int cell_orientation) const
2239
compute_jacobian_triangle_2d(J, vertex_coordinates);
2241
// Compute Jacobian inverse and determinant
2244
compute_jacobian_inverse_triangle_2d(K, detJ, J);
2248
// Compute constants
2249
const double C0 = vertex_coordinates[2] + vertex_coordinates[4];
2250
const double C1 = vertex_coordinates[3] + vertex_coordinates[5];
2252
// Get coordinates and map to the reference (FIAT) element
2253
double X = (J[1]*(C1 - 2.0*x[1]) + J[3]*(2.0*x[0] - C0)) / detJ;
2254
double Y = (J[0]*(2.0*x[1] - C1) + J[2]*(C0 - 2.0*x[0])) / detJ;
2265
// Array of basisvalues
2266
double basisvalues[3] = {0.0, 0.0, 0.0};
2268
// Declare helper variables
2269
double tmp0 = (1.0 + Y + 2.0*X)/2.0;
2271
// Compute basisvalues
2272
basisvalues[0] = 1.0;
2273
basisvalues[1] = tmp0;
2274
basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
2275
basisvalues[0] *= std::sqrt(0.5);
2276
basisvalues[2] *= std::sqrt(1.0);
2277
basisvalues[1] *= std::sqrt(3.0);
2279
// Table(s) of coefficients
2280
static const double coefficients0[3] = \
2281
{0.94280904, 0.57735027, -0.33333333};
2283
static const double coefficients1[3] = \
2284
{-0.47140452, 0.0, -0.33333333};
2287
for (unsigned int r = 0; r < 3; r++)
2289
values[0] += coefficients0[r]*basisvalues[r];
2290
values[1] += coefficients1[r]*basisvalues[r];
2291
}// end loop over 'r'
2293
// Using contravariant Piola transform to map values back to the physical element
2294
const double tmp_ref0 = values[0];
2295
const double tmp_ref1 = values[1];
2296
values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
2297
values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
2303
// Array of basisvalues
2304
double basisvalues[3] = {0.0, 0.0, 0.0};
2306
// Declare helper variables
2307
double tmp0 = (1.0 + Y + 2.0*X)/2.0;
2309
// Compute basisvalues
2310
basisvalues[0] = 1.0;
2311
basisvalues[1] = tmp0;
2312
basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
2313
basisvalues[0] *= std::sqrt(0.5);
2314
basisvalues[2] *= std::sqrt(1.0);
2315
basisvalues[1] *= std::sqrt(3.0);
2317
// Table(s) of coefficients
2318
static const double coefficients0[3] = \
2319
{-0.47140452, -0.28867513, 0.16666667};
2321
static const double coefficients1[3] = \
2322
{0.94280904, 0.0, 0.66666667};
2325
for (unsigned int r = 0; r < 3; r++)
2327
values[0] += coefficients0[r]*basisvalues[r];
2328
values[1] += coefficients1[r]*basisvalues[r];
2329
}// end loop over 'r'
2331
// Using contravariant Piola transform to map values back to the physical element
2332
const double tmp_ref0 = values[0];
2333
const double tmp_ref1 = values[1];
2334
values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
2335
values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
2341
// Array of basisvalues
2342
double basisvalues[3] = {0.0, 0.0, 0.0};
2344
// Declare helper variables
2345
double tmp0 = (1.0 + Y + 2.0*X)/2.0;
2347
// Compute basisvalues
2348
basisvalues[0] = 1.0;
2349
basisvalues[1] = tmp0;
2350
basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
2351
basisvalues[0] *= std::sqrt(0.5);
2352
basisvalues[2] *= std::sqrt(1.0);
2353
basisvalues[1] *= std::sqrt(3.0);
2355
// Table(s) of coefficients
2356
static const double coefficients0[3] = \
2357
{0.47140452, -0.57735027, -0.66666667};
2359
static const double coefficients1[3] = \
2360
{0.47140452, 0.0, 0.33333333};
2363
for (unsigned int r = 0; r < 3; r++)
2365
values[0] += coefficients0[r]*basisvalues[r];
2366
values[1] += coefficients1[r]*basisvalues[r];
2367
}// end loop over 'r'
2369
// Using contravariant Piola transform to map values back to the physical element
2370
const double tmp_ref0 = values[0];
2371
const double tmp_ref1 = values[1];
2372
values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
2373
values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
2379
// Array of basisvalues
2380
double basisvalues[3] = {0.0, 0.0, 0.0};
2382
// Declare helper variables
2383
double tmp0 = (1.0 + Y + 2.0*X)/2.0;
2385
// Compute basisvalues
2386
basisvalues[0] = 1.0;
2387
basisvalues[1] = tmp0;
2388
basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
2389
basisvalues[0] *= std::sqrt(0.5);
2390
basisvalues[2] *= std::sqrt(1.0);
2391
basisvalues[1] *= std::sqrt(3.0);
2393
// Table(s) of coefficients
2394
static const double coefficients0[3] = \
2395
{0.47140452, 0.28867513, 0.83333333};
2397
static const double coefficients1[3] = \
2398
{-0.94280904, 0.0, -0.66666667};
2401
for (unsigned int r = 0; r < 3; r++)
2403
values[0] += coefficients0[r]*basisvalues[r];
2404
values[1] += coefficients1[r]*basisvalues[r];
2405
}// end loop over 'r'
2407
// Using contravariant Piola transform to map values back to the physical element
2408
const double tmp_ref0 = values[0];
2409
const double tmp_ref1 = values[1];
2410
values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
2411
values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
2417
// Array of basisvalues
2418
double basisvalues[3] = {0.0, 0.0, 0.0};
2420
// Declare helper variables
2421
double tmp0 = (1.0 + Y + 2.0*X)/2.0;
2423
// Compute basisvalues
2424
basisvalues[0] = 1.0;
2425
basisvalues[1] = tmp0;
2426
basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
2427
basisvalues[0] *= std::sqrt(0.5);
2428
basisvalues[2] *= std::sqrt(1.0);
2429
basisvalues[1] *= std::sqrt(3.0);
2431
// Table(s) of coefficients
2432
static const double coefficients0[3] = \
2433
{-0.47140452, -0.28867513, 0.16666667};
2435
static const double coefficients1[3] = \
2436
{-0.47140452, 0.8660254, 0.16666667};
2439
for (unsigned int r = 0; r < 3; r++)
2441
values[0] += coefficients0[r]*basisvalues[r];
2442
values[1] += coefficients1[r]*basisvalues[r];
2443
}// end loop over 'r'
2445
// Using contravariant Piola transform to map values back to the physical element
2446
const double tmp_ref0 = values[0];
2447
const double tmp_ref1 = values[1];
2448
values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
2449
values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
2455
// Array of basisvalues
2456
double basisvalues[3] = {0.0, 0.0, 0.0};
2458
// Declare helper variables
2459
double tmp0 = (1.0 + Y + 2.0*X)/2.0;
2461
// Compute basisvalues
2462
basisvalues[0] = 1.0;
2463
basisvalues[1] = tmp0;
2464
basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
2465
basisvalues[0] *= std::sqrt(0.5);
2466
basisvalues[2] *= std::sqrt(1.0);
2467
basisvalues[1] *= std::sqrt(3.0);
2469
// Table(s) of coefficients
2470
static const double coefficients0[3] = \
2471
{0.94280904, 0.57735027, -0.33333333};
2473
static const double coefficients1[3] = \
2474
{-0.47140452, -0.8660254, 0.16666667};
2477
for (unsigned int r = 0; r < 3; r++)
2479
values[0] += coefficients0[r]*basisvalues[r];
2480
values[1] += coefficients1[r]*basisvalues[r];
2481
}// end loop over 'r'
2483
// Using contravariant Piola transform to map values back to the physical element
2484
const double tmp_ref0 = values[0];
2485
const double tmp_ref1 = values[1];
2486
values[0] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
2487
values[1] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
2493
// Array of basisvalues
2494
double basisvalues[1] = {0.0};
2496
// Declare helper variables
2498
// Compute basisvalues
2499
basisvalues[0] = 1.0;
2501
// Table(s) of coefficients
2502
static const double coefficients0[1] = \
2506
for (unsigned int r = 0; r < 1; r++)
2508
values[2] += coefficients0[r]*basisvalues[r];
2509
}// end loop over 'r'
2516
/// Evaluate all basis functions at given point x in cell
2517
virtual void evaluate_basis_all(double* values,
2519
const double* vertex_coordinates,
2520
int cell_orientation) const
2522
// Helper variable to hold values of a single dof.
2523
double dof_values[3] = {0.0, 0.0, 0.0};
2525
// Loop dofs and call evaluate_basis
2526
for (unsigned int r = 0; r < 7; r++)
2528
evaluate_basis(r, dof_values, x, vertex_coordinates, cell_orientation);
2529
for (unsigned int s = 0; s < 3; s++)
2531
values[r*3 + s] = dof_values[s];
2532
}// end loop over 's'
2533
}// end loop over 'r'
2536
/// Evaluate order n derivatives of basis function i at given point x in cell
2537
virtual void evaluate_basis_derivatives(std::size_t i,
2541
const double* vertex_coordinates,
2542
int cell_orientation) const
2546
compute_jacobian_triangle_2d(J, vertex_coordinates);
2548
// Compute Jacobian inverse and determinant
2551
compute_jacobian_inverse_triangle_2d(K, detJ, J);
2555
// Compute constants
2556
const double C0 = vertex_coordinates[2] + vertex_coordinates[4];
2557
const double C1 = vertex_coordinates[3] + vertex_coordinates[5];
2559
// Get coordinates and map to the reference (FIAT) element
2560
double X = (J[1]*(C1 - 2.0*x[1]) + J[3]*(2.0*x[0] - C0)) / detJ;
2561
double Y = (J[0]*(2.0*x[1] - C1) + J[2]*(C0 - 2.0*x[0])) / detJ;
2563
// Compute number of derivatives.
2564
unsigned int num_derivatives = 1;
2565
for (unsigned int r = 0; r < n; r++)
2567
num_derivatives *= 2;
2568
}// end loop over 'r'
2570
// Declare pointer to two dimensional array that holds combinations of derivatives and initialise
2571
unsigned int **combinations = new unsigned int *[num_derivatives];
2572
for (unsigned int row = 0; row < num_derivatives; row++)
2574
combinations[row] = new unsigned int [n];
2575
for (unsigned int col = 0; col < n; col++)
2576
combinations[row][col] = 0;
2579
// Generate combinations of derivatives
2580
for (unsigned int row = 1; row < num_derivatives; row++)
2582
for (unsigned int num = 0; num < row; num++)
2584
for (unsigned int col = n-1; col+1 > 0; col--)
2586
if (combinations[row][col] + 1 > 1)
2587
combinations[row][col] = 0;
2590
combinations[row][col] += 1;
2597
// Compute inverse of Jacobian
2598
const double Jinv[2][2] = {{K[0], K[1]}, {K[2], K[3]}};
2600
// Declare transformation matrix
2601
// Declare pointer to two dimensional array and initialise
2602
double **transform = new double *[num_derivatives];
2604
for (unsigned int j = 0; j < num_derivatives; j++)
2606
transform[j] = new double [num_derivatives];
2607
for (unsigned int k = 0; k < num_derivatives; k++)
2608
transform[j][k] = 1;
2611
// Construct transformation matrix
2612
for (unsigned int row = 0; row < num_derivatives; row++)
2614
for (unsigned int col = 0; col < num_derivatives; col++)
2616
for (unsigned int k = 0; k < n; k++)
2617
transform[row][col] *= Jinv[combinations[col][k]][combinations[row][k]];
2621
// Reset values. Assuming that values is always an array.
2622
for (unsigned int r = 0; r < 3*num_derivatives; r++)
2625
}// end loop over 'r'
2632
// Array of basisvalues
2633
double basisvalues[3] = {0.0, 0.0, 0.0};
2635
// Declare helper variables
2636
double tmp0 = (1.0 + Y + 2.0*X)/2.0;
2638
// Compute basisvalues
2639
basisvalues[0] = 1.0;
2640
basisvalues[1] = tmp0;
2641
basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
2642
basisvalues[0] *= std::sqrt(0.5);
2643
basisvalues[2] *= std::sqrt(1.0);
2644
basisvalues[1] *= std::sqrt(3.0);
2646
// Table(s) of coefficients
2647
static const double coefficients0[3] = \
2648
{0.94280904, 0.57735027, -0.33333333};
2650
static const double coefficients1[3] = \
2651
{-0.47140452, 0.0, -0.33333333};
2653
// Tables of derivatives of the polynomial base (transpose).
2654
static const double dmats0[3][3] = \
2656
{4.8989795, 0.0, 0.0},
2659
static const double dmats1[3][3] = \
2661
{2.4494897, 0.0, 0.0},
2662
{4.2426407, 0.0, 0.0}};
2664
// Compute reference derivatives.
2665
// Declare pointer to array of derivatives on FIAT element.
2666
double *derivatives = new double[2*num_derivatives];
2667
for (unsigned int r = 0; r < 2*num_derivatives; r++)
2669
derivatives[r] = 0.0;
2670
}// end loop over 'r'
2672
// Declare pointer to array of reference derivatives on physical element.
2673
double *derivatives_p = new double[2*num_derivatives];
2674
for (unsigned int r = 0; r < 2*num_derivatives; r++)
2676
derivatives_p[r] = 0.0;
2677
}// end loop over 'r'
2679
// Declare derivative matrix (of polynomial basis).
2680
double dmats[3][3] = \
2685
// Declare (auxiliary) derivative matrix (of polynomial basis).
2686
double dmats_old[3][3] = \
2691
// Loop possible derivatives.
2692
for (unsigned int r = 0; r < num_derivatives; r++)
2694
// Resetting dmats values to compute next derivative.
2695
for (unsigned int t = 0; t < 3; t++)
2697
for (unsigned int u = 0; u < 3; u++)
2705
}// end loop over 'u'
2706
}// end loop over 't'
2708
// Looping derivative order to generate dmats.
2709
for (unsigned int s = 0; s < n; s++)
2711
// Updating dmats_old with new values and resetting dmats.
2712
for (unsigned int t = 0; t < 3; t++)
2714
for (unsigned int u = 0; u < 3; u++)
2716
dmats_old[t][u] = dmats[t][u];
2718
}// end loop over 'u'
2719
}// end loop over 't'
2721
// Update dmats using an inner product.
2722
if (combinations[r][s] == 0)
2724
for (unsigned int t = 0; t < 3; t++)
2726
for (unsigned int u = 0; u < 3; u++)
2728
for (unsigned int tu = 0; tu < 3; tu++)
2730
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
2731
}// end loop over 'tu'
2732
}// end loop over 'u'
2733
}// end loop over 't'
2736
if (combinations[r][s] == 1)
2738
for (unsigned int t = 0; t < 3; t++)
2740
for (unsigned int u = 0; u < 3; u++)
2742
for (unsigned int tu = 0; tu < 3; tu++)
2744
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
2745
}// end loop over 'tu'
2746
}// end loop over 'u'
2747
}// end loop over 't'
2750
}// end loop over 's'
2751
for (unsigned int s = 0; s < 3; s++)
2753
for (unsigned int t = 0; t < 3; t++)
2755
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
2756
derivatives[num_derivatives + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
2757
}// end loop over 't'
2758
}// end loop over 's'
2760
// Using contravariant Piola transform to map values back to the physical element.
2761
const double tmp_ref0 = derivatives[r];
2762
const double tmp_ref1 = derivatives[num_derivatives + r];
2763
derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
2764
derivatives_p[num_derivatives + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
2765
}// end loop over 'r'
2767
// Transform derivatives back to physical element
2768
for (unsigned int r = 0; r < num_derivatives; r++)
2770
for (unsigned int s = 0; s < num_derivatives; s++)
2772
values[r] += transform[r][s]*derivatives_p[s];
2773
values[num_derivatives + r] += transform[r][s]*derivatives_p[num_derivatives + s];
2774
}// end loop over 's'
2775
}// end loop over 'r'
2777
// Delete pointer to array of derivatives on FIAT element
2778
delete [] derivatives;
2780
// Delete pointer to array of reference derivatives on physical element.
2781
delete [] derivatives_p;
2783
// Delete pointer to array of combinations of derivatives and transform
2784
for (unsigned int r = 0; r < num_derivatives; r++)
2786
delete [] combinations[r];
2787
}// end loop over 'r'
2788
delete [] combinations;
2789
for (unsigned int r = 0; r < num_derivatives; r++)
2791
delete [] transform[r];
2792
}// end loop over 'r'
2793
delete [] transform;
2799
// Array of basisvalues
2800
double basisvalues[3] = {0.0, 0.0, 0.0};
2802
// Declare helper variables
2803
double tmp0 = (1.0 + Y + 2.0*X)/2.0;
2805
// Compute basisvalues
2806
basisvalues[0] = 1.0;
2807
basisvalues[1] = tmp0;
2808
basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
2809
basisvalues[0] *= std::sqrt(0.5);
2810
basisvalues[2] *= std::sqrt(1.0);
2811
basisvalues[1] *= std::sqrt(3.0);
2813
// Table(s) of coefficients
2814
static const double coefficients0[3] = \
2815
{-0.47140452, -0.28867513, 0.16666667};
2817
static const double coefficients1[3] = \
2818
{0.94280904, 0.0, 0.66666667};
2820
// Tables of derivatives of the polynomial base (transpose).
2821
static const double dmats0[3][3] = \
2823
{4.8989795, 0.0, 0.0},
2826
static const double dmats1[3][3] = \
2828
{2.4494897, 0.0, 0.0},
2829
{4.2426407, 0.0, 0.0}};
2831
// Compute reference derivatives.
2832
// Declare pointer to array of derivatives on FIAT element.
2833
double *derivatives = new double[2*num_derivatives];
2834
for (unsigned int r = 0; r < 2*num_derivatives; r++)
2836
derivatives[r] = 0.0;
2837
}// end loop over 'r'
2839
// Declare pointer to array of reference derivatives on physical element.
2840
double *derivatives_p = new double[2*num_derivatives];
2841
for (unsigned int r = 0; r < 2*num_derivatives; r++)
2843
derivatives_p[r] = 0.0;
2844
}// end loop over 'r'
2846
// Declare derivative matrix (of polynomial basis).
2847
double dmats[3][3] = \
2852
// Declare (auxiliary) derivative matrix (of polynomial basis).
2853
double dmats_old[3][3] = \
2858
// Loop possible derivatives.
2859
for (unsigned int r = 0; r < num_derivatives; r++)
2861
// Resetting dmats values to compute next derivative.
2862
for (unsigned int t = 0; t < 3; t++)
2864
for (unsigned int u = 0; u < 3; u++)
2872
}// end loop over 'u'
2873
}// end loop over 't'
2875
// Looping derivative order to generate dmats.
2876
for (unsigned int s = 0; s < n; s++)
2878
// Updating dmats_old with new values and resetting dmats.
2879
for (unsigned int t = 0; t < 3; t++)
2881
for (unsigned int u = 0; u < 3; u++)
2883
dmats_old[t][u] = dmats[t][u];
2885
}// end loop over 'u'
2886
}// end loop over 't'
2888
// Update dmats using an inner product.
2889
if (combinations[r][s] == 0)
2891
for (unsigned int t = 0; t < 3; t++)
2893
for (unsigned int u = 0; u < 3; u++)
2895
for (unsigned int tu = 0; tu < 3; tu++)
2897
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
2898
}// end loop over 'tu'
2899
}// end loop over 'u'
2900
}// end loop over 't'
2903
if (combinations[r][s] == 1)
2905
for (unsigned int t = 0; t < 3; t++)
2907
for (unsigned int u = 0; u < 3; u++)
2909
for (unsigned int tu = 0; tu < 3; tu++)
2911
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
2912
}// end loop over 'tu'
2913
}// end loop over 'u'
2914
}// end loop over 't'
2917
}// end loop over 's'
2918
for (unsigned int s = 0; s < 3; s++)
2920
for (unsigned int t = 0; t < 3; t++)
2922
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
2923
derivatives[num_derivatives + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
2924
}// end loop over 't'
2925
}// end loop over 's'
2927
// Using contravariant Piola transform to map values back to the physical element.
2928
const double tmp_ref0 = derivatives[r];
2929
const double tmp_ref1 = derivatives[num_derivatives + r];
2930
derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
2931
derivatives_p[num_derivatives + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
2932
}// end loop over 'r'
2934
// Transform derivatives back to physical element
2935
for (unsigned int r = 0; r < num_derivatives; r++)
2937
for (unsigned int s = 0; s < num_derivatives; s++)
2939
values[r] += transform[r][s]*derivatives_p[s];
2940
values[num_derivatives + r] += transform[r][s]*derivatives_p[num_derivatives + s];
2941
}// end loop over 's'
2942
}// end loop over 'r'
2944
// Delete pointer to array of derivatives on FIAT element
2945
delete [] derivatives;
2947
// Delete pointer to array of reference derivatives on physical element.
2948
delete [] derivatives_p;
2950
// Delete pointer to array of combinations of derivatives and transform
2951
for (unsigned int r = 0; r < num_derivatives; r++)
2953
delete [] combinations[r];
2954
}// end loop over 'r'
2955
delete [] combinations;
2956
for (unsigned int r = 0; r < num_derivatives; r++)
2958
delete [] transform[r];
2959
}// end loop over 'r'
2960
delete [] transform;
2966
// Array of basisvalues
2967
double basisvalues[3] = {0.0, 0.0, 0.0};
2969
// Declare helper variables
2970
double tmp0 = (1.0 + Y + 2.0*X)/2.0;
2972
// Compute basisvalues
2973
basisvalues[0] = 1.0;
2974
basisvalues[1] = tmp0;
2975
basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
2976
basisvalues[0] *= std::sqrt(0.5);
2977
basisvalues[2] *= std::sqrt(1.0);
2978
basisvalues[1] *= std::sqrt(3.0);
2980
// Table(s) of coefficients
2981
static const double coefficients0[3] = \
2982
{0.47140452, -0.57735027, -0.66666667};
2984
static const double coefficients1[3] = \
2985
{0.47140452, 0.0, 0.33333333};
2987
// Tables of derivatives of the polynomial base (transpose).
2988
static const double dmats0[3][3] = \
2990
{4.8989795, 0.0, 0.0},
2993
static const double dmats1[3][3] = \
2995
{2.4494897, 0.0, 0.0},
2996
{4.2426407, 0.0, 0.0}};
2998
// Compute reference derivatives.
2999
// Declare pointer to array of derivatives on FIAT element.
3000
double *derivatives = new double[2*num_derivatives];
3001
for (unsigned int r = 0; r < 2*num_derivatives; r++)
3003
derivatives[r] = 0.0;
3004
}// end loop over 'r'
3006
// Declare pointer to array of reference derivatives on physical element.
3007
double *derivatives_p = new double[2*num_derivatives];
3008
for (unsigned int r = 0; r < 2*num_derivatives; r++)
3010
derivatives_p[r] = 0.0;
3011
}// end loop over 'r'
3013
// Declare derivative matrix (of polynomial basis).
3014
double dmats[3][3] = \
3019
// Declare (auxiliary) derivative matrix (of polynomial basis).
3020
double dmats_old[3][3] = \
3025
// Loop possible derivatives.
3026
for (unsigned int r = 0; r < num_derivatives; r++)
3028
// Resetting dmats values to compute next derivative.
3029
for (unsigned int t = 0; t < 3; t++)
3031
for (unsigned int u = 0; u < 3; u++)
3039
}// end loop over 'u'
3040
}// end loop over 't'
3042
// Looping derivative order to generate dmats.
3043
for (unsigned int s = 0; s < n; s++)
3045
// Updating dmats_old with new values and resetting dmats.
3046
for (unsigned int t = 0; t < 3; t++)
3048
for (unsigned int u = 0; u < 3; u++)
3050
dmats_old[t][u] = dmats[t][u];
3052
}// end loop over 'u'
3053
}// end loop over 't'
3055
// Update dmats using an inner product.
3056
if (combinations[r][s] == 0)
3058
for (unsigned int t = 0; t < 3; t++)
3060
for (unsigned int u = 0; u < 3; u++)
3062
for (unsigned int tu = 0; tu < 3; tu++)
3064
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
3065
}// end loop over 'tu'
3066
}// end loop over 'u'
3067
}// end loop over 't'
3070
if (combinations[r][s] == 1)
3072
for (unsigned int t = 0; t < 3; t++)
3074
for (unsigned int u = 0; u < 3; u++)
3076
for (unsigned int tu = 0; tu < 3; tu++)
3078
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
3079
}// end loop over 'tu'
3080
}// end loop over 'u'
3081
}// end loop over 't'
3084
}// end loop over 's'
3085
for (unsigned int s = 0; s < 3; s++)
3087
for (unsigned int t = 0; t < 3; t++)
3089
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
3090
derivatives[num_derivatives + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
3091
}// end loop over 't'
3092
}// end loop over 's'
3094
// Using contravariant Piola transform to map values back to the physical element.
3095
const double tmp_ref0 = derivatives[r];
3096
const double tmp_ref1 = derivatives[num_derivatives + r];
3097
derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
3098
derivatives_p[num_derivatives + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
3099
}// end loop over 'r'
3101
// Transform derivatives back to physical element
3102
for (unsigned int r = 0; r < num_derivatives; r++)
3104
for (unsigned int s = 0; s < num_derivatives; s++)
3106
values[r] += transform[r][s]*derivatives_p[s];
3107
values[num_derivatives + r] += transform[r][s]*derivatives_p[num_derivatives + s];
3108
}// end loop over 's'
3109
}// end loop over 'r'
3111
// Delete pointer to array of derivatives on FIAT element
3112
delete [] derivatives;
3114
// Delete pointer to array of reference derivatives on physical element.
3115
delete [] derivatives_p;
3117
// Delete pointer to array of combinations of derivatives and transform
3118
for (unsigned int r = 0; r < num_derivatives; r++)
3120
delete [] combinations[r];
3121
}// end loop over 'r'
3122
delete [] combinations;
3123
for (unsigned int r = 0; r < num_derivatives; r++)
3125
delete [] transform[r];
3126
}// end loop over 'r'
3127
delete [] transform;
3133
// Array of basisvalues
3134
double basisvalues[3] = {0.0, 0.0, 0.0};
3136
// Declare helper variables
3137
double tmp0 = (1.0 + Y + 2.0*X)/2.0;
3139
// Compute basisvalues
3140
basisvalues[0] = 1.0;
3141
basisvalues[1] = tmp0;
3142
basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
3143
basisvalues[0] *= std::sqrt(0.5);
3144
basisvalues[2] *= std::sqrt(1.0);
3145
basisvalues[1] *= std::sqrt(3.0);
3147
// Table(s) of coefficients
3148
static const double coefficients0[3] = \
3149
{0.47140452, 0.28867513, 0.83333333};
3151
static const double coefficients1[3] = \
3152
{-0.94280904, 0.0, -0.66666667};
3154
// Tables of derivatives of the polynomial base (transpose).
3155
static const double dmats0[3][3] = \
3157
{4.8989795, 0.0, 0.0},
3160
static const double dmats1[3][3] = \
3162
{2.4494897, 0.0, 0.0},
3163
{4.2426407, 0.0, 0.0}};
3165
// Compute reference derivatives.
3166
// Declare pointer to array of derivatives on FIAT element.
3167
double *derivatives = new double[2*num_derivatives];
3168
for (unsigned int r = 0; r < 2*num_derivatives; r++)
3170
derivatives[r] = 0.0;
3171
}// end loop over 'r'
3173
// Declare pointer to array of reference derivatives on physical element.
3174
double *derivatives_p = new double[2*num_derivatives];
3175
for (unsigned int r = 0; r < 2*num_derivatives; r++)
3177
derivatives_p[r] = 0.0;
3178
}// end loop over 'r'
3180
// Declare derivative matrix (of polynomial basis).
3181
double dmats[3][3] = \
3186
// Declare (auxiliary) derivative matrix (of polynomial basis).
3187
double dmats_old[3][3] = \
3192
// Loop possible derivatives.
3193
for (unsigned int r = 0; r < num_derivatives; r++)
3195
// Resetting dmats values to compute next derivative.
3196
for (unsigned int t = 0; t < 3; t++)
3198
for (unsigned int u = 0; u < 3; u++)
3206
}// end loop over 'u'
3207
}// end loop over 't'
3209
// Looping derivative order to generate dmats.
3210
for (unsigned int s = 0; s < n; s++)
3212
// Updating dmats_old with new values and resetting dmats.
3213
for (unsigned int t = 0; t < 3; t++)
3215
for (unsigned int u = 0; u < 3; u++)
3217
dmats_old[t][u] = dmats[t][u];
3219
}// end loop over 'u'
3220
}// end loop over 't'
3222
// Update dmats using an inner product.
3223
if (combinations[r][s] == 0)
3225
for (unsigned int t = 0; t < 3; t++)
3227
for (unsigned int u = 0; u < 3; u++)
3229
for (unsigned int tu = 0; tu < 3; tu++)
3231
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
3232
}// end loop over 'tu'
3233
}// end loop over 'u'
3234
}// end loop over 't'
3237
if (combinations[r][s] == 1)
3239
for (unsigned int t = 0; t < 3; t++)
3241
for (unsigned int u = 0; u < 3; u++)
3243
for (unsigned int tu = 0; tu < 3; tu++)
3245
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
3246
}// end loop over 'tu'
3247
}// end loop over 'u'
3248
}// end loop over 't'
3251
}// end loop over 's'
3252
for (unsigned int s = 0; s < 3; s++)
3254
for (unsigned int t = 0; t < 3; t++)
3256
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
3257
derivatives[num_derivatives + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
3258
}// end loop over 't'
3259
}// end loop over 's'
3261
// Using contravariant Piola transform to map values back to the physical element.
3262
const double tmp_ref0 = derivatives[r];
3263
const double tmp_ref1 = derivatives[num_derivatives + r];
3264
derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
3265
derivatives_p[num_derivatives + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
3266
}// end loop over 'r'
3268
// Transform derivatives back to physical element
3269
for (unsigned int r = 0; r < num_derivatives; r++)
3271
for (unsigned int s = 0; s < num_derivatives; s++)
3273
values[r] += transform[r][s]*derivatives_p[s];
3274
values[num_derivatives + r] += transform[r][s]*derivatives_p[num_derivatives + s];
3275
}// end loop over 's'
3276
}// end loop over 'r'
3278
// Delete pointer to array of derivatives on FIAT element
3279
delete [] derivatives;
3281
// Delete pointer to array of reference derivatives on physical element.
3282
delete [] derivatives_p;
3284
// Delete pointer to array of combinations of derivatives and transform
3285
for (unsigned int r = 0; r < num_derivatives; r++)
3287
delete [] combinations[r];
3288
}// end loop over 'r'
3289
delete [] combinations;
3290
for (unsigned int r = 0; r < num_derivatives; r++)
3292
delete [] transform[r];
3293
}// end loop over 'r'
3294
delete [] transform;
3300
// Array of basisvalues
3301
double basisvalues[3] = {0.0, 0.0, 0.0};
3303
// Declare helper variables
3304
double tmp0 = (1.0 + Y + 2.0*X)/2.0;
3306
// Compute basisvalues
3307
basisvalues[0] = 1.0;
3308
basisvalues[1] = tmp0;
3309
basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
3310
basisvalues[0] *= std::sqrt(0.5);
3311
basisvalues[2] *= std::sqrt(1.0);
3312
basisvalues[1] *= std::sqrt(3.0);
3314
// Table(s) of coefficients
3315
static const double coefficients0[3] = \
3316
{-0.47140452, -0.28867513, 0.16666667};
3318
static const double coefficients1[3] = \
3319
{-0.47140452, 0.8660254, 0.16666667};
3321
// Tables of derivatives of the polynomial base (transpose).
3322
static const double dmats0[3][3] = \
3324
{4.8989795, 0.0, 0.0},
3327
static const double dmats1[3][3] = \
3329
{2.4494897, 0.0, 0.0},
3330
{4.2426407, 0.0, 0.0}};
3332
// Compute reference derivatives.
3333
// Declare pointer to array of derivatives on FIAT element.
3334
double *derivatives = new double[2*num_derivatives];
3335
for (unsigned int r = 0; r < 2*num_derivatives; r++)
3337
derivatives[r] = 0.0;
3338
}// end loop over 'r'
3340
// Declare pointer to array of reference derivatives on physical element.
3341
double *derivatives_p = new double[2*num_derivatives];
3342
for (unsigned int r = 0; r < 2*num_derivatives; r++)
3344
derivatives_p[r] = 0.0;
3345
}// end loop over 'r'
3347
// Declare derivative matrix (of polynomial basis).
3348
double dmats[3][3] = \
3353
// Declare (auxiliary) derivative matrix (of polynomial basis).
3354
double dmats_old[3][3] = \
3359
// Loop possible derivatives.
3360
for (unsigned int r = 0; r < num_derivatives; r++)
3362
// Resetting dmats values to compute next derivative.
3363
for (unsigned int t = 0; t < 3; t++)
3365
for (unsigned int u = 0; u < 3; u++)
3373
}// end loop over 'u'
3374
}// end loop over 't'
3376
// Looping derivative order to generate dmats.
3377
for (unsigned int s = 0; s < n; s++)
3379
// Updating dmats_old with new values and resetting dmats.
3380
for (unsigned int t = 0; t < 3; t++)
3382
for (unsigned int u = 0; u < 3; u++)
3384
dmats_old[t][u] = dmats[t][u];
3386
}// end loop over 'u'
3387
}// end loop over 't'
3389
// Update dmats using an inner product.
3390
if (combinations[r][s] == 0)
3392
for (unsigned int t = 0; t < 3; t++)
3394
for (unsigned int u = 0; u < 3; u++)
3396
for (unsigned int tu = 0; tu < 3; tu++)
3398
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
3399
}// end loop over 'tu'
3400
}// end loop over 'u'
3401
}// end loop over 't'
3404
if (combinations[r][s] == 1)
3406
for (unsigned int t = 0; t < 3; t++)
3408
for (unsigned int u = 0; u < 3; u++)
3410
for (unsigned int tu = 0; tu < 3; tu++)
3412
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
3413
}// end loop over 'tu'
3414
}// end loop over 'u'
3415
}// end loop over 't'
3418
}// end loop over 's'
3419
for (unsigned int s = 0; s < 3; s++)
3421
for (unsigned int t = 0; t < 3; t++)
3423
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
3424
derivatives[num_derivatives + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
3425
}// end loop over 't'
3426
}// end loop over 's'
3428
// Using contravariant Piola transform to map values back to the physical element.
3429
const double tmp_ref0 = derivatives[r];
3430
const double tmp_ref1 = derivatives[num_derivatives + r];
3431
derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
3432
derivatives_p[num_derivatives + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
3433
}// end loop over 'r'
3435
// Transform derivatives back to physical element
3436
for (unsigned int r = 0; r < num_derivatives; r++)
3438
for (unsigned int s = 0; s < num_derivatives; s++)
3440
values[r] += transform[r][s]*derivatives_p[s];
3441
values[num_derivatives + r] += transform[r][s]*derivatives_p[num_derivatives + s];
3442
}// end loop over 's'
3443
}// end loop over 'r'
3445
// Delete pointer to array of derivatives on FIAT element
3446
delete [] derivatives;
3448
// Delete pointer to array of reference derivatives on physical element.
3449
delete [] derivatives_p;
3451
// Delete pointer to array of combinations of derivatives and transform
3452
for (unsigned int r = 0; r < num_derivatives; r++)
3454
delete [] combinations[r];
3455
}// end loop over 'r'
3456
delete [] combinations;
3457
for (unsigned int r = 0; r < num_derivatives; r++)
3459
delete [] transform[r];
3460
}// end loop over 'r'
3461
delete [] transform;
3467
// Array of basisvalues
3468
double basisvalues[3] = {0.0, 0.0, 0.0};
3470
// Declare helper variables
3471
double tmp0 = (1.0 + Y + 2.0*X)/2.0;
3473
// Compute basisvalues
3474
basisvalues[0] = 1.0;
3475
basisvalues[1] = tmp0;
3476
basisvalues[2] = basisvalues[0]*(0.5 + 1.5*Y);
3477
basisvalues[0] *= std::sqrt(0.5);
3478
basisvalues[2] *= std::sqrt(1.0);
3479
basisvalues[1] *= std::sqrt(3.0);
3481
// Table(s) of coefficients
3482
static const double coefficients0[3] = \
3483
{0.94280904, 0.57735027, -0.33333333};
3485
static const double coefficients1[3] = \
3486
{-0.47140452, -0.8660254, 0.16666667};
3488
// Tables of derivatives of the polynomial base (transpose).
3489
static const double dmats0[3][3] = \
3491
{4.8989795, 0.0, 0.0},
3494
static const double dmats1[3][3] = \
3496
{2.4494897, 0.0, 0.0},
3497
{4.2426407, 0.0, 0.0}};
3499
// Compute reference derivatives.
3500
// Declare pointer to array of derivatives on FIAT element.
3501
double *derivatives = new double[2*num_derivatives];
3502
for (unsigned int r = 0; r < 2*num_derivatives; r++)
3504
derivatives[r] = 0.0;
3505
}// end loop over 'r'
3507
// Declare pointer to array of reference derivatives on physical element.
3508
double *derivatives_p = new double[2*num_derivatives];
3509
for (unsigned int r = 0; r < 2*num_derivatives; r++)
3511
derivatives_p[r] = 0.0;
3512
}// end loop over 'r'
3514
// Declare derivative matrix (of polynomial basis).
3515
double dmats[3][3] = \
3520
// Declare (auxiliary) derivative matrix (of polynomial basis).
3521
double dmats_old[3][3] = \
3526
// Loop possible derivatives.
3527
for (unsigned int r = 0; r < num_derivatives; r++)
3529
// Resetting dmats values to compute next derivative.
3530
for (unsigned int t = 0; t < 3; t++)
3532
for (unsigned int u = 0; u < 3; u++)
3540
}// end loop over 'u'
3541
}// end loop over 't'
3543
// Looping derivative order to generate dmats.
3544
for (unsigned int s = 0; s < n; s++)
3546
// Updating dmats_old with new values and resetting dmats.
3547
for (unsigned int t = 0; t < 3; t++)
3549
for (unsigned int u = 0; u < 3; u++)
3551
dmats_old[t][u] = dmats[t][u];
3553
}// end loop over 'u'
3554
}// end loop over 't'
3556
// Update dmats using an inner product.
3557
if (combinations[r][s] == 0)
3559
for (unsigned int t = 0; t < 3; t++)
3561
for (unsigned int u = 0; u < 3; u++)
3563
for (unsigned int tu = 0; tu < 3; tu++)
3565
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
3566
}// end loop over 'tu'
3567
}// end loop over 'u'
3568
}// end loop over 't'
3571
if (combinations[r][s] == 1)
3573
for (unsigned int t = 0; t < 3; t++)
3575
for (unsigned int u = 0; u < 3; u++)
3577
for (unsigned int tu = 0; tu < 3; tu++)
3579
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
3580
}// end loop over 'tu'
3581
}// end loop over 'u'
3582
}// end loop over 't'
3585
}// end loop over 's'
3586
for (unsigned int s = 0; s < 3; s++)
3588
for (unsigned int t = 0; t < 3; t++)
3590
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
3591
derivatives[num_derivatives + r] += coefficients1[s]*dmats[s][t]*basisvalues[t];
3592
}// end loop over 't'
3593
}// end loop over 's'
3595
// Using contravariant Piola transform to map values back to the physical element.
3596
const double tmp_ref0 = derivatives[r];
3597
const double tmp_ref1 = derivatives[num_derivatives + r];
3598
derivatives_p[r] = (1.0/detJ)*(J[0]*tmp_ref0 + J[1]*tmp_ref1);
3599
derivatives_p[num_derivatives + r] = (1.0/detJ)*(J[2]*tmp_ref0 + J[3]*tmp_ref1);
3600
}// end loop over 'r'
3602
// Transform derivatives back to physical element
3603
for (unsigned int r = 0; r < num_derivatives; r++)
3605
for (unsigned int s = 0; s < num_derivatives; s++)
3607
values[r] += transform[r][s]*derivatives_p[s];
3608
values[num_derivatives + r] += transform[r][s]*derivatives_p[num_derivatives + s];
3609
}// end loop over 's'
3610
}// end loop over 'r'
3612
// Delete pointer to array of derivatives on FIAT element
3613
delete [] derivatives;
3615
// Delete pointer to array of reference derivatives on physical element.
3616
delete [] derivatives_p;
3618
// Delete pointer to array of combinations of derivatives and transform
3619
for (unsigned int r = 0; r < num_derivatives; r++)
3621
delete [] combinations[r];
3622
}// end loop over 'r'
3623
delete [] combinations;
3624
for (unsigned int r = 0; r < num_derivatives; r++)
3626
delete [] transform[r];
3627
}// end loop over 'r'
3628
delete [] transform;
3634
// Array of basisvalues
3635
double basisvalues[1] = {0.0};
3637
// Declare helper variables
3639
// Compute basisvalues
3640
basisvalues[0] = 1.0;
3642
// Table(s) of coefficients
3643
static const double coefficients0[1] = \
3646
// Tables of derivatives of the polynomial base (transpose).
3647
static const double dmats0[1][1] = \
3650
static const double dmats1[1][1] = \
3653
// Compute reference derivatives.
3654
// Declare pointer to array of derivatives on FIAT element.
3655
double *derivatives = new double[num_derivatives];
3656
for (unsigned int r = 0; r < num_derivatives; r++)
3658
derivatives[r] = 0.0;
3659
}// end loop over 'r'
3661
// Declare derivative matrix (of polynomial basis).
3662
double dmats[1][1] = \
3665
// Declare (auxiliary) derivative matrix (of polynomial basis).
3666
double dmats_old[1][1] = \
3669
// Loop possible derivatives.
3670
for (unsigned int r = 0; r < num_derivatives; r++)
3672
// Resetting dmats values to compute next derivative.
3673
for (unsigned int t = 0; t < 1; t++)
3675
for (unsigned int u = 0; u < 1; u++)
3683
}// end loop over 'u'
3684
}// end loop over 't'
3686
// Looping derivative order to generate dmats.
3687
for (unsigned int s = 0; s < n; s++)
3689
// Updating dmats_old with new values and resetting dmats.
3690
for (unsigned int t = 0; t < 1; t++)
3692
for (unsigned int u = 0; u < 1; u++)
3694
dmats_old[t][u] = dmats[t][u];
3696
}// end loop over 'u'
3697
}// end loop over 't'
3699
// Update dmats using an inner product.
3700
if (combinations[r][s] == 0)
3702
for (unsigned int t = 0; t < 1; t++)
3704
for (unsigned int u = 0; u < 1; u++)
3706
for (unsigned int tu = 0; tu < 1; tu++)
3708
dmats[t][u] += dmats0[t][tu]*dmats_old[tu][u];
3709
}// end loop over 'tu'
3710
}// end loop over 'u'
3711
}// end loop over 't'
3714
if (combinations[r][s] == 1)
3716
for (unsigned int t = 0; t < 1; t++)
3718
for (unsigned int u = 0; u < 1; u++)
3720
for (unsigned int tu = 0; tu < 1; tu++)
3722
dmats[t][u] += dmats1[t][tu]*dmats_old[tu][u];
3723
}// end loop over 'tu'
3724
}// end loop over 'u'
3725
}// end loop over 't'
3728
}// end loop over 's'
3729
for (unsigned int s = 0; s < 1; s++)
3731
for (unsigned int t = 0; t < 1; t++)
3733
derivatives[r] += coefficients0[s]*dmats[s][t]*basisvalues[t];
3734
}// end loop over 't'
3735
}// end loop over 's'
3736
}// end loop over 'r'
3738
// Transform derivatives back to physical element
3739
for (unsigned int r = 0; r < num_derivatives; r++)
3741
for (unsigned int s = 0; s < num_derivatives; s++)
3743
values[2*num_derivatives + r] += transform[r][s]*derivatives[s];
3744
}// end loop over 's'
3745
}// end loop over 'r'
3747
// Delete pointer to array of derivatives on FIAT element
3748
delete [] derivatives;
3750
// Delete pointer to array of combinations of derivatives and transform
3751
for (unsigned int r = 0; r < num_derivatives; r++)
3753
delete [] combinations[r];
3754
}// end loop over 'r'
3755
delete [] combinations;
3756
for (unsigned int r = 0; r < num_derivatives; r++)
3758
delete [] transform[r];
3759
}// end loop over 'r'
3760
delete [] transform;
3767
/// Evaluate order n derivatives of all basis functions at given point x in cell
3768
virtual void evaluate_basis_derivatives_all(std::size_t n,
3771
const double* vertex_coordinates,
3772
int cell_orientation) const
3774
// Compute number of derivatives.
3775
unsigned int num_derivatives = 1;
3776
for (unsigned int r = 0; r < n; r++)
3778
num_derivatives *= 2;
3779
}// end loop over 'r'
3781
// Helper variable to hold values of a single dof.
3782
double *dof_values = new double[3*num_derivatives];
3783
for (unsigned int r = 0; r < 3*num_derivatives; r++)
3785
dof_values[r] = 0.0;
3786
}// end loop over 'r'
3788
// Loop dofs and call evaluate_basis_derivatives.
3789
for (unsigned int r = 0; r < 7; r++)
3791
evaluate_basis_derivatives(r, n, dof_values, x, vertex_coordinates, cell_orientation);
3792
for (unsigned int s = 0; s < 3*num_derivatives; s++)
3794
values[r*3*num_derivatives + s] = dof_values[s];
3795
}// end loop over 's'
3796
}// end loop over 'r'
3799
delete [] dof_values;
3802
/// Evaluate linear functional for dof i on the function f
3803
virtual double evaluate_dof(std::size_t i,
3804
const ufc::function& f,
3805
const double* vertex_coordinates,
3806
int cell_orientation,
3807
const ufc::cell& c) const
3809
// Declare variables for result of evaluation
3812
// Declare variable for physical coordinates
3818
compute_jacobian_triangle_2d(J, vertex_coordinates);
3821
// Compute Jacobian inverse and determinant
3824
compute_jacobian_inverse_triangle_2d(K, detJ, J);
3831
y[0] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[4];
3832
y[1] = 0.66666667*vertex_coordinates[3] + 0.33333333*vertex_coordinates[5];
3833
f.evaluate(vals, y, c);
3834
result = (detJ*(K[0]*vals[0] + K[1]*vals[1])) + (detJ*(K[2]*vals[0] + K[3]*vals[1]));
3840
y[0] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[4];
3841
y[1] = 0.33333333*vertex_coordinates[3] + 0.66666667*vertex_coordinates[5];
3842
f.evaluate(vals, y, c);
3843
result = (detJ*(K[0]*vals[0] + K[1]*vals[1])) + (detJ*(K[2]*vals[0] + K[3]*vals[1]));
3849
y[0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[4];
3850
y[1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[5];
3851
f.evaluate(vals, y, c);
3852
result = (detJ*(K[0]*vals[0] + K[1]*vals[1]));
3858
y[0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[4];
3859
y[1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[5];
3860
f.evaluate(vals, y, c);
3861
result = (detJ*(K[0]*vals[0] + K[1]*vals[1]));
3867
y[0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[2];
3868
y[1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[3];
3869
f.evaluate(vals, y, c);
3870
result = (-1.0)*(detJ*(K[2]*vals[0] + K[3]*vals[1]));
3876
y[0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[2];
3877
y[1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[3];
3878
f.evaluate(vals, y, c);
3879
result = (-1.0)*(detJ*(K[2]*vals[0] + K[3]*vals[1]));
3885
y[0] = 0.33333333*vertex_coordinates[0] + 0.33333333*vertex_coordinates[2] + 0.33333333*vertex_coordinates[4];
3886
y[1] = 0.33333333*vertex_coordinates[1] + 0.33333333*vertex_coordinates[3] + 0.33333333*vertex_coordinates[5];
3887
f.evaluate(vals, y, c);
3896
/// Evaluate linear functionals for all dofs on the function f
3897
virtual void evaluate_dofs(double* values,
3898
const ufc::function& f,
3899
const double* vertex_coordinates,
3900
int cell_orientation,
3901
const ufc::cell& c) const
3903
// Declare variables for result of evaluation
3906
// Declare variable for physical coordinates
3912
compute_jacobian_triangle_2d(J, vertex_coordinates);
3915
// Compute Jacobian inverse and determinant
3918
compute_jacobian_inverse_triangle_2d(K, detJ, J);
3921
y[0] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[4];
3922
y[1] = 0.66666667*vertex_coordinates[3] + 0.33333333*vertex_coordinates[5];
3923
f.evaluate(vals, y, c);
3924
result = (detJ*(K[0]*vals[0] + K[1]*vals[1])) + (detJ*(K[2]*vals[0] + K[3]*vals[1]));
3926
y[0] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[4];
3927
y[1] = 0.33333333*vertex_coordinates[3] + 0.66666667*vertex_coordinates[5];
3928
f.evaluate(vals, y, c);
3929
result = (detJ*(K[0]*vals[0] + K[1]*vals[1])) + (detJ*(K[2]*vals[0] + K[3]*vals[1]));
3931
y[0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[4];
3932
y[1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[5];
3933
f.evaluate(vals, y, c);
3934
result = (detJ*(K[0]*vals[0] + K[1]*vals[1]));
3936
y[0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[4];
3937
y[1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[5];
3938
f.evaluate(vals, y, c);
3939
result = (detJ*(K[0]*vals[0] + K[1]*vals[1]));
3941
y[0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[2];
3942
y[1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[3];
3943
f.evaluate(vals, y, c);
3944
result = (-1.0)*(detJ*(K[2]*vals[0] + K[3]*vals[1]));
3946
y[0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[2];
3947
y[1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[3];
3948
f.evaluate(vals, y, c);
3949
result = (-1.0)*(detJ*(K[2]*vals[0] + K[3]*vals[1]));
3951
y[0] = 0.33333333*vertex_coordinates[0] + 0.33333333*vertex_coordinates[2] + 0.33333333*vertex_coordinates[4];
3952
y[1] = 0.33333333*vertex_coordinates[1] + 0.33333333*vertex_coordinates[3] + 0.33333333*vertex_coordinates[5];
3953
f.evaluate(vals, y, c);
3954
values[6] = vals[2];
3957
/// Interpolate vertex values from dof values
3958
virtual void interpolate_vertex_values(double* vertex_values,
3959
const double* dof_values,
3960
const double* vertex_coordinates,
3961
int cell_orientation,
3962
const ufc::cell& c) const
3966
compute_jacobian_triangle_2d(J, vertex_coordinates);
3969
// Compute Jacobian inverse and determinant
3972
compute_jacobian_inverse_triangle_2d(K, detJ, J);
3976
// Evaluate function and change variables
3977
vertex_values[0] = dof_values[2]*(1.0/detJ)*J[0]*2.0 + dof_values[3]*((1.0/detJ)*(J[0]*(-1.0))) + dof_values[4]*((1.0/detJ)*(J[1]*(-2.0))) + dof_values[5]*(1.0/detJ)*J[1];
3978
vertex_values[3] = dof_values[0]*(1.0/detJ)*J[0]*2.0 + dof_values[1]*((1.0/detJ)*(J[0]*(-1.0))) + dof_values[4]*((1.0/detJ)*(J[0]*(-1.0) + J[1])) + dof_values[5]*((1.0/detJ)*(J[0]*2.0 + J[1]*(-2.0)));
3979
vertex_values[6] = dof_values[0]*((1.0/detJ)*(J[1]*(-1.0))) + dof_values[1]*(1.0/detJ)*J[1]*2.0 + dof_values[2]*((1.0/detJ)*(J[0]*(-1.0) + J[1])) + dof_values[3]*((1.0/detJ)*(J[0]*2.0 + J[1]*(-2.0)));
3980
vertex_values[1] = dof_values[2]*(1.0/detJ)*J[2]*2.0 + dof_values[3]*((1.0/detJ)*(J[2]*(-1.0))) + dof_values[4]*((1.0/detJ)*(J[3]*(-2.0))) + dof_values[5]*(1.0/detJ)*J[3];
3981
vertex_values[4] = dof_values[0]*(1.0/detJ)*J[2]*2.0 + dof_values[1]*((1.0/detJ)*(J[2]*(-1.0))) + dof_values[4]*((1.0/detJ)*(J[2]*(-1.0) + J[3])) + dof_values[5]*((1.0/detJ)*(J[2]*2.0 + J[3]*(-2.0)));
3982
vertex_values[7] = dof_values[0]*((1.0/detJ)*(J[3]*(-1.0))) + dof_values[1]*(1.0/detJ)*J[3]*2.0 + dof_values[2]*((1.0/detJ)*(J[2]*(-1.0) + J[3])) + dof_values[3]*((1.0/detJ)*(J[2]*2.0 + J[3]*(-2.0)));
3983
// Evaluate function and change variables
3984
vertex_values[2] = dof_values[6];
3985
vertex_values[5] = dof_values[6];
3986
vertex_values[8] = dof_values[6];
3989
/// Map coordinate xhat from reference cell to coordinate x in cell
3990
virtual void map_from_reference_cell(double* x,
3992
const ufc::cell& c) const
3994
std::cerr << "*** FFC warning: " << "map_from_reference_cell not yet implemented." << std::endl;
3997
/// Map from coordinate x in cell to coordinate xhat in reference cell
3998
virtual void map_to_reference_cell(double* xhat,
4000
const ufc::cell& c) const
4002
std::cerr << "*** FFC warning: " << "map_to_reference_cell not yet implemented." << std::endl;
4005
/// Return the number of sub elements (for a mixed element)
4006
virtual std::size_t num_sub_elements() const
4011
/// Create a new finite element for sub element i (for a mixed element)
4012
virtual ufc::finite_element* create_sub_element(std::size_t i) const
4018
return new mixedpoisson_finite_element_0();
4023
return new mixedpoisson_finite_element_1();
4031
/// Create a new class instance
4032
virtual ufc::finite_element* create() const
4034
return new mixedpoisson_finite_element_2();
4039
/// This class defines the interface for a local-to-global mapping of
4040
/// degrees of freedom (dofs).
4042
class mixedpoisson_dofmap_0: public ufc::dofmap
4047
mixedpoisson_dofmap_0() : ufc::dofmap()
4053
virtual ~mixedpoisson_dofmap_0()
4058
/// Return a string identifying the dofmap
4059
virtual const char* signature() const
4061
return "FFC dofmap for FiniteElement('Brezzi-Douglas-Marini', Domain(Cell('triangle', 2), 'triangle_multiverse', 2, 2), 1, None)";
4064
/// Return true iff mesh entities of topological dimension d are needed
4065
virtual bool needs_mesh_entities(std::size_t d) const
4089
/// Return the topological dimension of the associated cell shape
4090
virtual std::size_t topological_dimension() const
4095
/// Return the geometric dimension of the associated cell shape
4096
virtual std::size_t geometric_dimension() const
4101
/// Return the dimension of the global finite element function space
4102
virtual std::size_t global_dimension(const std::vector<std::size_t>&
4103
num_global_entities) const
4105
return 2*num_global_entities[1];
4108
/// Return the dimension of the local finite element function space for a cell
4109
virtual std::size_t local_dimension(const ufc::cell& c) const
4114
/// Return the maximum dimension of the local finite element function space
4115
virtual std::size_t max_local_dimension() const
4120
/// Return the number of dofs on each cell facet
4121
virtual std::size_t num_facet_dofs() const
4126
/// Return the number of dofs associated with each cell entity of dimension d
4127
virtual std::size_t num_entity_dofs(std::size_t d) const
4151
/// Tabulate the local-to-global mapping of dofs on a cell
4152
virtual void tabulate_dofs(std::size_t* dofs,
4153
const std::vector<std::size_t>& num_global_entities,
4154
const ufc::cell& c) const
4156
dofs[0] = 2*c.entity_indices[1][0];
4157
dofs[1] = 2*c.entity_indices[1][0] + 1;
4158
dofs[2] = 2*c.entity_indices[1][1];
4159
dofs[3] = 2*c.entity_indices[1][1] + 1;
4160
dofs[4] = 2*c.entity_indices[1][2];
4161
dofs[5] = 2*c.entity_indices[1][2] + 1;
4164
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
4165
virtual void tabulate_facet_dofs(std::size_t* dofs,
4166
std::size_t facet) const
4192
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
4193
virtual void tabulate_entity_dofs(std::size_t* dofs,
4194
std::size_t d, std::size_t i) const
4198
std::cerr << "*** FFC warning: " << "d is larger than dimension (2)" << std::endl;
4212
std::cerr << "*** FFC warning: " << "i is larger than number of entities (2)" << std::endl;
4248
/// Tabulate the coordinates of all dofs on a cell
4249
virtual void tabulate_coordinates(double** dof_coordinates,
4250
const double* vertex_coordinates) const
4252
dof_coordinates[0][0] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[4];
4253
dof_coordinates[0][1] = 0.66666667*vertex_coordinates[3] + 0.33333333*vertex_coordinates[5];
4254
dof_coordinates[1][0] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[4];
4255
dof_coordinates[1][1] = 0.33333333*vertex_coordinates[3] + 0.66666667*vertex_coordinates[5];
4256
dof_coordinates[2][0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[4];
4257
dof_coordinates[2][1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[5];
4258
dof_coordinates[3][0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[4];
4259
dof_coordinates[3][1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[5];
4260
dof_coordinates[4][0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[2];
4261
dof_coordinates[4][1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[3];
4262
dof_coordinates[5][0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[2];
4263
dof_coordinates[5][1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[3];
4266
/// Return the number of sub dofmaps (for a mixed element)
4267
virtual std::size_t num_sub_dofmaps() const
4272
/// Create a new dofmap for sub dofmap i (for a mixed element)
4273
virtual ufc::dofmap* create_sub_dofmap(std::size_t i) const
4278
/// Create a new class instance
4279
virtual ufc::dofmap* create() const
4281
return new mixedpoisson_dofmap_0();
4286
/// This class defines the interface for a local-to-global mapping of
4287
/// degrees of freedom (dofs).
4289
class mixedpoisson_dofmap_1: public ufc::dofmap
4294
mixedpoisson_dofmap_1() : ufc::dofmap()
4300
virtual ~mixedpoisson_dofmap_1()
4305
/// Return a string identifying the dofmap
4306
virtual const char* signature() const
4308
return "FFC dofmap for FiniteElement('Discontinuous Lagrange', Domain(Cell('triangle', 2), 'triangle_multiverse', 2, 2), 0, None)";
4311
/// Return true iff mesh entities of topological dimension d are needed
4312
virtual bool needs_mesh_entities(std::size_t d) const
4336
/// Return the topological dimension of the associated cell shape
4337
virtual std::size_t topological_dimension() const
4342
/// Return the geometric dimension of the associated cell shape
4343
virtual std::size_t geometric_dimension() const
4348
/// Return the dimension of the global finite element function space
4349
virtual std::size_t global_dimension(const std::vector<std::size_t>&
4350
num_global_entities) const
4352
return num_global_entities[2];
4355
/// Return the dimension of the local finite element function space for a cell
4356
virtual std::size_t local_dimension(const ufc::cell& c) const
4361
/// Return the maximum dimension of the local finite element function space
4362
virtual std::size_t max_local_dimension() const
4367
/// Return the number of dofs on each cell facet
4368
virtual std::size_t num_facet_dofs() const
4373
/// Return the number of dofs associated with each cell entity of dimension d
4374
virtual std::size_t num_entity_dofs(std::size_t d) const
4398
/// Tabulate the local-to-global mapping of dofs on a cell
4399
virtual void tabulate_dofs(std::size_t* dofs,
4400
const std::vector<std::size_t>& num_global_entities,
4401
const ufc::cell& c) const
4403
dofs[0] = c.entity_indices[2][0];
4406
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
4407
virtual void tabulate_facet_dofs(std::size_t* dofs,
4408
std::size_t facet) const
4431
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
4432
virtual void tabulate_entity_dofs(std::size_t* dofs,
4433
std::size_t d, std::size_t i) const
4437
std::cerr << "*** FFC warning: " << "d is larger than dimension (2)" << std::endl;
4456
std::cerr << "*** FFC warning: " << "i is larger than number of entities (0)" << std::endl;
4466
/// Tabulate the coordinates of all dofs on a cell
4467
virtual void tabulate_coordinates(double** dof_coordinates,
4468
const double* vertex_coordinates) const
4470
dof_coordinates[0][0] = 0.33333333*vertex_coordinates[0] + 0.33333333*vertex_coordinates[2] + 0.33333333*vertex_coordinates[4];
4471
dof_coordinates[0][1] = 0.33333333*vertex_coordinates[1] + 0.33333333*vertex_coordinates[3] + 0.33333333*vertex_coordinates[5];
4474
/// Return the number of sub dofmaps (for a mixed element)
4475
virtual std::size_t num_sub_dofmaps() const
4480
/// Create a new dofmap for sub dofmap i (for a mixed element)
4481
virtual ufc::dofmap* create_sub_dofmap(std::size_t i) const
4486
/// Create a new class instance
4487
virtual ufc::dofmap* create() const
4489
return new mixedpoisson_dofmap_1();
4494
/// This class defines the interface for a local-to-global mapping of
4495
/// degrees of freedom (dofs).
4497
class mixedpoisson_dofmap_2: public ufc::dofmap
4502
mixedpoisson_dofmap_2() : ufc::dofmap()
4508
virtual ~mixedpoisson_dofmap_2()
4513
/// Return a string identifying the dofmap
4514
virtual const char* signature() const
4516
return "FFC dofmap for MixedElement(*[FiniteElement('Brezzi-Douglas-Marini', Domain(Cell('triangle', 2), 'triangle_multiverse', 2, 2), 1, None), FiniteElement('Discontinuous Lagrange', Domain(Cell('triangle', 2), 'triangle_multiverse', 2, 2), 0, None)], **{'value_shape': (3,) })";
4519
/// Return true iff mesh entities of topological dimension d are needed
4520
virtual bool needs_mesh_entities(std::size_t d) const
4544
/// Return the topological dimension of the associated cell shape
4545
virtual std::size_t topological_dimension() const
4550
/// Return the geometric dimension of the associated cell shape
4551
virtual std::size_t geometric_dimension() const
4556
/// Return the dimension of the global finite element function space
4557
virtual std::size_t global_dimension(const std::vector<std::size_t>&
4558
num_global_entities) const
4560
return 2*num_global_entities[1] + num_global_entities[2];
4563
/// Return the dimension of the local finite element function space for a cell
4564
virtual std::size_t local_dimension(const ufc::cell& c) const
4569
/// Return the maximum dimension of the local finite element function space
4570
virtual std::size_t max_local_dimension() const
4575
/// Return the number of dofs on each cell facet
4576
virtual std::size_t num_facet_dofs() const
4581
/// Return the number of dofs associated with each cell entity of dimension d
4582
virtual std::size_t num_entity_dofs(std::size_t d) const
4606
/// Tabulate the local-to-global mapping of dofs on a cell
4607
virtual void tabulate_dofs(std::size_t* dofs,
4608
const std::vector<std::size_t>& num_global_entities,
4609
const ufc::cell& c) const
4611
unsigned int offset = 0;
4612
dofs[0] = offset + 2*c.entity_indices[1][0];
4613
dofs[1] = offset + 2*c.entity_indices[1][0] + 1;
4614
dofs[2] = offset + 2*c.entity_indices[1][1];
4615
dofs[3] = offset + 2*c.entity_indices[1][1] + 1;
4616
dofs[4] = offset + 2*c.entity_indices[1][2];
4617
dofs[5] = offset + 2*c.entity_indices[1][2] + 1;
4618
offset += 2*num_global_entities[1];
4619
dofs[6] = offset + c.entity_indices[2][0];
4620
offset += num_global_entities[2];
4623
/// Tabulate the local-to-local mapping from facet dofs to cell dofs
4624
virtual void tabulate_facet_dofs(std::size_t* dofs,
4625
std::size_t facet) const
4651
/// Tabulate the local-to-local mapping of dofs on entity (d, i)
4652
virtual void tabulate_entity_dofs(std::size_t* dofs,
4653
std::size_t d, std::size_t i) const
4657
std::cerr << "*** FFC warning: " << "d is larger than dimension (2)" << std::endl;
4671
std::cerr << "*** FFC warning: " << "i is larger than number of entities (2)" << std::endl;
4702
std::cerr << "*** FFC warning: " << "i is larger than number of entities (0)" << std::endl;
4712
/// Tabulate the coordinates of all dofs on a cell
4713
virtual void tabulate_coordinates(double** dof_coordinates,
4714
const double* vertex_coordinates) const
4716
dof_coordinates[0][0] = 0.66666667*vertex_coordinates[2] + 0.33333333*vertex_coordinates[4];
4717
dof_coordinates[0][1] = 0.66666667*vertex_coordinates[3] + 0.33333333*vertex_coordinates[5];
4718
dof_coordinates[1][0] = 0.33333333*vertex_coordinates[2] + 0.66666667*vertex_coordinates[4];
4719
dof_coordinates[1][1] = 0.33333333*vertex_coordinates[3] + 0.66666667*vertex_coordinates[5];
4720
dof_coordinates[2][0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[4];
4721
dof_coordinates[2][1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[5];
4722
dof_coordinates[3][0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[4];
4723
dof_coordinates[3][1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[5];
4724
dof_coordinates[4][0] = 0.66666667*vertex_coordinates[0] + 0.33333333*vertex_coordinates[2];
4725
dof_coordinates[4][1] = 0.66666667*vertex_coordinates[1] + 0.33333333*vertex_coordinates[3];
4726
dof_coordinates[5][0] = 0.33333333*vertex_coordinates[0] + 0.66666667*vertex_coordinates[2];
4727
dof_coordinates[5][1] = 0.33333333*vertex_coordinates[1] + 0.66666667*vertex_coordinates[3];
4728
dof_coordinates[6][0] = 0.33333333*vertex_coordinates[0] + 0.33333333*vertex_coordinates[2] + 0.33333333*vertex_coordinates[4];
4729
dof_coordinates[6][1] = 0.33333333*vertex_coordinates[1] + 0.33333333*vertex_coordinates[3] + 0.33333333*vertex_coordinates[5];
4732
/// Return the number of sub dofmaps (for a mixed element)
4733
virtual std::size_t num_sub_dofmaps() const
4738
/// Create a new dofmap for sub dofmap i (for a mixed element)
4739
virtual ufc::dofmap* create_sub_dofmap(std::size_t i) const
4745
return new mixedpoisson_dofmap_0();
4750
return new mixedpoisson_dofmap_1();
4758
/// Create a new class instance
4759
virtual ufc::dofmap* create() const
4761
return new mixedpoisson_dofmap_2();
4766
/// This class defines the interface for the tabulation of the cell
4767
/// tensor corresponding to the local contribution to a form from
4768
/// the integral over a cell.
4770
class mixedpoisson_cell_integral_0_otherwise: public ufc::cell_integral
4775
mixedpoisson_cell_integral_0_otherwise() : ufc::cell_integral()
4781
virtual ~mixedpoisson_cell_integral_0_otherwise()
4786
/// Tabulate the tensor for the contribution from a local cell
4787
virtual void tabulate_tensor(double* A,
4788
const double * const * w,
4789
const double* vertex_coordinates,
4790
int cell_orientation) const
4794
compute_jacobian_triangle_2d(J, vertex_coordinates);
4796
// Compute Jacobian inverse and determinant
4799
compute_jacobian_inverse_triangle_2d(K, detJ, J);
4802
const double det = std::abs(detJ);
4806
// Compute circumradius of triangle in 2D
4811
// Array of quadrature weights.
4812
static const double W3[3] = {0.16666667, 0.16666667, 0.16666667};
4813
// Quadrature points on the UFC reference element: (0.16666667, 0.16666667), (0.16666667, 0.66666667), (0.66666667, 0.16666667)
4815
// Value of basis functions at quadrature points.
4816
static const double FE0_C0[3][7] = \
4817
{{0.33333333, -0.16666667, 1.1666667, -0.33333333, -0.16666667, 0.33333333, 0.0},
4818
{0.33333333, -0.16666667, -0.33333333, 1.1666667, -0.16666667, 0.33333333, 0.0},
4819
{1.3333333, -0.66666667, 0.16666667, 0.16666667, -0.66666667, 1.3333333, 0.0}};
4821
static const double FE0_C0_D01[3][7] = \
4822
{{0.0, 0.0, -3.0, 3.0, 0.0, 0.0, 0.0},
4823
{0.0, 0.0, -3.0, 3.0, 0.0, 0.0, 0.0},
4824
{0.0, 0.0, -3.0, 3.0, 0.0, 0.0, 0.0}};
4826
static const double FE0_C0_D10[3][7] = \
4827
{{2.0, -1.0, -2.0, 1.0, -1.0, 2.0, 0.0},
4828
{2.0, -1.0, -2.0, 1.0, -1.0, 2.0, 0.0},
4829
{2.0, -1.0, -2.0, 1.0, -1.0, 2.0, 0.0}};
4831
static const double FE0_C1[3][7] = \
4832
{{-0.16666667, 0.33333333, 0.16666667, -0.33333333, -1.1666667, 0.33333333, 0.0},
4833
{-0.66666667, 1.3333333, 0.66666667, -1.3333333, -0.16666667, -0.16666667, 0.0},
4834
{-0.16666667, 0.33333333, 0.16666667, -0.33333333, 0.33333333, -1.1666667, 0.0}};
4836
static const double FE0_C1_D01[3][7] = \
4837
{{-1.0, 2.0, 1.0, -2.0, 2.0, -1.0, 0.0},
4838
{-1.0, 2.0, 1.0, -2.0, 2.0, -1.0, 0.0},
4839
{-1.0, 2.0, 1.0, -2.0, 2.0, -1.0, 0.0}};
4841
static const double FE0_C1_D10[3][7] = \
4842
{{0.0, 0.0, 0.0, 0.0, 3.0, -3.0, 0.0},
4843
{0.0, 0.0, 0.0, 0.0, 3.0, -3.0, 0.0},
4844
{0.0, 0.0, 0.0, 0.0, 3.0, -3.0, 0.0}};
4846
static const double FE0_C2[3][7] = \
4847
{{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0},
4848
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0},
4849
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
4851
// Reset values in the element tensor.
4852
for (unsigned int r = 0; r < 49; r++)
4855
}// end loop over 'r'
4857
// Compute element tensor using UFL quadrature representation
4858
// Optimisations: ('eliminate zeros', False), ('ignore ones', False), ('ignore zero tables', False), ('optimisation', False), ('remove zero terms', False)
4860
// Loop quadrature points for integral.
4861
// Number of operations to compute element tensor for following IP loop = 13671
4862
for (unsigned int ip = 0; ip < 3; ip++)
4865
// Number of operations for primary indices: 4557
4866
for (unsigned int j = 0; j < 7; j++)
4868
for (unsigned int k = 0; k < 7; k++)
4870
// Number of operations to compute entry: 93
4871
A[j*7 + k] += ((((((K[1]*(1.0/detJ)*J[2]*FE0_C0_D10[ip][j] + K[1]*(1.0/detJ)*J[3]*FE0_C1_D10[ip][j] + K[3]*(1.0/detJ)*J[2]*FE0_C0_D01[ip][j] + K[3]*(1.0/detJ)*J[3]*FE0_C1_D01[ip][j]) + (K[0]*(1.0/detJ)*J[0]*FE0_C0_D10[ip][j] + K[0]*(1.0/detJ)*J[1]*FE0_C1_D10[ip][j] + K[2]*(1.0/detJ)*J[0]*FE0_C0_D01[ip][j] + K[2]*(1.0/detJ)*J[1]*FE0_C1_D01[ip][j])))*FE0_C2[ip][k])*(-1.0) + ((((1.0/detJ)*J[0]*FE0_C0[ip][j] + (1.0/detJ)*J[1]*FE0_C1[ip][j]))*(((1.0/detJ)*J[0]*FE0_C0[ip][k] + (1.0/detJ)*J[1]*FE0_C1[ip][k])) + (((1.0/detJ)*J[2]*FE0_C0[ip][j] + (1.0/detJ)*J[3]*FE0_C1[ip][j]))*(((1.0/detJ)*J[2]*FE0_C0[ip][k] + (1.0/detJ)*J[3]*FE0_C1[ip][k])))) + (((K[1]*(1.0/detJ)*J[2]*FE0_C0_D10[ip][k] + K[1]*(1.0/detJ)*J[3]*FE0_C1_D10[ip][k] + K[3]*(1.0/detJ)*J[2]*FE0_C0_D01[ip][k] + K[3]*(1.0/detJ)*J[3]*FE0_C1_D01[ip][k]) + (K[0]*(1.0/detJ)*J[0]*FE0_C0_D10[ip][k] + K[0]*(1.0/detJ)*J[1]*FE0_C1_D10[ip][k] + K[2]*(1.0/detJ)*J[0]*FE0_C0_D01[ip][k] + K[2]*(1.0/detJ)*J[1]*FE0_C1_D01[ip][k])))*FE0_C2[ip][j])*W3[ip]*det;
4872
}// end loop over 'k'
4873
}// end loop over 'j'
4874
}// end loop over 'ip'
4879
/// This class defines the interface for the tabulation of the cell
4880
/// tensor corresponding to the local contribution to a form from
4881
/// the integral over a cell.
4883
class mixedpoisson_cell_integral_1_otherwise: public ufc::cell_integral
4888
mixedpoisson_cell_integral_1_otherwise() : ufc::cell_integral()
4894
virtual ~mixedpoisson_cell_integral_1_otherwise()
4899
/// Tabulate the tensor for the contribution from a local cell
4900
virtual void tabulate_tensor(double* A,
4901
const double * const * w,
4902
const double* vertex_coordinates,
4903
int cell_orientation) const
4907
compute_jacobian_triangle_2d(J, vertex_coordinates);
4909
// Compute Jacobian inverse and determinant
4912
compute_jacobian_inverse_triangle_2d(K, detJ, J);
4915
const double det = std::abs(detJ);
4919
// Compute circumradius of triangle in 2D
4924
// Array of quadrature weights.
4925
static const double W1 = 0.5;
4926
// Quadrature points on the UFC reference element: (0.33333333, 0.33333333)
4928
// Value of basis functions at quadrature points.
4929
static const double FE0[1][1] = \
4932
static const double FE1_C2[1][7] = \
4933
{{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}};
4935
// Reset values in the element tensor.
4936
for (unsigned int r = 0; r < 7; r++)
4939
}// end loop over 'r'
4941
// Compute element tensor using UFL quadrature representation
4942
// Optimisations: ('eliminate zeros', False), ('ignore ones', False), ('ignore zero tables', False), ('optimisation', False), ('remove zero terms', False)
4944
// Loop quadrature points for integral.
4945
// Number of operations to compute element tensor for following IP loop = 30
4946
// Only 1 integration point, omitting IP loop.
4948
// Coefficient declarations.
4951
// Total number of operations to compute function values = 2
4952
for (unsigned int r = 0; r < 1; r++)
4954
F0 += FE0[0][0]*w[0][0];
4955
}// end loop over 'r'
4957
// Number of operations for primary indices: 28
4958
for (unsigned int j = 0; j < 7; j++)
4960
// Number of operations to compute entry: 4
4961
A[j] += FE1_C2[0][j]*F0*W1*det;
4962
}// end loop over 'j'
4967
/// This class defines the interface for the assembly of the global
4968
/// tensor corresponding to a form with r + n arguments, that is, a
4971
/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
4973
/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
4974
/// global tensor A is defined by
4976
/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
4978
/// where each argument Vj represents the application to the
4979
/// sequence of basis functions of Vj and w1, w2, ..., wn are given
4980
/// fixed functions (coefficients).
4982
class mixedpoisson_form_0: public ufc::form
4987
mixedpoisson_form_0() : ufc::form()
4993
virtual ~mixedpoisson_form_0()
4998
/// Return a string identifying the form
4999
virtual const char* signature() const
5001
return "ba8f7ee8a474704904426d1ae24218877c4fffaff40757e3b3504cd391e7ccb869536395afe73d8e955900506f62cec5a6bb0981dfdd9f562ab4ca394a2cac97";
5004
/// Return the rank of the global tensor (r)
5005
virtual std::size_t rank() const
5010
/// Return the number of coefficients (n)
5011
virtual std::size_t num_coefficients() const
5016
/// Return the number of cell domains
5017
virtual std::size_t num_cell_domains() const
5022
/// Return the number of exterior facet domains
5023
virtual std::size_t num_exterior_facet_domains() const
5028
/// Return the number of interior facet domains
5029
virtual std::size_t num_interior_facet_domains() const
5034
/// Return the number of point domains
5035
virtual std::size_t num_point_domains() const
5040
/// Return whether the form has any cell integrals
5041
virtual bool has_cell_integrals() const
5046
/// Return whether the form has any exterior facet integrals
5047
virtual bool has_exterior_facet_integrals() const
5052
/// Return whether the form has any interior facet integrals
5053
virtual bool has_interior_facet_integrals() const
5058
/// Return whether the form has any point integrals
5059
virtual bool has_point_integrals() const
5064
/// Create a new finite element for argument function i
5065
virtual ufc::finite_element* create_finite_element(std::size_t i) const
5071
return new mixedpoisson_finite_element_2();
5076
return new mixedpoisson_finite_element_2();
5084
/// Create a new dofmap for argument function i
5085
virtual ufc::dofmap* create_dofmap(std::size_t i) const
5091
return new mixedpoisson_dofmap_2();
5096
return new mixedpoisson_dofmap_2();
5104
/// Create a new cell integral on sub domain i
5105
virtual ufc::cell_integral* create_cell_integral(std::size_t i) const
5110
/// Create a new exterior facet integral on sub domain i
5111
virtual ufc::exterior_facet_integral* create_exterior_facet_integral(std::size_t i) const
5116
/// Create a new interior facet integral on sub domain i
5117
virtual ufc::interior_facet_integral* create_interior_facet_integral(std::size_t i) const
5122
/// Create a new point integral on sub domain i
5123
virtual ufc::point_integral* create_point_integral(std::size_t i) const
5128
/// Create a new cell integral on everywhere else
5129
virtual ufc::cell_integral* create_default_cell_integral() const
5131
return new mixedpoisson_cell_integral_0_otherwise();
5134
/// Create a new exterior facet integral on everywhere else
5135
virtual ufc::exterior_facet_integral* create_default_exterior_facet_integral() const
5140
/// Create a new interior facet integral on everywhere else
5141
virtual ufc::interior_facet_integral* create_default_interior_facet_integral() const
5146
/// Create a new point integral on everywhere else
5147
virtual ufc::point_integral* create_default_point_integral() const
5154
/// This class defines the interface for the assembly of the global
5155
/// tensor corresponding to a form with r + n arguments, that is, a
5158
/// a : V1 x V2 x ... Vr x W1 x W2 x ... x Wn -> R
5160
/// with arguments v1, v2, ..., vr, w1, w2, ..., wn. The rank r
5161
/// global tensor A is defined by
5163
/// A = a(V1, V2, ..., Vr, w1, w2, ..., wn),
5165
/// where each argument Vj represents the application to the
5166
/// sequence of basis functions of Vj and w1, w2, ..., wn are given
5167
/// fixed functions (coefficients).
5169
class mixedpoisson_form_1: public ufc::form
5174
mixedpoisson_form_1() : ufc::form()
5180
virtual ~mixedpoisson_form_1()
5185
/// Return a string identifying the form
5186
virtual const char* signature() const
5188
return "ba4bf21fb268523b07e03e4afd5337c82cf9a48e5b60f077e619b7de28c804d51cb9e5832eab0f3ec048a42b64a007c831e68416fd4e56b0f2a4f8a4b5a863ca";
5191
/// Return the rank of the global tensor (r)
5192
virtual std::size_t rank() const
5197
/// Return the number of coefficients (n)
5198
virtual std::size_t num_coefficients() const
5203
/// Return the number of cell domains
5204
virtual std::size_t num_cell_domains() const
5209
/// Return the number of exterior facet domains
5210
virtual std::size_t num_exterior_facet_domains() const
5215
/// Return the number of interior facet domains
5216
virtual std::size_t num_interior_facet_domains() const
5221
/// Return the number of point domains
5222
virtual std::size_t num_point_domains() const
5227
/// Return whether the form has any cell integrals
5228
virtual bool has_cell_integrals() const
5233
/// Return whether the form has any exterior facet integrals
5234
virtual bool has_exterior_facet_integrals() const
5239
/// Return whether the form has any interior facet integrals
5240
virtual bool has_interior_facet_integrals() const
5245
/// Return whether the form has any point integrals
5246
virtual bool has_point_integrals() const
5251
/// Create a new finite element for argument function i
5252
virtual ufc::finite_element* create_finite_element(std::size_t i) const
5258
return new mixedpoisson_finite_element_2();
5263
return new mixedpoisson_finite_element_1();
5271
/// Create a new dofmap for argument function i
5272
virtual ufc::dofmap* create_dofmap(std::size_t i) const
5278
return new mixedpoisson_dofmap_2();
5283
return new mixedpoisson_dofmap_1();
5291
/// Create a new cell integral on sub domain i
5292
virtual ufc::cell_integral* create_cell_integral(std::size_t i) const
5297
/// Create a new exterior facet integral on sub domain i
5298
virtual ufc::exterior_facet_integral* create_exterior_facet_integral(std::size_t i) const
5303
/// Create a new interior facet integral on sub domain i
5304
virtual ufc::interior_facet_integral* create_interior_facet_integral(std::size_t i) const
5309
/// Create a new point integral on sub domain i
5310
virtual ufc::point_integral* create_point_integral(std::size_t i) const
5315
/// Create a new cell integral on everywhere else
5316
virtual ufc::cell_integral* create_default_cell_integral() const
5318
return new mixedpoisson_cell_integral_1_otherwise();
5321
/// Create a new exterior facet integral on everywhere else
5322
virtual ufc::exterior_facet_integral* create_default_exterior_facet_integral() const
5327
/// Create a new interior facet integral on everywhere else
5328
virtual ufc::interior_facet_integral* create_default_interior_facet_integral() const
5333
/// Create a new point integral on everywhere else
5334
virtual ufc::point_integral* create_default_point_integral() const