23
24
class BilinearForm : public dolfin::BilinearForm
27
class TestElement : public dolfin::FiniteElement
31
TestElement() : dolfin::FiniteElement(), tensordims(0), subelements(0)
33
tensordims = new unsigned int [1];
36
subelements = new FiniteElement* [2];
37
subelements[0] = new SubElement_0();
38
subelements[1] = new SubElement_1();
43
if ( tensordims ) delete [] tensordims;
46
for (unsigned int i = 0; i < elementdim(); i++)
47
delete subelements[i];
48
delete [] subelements;
52
inline unsigned int spacedim() const
57
inline unsigned int shapedim() const
62
inline unsigned int tensordim(unsigned int i) const
68
inline unsigned int elementdim() const
73
inline unsigned int rank() const
78
void nodemap(int nodes[], const Cell& cell, const Mesh& mesh) const
80
nodes[0] = cell.vertexID(0);
81
nodes[1] = cell.vertexID(1);
82
nodes[2] = cell.vertexID(2);
83
int offset = mesh.numVertices();
84
nodes[3] = offset + cell.edgeID(0);
85
nodes[4] = offset + cell.edgeID(1);
86
nodes[5] = offset + cell.edgeID(2);
87
offset = offset + mesh.numEdges();
88
nodes[6] = offset + cell.vertexID(0);
89
nodes[7] = offset + cell.vertexID(1);
90
nodes[8] = offset + cell.vertexID(2);
91
offset = offset + mesh.numVertices();
92
nodes[9] = offset + cell.edgeID(0);
93
nodes[10] = offset + cell.edgeID(1);
94
nodes[11] = offset + cell.edgeID(2);
95
offset = offset + mesh.numEdges();
96
nodes[12] = offset + cell.vertexID(0);
97
nodes[13] = offset + cell.vertexID(1);
98
nodes[14] = offset + cell.vertexID(2);
101
void pointmap(Point points[], unsigned int components[], const AffineMap& map) const
103
points[0] = map(0.000000000000000e+00, 0.000000000000000e+00);
104
points[1] = map(1.000000000000000e+00, 0.000000000000000e+00);
105
points[2] = map(0.000000000000000e+00, 1.000000000000000e+00);
106
points[3] = map(5.000000000000000e-01, 5.000000000000000e-01);
107
points[4] = map(0.000000000000000e+00, 5.000000000000000e-01);
108
points[5] = map(5.000000000000000e-01, 0.000000000000000e+00);
109
points[6] = map(0.000000000000000e+00, 0.000000000000000e+00);
110
points[7] = map(1.000000000000000e+00, 0.000000000000000e+00);
111
points[8] = map(0.000000000000000e+00, 1.000000000000000e+00);
112
points[9] = map(5.000000000000000e-01, 5.000000000000000e-01);
113
points[10] = map(0.000000000000000e+00, 5.000000000000000e-01);
114
points[11] = map(5.000000000000000e-01, 0.000000000000000e+00);
127
points[12] = map(0.000000000000000e+00, 0.000000000000000e+00);
128
points[13] = map(1.000000000000000e+00, 0.000000000000000e+00);
129
points[14] = map(0.000000000000000e+00, 1.000000000000000e+00);
135
void vertexeval(real values[], unsigned int vertex, const real x[], const Mesh& mesh) const
137
// FIXME: Temporary fix for Lagrange elements
138
values[0] = x[vertex];
139
int offset = mesh.numVertices() + mesh.numEdges();
140
values[1] = x[offset + vertex];
141
offset = offset + mesh.numVertices() + mesh.numEdges();
142
values[2] = x[offset + vertex];
145
const FiniteElement& operator[] (unsigned int i) const
147
return *subelements[i];
150
FiniteElement& operator[] (unsigned int i)
152
return *subelements[i];
155
FiniteElementSpec spec() const
157
FiniteElementSpec s("mixed");
163
class SubElement_0 : public dolfin::FiniteElement
167
SubElement_0() : dolfin::FiniteElement(), tensordims(0), subelements(0)
169
tensordims = new unsigned int [1];
172
// Element is simple, don't need to initialize subelements
177
if ( tensordims ) delete [] tensordims;
180
for (unsigned int i = 0; i < elementdim(); i++)
181
delete subelements[i];
182
delete [] subelements;
186
inline unsigned int spacedim() const
191
inline unsigned int shapedim() const
196
inline unsigned int tensordim(unsigned int i) const
198
dolfin_assert(i < 1);
199
return tensordims[i];
202
inline unsigned int elementdim() const
207
inline unsigned int rank() const
212
void nodemap(int nodes[], const Cell& cell, const Mesh& mesh) const
214
nodes[0] = cell.vertexID(0);
215
nodes[1] = cell.vertexID(1);
216
nodes[2] = cell.vertexID(2);
217
int offset = mesh.numVertices();
218
nodes[3] = offset + cell.edgeID(0);
219
nodes[4] = offset + cell.edgeID(1);
220
nodes[5] = offset + cell.edgeID(2);
221
offset = offset + mesh.numEdges();
222
nodes[6] = offset + cell.vertexID(0);
223
nodes[7] = offset + cell.vertexID(1);
224
nodes[8] = offset + cell.vertexID(2);
225
offset = offset + mesh.numVertices();
226
nodes[9] = offset + cell.edgeID(0);
227
nodes[10] = offset + cell.edgeID(1);
228
nodes[11] = offset + cell.edgeID(2);
231
void pointmap(Point points[], unsigned int components[], const AffineMap& map) const
233
points[0] = map(0.000000000000000e+00, 0.000000000000000e+00);
234
points[1] = map(1.000000000000000e+00, 0.000000000000000e+00);
235
points[2] = map(0.000000000000000e+00, 1.000000000000000e+00);
236
points[3] = map(5.000000000000000e-01, 5.000000000000000e-01);
237
points[4] = map(0.000000000000000e+00, 5.000000000000000e-01);
238
points[5] = map(5.000000000000000e-01, 0.000000000000000e+00);
239
points[6] = map(0.000000000000000e+00, 0.000000000000000e+00);
240
points[7] = map(1.000000000000000e+00, 0.000000000000000e+00);
241
points[8] = map(0.000000000000000e+00, 1.000000000000000e+00);
242
points[9] = map(5.000000000000000e-01, 5.000000000000000e-01);
243
points[10] = map(0.000000000000000e+00, 5.000000000000000e-01);
244
points[11] = map(5.000000000000000e-01, 0.000000000000000e+00);
259
void vertexeval(real values[], unsigned int vertex, const real x[], const Mesh& mesh) const
261
// FIXME: Temporary fix for Lagrange elements
262
values[0] = x[vertex];
263
int offset = mesh.numVertices() + mesh.numEdges();
264
values[1] = x[offset + vertex];
267
const FiniteElement& operator[] (unsigned int i) const
272
FiniteElement& operator[] (unsigned int i)
277
FiniteElementSpec spec() const
279
FiniteElementSpec s("Vector Lagrange", "triangle", 2, 2);
285
unsigned int* tensordims;
286
FiniteElement** subelements;
290
class SubElement_1 : public dolfin::FiniteElement
294
SubElement_1() : dolfin::FiniteElement(), tensordims(0), subelements(0)
296
// Element is scalar, don't need to initialize tensordims
298
// Element is simple, don't need to initialize subelements
303
if ( tensordims ) delete [] tensordims;
306
for (unsigned int i = 0; i < elementdim(); i++)
307
delete subelements[i];
308
delete [] subelements;
312
inline unsigned int spacedim() const
317
inline unsigned int shapedim() const
322
inline unsigned int tensordim(unsigned int i) const
324
dolfin_error("Element is scalar.");
328
inline unsigned int elementdim() const
333
inline unsigned int rank() const
338
void nodemap(int nodes[], const Cell& cell, const Mesh& mesh) const
340
nodes[0] = cell.vertexID(0);
341
nodes[1] = cell.vertexID(1);
342
nodes[2] = cell.vertexID(2);
345
void pointmap(Point points[], unsigned int components[], const AffineMap& map) const
347
points[0] = map(0.000000000000000e+00, 0.000000000000000e+00);
348
points[1] = map(1.000000000000000e+00, 0.000000000000000e+00);
349
points[2] = map(0.000000000000000e+00, 1.000000000000000e+00);
355
void vertexeval(real values[], unsigned int vertex, const real x[], const Mesh& mesh) const
357
// FIXME: Temporary fix for Lagrange elements
358
values[0] = x[vertex];
361
const FiniteElement& operator[] (unsigned int i) const
366
FiniteElement& operator[] (unsigned int i)
371
FiniteElementSpec spec() const
373
FiniteElementSpec s("Lagrange", "triangle", 1);
379
unsigned int* tensordims;
380
FiniteElement** subelements;
384
unsigned int* tensordims;
385
FiniteElement** subelements;
389
class TrialElement : public dolfin::FiniteElement
393
TrialElement() : dolfin::FiniteElement(), tensordims(0), subelements(0)
395
tensordims = new unsigned int [1];
398
subelements = new FiniteElement* [2];
399
subelements[0] = new SubElement_0();
400
subelements[1] = new SubElement_1();
405
if ( tensordims ) delete [] tensordims;
408
for (unsigned int i = 0; i < elementdim(); i++)
409
delete subelements[i];
410
delete [] subelements;
414
inline unsigned int spacedim() const
419
inline unsigned int shapedim() const
424
inline unsigned int tensordim(unsigned int i) const
426
dolfin_assert(i < 1);
427
return tensordims[i];
430
inline unsigned int elementdim() const
435
inline unsigned int rank() const
440
void nodemap(int nodes[], const Cell& cell, const Mesh& mesh) const
442
nodes[0] = cell.vertexID(0);
443
nodes[1] = cell.vertexID(1);
444
nodes[2] = cell.vertexID(2);
445
int offset = mesh.numVertices();
446
nodes[3] = offset + cell.edgeID(0);
447
nodes[4] = offset + cell.edgeID(1);
448
nodes[5] = offset + cell.edgeID(2);
449
offset = offset + mesh.numEdges();
450
nodes[6] = offset + cell.vertexID(0);
451
nodes[7] = offset + cell.vertexID(1);
452
nodes[8] = offset + cell.vertexID(2);
453
offset = offset + mesh.numVertices();
454
nodes[9] = offset + cell.edgeID(0);
455
nodes[10] = offset + cell.edgeID(1);
456
nodes[11] = offset + cell.edgeID(2);
457
offset = offset + mesh.numEdges();
458
nodes[12] = offset + cell.vertexID(0);
459
nodes[13] = offset + cell.vertexID(1);
460
nodes[14] = offset + cell.vertexID(2);
463
void pointmap(Point points[], unsigned int components[], const AffineMap& map) const
465
points[0] = map(0.000000000000000e+00, 0.000000000000000e+00);
466
points[1] = map(1.000000000000000e+00, 0.000000000000000e+00);
467
points[2] = map(0.000000000000000e+00, 1.000000000000000e+00);
468
points[3] = map(5.000000000000000e-01, 5.000000000000000e-01);
469
points[4] = map(0.000000000000000e+00, 5.000000000000000e-01);
470
points[5] = map(5.000000000000000e-01, 0.000000000000000e+00);
471
points[6] = map(0.000000000000000e+00, 0.000000000000000e+00);
472
points[7] = map(1.000000000000000e+00, 0.000000000000000e+00);
473
points[8] = map(0.000000000000000e+00, 1.000000000000000e+00);
474
points[9] = map(5.000000000000000e-01, 5.000000000000000e-01);
475
points[10] = map(0.000000000000000e+00, 5.000000000000000e-01);
476
points[11] = map(5.000000000000000e-01, 0.000000000000000e+00);
489
points[12] = map(0.000000000000000e+00, 0.000000000000000e+00);
490
points[13] = map(1.000000000000000e+00, 0.000000000000000e+00);
491
points[14] = map(0.000000000000000e+00, 1.000000000000000e+00);
497
void vertexeval(real values[], unsigned int vertex, const real x[], const Mesh& mesh) const
499
// FIXME: Temporary fix for Lagrange elements
500
values[0] = x[vertex];
501
int offset = mesh.numVertices() + mesh.numEdges();
502
values[1] = x[offset + vertex];
503
offset = offset + mesh.numVertices() + mesh.numEdges();
504
values[2] = x[offset + vertex];
507
const FiniteElement& operator[] (unsigned int i) const
509
return *subelements[i];
512
FiniteElement& operator[] (unsigned int i)
514
return *subelements[i];
517
FiniteElementSpec spec() const
519
FiniteElementSpec s("mixed");
525
class SubElement_0 : public dolfin::FiniteElement
529
SubElement_0() : dolfin::FiniteElement(), tensordims(0), subelements(0)
531
tensordims = new unsigned int [1];
534
// Element is simple, don't need to initialize subelements
539
if ( tensordims ) delete [] tensordims;
542
for (unsigned int i = 0; i < elementdim(); i++)
543
delete subelements[i];
544
delete [] subelements;
548
inline unsigned int spacedim() const
553
inline unsigned int shapedim() const
558
inline unsigned int tensordim(unsigned int i) const
560
dolfin_assert(i < 1);
561
return tensordims[i];
564
inline unsigned int elementdim() const
569
inline unsigned int rank() const
574
void nodemap(int nodes[], const Cell& cell, const Mesh& mesh) const
576
nodes[0] = cell.vertexID(0);
577
nodes[1] = cell.vertexID(1);
578
nodes[2] = cell.vertexID(2);
579
int offset = mesh.numVertices();
580
nodes[3] = offset + cell.edgeID(0);
581
nodes[4] = offset + cell.edgeID(1);
582
nodes[5] = offset + cell.edgeID(2);
583
offset = offset + mesh.numEdges();
584
nodes[6] = offset + cell.vertexID(0);
585
nodes[7] = offset + cell.vertexID(1);
586
nodes[8] = offset + cell.vertexID(2);
587
offset = offset + mesh.numVertices();
588
nodes[9] = offset + cell.edgeID(0);
589
nodes[10] = offset + cell.edgeID(1);
590
nodes[11] = offset + cell.edgeID(2);
593
void pointmap(Point points[], unsigned int components[], const AffineMap& map) const
595
points[0] = map(0.000000000000000e+00, 0.000000000000000e+00);
596
points[1] = map(1.000000000000000e+00, 0.000000000000000e+00);
597
points[2] = map(0.000000000000000e+00, 1.000000000000000e+00);
598
points[3] = map(5.000000000000000e-01, 5.000000000000000e-01);
599
points[4] = map(0.000000000000000e+00, 5.000000000000000e-01);
600
points[5] = map(5.000000000000000e-01, 0.000000000000000e+00);
601
points[6] = map(0.000000000000000e+00, 0.000000000000000e+00);
602
points[7] = map(1.000000000000000e+00, 0.000000000000000e+00);
603
points[8] = map(0.000000000000000e+00, 1.000000000000000e+00);
604
points[9] = map(5.000000000000000e-01, 5.000000000000000e-01);
605
points[10] = map(0.000000000000000e+00, 5.000000000000000e-01);
606
points[11] = map(5.000000000000000e-01, 0.000000000000000e+00);
621
void vertexeval(real values[], unsigned int vertex, const real x[], const Mesh& mesh) const
623
// FIXME: Temporary fix for Lagrange elements
624
values[0] = x[vertex];
625
int offset = mesh.numVertices() + mesh.numEdges();
626
values[1] = x[offset + vertex];
629
const FiniteElement& operator[] (unsigned int i) const
634
FiniteElement& operator[] (unsigned int i)
639
FiniteElementSpec spec() const
641
FiniteElementSpec s("Vector Lagrange", "triangle", 2, 2);
647
unsigned int* tensordims;
648
FiniteElement** subelements;
652
class SubElement_1 : public dolfin::FiniteElement
656
SubElement_1() : dolfin::FiniteElement(), tensordims(0), subelements(0)
658
// Element is scalar, don't need to initialize tensordims
660
// Element is simple, don't need to initialize subelements
665
if ( tensordims ) delete [] tensordims;
668
for (unsigned int i = 0; i < elementdim(); i++)
669
delete subelements[i];
670
delete [] subelements;
674
inline unsigned int spacedim() const
679
inline unsigned int shapedim() const
684
inline unsigned int tensordim(unsigned int i) const
686
dolfin_error("Element is scalar.");
690
inline unsigned int elementdim() const
695
inline unsigned int rank() const
700
void nodemap(int nodes[], const Cell& cell, const Mesh& mesh) const
702
nodes[0] = cell.vertexID(0);
703
nodes[1] = cell.vertexID(1);
704
nodes[2] = cell.vertexID(2);
707
void pointmap(Point points[], unsigned int components[], const AffineMap& map) const
709
points[0] = map(0.000000000000000e+00, 0.000000000000000e+00);
710
points[1] = map(1.000000000000000e+00, 0.000000000000000e+00);
711
points[2] = map(0.000000000000000e+00, 1.000000000000000e+00);
717
void vertexeval(real values[], unsigned int vertex, const real x[], const Mesh& mesh) const
719
// FIXME: Temporary fix for Lagrange elements
720
values[0] = x[vertex];
723
const FiniteElement& operator[] (unsigned int i) const
728
FiniteElement& operator[] (unsigned int i)
733
FiniteElementSpec spec() const
735
FiniteElementSpec s("Lagrange", "triangle", 1);
741
unsigned int* tensordims;
742
FiniteElement** subelements;
746
unsigned int* tensordims;
747
FiniteElement** subelements;
751
BilinearForm() : dolfin::BilinearForm(0)
753
// Create finite element for test space
754
_test = new TestElement();
756
// Create finite element for trial space
757
_trial = new TrialElement();
760
void eval(real block[], const AffineMap& map) const
762
// Compute geometry tensors
763
const real G0_0_0 = map.det*map.g00*map.g00 + map.det*map.g01*map.g01;
764
const real G0_0_1 = map.det*map.g00*map.g10 + map.det*map.g01*map.g11;
765
const real G0_1_0 = map.det*map.g10*map.g00 + map.det*map.g11*map.g01;
766
const real G0_1_1 = map.det*map.g10*map.g10 + map.det*map.g11*map.g11;
767
const real G1_0_0 = map.det*map.g00*map.g00 + map.det*map.g01*map.g01;
768
const real G1_0_1 = map.det*map.g00*map.g10 + map.det*map.g01*map.g11;
769
const real G1_1_0 = map.det*map.g10*map.g00 + map.det*map.g11*map.g01;
770
const real G1_1_1 = map.det*map.g10*map.g10 + map.det*map.g11*map.g11;
771
const real G2_0 = map.det*map.g00;
772
const real G2_1 = map.det*map.g10;
773
const real G3_0 = map.det*map.g01;
774
const real G3_1 = map.det*map.g11;
775
const real G4_0 = map.det*map.g00;
776
const real G4_1 = map.det*map.g10;
777
const real G5_0 = map.det*map.g01;
778
const real G5_1 = map.det*map.g11;
780
// Compute element tensor
781
block[0] = 4.999999999999992e-01*G0_0_0 + 4.999999999999991e-01*G0_0_1 + 4.999999999999991e-01*G0_1_0 + 4.999999999999991e-01*G0_1_1;
782
block[1] = 1.666666666666663e-01*G0_0_0 + 1.666666666666664e-01*G0_1_0;
783
block[2] = 1.666666666666665e-01*G0_0_1 + 1.666666666666665e-01*G0_1_1;
784
block[3] = 0.000000000000000e+00;
785
block[4] = -6.666666666666657e-01*G0_0_1 - 6.666666666666656e-01*G0_1_1;
786
block[5] = -6.666666666666655e-01*G0_0_0 - 6.666666666666655e-01*G0_1_0;
787
block[6] = 0.000000000000000e+00;
788
block[7] = 0.000000000000000e+00;
789
block[8] = 0.000000000000000e+00;
790
block[9] = 0.000000000000000e+00;
791
block[10] = 0.000000000000000e+00;
792
block[11] = 0.000000000000000e+00;
793
block[12] = 1.666666666666664e-01*G2_0 + 1.666666666666663e-01*G2_1;
794
block[13] = 0.000000000000000e+00;
795
block[14] = 0.000000000000000e+00;
796
block[15] = 1.666666666666663e-01*G0_0_0 + 1.666666666666664e-01*G0_0_1;
797
block[16] = 4.999999999999992e-01*G0_0_0;
798
block[17] = -1.666666666666664e-01*G0_0_1;
799
block[18] = 6.666666666666654e-01*G0_0_1;
800
block[19] = 0.000000000000000e+00;
801
block[20] = -6.666666666666654e-01*G0_0_0 - 6.666666666666656e-01*G0_0_1;
802
block[21] = 0.000000000000000e+00;
803
block[22] = 0.000000000000000e+00;
804
block[23] = 0.000000000000000e+00;
805
block[24] = 0.000000000000000e+00;
806
block[25] = 0.000000000000000e+00;
807
block[26] = 0.000000000000000e+00;
808
block[27] = 0.000000000000000e+00;
809
block[28] = -1.666666666666664e-01*G2_0;
810
block[29] = 0.000000000000000e+00;
811
block[30] = 1.666666666666665e-01*G0_1_0 + 1.666666666666665e-01*G0_1_1;
812
block[31] = -1.666666666666664e-01*G0_1_0;
813
block[32] = 4.999999999999991e-01*G0_1_1;
814
block[33] = 6.666666666666653e-01*G0_1_0;
815
block[34] = -6.666666666666654e-01*G0_1_0 - 6.666666666666656e-01*G0_1_1;
816
block[35] = 0.000000000000000e+00;
817
block[36] = 0.000000000000000e+00;
818
block[37] = 0.000000000000000e+00;
819
block[38] = 0.000000000000000e+00;
820
block[39] = 0.000000000000000e+00;
821
block[40] = 0.000000000000000e+00;
822
block[41] = 0.000000000000000e+00;
823
block[42] = 0.000000000000000e+00;
824
block[43] = 0.000000000000000e+00;
825
block[44] = -1.666666666666664e-01*G2_1;
826
block[45] = 0.000000000000000e+00;
827
block[46] = 6.666666666666654e-01*G0_1_0;
828
block[47] = 6.666666666666653e-01*G0_0_1;
829
block[48] = 1.333333333333330e+00*G0_0_0 + 6.666666666666652e-01*G0_0_1 + 6.666666666666652e-01*G0_1_0 + 1.333333333333330e+00*G0_1_1;
830
block[49] = -1.333333333333331e+00*G0_0_0 - 6.666666666666656e-01*G0_0_1 - 6.666666666666653e-01*G0_1_0;
831
block[50] = -6.666666666666652e-01*G0_0_1 - 6.666666666666653e-01*G0_1_0 - 1.333333333333331e+00*G0_1_1;
832
block[51] = 0.000000000000000e+00;
833
block[52] = 0.000000000000000e+00;
834
block[53] = 0.000000000000000e+00;
835
block[54] = 0.000000000000000e+00;
836
block[55] = 0.000000000000000e+00;
837
block[56] = 0.000000000000000e+00;
838
block[57] = -1.666666666666663e-01*G2_0 - 1.666666666666664e-01*G2_1;
839
block[58] = -1.666666666666663e-01*G2_0 - 3.333333333333327e-01*G2_1;
840
block[59] = -3.333333333333326e-01*G2_0 - 1.666666666666663e-01*G2_1;
841
block[60] = -6.666666666666656e-01*G0_1_0 - 6.666666666666656e-01*G0_1_1;
842
block[61] = 0.000000000000000e+00;
843
block[62] = -6.666666666666654e-01*G0_0_1 - 6.666666666666659e-01*G0_1_1;
844
block[63] = -1.333333333333331e+00*G0_0_0 - 6.666666666666653e-01*G0_0_1 - 6.666666666666656e-01*G0_1_0;
845
block[64] = 1.333333333333331e+00*G0_0_0 + 6.666666666666656e-01*G0_0_1 + 6.666666666666657e-01*G0_1_0 + 1.333333333333331e+00*G0_1_1;
846
block[65] = 6.666666666666654e-01*G0_0_1 + 6.666666666666655e-01*G0_1_0;
847
block[66] = 0.000000000000000e+00;
848
block[67] = 0.000000000000000e+00;
849
block[68] = 0.000000000000000e+00;
850
block[69] = 0.000000000000000e+00;
851
block[70] = 0.000000000000000e+00;
852
block[71] = 0.000000000000000e+00;
853
block[72] = 1.666666666666663e-01*G2_0 - 1.666666666666664e-01*G2_1;
854
block[73] = 1.666666666666664e-01*G2_0;
855
block[74] = 3.333333333333327e-01*G2_0 + 1.666666666666664e-01*G2_1;
856
block[75] = -6.666666666666655e-01*G0_0_0 - 6.666666666666656e-01*G0_0_1;
857
block[76] = -6.666666666666654e-01*G0_0_0 - 6.666666666666656e-01*G0_1_0;
858
block[77] = 0.000000000000000e+00;
859
block[78] = -6.666666666666652e-01*G0_0_1 - 6.666666666666653e-01*G0_1_0 - 1.333333333333331e+00*G0_1_1;
860
block[79] = 6.666666666666657e-01*G0_0_1 + 6.666666666666654e-01*G0_1_0;
861
block[80] = 1.333333333333331e+00*G0_0_0 + 6.666666666666656e-01*G0_0_1 + 6.666666666666656e-01*G0_1_0 + 1.333333333333331e+00*G0_1_1;
862
block[81] = 0.000000000000000e+00;
863
block[82] = 0.000000000000000e+00;
864
block[83] = 0.000000000000000e+00;
865
block[84] = 0.000000000000000e+00;
866
block[85] = 0.000000000000000e+00;
867
block[86] = 0.000000000000000e+00;
868
block[87] = -1.666666666666664e-01*G2_0 + 1.666666666666664e-01*G2_1;
869
block[88] = 1.666666666666664e-01*G2_0 + 3.333333333333328e-01*G2_1;
870
block[89] = 1.666666666666664e-01*G2_1;
871
block[90] = 0.000000000000000e+00;
872
block[91] = 0.000000000000000e+00;
873
block[92] = 0.000000000000000e+00;
874
block[93] = 0.000000000000000e+00;
875
block[94] = 0.000000000000000e+00;
876
block[95] = 0.000000000000000e+00;
877
block[96] = 4.999999999999991e-01*G1_0_0 + 4.999999999999991e-01*G1_0_1 + 4.999999999999991e-01*G1_1_0 + 4.999999999999991e-01*G1_1_1;
878
block[97] = 1.666666666666664e-01*G1_0_0 + 1.666666666666664e-01*G1_1_0;
879
block[98] = 1.666666666666666e-01*G1_0_1 + 1.666666666666665e-01*G1_1_1;
880
block[99] = 0.000000000000000e+00;
881
block[100] = -6.666666666666656e-01*G1_0_1 - 6.666666666666656e-01*G1_1_1;
882
block[101] = -6.666666666666655e-01*G1_0_0 - 6.666666666666655e-01*G1_1_0;
883
block[102] = 1.666666666666663e-01*G3_0 + 1.666666666666663e-01*G3_1;
884
block[103] = 0.000000000000000e+00;
885
block[104] = 0.000000000000000e+00;
886
block[105] = 0.000000000000000e+00;
887
block[106] = 0.000000000000000e+00;
888
block[107] = 0.000000000000000e+00;
889
block[108] = 0.000000000000000e+00;
890
block[109] = 0.000000000000000e+00;
891
block[110] = 0.000000000000000e+00;
892
block[111] = 1.666666666666663e-01*G1_0_0 + 1.666666666666664e-01*G1_0_1;
893
block[112] = 4.999999999999992e-01*G1_0_0;
894
block[113] = -1.666666666666664e-01*G1_0_1;
895
block[114] = 6.666666666666654e-01*G1_0_1;
896
block[115] = 0.000000000000000e+00;
897
block[116] = -6.666666666666654e-01*G1_0_0 - 6.666666666666656e-01*G1_0_1;
898
block[117] = 0.000000000000000e+00;
899
block[118] = -1.666666666666664e-01*G3_0;
900
block[119] = 0.000000000000000e+00;
901
block[120] = 0.000000000000000e+00;
902
block[121] = 0.000000000000000e+00;
903
block[122] = 0.000000000000000e+00;
904
block[123] = 0.000000000000000e+00;
905
block[124] = 0.000000000000000e+00;
906
block[125] = 0.000000000000000e+00;
907
block[126] = 1.666666666666666e-01*G1_1_0 + 1.666666666666665e-01*G1_1_1;
908
block[127] = -1.666666666666664e-01*G1_1_0;
909
block[128] = 4.999999999999991e-01*G1_1_1;
910
block[129] = 6.666666666666653e-01*G1_1_0;
911
block[130] = -6.666666666666654e-01*G1_1_0 - 6.666666666666656e-01*G1_1_1;
912
block[131] = 0.000000000000000e+00;
913
block[132] = 0.000000000000000e+00;
914
block[133] = 0.000000000000000e+00;
915
block[134] = -1.666666666666664e-01*G3_1;
916
block[135] = 0.000000000000000e+00;
917
block[136] = 0.000000000000000e+00;
918
block[137] = 0.000000000000000e+00;
919
block[138] = 0.000000000000000e+00;
920
block[139] = 0.000000000000000e+00;
921
block[140] = 0.000000000000000e+00;
922
block[141] = 0.000000000000000e+00;
923
block[142] = 6.666666666666654e-01*G1_1_0;
924
block[143] = 6.666666666666653e-01*G1_0_1;
925
block[144] = 1.333333333333330e+00*G1_0_0 + 6.666666666666652e-01*G1_0_1 + 6.666666666666652e-01*G1_1_0 + 1.333333333333330e+00*G1_1_1;
926
block[145] = -1.333333333333331e+00*G1_0_0 - 6.666666666666656e-01*G1_0_1 - 6.666666666666653e-01*G1_1_0;
927
block[146] = -6.666666666666652e-01*G1_0_1 - 6.666666666666653e-01*G1_1_0 - 1.333333333333331e+00*G1_1_1;
928
block[147] = -1.666666666666663e-01*G3_0 - 1.666666666666664e-01*G3_1;
929
block[148] = -1.666666666666663e-01*G3_0 - 3.333333333333327e-01*G3_1;
930
block[149] = -3.333333333333326e-01*G3_0 - 1.666666666666663e-01*G3_1;
931
block[150] = 0.000000000000000e+00;
932
block[151] = 0.000000000000000e+00;
933
block[152] = 0.000000000000000e+00;
934
block[153] = 0.000000000000000e+00;
935
block[154] = 0.000000000000000e+00;
936
block[155] = 0.000000000000000e+00;
937
block[156] = -6.666666666666656e-01*G1_1_0 - 6.666666666666656e-01*G1_1_1;
938
block[157] = 0.000000000000000e+00;
939
block[158] = -6.666666666666654e-01*G1_0_1 - 6.666666666666659e-01*G1_1_1;
940
block[159] = -1.333333333333331e+00*G1_0_0 - 6.666666666666653e-01*G1_0_1 - 6.666666666666656e-01*G1_1_0;
941
block[160] = 1.333333333333331e+00*G1_0_0 + 6.666666666666656e-01*G1_0_1 + 6.666666666666657e-01*G1_1_0 + 1.333333333333331e+00*G1_1_1;
942
block[161] = 6.666666666666654e-01*G1_0_1 + 6.666666666666655e-01*G1_1_0;
943
block[162] = 1.666666666666663e-01*G3_0 - 1.666666666666664e-01*G3_1;
944
block[163] = 1.666666666666664e-01*G3_0;
945
block[164] = 3.333333333333327e-01*G3_0 + 1.666666666666664e-01*G3_1;
946
block[165] = 0.000000000000000e+00;
947
block[166] = 0.000000000000000e+00;
948
block[167] = 0.000000000000000e+00;
949
block[168] = 0.000000000000000e+00;
950
block[169] = 0.000000000000000e+00;
951
block[170] = 0.000000000000000e+00;
952
block[171] = -6.666666666666656e-01*G1_0_0 - 6.666666666666656e-01*G1_0_1;
953
block[172] = -6.666666666666654e-01*G1_0_0 - 6.666666666666656e-01*G1_1_0;
954
block[173] = 0.000000000000000e+00;
955
block[174] = -6.666666666666652e-01*G1_0_1 - 6.666666666666653e-01*G1_1_0 - 1.333333333333331e+00*G1_1_1;
956
block[175] = 6.666666666666657e-01*G1_0_1 + 6.666666666666654e-01*G1_1_0;
957
block[176] = 1.333333333333331e+00*G1_0_0 + 6.666666666666656e-01*G1_0_1 + 6.666666666666656e-01*G1_1_0 + 1.333333333333331e+00*G1_1_1;
958
block[177] = -1.666666666666664e-01*G3_0 + 1.666666666666664e-01*G3_1;
959
block[178] = 1.666666666666664e-01*G3_0 + 3.333333333333328e-01*G3_1;
960
block[179] = 1.666666666666664e-01*G3_1;
961
block[180] = -1.666666666666664e-01*G4_0 - 1.666666666666663e-01*G4_1;
962
block[181] = 0.000000000000000e+00;
963
block[182] = 0.000000000000000e+00;
964
block[183] = 1.666666666666663e-01*G4_0 + 1.666666666666664e-01*G4_1;
965
block[184] = -1.666666666666663e-01*G4_0 + 1.666666666666664e-01*G4_1;
966
block[185] = 1.666666666666664e-01*G4_0 - 1.666666666666664e-01*G4_1;
967
block[186] = -1.666666666666663e-01*G5_0 - 1.666666666666663e-01*G5_1;
968
block[187] = 0.000000000000000e+00;
969
block[188] = 0.000000000000000e+00;
970
block[189] = 1.666666666666663e-01*G5_0 + 1.666666666666664e-01*G5_1;
971
block[190] = -1.666666666666663e-01*G5_0 + 1.666666666666664e-01*G5_1;
972
block[191] = 1.666666666666664e-01*G5_0 - 1.666666666666664e-01*G5_1;
973
block[192] = 0.000000000000000e+00;
974
block[193] = 0.000000000000000e+00;
975
block[194] = 0.000000000000000e+00;
976
block[195] = 0.000000000000000e+00;
977
block[196] = 1.666666666666664e-01*G4_0;
978
block[197] = 0.000000000000000e+00;
979
block[198] = 1.666666666666663e-01*G4_0 + 3.333333333333326e-01*G4_1;
980
block[199] = -1.666666666666664e-01*G4_0;
981
block[200] = -1.666666666666664e-01*G4_0 - 3.333333333333328e-01*G4_1;
982
block[201] = 0.000000000000000e+00;
983
block[202] = 1.666666666666664e-01*G5_0;
984
block[203] = 0.000000000000000e+00;
985
block[204] = 1.666666666666663e-01*G5_0 + 3.333333333333326e-01*G5_1;
986
block[205] = -1.666666666666664e-01*G5_0;
987
block[206] = -1.666666666666664e-01*G5_0 - 3.333333333333328e-01*G5_1;
988
block[207] = 0.000000000000000e+00;
989
block[208] = 0.000000000000000e+00;
990
block[209] = 0.000000000000000e+00;
991
block[210] = 0.000000000000000e+00;
992
block[211] = 0.000000000000000e+00;
993
block[212] = 1.666666666666663e-01*G4_1;
994
block[213] = 3.333333333333326e-01*G4_0 + 1.666666666666663e-01*G4_1;
995
block[214] = -3.333333333333327e-01*G4_0 - 1.666666666666664e-01*G4_1;
996
block[215] = -1.666666666666664e-01*G4_1;
997
block[216] = 0.000000000000000e+00;
998
block[217] = 0.000000000000000e+00;
999
block[218] = 1.666666666666663e-01*G5_1;
1000
block[219] = 3.333333333333326e-01*G5_0 + 1.666666666666663e-01*G5_1;
1001
block[220] = -3.333333333333327e-01*G5_0 - 1.666666666666664e-01*G5_1;
1002
block[221] = -1.666666666666664e-01*G5_1;
1003
block[222] = 0.000000000000000e+00;
1004
block[223] = 0.000000000000000e+00;
1005
block[224] = 0.000000000000000e+00;
35
bool interior_contribution() const;
37
void eval(real block[], const AffineMap& map, real det) const;
39
bool boundary_contribution() const;
41
void eval(real block[], const AffineMap& map, real det, unsigned int facet) const;
43
bool interior_boundary_contribution() const;
45
void eval(real block[], const AffineMap& map0, const AffineMap& map1, real det, unsigned int facet0, unsigned int facet1, unsigned int alignment) const;
49
class BilinearForm::TestElement : public dolfin::FiniteElement
53
TestElement() : dolfin::FiniteElement(), tensordims(0), subelements(0)
55
tensordims = new unsigned int [1];
58
subelements = new FiniteElement* [2];
59
subelements[0] = new SubElement_0();
60
subelements[1] = new SubElement_1();
65
if ( tensordims ) delete [] tensordims;
68
for (unsigned int i = 0; i < elementdim(); i++)
69
delete subelements[i];
70
delete [] subelements;
74
inline unsigned int spacedim() const
79
inline unsigned int shapedim() const
84
inline unsigned int tensordim(unsigned int i) const
90
inline unsigned int elementdim() const
95
inline unsigned int rank() const
100
void nodemap(int nodes[], const Cell& cell, const Mesh& mesh) const
102
nodes[0] = cell.entities(0)[0];
103
nodes[1] = cell.entities(0)[1];
104
nodes[2] = cell.entities(0)[2];
105
int offset = mesh.topology().size(0);
106
nodes[3] = offset + cell.entities(1)[0];
107
nodes[4] = offset + cell.entities(1)[1];
108
nodes[5] = offset + cell.entities(1)[2];
109
offset = offset + mesh.topology().size(1);
110
nodes[6] = offset + cell.entities(0)[0];
111
nodes[7] = offset + cell.entities(0)[1];
112
nodes[8] = offset + cell.entities(0)[2];
113
offset = offset + mesh.topology().size(0);
114
nodes[9] = offset + cell.entities(1)[0];
115
nodes[10] = offset + cell.entities(1)[1];
116
nodes[11] = offset + cell.entities(1)[2];
117
offset = offset + mesh.topology().size(1);
118
nodes[12] = offset + cell.entities(0)[0];
119
nodes[13] = offset + cell.entities(0)[1];
120
nodes[14] = offset + cell.entities(0)[2];
123
void pointmap(Point points[], unsigned int components[], const AffineMap& map) const
125
points[0] = map(0.000000000000000e+00, 0.000000000000000e+00);
126
points[1] = map(1.000000000000000e+00, 0.000000000000000e+00);
127
points[2] = map(0.000000000000000e+00, 1.000000000000000e+00);
128
points[3] = map(5.000000000000000e-01, 5.000000000000000e-01);
129
points[4] = map(0.000000000000000e+00, 5.000000000000000e-01);
130
points[5] = map(5.000000000000000e-01, 0.000000000000000e+00);
131
points[6] = map(0.000000000000000e+00, 0.000000000000000e+00);
132
points[7] = map(1.000000000000000e+00, 0.000000000000000e+00);
133
points[8] = map(0.000000000000000e+00, 1.000000000000000e+00);
134
points[9] = map(5.000000000000000e-01, 5.000000000000000e-01);
135
points[10] = map(0.000000000000000e+00, 5.000000000000000e-01);
136
points[11] = map(5.000000000000000e-01, 0.000000000000000e+00);
149
points[12] = map(0.000000000000000e+00, 0.000000000000000e+00);
150
points[13] = map(1.000000000000000e+00, 0.000000000000000e+00);
151
points[14] = map(0.000000000000000e+00, 1.000000000000000e+00);
157
void vertexeval(uint vertex_nodes[], unsigned int vertex, const Mesh& mesh) const
159
// FIXME: Temporary fix for Lagrange elements
160
vertex_nodes[0] = vertex;
161
int offset = mesh.topology().size(0) + mesh.topology().size(1);
162
vertex_nodes[1] = offset + vertex;
163
offset = offset + mesh.topology().size(0) + mesh.topology().size(1);
164
vertex_nodes[2] = offset + vertex;
167
const FiniteElement& operator[] (unsigned int i) const
169
return *subelements[i];
172
FiniteElement& operator[] (unsigned int i)
174
return *subelements[i];
177
FiniteElementSpec spec() const
179
FiniteElementSpec s("mixed");
185
class SubElement_0 : public dolfin::FiniteElement
189
SubElement_0() : dolfin::FiniteElement(), tensordims(0), subelements(0)
191
tensordims = new unsigned int [1];
194
// Element is simple, don't need to initialize subelements
199
if ( tensordims ) delete [] tensordims;
202
for (unsigned int i = 0; i < elementdim(); i++)
203
delete subelements[i];
204
delete [] subelements;
208
inline unsigned int spacedim() const
213
inline unsigned int shapedim() const
218
inline unsigned int tensordim(unsigned int i) const
220
dolfin_assert(i < 1);
221
return tensordims[i];
224
inline unsigned int elementdim() const
229
inline unsigned int rank() const
234
void nodemap(int nodes[], const Cell& cell, const Mesh& mesh) const
236
nodes[0] = cell.entities(0)[0];
237
nodes[1] = cell.entities(0)[1];
238
nodes[2] = cell.entities(0)[2];
239
int offset = mesh.topology().size(0);
240
nodes[3] = offset + cell.entities(1)[0];
241
nodes[4] = offset + cell.entities(1)[1];
242
nodes[5] = offset + cell.entities(1)[2];
243
offset = offset + mesh.topology().size(1);
244
nodes[6] = offset + cell.entities(0)[0];
245
nodes[7] = offset + cell.entities(0)[1];
246
nodes[8] = offset + cell.entities(0)[2];
247
offset = offset + mesh.topology().size(0);
248
nodes[9] = offset + cell.entities(1)[0];
249
nodes[10] = offset + cell.entities(1)[1];
250
nodes[11] = offset + cell.entities(1)[2];
253
void pointmap(Point points[], unsigned int components[], const AffineMap& map) const
255
points[0] = map(0.000000000000000e+00, 0.000000000000000e+00);
256
points[1] = map(1.000000000000000e+00, 0.000000000000000e+00);
257
points[2] = map(0.000000000000000e+00, 1.000000000000000e+00);
258
points[3] = map(5.000000000000000e-01, 5.000000000000000e-01);
259
points[4] = map(0.000000000000000e+00, 5.000000000000000e-01);
260
points[5] = map(5.000000000000000e-01, 0.000000000000000e+00);
261
points[6] = map(0.000000000000000e+00, 0.000000000000000e+00);
262
points[7] = map(1.000000000000000e+00, 0.000000000000000e+00);
263
points[8] = map(0.000000000000000e+00, 1.000000000000000e+00);
264
points[9] = map(5.000000000000000e-01, 5.000000000000000e-01);
265
points[10] = map(0.000000000000000e+00, 5.000000000000000e-01);
266
points[11] = map(5.000000000000000e-01, 0.000000000000000e+00);
281
void vertexeval(uint vertex_nodes[], unsigned int vertex, const Mesh& mesh) const
283
// FIXME: Temporary fix for Lagrange elements
284
vertex_nodes[0] = vertex;
285
int offset = mesh.topology().size(0) + mesh.topology().size(1);
286
vertex_nodes[1] = offset + vertex;
289
const FiniteElement& operator[] (unsigned int i) const
294
FiniteElement& operator[] (unsigned int i)
299
FiniteElementSpec spec() const
301
FiniteElementSpec s("Vector Lagrange", "triangle", 2, 2);
307
unsigned int* tensordims;
308
FiniteElement** subelements;
312
class SubElement_1 : public dolfin::FiniteElement
316
SubElement_1() : dolfin::FiniteElement(), tensordims(0), subelements(0)
318
// Element is scalar, don't need to initialize tensordims
320
// Element is simple, don't need to initialize subelements
325
if ( tensordims ) delete [] tensordims;
328
for (unsigned int i = 0; i < elementdim(); i++)
329
delete subelements[i];
330
delete [] subelements;
334
inline unsigned int spacedim() const
339
inline unsigned int shapedim() const
344
inline unsigned int tensordim(unsigned int i) const
346
dolfin_error("Element is scalar.");
350
inline unsigned int elementdim() const
355
inline unsigned int rank() const
360
void nodemap(int nodes[], const Cell& cell, const Mesh& mesh) const
362
nodes[0] = cell.entities(0)[0];
363
nodes[1] = cell.entities(0)[1];
364
nodes[2] = cell.entities(0)[2];
367
void pointmap(Point points[], unsigned int components[], const AffineMap& map) const
369
points[0] = map(0.000000000000000e+00, 0.000000000000000e+00);
370
points[1] = map(1.000000000000000e+00, 0.000000000000000e+00);
371
points[2] = map(0.000000000000000e+00, 1.000000000000000e+00);
377
void vertexeval(uint vertex_nodes[], unsigned int vertex, const Mesh& mesh) const
379
// FIXME: Temporary fix for Lagrange elements
380
vertex_nodes[0] = vertex;
383
const FiniteElement& operator[] (unsigned int i) const
388
FiniteElement& operator[] (unsigned int i)
393
FiniteElementSpec spec() const
395
FiniteElementSpec s("Lagrange", "triangle", 1);
401
unsigned int* tensordims;
402
FiniteElement** subelements;
406
unsigned int* tensordims;
407
FiniteElement** subelements;
411
class BilinearForm::TrialElement : public dolfin::FiniteElement
415
TrialElement() : dolfin::FiniteElement(), tensordims(0), subelements(0)
417
tensordims = new unsigned int [1];
420
subelements = new FiniteElement* [2];
421
subelements[0] = new SubElement_0();
422
subelements[1] = new SubElement_1();
427
if ( tensordims ) delete [] tensordims;
430
for (unsigned int i = 0; i < elementdim(); i++)
431
delete subelements[i];
432
delete [] subelements;
436
inline unsigned int spacedim() const
441
inline unsigned int shapedim() const
446
inline unsigned int tensordim(unsigned int i) const
448
dolfin_assert(i < 1);
449
return tensordims[i];
452
inline unsigned int elementdim() const
457
inline unsigned int rank() const
462
void nodemap(int nodes[], const Cell& cell, const Mesh& mesh) const
464
nodes[0] = cell.entities(0)[0];
465
nodes[1] = cell.entities(0)[1];
466
nodes[2] = cell.entities(0)[2];
467
int offset = mesh.topology().size(0);
468
nodes[3] = offset + cell.entities(1)[0];
469
nodes[4] = offset + cell.entities(1)[1];
470
nodes[5] = offset + cell.entities(1)[2];
471
offset = offset + mesh.topology().size(1);
472
nodes[6] = offset + cell.entities(0)[0];
473
nodes[7] = offset + cell.entities(0)[1];
474
nodes[8] = offset + cell.entities(0)[2];
475
offset = offset + mesh.topology().size(0);
476
nodes[9] = offset + cell.entities(1)[0];
477
nodes[10] = offset + cell.entities(1)[1];
478
nodes[11] = offset + cell.entities(1)[2];
479
offset = offset + mesh.topology().size(1);
480
nodes[12] = offset + cell.entities(0)[0];
481
nodes[13] = offset + cell.entities(0)[1];
482
nodes[14] = offset + cell.entities(0)[2];
485
void pointmap(Point points[], unsigned int components[], const AffineMap& map) const
487
points[0] = map(0.000000000000000e+00, 0.000000000000000e+00);
488
points[1] = map(1.000000000000000e+00, 0.000000000000000e+00);
489
points[2] = map(0.000000000000000e+00, 1.000000000000000e+00);
490
points[3] = map(5.000000000000000e-01, 5.000000000000000e-01);
491
points[4] = map(0.000000000000000e+00, 5.000000000000000e-01);
492
points[5] = map(5.000000000000000e-01, 0.000000000000000e+00);
493
points[6] = map(0.000000000000000e+00, 0.000000000000000e+00);
494
points[7] = map(1.000000000000000e+00, 0.000000000000000e+00);
495
points[8] = map(0.000000000000000e+00, 1.000000000000000e+00);
496
points[9] = map(5.000000000000000e-01, 5.000000000000000e-01);
497
points[10] = map(0.000000000000000e+00, 5.000000000000000e-01);
498
points[11] = map(5.000000000000000e-01, 0.000000000000000e+00);
511
points[12] = map(0.000000000000000e+00, 0.000000000000000e+00);
512
points[13] = map(1.000000000000000e+00, 0.000000000000000e+00);
513
points[14] = map(0.000000000000000e+00, 1.000000000000000e+00);
519
void vertexeval(uint vertex_nodes[], unsigned int vertex, const Mesh& mesh) const
521
// FIXME: Temporary fix for Lagrange elements
522
vertex_nodes[0] = vertex;
523
int offset = mesh.topology().size(0) + mesh.topology().size(1);
524
vertex_nodes[1] = offset + vertex;
525
offset = offset + mesh.topology().size(0) + mesh.topology().size(1);
526
vertex_nodes[2] = offset + vertex;
529
const FiniteElement& operator[] (unsigned int i) const
531
return *subelements[i];
534
FiniteElement& operator[] (unsigned int i)
536
return *subelements[i];
539
FiniteElementSpec spec() const
541
FiniteElementSpec s("mixed");
547
class SubElement_0 : public dolfin::FiniteElement
551
SubElement_0() : dolfin::FiniteElement(), tensordims(0), subelements(0)
553
tensordims = new unsigned int [1];
556
// Element is simple, don't need to initialize subelements
561
if ( tensordims ) delete [] tensordims;
564
for (unsigned int i = 0; i < elementdim(); i++)
565
delete subelements[i];
566
delete [] subelements;
570
inline unsigned int spacedim() const
575
inline unsigned int shapedim() const
580
inline unsigned int tensordim(unsigned int i) const
582
dolfin_assert(i < 1);
583
return tensordims[i];
586
inline unsigned int elementdim() const
591
inline unsigned int rank() const
596
void nodemap(int nodes[], const Cell& cell, const Mesh& mesh) const
598
nodes[0] = cell.entities(0)[0];
599
nodes[1] = cell.entities(0)[1];
600
nodes[2] = cell.entities(0)[2];
601
int offset = mesh.topology().size(0);
602
nodes[3] = offset + cell.entities(1)[0];
603
nodes[4] = offset + cell.entities(1)[1];
604
nodes[5] = offset + cell.entities(1)[2];
605
offset = offset + mesh.topology().size(1);
606
nodes[6] = offset + cell.entities(0)[0];
607
nodes[7] = offset + cell.entities(0)[1];
608
nodes[8] = offset + cell.entities(0)[2];
609
offset = offset + mesh.topology().size(0);
610
nodes[9] = offset + cell.entities(1)[0];
611
nodes[10] = offset + cell.entities(1)[1];
612
nodes[11] = offset + cell.entities(1)[2];
615
void pointmap(Point points[], unsigned int components[], const AffineMap& map) const
617
points[0] = map(0.000000000000000e+00, 0.000000000000000e+00);
618
points[1] = map(1.000000000000000e+00, 0.000000000000000e+00);
619
points[2] = map(0.000000000000000e+00, 1.000000000000000e+00);
620
points[3] = map(5.000000000000000e-01, 5.000000000000000e-01);
621
points[4] = map(0.000000000000000e+00, 5.000000000000000e-01);
622
points[5] = map(5.000000000000000e-01, 0.000000000000000e+00);
623
points[6] = map(0.000000000000000e+00, 0.000000000000000e+00);
624
points[7] = map(1.000000000000000e+00, 0.000000000000000e+00);
625
points[8] = map(0.000000000000000e+00, 1.000000000000000e+00);
626
points[9] = map(5.000000000000000e-01, 5.000000000000000e-01);
627
points[10] = map(0.000000000000000e+00, 5.000000000000000e-01);
628
points[11] = map(5.000000000000000e-01, 0.000000000000000e+00);
643
void vertexeval(uint vertex_nodes[], unsigned int vertex, const Mesh& mesh) const
645
// FIXME: Temporary fix for Lagrange elements
646
vertex_nodes[0] = vertex;
647
int offset = mesh.topology().size(0) + mesh.topology().size(1);
648
vertex_nodes[1] = offset + vertex;
651
const FiniteElement& operator[] (unsigned int i) const
656
FiniteElement& operator[] (unsigned int i)
661
FiniteElementSpec spec() const
663
FiniteElementSpec s("Vector Lagrange", "triangle", 2, 2);
669
unsigned int* tensordims;
670
FiniteElement** subelements;
674
class SubElement_1 : public dolfin::FiniteElement
678
SubElement_1() : dolfin::FiniteElement(), tensordims(0), subelements(0)
680
// Element is scalar, don't need to initialize tensordims
682
// Element is simple, don't need to initialize subelements
687
if ( tensordims ) delete [] tensordims;
690
for (unsigned int i = 0; i < elementdim(); i++)
691
delete subelements[i];
692
delete [] subelements;
696
inline unsigned int spacedim() const
701
inline unsigned int shapedim() const
706
inline unsigned int tensordim(unsigned int i) const
708
dolfin_error("Element is scalar.");
712
inline unsigned int elementdim() const
717
inline unsigned int rank() const
722
void nodemap(int nodes[], const Cell& cell, const Mesh& mesh) const
724
nodes[0] = cell.entities(0)[0];
725
nodes[1] = cell.entities(0)[1];
726
nodes[2] = cell.entities(0)[2];
729
void pointmap(Point points[], unsigned int components[], const AffineMap& map) const
731
points[0] = map(0.000000000000000e+00, 0.000000000000000e+00);
732
points[1] = map(1.000000000000000e+00, 0.000000000000000e+00);
733
points[2] = map(0.000000000000000e+00, 1.000000000000000e+00);
739
void vertexeval(uint vertex_nodes[], unsigned int vertex, const Mesh& mesh) const
741
// FIXME: Temporary fix for Lagrange elements
742
vertex_nodes[0] = vertex;
745
const FiniteElement& operator[] (unsigned int i) const
750
FiniteElement& operator[] (unsigned int i)
755
FiniteElementSpec spec() const
757
FiniteElementSpec s("Lagrange", "triangle", 1);
763
unsigned int* tensordims;
764
FiniteElement** subelements;
768
unsigned int* tensordims;
769
FiniteElement** subelements;
773
BilinearForm::BilinearForm() : dolfin::BilinearForm(0)
775
// Create finite element for test space
776
_test = new TestElement();
778
// Create finite element for trial space
779
_trial = new TrialElement();
782
// Contribution from the interior
783
bool BilinearForm::interior_contribution() const { return true; }
785
void BilinearForm::eval(real block[], const AffineMap& map, real det) const
787
// Compute geometry tensors
788
const real G0_0_0 = det*map.g00*map.g00 + det*map.g01*map.g01;
789
const real G0_0_1 = det*map.g00*map.g10 + det*map.g01*map.g11;
790
const real G0_1_0 = det*map.g10*map.g00 + det*map.g11*map.g01;
791
const real G0_1_1 = det*map.g10*map.g10 + det*map.g11*map.g11;
792
const real G1_0_0 = det*map.g00*map.g00 + det*map.g01*map.g01;
793
const real G1_0_1 = det*map.g00*map.g10 + det*map.g01*map.g11;
794
const real G1_1_0 = det*map.g10*map.g00 + det*map.g11*map.g01;
795
const real G1_1_1 = det*map.g10*map.g10 + det*map.g11*map.g11;
796
const real G2_0 = det*map.g00;
797
const real G2_1 = det*map.g10;
798
const real G3_0 = det*map.g01;
799
const real G3_1 = det*map.g11;
800
const real G4_0 = det*map.g00;
801
const real G4_1 = det*map.g10;
802
const real G5_0 = det*map.g01;
803
const real G5_1 = det*map.g11;
805
// Compute element tensor
806
block[0] = 4.999999999999992e-01*G0_0_0 + 4.999999999999991e-01*G0_0_1 + 4.999999999999991e-01*G0_1_0 + 4.999999999999991e-01*G0_1_1;
807
block[1] = 1.666666666666663e-01*G0_0_0 + 1.666666666666664e-01*G0_1_0;
808
block[2] = 1.666666666666665e-01*G0_0_1 + 1.666666666666665e-01*G0_1_1;
809
block[3] = 0.000000000000000e+00;
810
block[4] = -6.666666666666657e-01*G0_0_1 - 6.666666666666656e-01*G0_1_1;
811
block[5] = -6.666666666666655e-01*G0_0_0 - 6.666666666666655e-01*G0_1_0;
812
block[6] = 0.000000000000000e+00;
813
block[7] = 0.000000000000000e+00;
814
block[8] = 0.000000000000000e+00;
815
block[9] = 0.000000000000000e+00;
816
block[10] = 0.000000000000000e+00;
817
block[11] = 0.000000000000000e+00;
818
block[12] = 1.666666666666664e-01*G2_0 + 1.666666666666663e-01*G2_1;
819
block[13] = 0.000000000000000e+00;
820
block[14] = 0.000000000000000e+00;
821
block[15] = 1.666666666666663e-01*G0_0_0 + 1.666666666666664e-01*G0_0_1;
822
block[16] = 4.999999999999992e-01*G0_0_0;
823
block[17] = -1.666666666666664e-01*G0_0_1;
824
block[18] = 6.666666666666654e-01*G0_0_1;
825
block[19] = 0.000000000000000e+00;
826
block[20] = -6.666666666666654e-01*G0_0_0 - 6.666666666666656e-01*G0_0_1;
827
block[21] = 0.000000000000000e+00;
828
block[22] = 0.000000000000000e+00;
829
block[23] = 0.000000000000000e+00;
830
block[24] = 0.000000000000000e+00;
831
block[25] = 0.000000000000000e+00;
832
block[26] = 0.000000000000000e+00;
833
block[27] = 0.000000000000000e+00;
834
block[28] = -1.666666666666664e-01*G2_0;
835
block[29] = 0.000000000000000e+00;
836
block[30] = 1.666666666666665e-01*G0_1_0 + 1.666666666666665e-01*G0_1_1;
837
block[31] = -1.666666666666664e-01*G0_1_0;
838
block[32] = 4.999999999999991e-01*G0_1_1;
839
block[33] = 6.666666666666653e-01*G0_1_0;
840
block[34] = -6.666666666666654e-01*G0_1_0 - 6.666666666666656e-01*G0_1_1;
841
block[35] = 0.000000000000000e+00;
842
block[36] = 0.000000000000000e+00;
843
block[37] = 0.000000000000000e+00;
844
block[38] = 0.000000000000000e+00;
845
block[39] = 0.000000000000000e+00;
846
block[40] = 0.000000000000000e+00;
847
block[41] = 0.000000000000000e+00;
848
block[42] = 0.000000000000000e+00;
849
block[43] = 0.000000000000000e+00;
850
block[44] = -1.666666666666664e-01*G2_1;
851
block[45] = 0.000000000000000e+00;
852
block[46] = 6.666666666666654e-01*G0_1_0;
853
block[47] = 6.666666666666653e-01*G0_0_1;
854
block[48] = 1.333333333333330e+00*G0_0_0 + 6.666666666666652e-01*G0_0_1 + 6.666666666666652e-01*G0_1_0 + 1.333333333333330e+00*G0_1_1;
855
block[49] = -1.333333333333331e+00*G0_0_0 - 6.666666666666656e-01*G0_0_1 - 6.666666666666653e-01*G0_1_0;
856
block[50] = -6.666666666666652e-01*G0_0_1 - 6.666666666666653e-01*G0_1_0 - 1.333333333333331e+00*G0_1_1;
857
block[51] = 0.000000000000000e+00;
858
block[52] = 0.000000000000000e+00;
859
block[53] = 0.000000000000000e+00;
860
block[54] = 0.000000000000000e+00;
861
block[55] = 0.000000000000000e+00;
862
block[56] = 0.000000000000000e+00;
863
block[57] = -1.666666666666663e-01*G2_0 - 1.666666666666664e-01*G2_1;
864
block[58] = -1.666666666666663e-01*G2_0 - 3.333333333333327e-01*G2_1;
865
block[59] = -3.333333333333326e-01*G2_0 - 1.666666666666663e-01*G2_1;
866
block[60] = -6.666666666666656e-01*G0_1_0 - 6.666666666666656e-01*G0_1_1;
867
block[61] = 0.000000000000000e+00;
868
block[62] = -6.666666666666654e-01*G0_0_1 - 6.666666666666659e-01*G0_1_1;
869
block[63] = -1.333333333333331e+00*G0_0_0 - 6.666666666666653e-01*G0_0_1 - 6.666666666666656e-01*G0_1_0;
870
block[64] = 1.333333333333331e+00*G0_0_0 + 6.666666666666656e-01*G0_0_1 + 6.666666666666657e-01*G0_1_0 + 1.333333333333331e+00*G0_1_1;
871
block[65] = 6.666666666666654e-01*G0_0_1 + 6.666666666666655e-01*G0_1_0;
872
block[66] = 0.000000000000000e+00;
873
block[67] = 0.000000000000000e+00;
874
block[68] = 0.000000000000000e+00;
875
block[69] = 0.000000000000000e+00;
876
block[70] = 0.000000000000000e+00;
877
block[71] = 0.000000000000000e+00;
878
block[72] = 1.666666666666663e-01*G2_0 - 1.666666666666664e-01*G2_1;
879
block[73] = 1.666666666666664e-01*G2_0;
880
block[74] = 3.333333333333327e-01*G2_0 + 1.666666666666664e-01*G2_1;
881
block[75] = -6.666666666666655e-01*G0_0_0 - 6.666666666666656e-01*G0_0_1;
882
block[76] = -6.666666666666654e-01*G0_0_0 - 6.666666666666656e-01*G0_1_0;
883
block[77] = 0.000000000000000e+00;
884
block[78] = -6.666666666666652e-01*G0_0_1 - 6.666666666666653e-01*G0_1_0 - 1.333333333333331e+00*G0_1_1;
885
block[79] = 6.666666666666657e-01*G0_0_1 + 6.666666666666654e-01*G0_1_0;
886
block[80] = 1.333333333333331e+00*G0_0_0 + 6.666666666666656e-01*G0_0_1 + 6.666666666666656e-01*G0_1_0 + 1.333333333333331e+00*G0_1_1;
887
block[81] = 0.000000000000000e+00;
888
block[82] = 0.000000000000000e+00;
889
block[83] = 0.000000000000000e+00;
890
block[84] = 0.000000000000000e+00;
891
block[85] = 0.000000000000000e+00;
892
block[86] = 0.000000000000000e+00;
893
block[87] = -1.666666666666664e-01*G2_0 + 1.666666666666664e-01*G2_1;
894
block[88] = 1.666666666666664e-01*G2_0 + 3.333333333333328e-01*G2_1;
895
block[89] = 1.666666666666664e-01*G2_1;
896
block[90] = 0.000000000000000e+00;
897
block[91] = 0.000000000000000e+00;
898
block[92] = 0.000000000000000e+00;
899
block[93] = 0.000000000000000e+00;
900
block[94] = 0.000000000000000e+00;
901
block[95] = 0.000000000000000e+00;
902
block[96] = 4.999999999999991e-01*G1_0_0 + 4.999999999999991e-01*G1_0_1 + 4.999999999999991e-01*G1_1_0 + 4.999999999999991e-01*G1_1_1;
903
block[97] = 1.666666666666664e-01*G1_0_0 + 1.666666666666664e-01*G1_1_0;
904
block[98] = 1.666666666666666e-01*G1_0_1 + 1.666666666666665e-01*G1_1_1;
905
block[99] = 0.000000000000000e+00;
906
block[100] = -6.666666666666656e-01*G1_0_1 - 6.666666666666656e-01*G1_1_1;
907
block[101] = -6.666666666666655e-01*G1_0_0 - 6.666666666666655e-01*G1_1_0;
908
block[102] = 1.666666666666663e-01*G3_0 + 1.666666666666663e-01*G3_1;
909
block[103] = 0.000000000000000e+00;
910
block[104] = 0.000000000000000e+00;
911
block[105] = 0.000000000000000e+00;
912
block[106] = 0.000000000000000e+00;
913
block[107] = 0.000000000000000e+00;
914
block[108] = 0.000000000000000e+00;
915
block[109] = 0.000000000000000e+00;
916
block[110] = 0.000000000000000e+00;
917
block[111] = 1.666666666666663e-01*G1_0_0 + 1.666666666666664e-01*G1_0_1;
918
block[112] = 4.999999999999992e-01*G1_0_0;
919
block[113] = -1.666666666666664e-01*G1_0_1;
920
block[114] = 6.666666666666654e-01*G1_0_1;
921
block[115] = 0.000000000000000e+00;
922
block[116] = -6.666666666666654e-01*G1_0_0 - 6.666666666666656e-01*G1_0_1;
923
block[117] = 0.000000000000000e+00;
924
block[118] = -1.666666666666664e-01*G3_0;
925
block[119] = 0.000000000000000e+00;
926
block[120] = 0.000000000000000e+00;
927
block[121] = 0.000000000000000e+00;
928
block[122] = 0.000000000000000e+00;
929
block[123] = 0.000000000000000e+00;
930
block[124] = 0.000000000000000e+00;
931
block[125] = 0.000000000000000e+00;
932
block[126] = 1.666666666666666e-01*G1_1_0 + 1.666666666666665e-01*G1_1_1;
933
block[127] = -1.666666666666664e-01*G1_1_0;
934
block[128] = 4.999999999999991e-01*G1_1_1;
935
block[129] = 6.666666666666653e-01*G1_1_0;
936
block[130] = -6.666666666666654e-01*G1_1_0 - 6.666666666666656e-01*G1_1_1;
937
block[131] = 0.000000000000000e+00;
938
block[132] = 0.000000000000000e+00;
939
block[133] = 0.000000000000000e+00;
940
block[134] = -1.666666666666664e-01*G3_1;
941
block[135] = 0.000000000000000e+00;
942
block[136] = 0.000000000000000e+00;
943
block[137] = 0.000000000000000e+00;
944
block[138] = 0.000000000000000e+00;
945
block[139] = 0.000000000000000e+00;
946
block[140] = 0.000000000000000e+00;
947
block[141] = 0.000000000000000e+00;
948
block[142] = 6.666666666666654e-01*G1_1_0;
949
block[143] = 6.666666666666653e-01*G1_0_1;
950
block[144] = 1.333333333333330e+00*G1_0_0 + 6.666666666666652e-01*G1_0_1 + 6.666666666666652e-01*G1_1_0 + 1.333333333333330e+00*G1_1_1;
951
block[145] = -1.333333333333331e+00*G1_0_0 - 6.666666666666656e-01*G1_0_1 - 6.666666666666653e-01*G1_1_0;
952
block[146] = -6.666666666666652e-01*G1_0_1 - 6.666666666666653e-01*G1_1_0 - 1.333333333333331e+00*G1_1_1;
953
block[147] = -1.666666666666663e-01*G3_0 - 1.666666666666664e-01*G3_1;
954
block[148] = -1.666666666666663e-01*G3_0 - 3.333333333333327e-01*G3_1;
955
block[149] = -3.333333333333326e-01*G3_0 - 1.666666666666663e-01*G3_1;
956
block[150] = 0.000000000000000e+00;
957
block[151] = 0.000000000000000e+00;
958
block[152] = 0.000000000000000e+00;
959
block[153] = 0.000000000000000e+00;
960
block[154] = 0.000000000000000e+00;
961
block[155] = 0.000000000000000e+00;
962
block[156] = -6.666666666666656e-01*G1_1_0 - 6.666666666666656e-01*G1_1_1;
963
block[157] = 0.000000000000000e+00;
964
block[158] = -6.666666666666654e-01*G1_0_1 - 6.666666666666659e-01*G1_1_1;
965
block[159] = -1.333333333333331e+00*G1_0_0 - 6.666666666666653e-01*G1_0_1 - 6.666666666666656e-01*G1_1_0;
966
block[160] = 1.333333333333331e+00*G1_0_0 + 6.666666666666656e-01*G1_0_1 + 6.666666666666657e-01*G1_1_0 + 1.333333333333331e+00*G1_1_1;
967
block[161] = 6.666666666666654e-01*G1_0_1 + 6.666666666666655e-01*G1_1_0;
968
block[162] = 1.666666666666663e-01*G3_0 - 1.666666666666664e-01*G3_1;
969
block[163] = 1.666666666666664e-01*G3_0;
970
block[164] = 3.333333333333327e-01*G3_0 + 1.666666666666664e-01*G3_1;
971
block[165] = 0.000000000000000e+00;
972
block[166] = 0.000000000000000e+00;
973
block[167] = 0.000000000000000e+00;
974
block[168] = 0.000000000000000e+00;
975
block[169] = 0.000000000000000e+00;
976
block[170] = 0.000000000000000e+00;
977
block[171] = -6.666666666666656e-01*G1_0_0 - 6.666666666666656e-01*G1_0_1;
978
block[172] = -6.666666666666654e-01*G1_0_0 - 6.666666666666656e-01*G1_1_0;
979
block[173] = 0.000000000000000e+00;
980
block[174] = -6.666666666666652e-01*G1_0_1 - 6.666666666666653e-01*G1_1_0 - 1.333333333333331e+00*G1_1_1;
981
block[175] = 6.666666666666657e-01*G1_0_1 + 6.666666666666654e-01*G1_1_0;
982
block[176] = 1.333333333333331e+00*G1_0_0 + 6.666666666666656e-01*G1_0_1 + 6.666666666666656e-01*G1_1_0 + 1.333333333333331e+00*G1_1_1;
983
block[177] = -1.666666666666664e-01*G3_0 + 1.666666666666664e-01*G3_1;
984
block[178] = 1.666666666666664e-01*G3_0 + 3.333333333333328e-01*G3_1;
985
block[179] = 1.666666666666664e-01*G3_1;
986
block[180] = -1.666666666666664e-01*G4_0 - 1.666666666666663e-01*G4_1;
987
block[181] = 0.000000000000000e+00;
988
block[182] = 0.000000000000000e+00;
989
block[183] = 1.666666666666663e-01*G4_0 + 1.666666666666664e-01*G4_1;
990
block[184] = -1.666666666666663e-01*G4_0 + 1.666666666666664e-01*G4_1;
991
block[185] = 1.666666666666664e-01*G4_0 - 1.666666666666664e-01*G4_1;
992
block[186] = -1.666666666666663e-01*G5_0 - 1.666666666666663e-01*G5_1;
993
block[187] = 0.000000000000000e+00;
994
block[188] = 0.000000000000000e+00;
995
block[189] = 1.666666666666663e-01*G5_0 + 1.666666666666664e-01*G5_1;
996
block[190] = -1.666666666666663e-01*G5_0 + 1.666666666666664e-01*G5_1;
997
block[191] = 1.666666666666664e-01*G5_0 - 1.666666666666664e-01*G5_1;
998
block[192] = 0.000000000000000e+00;
999
block[193] = 0.000000000000000e+00;
1000
block[194] = 0.000000000000000e+00;
1001
block[195] = 0.000000000000000e+00;
1002
block[196] = 1.666666666666664e-01*G4_0;
1003
block[197] = 0.000000000000000e+00;
1004
block[198] = 1.666666666666663e-01*G4_0 + 3.333333333333326e-01*G4_1;
1005
block[199] = -1.666666666666664e-01*G4_0;
1006
block[200] = -1.666666666666664e-01*G4_0 - 3.333333333333328e-01*G4_1;
1007
block[201] = 0.000000000000000e+00;
1008
block[202] = 1.666666666666664e-01*G5_0;
1009
block[203] = 0.000000000000000e+00;
1010
block[204] = 1.666666666666663e-01*G5_0 + 3.333333333333326e-01*G5_1;
1011
block[205] = -1.666666666666664e-01*G5_0;
1012
block[206] = -1.666666666666664e-01*G5_0 - 3.333333333333328e-01*G5_1;
1013
block[207] = 0.000000000000000e+00;
1014
block[208] = 0.000000000000000e+00;
1015
block[209] = 0.000000000000000e+00;
1016
block[210] = 0.000000000000000e+00;
1017
block[211] = 0.000000000000000e+00;
1018
block[212] = 1.666666666666663e-01*G4_1;
1019
block[213] = 3.333333333333326e-01*G4_0 + 1.666666666666663e-01*G4_1;
1020
block[214] = -3.333333333333327e-01*G4_0 - 1.666666666666664e-01*G4_1;
1021
block[215] = -1.666666666666664e-01*G4_1;
1022
block[216] = 0.000000000000000e+00;
1023
block[217] = 0.000000000000000e+00;
1024
block[218] = 1.666666666666663e-01*G5_1;
1025
block[219] = 3.333333333333326e-01*G5_0 + 1.666666666666663e-01*G5_1;
1026
block[220] = -3.333333333333327e-01*G5_0 - 1.666666666666664e-01*G5_1;
1027
block[221] = -1.666666666666664e-01*G5_1;
1028
block[222] = 0.000000000000000e+00;
1029
block[223] = 0.000000000000000e+00;
1030
block[224] = 0.000000000000000e+00;
1033
// No contribution from the boundary
1034
bool BilinearForm::boundary_contribution() const { return false; }
1036
void BilinearForm::eval(real block[], const AffineMap& map, real det, unsigned int facet) const {}
1038
// No contribution from interior boundaries
1039
bool BilinearForm::interior_boundary_contribution() const { return false; }
1041
void BilinearForm::eval(real block[], const AffineMap& map0, const AffineMap& map1, real det, unsigned int facet0, unsigned int facet1, unsigned int alignment) const {}
1010
1043
/// This class contains the form to be evaluated, including
1011
1044
/// contributions from the interior and boundary of the domain.
1013
1046
class LinearForm : public dolfin::LinearForm
1017
class TestElement : public dolfin::FiniteElement
1021
TestElement() : dolfin::FiniteElement(), tensordims(0), subelements(0)
1023
tensordims = new unsigned int [1];
1026
subelements = new FiniteElement* [2];
1027
subelements[0] = new SubElement_0();
1028
subelements[1] = new SubElement_1();
1033
if ( tensordims ) delete [] tensordims;
1036
for (unsigned int i = 0; i < elementdim(); i++)
1037
delete subelements[i];
1038
delete [] subelements;
1042
inline unsigned int spacedim() const
1047
inline unsigned int shapedim() const
1052
inline unsigned int tensordim(unsigned int i) const
1054
dolfin_assert(i < 1);
1055
return tensordims[i];
1058
inline unsigned int elementdim() const
1063
inline unsigned int rank() const
1068
void nodemap(int nodes[], const Cell& cell, const Mesh& mesh) const
1070
nodes[0] = cell.vertexID(0);
1071
nodes[1] = cell.vertexID(1);
1072
nodes[2] = cell.vertexID(2);
1073
int offset = mesh.numVertices();
1074
nodes[3] = offset + cell.edgeID(0);
1075
nodes[4] = offset + cell.edgeID(1);
1076
nodes[5] = offset + cell.edgeID(2);
1077
offset = offset + mesh.numEdges();
1078
nodes[6] = offset + cell.vertexID(0);
1079
nodes[7] = offset + cell.vertexID(1);
1080
nodes[8] = offset + cell.vertexID(2);
1081
offset = offset + mesh.numVertices();
1082
nodes[9] = offset + cell.edgeID(0);
1083
nodes[10] = offset + cell.edgeID(1);
1084
nodes[11] = offset + cell.edgeID(2);
1085
offset = offset + mesh.numEdges();
1086
nodes[12] = offset + cell.vertexID(0);
1087
nodes[13] = offset + cell.vertexID(1);
1088
nodes[14] = offset + cell.vertexID(2);
1091
void pointmap(Point points[], unsigned int components[], const AffineMap& map) const
1093
points[0] = map(0.000000000000000e+00, 0.000000000000000e+00);
1094
points[1] = map(1.000000000000000e+00, 0.000000000000000e+00);
1095
points[2] = map(0.000000000000000e+00, 1.000000000000000e+00);
1096
points[3] = map(5.000000000000000e-01, 5.000000000000000e-01);
1097
points[4] = map(0.000000000000000e+00, 5.000000000000000e-01);
1098
points[5] = map(5.000000000000000e-01, 0.000000000000000e+00);
1099
points[6] = map(0.000000000000000e+00, 0.000000000000000e+00);
1100
points[7] = map(1.000000000000000e+00, 0.000000000000000e+00);
1101
points[8] = map(0.000000000000000e+00, 1.000000000000000e+00);
1102
points[9] = map(5.000000000000000e-01, 5.000000000000000e-01);
1103
points[10] = map(0.000000000000000e+00, 5.000000000000000e-01);
1104
points[11] = map(5.000000000000000e-01, 0.000000000000000e+00);
1117
points[12] = map(0.000000000000000e+00, 0.000000000000000e+00);
1118
points[13] = map(1.000000000000000e+00, 0.000000000000000e+00);
1119
points[14] = map(0.000000000000000e+00, 1.000000000000000e+00);
1125
void vertexeval(real values[], unsigned int vertex, const real x[], const Mesh& mesh) const
1127
// FIXME: Temporary fix for Lagrange elements
1128
values[0] = x[vertex];
1129
int offset = mesh.numVertices() + mesh.numEdges();
1130
values[1] = x[offset + vertex];
1131
offset = offset + mesh.numVertices() + mesh.numEdges();
1132
values[2] = x[offset + vertex];
1135
const FiniteElement& operator[] (unsigned int i) const
1137
return *subelements[i];
1140
FiniteElement& operator[] (unsigned int i)
1142
return *subelements[i];
1145
FiniteElementSpec spec() const
1147
FiniteElementSpec s("mixed");
1153
class SubElement_0 : public dolfin::FiniteElement
1157
SubElement_0() : dolfin::FiniteElement(), tensordims(0), subelements(0)
1159
tensordims = new unsigned int [1];
1162
// Element is simple, don't need to initialize subelements
1167
if ( tensordims ) delete [] tensordims;
1170
for (unsigned int i = 0; i < elementdim(); i++)
1171
delete subelements[i];
1172
delete [] subelements;
1176
inline unsigned int spacedim() const
1181
inline unsigned int shapedim() const
1186
inline unsigned int tensordim(unsigned int i) const
1188
dolfin_assert(i < 1);
1189
return tensordims[i];
1192
inline unsigned int elementdim() const
1197
inline unsigned int rank() const
1202
void nodemap(int nodes[], const Cell& cell, const Mesh& mesh) const
1204
nodes[0] = cell.vertexID(0);
1205
nodes[1] = cell.vertexID(1);
1206
nodes[2] = cell.vertexID(2);
1207
int offset = mesh.numVertices();
1208
nodes[3] = offset + cell.edgeID(0);
1209
nodes[4] = offset + cell.edgeID(1);
1210
nodes[5] = offset + cell.edgeID(2);
1211
offset = offset + mesh.numEdges();
1212
nodes[6] = offset + cell.vertexID(0);
1213
nodes[7] = offset + cell.vertexID(1);
1214
nodes[8] = offset + cell.vertexID(2);
1215
offset = offset + mesh.numVertices();
1216
nodes[9] = offset + cell.edgeID(0);
1217
nodes[10] = offset + cell.edgeID(1);
1218
nodes[11] = offset + cell.edgeID(2);
1221
void pointmap(Point points[], unsigned int components[], const AffineMap& map) const
1223
points[0] = map(0.000000000000000e+00, 0.000000000000000e+00);
1224
points[1] = map(1.000000000000000e+00, 0.000000000000000e+00);
1225
points[2] = map(0.000000000000000e+00, 1.000000000000000e+00);
1226
points[3] = map(5.000000000000000e-01, 5.000000000000000e-01);
1227
points[4] = map(0.000000000000000e+00, 5.000000000000000e-01);
1228
points[5] = map(5.000000000000000e-01, 0.000000000000000e+00);
1229
points[6] = map(0.000000000000000e+00, 0.000000000000000e+00);
1230
points[7] = map(1.000000000000000e+00, 0.000000000000000e+00);
1231
points[8] = map(0.000000000000000e+00, 1.000000000000000e+00);
1232
points[9] = map(5.000000000000000e-01, 5.000000000000000e-01);
1233
points[10] = map(0.000000000000000e+00, 5.000000000000000e-01);
1234
points[11] = map(5.000000000000000e-01, 0.000000000000000e+00);
1249
void vertexeval(real values[], unsigned int vertex, const real x[], const Mesh& mesh) const
1251
// FIXME: Temporary fix for Lagrange elements
1252
values[0] = x[vertex];
1253
int offset = mesh.numVertices() + mesh.numEdges();
1254
values[1] = x[offset + vertex];
1257
const FiniteElement& operator[] (unsigned int i) const
1262
FiniteElement& operator[] (unsigned int i)
1267
FiniteElementSpec spec() const
1269
FiniteElementSpec s("Vector Lagrange", "triangle", 2, 2);
1275
unsigned int* tensordims;
1276
FiniteElement** subelements;
1280
class SubElement_1 : public dolfin::FiniteElement
1284
SubElement_1() : dolfin::FiniteElement(), tensordims(0), subelements(0)
1286
// Element is scalar, don't need to initialize tensordims
1288
// Element is simple, don't need to initialize subelements
1293
if ( tensordims ) delete [] tensordims;
1296
for (unsigned int i = 0; i < elementdim(); i++)
1297
delete subelements[i];
1298
delete [] subelements;
1302
inline unsigned int spacedim() const
1307
inline unsigned int shapedim() const
1312
inline unsigned int tensordim(unsigned int i) const
1314
dolfin_error("Element is scalar.");
1318
inline unsigned int elementdim() const
1323
inline unsigned int rank() const
1328
void nodemap(int nodes[], const Cell& cell, const Mesh& mesh) const
1330
nodes[0] = cell.vertexID(0);
1331
nodes[1] = cell.vertexID(1);
1332
nodes[2] = cell.vertexID(2);
1335
void pointmap(Point points[], unsigned int components[], const AffineMap& map) const
1337
points[0] = map(0.000000000000000e+00, 0.000000000000000e+00);
1338
points[1] = map(1.000000000000000e+00, 0.000000000000000e+00);
1339
points[2] = map(0.000000000000000e+00, 1.000000000000000e+00);
1345
void vertexeval(real values[], unsigned int vertex, const real x[], const Mesh& mesh) const
1347
// FIXME: Temporary fix for Lagrange elements
1348
values[0] = x[vertex];
1351
const FiniteElement& operator[] (unsigned int i) const
1356
FiniteElement& operator[] (unsigned int i)
1361
FiniteElementSpec spec() const
1363
FiniteElementSpec s("Lagrange", "triangle", 1);
1369
unsigned int* tensordims;
1370
FiniteElement** subelements;
1374
unsigned int* tensordims;
1375
FiniteElement** subelements;
1379
class FunctionElement_0 : public dolfin::FiniteElement
1383
FunctionElement_0() : dolfin::FiniteElement(), tensordims(0), subelements(0)
1385
tensordims = new unsigned int [1];
1388
// Element is simple, don't need to initialize subelements
1391
~FunctionElement_0()
1393
if ( tensordims ) delete [] tensordims;
1396
for (unsigned int i = 0; i < elementdim(); i++)
1397
delete subelements[i];
1398
delete [] subelements;
1402
inline unsigned int spacedim() const
1407
inline unsigned int shapedim() const
1412
inline unsigned int tensordim(unsigned int i) const
1414
dolfin_assert(i < 1);
1415
return tensordims[i];
1418
inline unsigned int elementdim() const
1423
inline unsigned int rank() const
1428
void nodemap(int nodes[], const Cell& cell, const Mesh& mesh) const
1430
nodes[0] = cell.vertexID(0);
1431
nodes[1] = cell.vertexID(1);
1432
nodes[2] = cell.vertexID(2);
1433
int offset = mesh.numVertices();
1434
nodes[3] = offset + cell.edgeID(0);
1435
nodes[4] = offset + cell.edgeID(1);
1436
nodes[5] = offset + cell.edgeID(2);
1437
offset = offset + mesh.numEdges();
1438
nodes[6] = offset + cell.vertexID(0);
1439
nodes[7] = offset + cell.vertexID(1);
1440
nodes[8] = offset + cell.vertexID(2);
1441
offset = offset + mesh.numVertices();
1442
nodes[9] = offset + cell.edgeID(0);
1443
nodes[10] = offset + cell.edgeID(1);
1444
nodes[11] = offset + cell.edgeID(2);
1447
void pointmap(Point points[], unsigned int components[], const AffineMap& map) const
1449
points[0] = map(0.000000000000000e+00, 0.000000000000000e+00);
1450
points[1] = map(1.000000000000000e+00, 0.000000000000000e+00);
1451
points[2] = map(0.000000000000000e+00, 1.000000000000000e+00);
1452
points[3] = map(5.000000000000000e-01, 5.000000000000000e-01);
1453
points[4] = map(0.000000000000000e+00, 5.000000000000000e-01);
1454
points[5] = map(5.000000000000000e-01, 0.000000000000000e+00);
1455
points[6] = map(0.000000000000000e+00, 0.000000000000000e+00);
1456
points[7] = map(1.000000000000000e+00, 0.000000000000000e+00);
1457
points[8] = map(0.000000000000000e+00, 1.000000000000000e+00);
1458
points[9] = map(5.000000000000000e-01, 5.000000000000000e-01);
1459
points[10] = map(0.000000000000000e+00, 5.000000000000000e-01);
1460
points[11] = map(5.000000000000000e-01, 0.000000000000000e+00);
1475
void vertexeval(real values[], unsigned int vertex, const real x[], const Mesh& mesh) const
1477
// FIXME: Temporary fix for Lagrange elements
1478
values[0] = x[vertex];
1479
int offset = mesh.numVertices() + mesh.numEdges();
1480
values[1] = x[offset + vertex];
1483
const FiniteElement& operator[] (unsigned int i) const
1488
FiniteElement& operator[] (unsigned int i)
1493
FiniteElementSpec spec() const
1495
FiniteElementSpec s("Vector Lagrange", "triangle", 2, 2);
1501
unsigned int* tensordims;
1502
FiniteElement** subelements;
1506
LinearForm(Function& w0) : dolfin::LinearForm(1)
1508
// Create finite element for test space
1509
_test = new TestElement();
1512
add(w0, new FunctionElement_0());
1515
void eval(real block[], const AffineMap& map) const
1517
// Compute coefficients
1518
const real c0_0 = c[0][0];
1519
const real c0_1 = c[0][1];
1520
const real c0_2 = c[0][2];
1521
const real c0_3 = c[0][3];
1522
const real c0_4 = c[0][4];
1523
const real c0_5 = c[0][5];
1524
const real c0_6 = c[0][6];
1525
const real c0_7 = c[0][7];
1526
const real c0_8 = c[0][8];
1527
const real c0_9 = c[0][9];
1528
const real c0_10 = c[0][10];
1529
const real c0_11 = c[0][11];
1531
// Compute geometry tensors
1532
const real G0_0 = map.det*c0_0;
1533
const real G0_1 = map.det*c0_1;
1534
const real G0_2 = map.det*c0_2;
1535
const real G0_3 = map.det*c0_3;
1536
const real G0_4 = map.det*c0_4;
1537
const real G0_5 = map.det*c0_5;
1538
const real G1_6 = map.det*c0_6;
1539
const real G1_7 = map.det*c0_7;
1540
const real G1_8 = map.det*c0_8;
1541
const real G1_9 = map.det*c0_9;
1542
const real G1_10 = map.det*c0_10;
1543
const real G1_11 = map.det*c0_11;
1545
// Compute element tensor
1546
block[0] = 1.666666666666665e-02*G0_0 - 2.777777777777774e-03*G0_1 - 2.777777777777775e-03*G0_2 - 1.111111111111110e-02*G0_3;
1547
block[1] = -2.777777777777774e-03*G0_0 + 1.666666666666665e-02*G0_1 - 2.777777777777776e-03*G0_2 - 1.111111111111111e-02*G0_4;
1548
block[2] = -2.777777777777775e-03*G0_0 - 2.777777777777776e-03*G0_1 + 1.666666666666666e-02*G0_2 - 1.111111111111111e-02*G0_5;
1549
block[3] = -1.111111111111110e-02*G0_0 + 8.888888888888882e-02*G0_3 + 4.444444444444443e-02*G0_4 + 4.444444444444443e-02*G0_5;
1550
block[4] = -1.111111111111111e-02*G0_1 + 4.444444444444443e-02*G0_3 + 8.888888888888884e-02*G0_4 + 4.444444444444442e-02*G0_5;
1551
block[5] = -1.111111111111111e-02*G0_2 + 4.444444444444443e-02*G0_3 + 4.444444444444443e-02*G0_4 + 8.888888888888882e-02*G0_5;
1552
block[6] = 1.666666666666665e-02*G1_6 - 2.777777777777774e-03*G1_7 - 2.777777777777774e-03*G1_8 - 1.111111111111109e-02*G1_9;
1553
block[7] = -2.777777777777774e-03*G1_6 + 1.666666666666665e-02*G1_7 - 2.777777777777775e-03*G1_8 - 1.111111111111111e-02*G1_10;
1554
block[8] = -2.777777777777774e-03*G1_6 - 2.777777777777775e-03*G1_7 + 1.666666666666666e-02*G1_8 - 1.111111111111111e-02*G1_11;
1555
block[9] = -1.111111111111109e-02*G1_6 + 8.888888888888882e-02*G1_9 + 4.444444444444443e-02*G1_10 + 4.444444444444443e-02*G1_11;
1556
block[10] = -1.111111111111111e-02*G1_7 + 4.444444444444443e-02*G1_9 + 8.888888888888884e-02*G1_10 + 4.444444444444442e-02*G1_11;
1557
block[11] = -1.111111111111111e-02*G1_8 + 4.444444444444443e-02*G1_9 + 4.444444444444443e-02*G1_10 + 8.888888888888882e-02*G1_11;
1558
block[12] = 0.000000000000000e+00;
1559
block[13] = 0.000000000000000e+00;
1560
block[14] = 0.000000000000000e+00;
1052
class FunctionElement_0;
1054
LinearForm(Function& w0);
1057
bool interior_contribution() const;
1059
void eval(real block[], const AffineMap& map, real det) const;
1061
bool boundary_contribution() const;
1063
void eval(real block[], const AffineMap& map, real det, unsigned int facet) const;
1065
bool interior_boundary_contribution() const;
1067
void eval(real block[], const AffineMap& map0, const AffineMap& map1, real det, unsigned int facet0, unsigned int facet1, unsigned int alignment) const;
1071
class LinearForm::TestElement : public dolfin::FiniteElement
1075
TestElement() : dolfin::FiniteElement(), tensordims(0), subelements(0)
1077
tensordims = new unsigned int [1];
1080
subelements = new FiniteElement* [2];
1081
subelements[0] = new SubElement_0();
1082
subelements[1] = new SubElement_1();
1087
if ( tensordims ) delete [] tensordims;
1090
for (unsigned int i = 0; i < elementdim(); i++)
1091
delete subelements[i];
1092
delete [] subelements;
1096
inline unsigned int spacedim() const
1101
inline unsigned int shapedim() const
1106
inline unsigned int tensordim(unsigned int i) const
1108
dolfin_assert(i < 1);
1109
return tensordims[i];
1112
inline unsigned int elementdim() const
1117
inline unsigned int rank() const
1122
void nodemap(int nodes[], const Cell& cell, const Mesh& mesh) const
1124
nodes[0] = cell.entities(0)[0];
1125
nodes[1] = cell.entities(0)[1];
1126
nodes[2] = cell.entities(0)[2];
1127
int offset = mesh.topology().size(0);
1128
nodes[3] = offset + cell.entities(1)[0];
1129
nodes[4] = offset + cell.entities(1)[1];
1130
nodes[5] = offset + cell.entities(1)[2];
1131
offset = offset + mesh.topology().size(1);
1132
nodes[6] = offset + cell.entities(0)[0];
1133
nodes[7] = offset + cell.entities(0)[1];
1134
nodes[8] = offset + cell.entities(0)[2];
1135
offset = offset + mesh.topology().size(0);
1136
nodes[9] = offset + cell.entities(1)[0];
1137
nodes[10] = offset + cell.entities(1)[1];
1138
nodes[11] = offset + cell.entities(1)[2];
1139
offset = offset + mesh.topology().size(1);
1140
nodes[12] = offset + cell.entities(0)[0];
1141
nodes[13] = offset + cell.entities(0)[1];
1142
nodes[14] = offset + cell.entities(0)[2];
1145
void pointmap(Point points[], unsigned int components[], const AffineMap& map) const
1147
points[0] = map(0.000000000000000e+00, 0.000000000000000e+00);
1148
points[1] = map(1.000000000000000e+00, 0.000000000000000e+00);
1149
points[2] = map(0.000000000000000e+00, 1.000000000000000e+00);
1150
points[3] = map(5.000000000000000e-01, 5.000000000000000e-01);
1151
points[4] = map(0.000000000000000e+00, 5.000000000000000e-01);
1152
points[5] = map(5.000000000000000e-01, 0.000000000000000e+00);
1153
points[6] = map(0.000000000000000e+00, 0.000000000000000e+00);
1154
points[7] = map(1.000000000000000e+00, 0.000000000000000e+00);
1155
points[8] = map(0.000000000000000e+00, 1.000000000000000e+00);
1156
points[9] = map(5.000000000000000e-01, 5.000000000000000e-01);
1157
points[10] = map(0.000000000000000e+00, 5.000000000000000e-01);
1158
points[11] = map(5.000000000000000e-01, 0.000000000000000e+00);
1171
points[12] = map(0.000000000000000e+00, 0.000000000000000e+00);
1172
points[13] = map(1.000000000000000e+00, 0.000000000000000e+00);
1173
points[14] = map(0.000000000000000e+00, 1.000000000000000e+00);
1179
void vertexeval(uint vertex_nodes[], unsigned int vertex, const Mesh& mesh) const
1181
// FIXME: Temporary fix for Lagrange elements
1182
vertex_nodes[0] = vertex;
1183
int offset = mesh.topology().size(0) + mesh.topology().size(1);
1184
vertex_nodes[1] = offset + vertex;
1185
offset = offset + mesh.topology().size(0) + mesh.topology().size(1);
1186
vertex_nodes[2] = offset + vertex;
1189
const FiniteElement& operator[] (unsigned int i) const
1191
return *subelements[i];
1194
FiniteElement& operator[] (unsigned int i)
1196
return *subelements[i];
1199
FiniteElementSpec spec() const
1201
FiniteElementSpec s("mixed");
1207
class SubElement_0 : public dolfin::FiniteElement
1211
SubElement_0() : dolfin::FiniteElement(), tensordims(0), subelements(0)
1213
tensordims = new unsigned int [1];
1216
// Element is simple, don't need to initialize subelements
1221
if ( tensordims ) delete [] tensordims;
1224
for (unsigned int i = 0; i < elementdim(); i++)
1225
delete subelements[i];
1226
delete [] subelements;
1230
inline unsigned int spacedim() const
1235
inline unsigned int shapedim() const
1240
inline unsigned int tensordim(unsigned int i) const
1242
dolfin_assert(i < 1);
1243
return tensordims[i];
1246
inline unsigned int elementdim() const
1251
inline unsigned int rank() const
1256
void nodemap(int nodes[], const Cell& cell, const Mesh& mesh) const
1258
nodes[0] = cell.entities(0)[0];
1259
nodes[1] = cell.entities(0)[1];
1260
nodes[2] = cell.entities(0)[2];
1261
int offset = mesh.topology().size(0);
1262
nodes[3] = offset + cell.entities(1)[0];
1263
nodes[4] = offset + cell.entities(1)[1];
1264
nodes[5] = offset + cell.entities(1)[2];
1265
offset = offset + mesh.topology().size(1);
1266
nodes[6] = offset + cell.entities(0)[0];
1267
nodes[7] = offset + cell.entities(0)[1];
1268
nodes[8] = offset + cell.entities(0)[2];
1269
offset = offset + mesh.topology().size(0);
1270
nodes[9] = offset + cell.entities(1)[0];
1271
nodes[10] = offset + cell.entities(1)[1];
1272
nodes[11] = offset + cell.entities(1)[2];
1275
void pointmap(Point points[], unsigned int components[], const AffineMap& map) const
1277
points[0] = map(0.000000000000000e+00, 0.000000000000000e+00);
1278
points[1] = map(1.000000000000000e+00, 0.000000000000000e+00);
1279
points[2] = map(0.000000000000000e+00, 1.000000000000000e+00);
1280
points[3] = map(5.000000000000000e-01, 5.000000000000000e-01);
1281
points[4] = map(0.000000000000000e+00, 5.000000000000000e-01);
1282
points[5] = map(5.000000000000000e-01, 0.000000000000000e+00);
1283
points[6] = map(0.000000000000000e+00, 0.000000000000000e+00);
1284
points[7] = map(1.000000000000000e+00, 0.000000000000000e+00);
1285
points[8] = map(0.000000000000000e+00, 1.000000000000000e+00);
1286
points[9] = map(5.000000000000000e-01, 5.000000000000000e-01);
1287
points[10] = map(0.000000000000000e+00, 5.000000000000000e-01);
1288
points[11] = map(5.000000000000000e-01, 0.000000000000000e+00);
1303
void vertexeval(uint vertex_nodes[], unsigned int vertex, const Mesh& mesh) const
1305
// FIXME: Temporary fix for Lagrange elements
1306
vertex_nodes[0] = vertex;
1307
int offset = mesh.topology().size(0) + mesh.topology().size(1);
1308
vertex_nodes[1] = offset + vertex;
1311
const FiniteElement& operator[] (unsigned int i) const
1316
FiniteElement& operator[] (unsigned int i)
1321
FiniteElementSpec spec() const
1323
FiniteElementSpec s("Vector Lagrange", "triangle", 2, 2);
1329
unsigned int* tensordims;
1330
FiniteElement** subelements;
1334
class SubElement_1 : public dolfin::FiniteElement
1338
SubElement_1() : dolfin::FiniteElement(), tensordims(0), subelements(0)
1340
// Element is scalar, don't need to initialize tensordims
1342
// Element is simple, don't need to initialize subelements
1347
if ( tensordims ) delete [] tensordims;
1350
for (unsigned int i = 0; i < elementdim(); i++)
1351
delete subelements[i];
1352
delete [] subelements;
1356
inline unsigned int spacedim() const
1361
inline unsigned int shapedim() const
1366
inline unsigned int tensordim(unsigned int i) const
1368
dolfin_error("Element is scalar.");
1372
inline unsigned int elementdim() const
1377
inline unsigned int rank() const
1382
void nodemap(int nodes[], const Cell& cell, const Mesh& mesh) const
1384
nodes[0] = cell.entities(0)[0];
1385
nodes[1] = cell.entities(0)[1];
1386
nodes[2] = cell.entities(0)[2];
1389
void pointmap(Point points[], unsigned int components[], const AffineMap& map) const
1391
points[0] = map(0.000000000000000e+00, 0.000000000000000e+00);
1392
points[1] = map(1.000000000000000e+00, 0.000000000000000e+00);
1393
points[2] = map(0.000000000000000e+00, 1.000000000000000e+00);
1399
void vertexeval(uint vertex_nodes[], unsigned int vertex, const Mesh& mesh) const
1401
// FIXME: Temporary fix for Lagrange elements
1402
vertex_nodes[0] = vertex;
1405
const FiniteElement& operator[] (unsigned int i) const
1410
FiniteElement& operator[] (unsigned int i)
1415
FiniteElementSpec spec() const
1417
FiniteElementSpec s("Lagrange", "triangle", 1);
1423
unsigned int* tensordims;
1424
FiniteElement** subelements;
1428
unsigned int* tensordims;
1429
FiniteElement** subelements;
1433
class LinearForm::FunctionElement_0 : public dolfin::FiniteElement
1437
FunctionElement_0() : dolfin::FiniteElement(), tensordims(0), subelements(0)
1439
tensordims = new unsigned int [1];
1442
// Element is simple, don't need to initialize subelements
1445
~FunctionElement_0()
1447
if ( tensordims ) delete [] tensordims;
1450
for (unsigned int i = 0; i < elementdim(); i++)
1451
delete subelements[i];
1452
delete [] subelements;
1456
inline unsigned int spacedim() const
1461
inline unsigned int shapedim() const
1466
inline unsigned int tensordim(unsigned int i) const
1468
dolfin_assert(i < 1);
1469
return tensordims[i];
1472
inline unsigned int elementdim() const
1477
inline unsigned int rank() const
1482
void nodemap(int nodes[], const Cell& cell, const Mesh& mesh) const
1484
nodes[0] = cell.entities(0)[0];
1485
nodes[1] = cell.entities(0)[1];
1486
nodes[2] = cell.entities(0)[2];
1487
int offset = mesh.topology().size(0);
1488
nodes[3] = offset + cell.entities(1)[0];
1489
nodes[4] = offset + cell.entities(1)[1];
1490
nodes[5] = offset + cell.entities(1)[2];
1491
offset = offset + mesh.topology().size(1);
1492
nodes[6] = offset + cell.entities(0)[0];
1493
nodes[7] = offset + cell.entities(0)[1];
1494
nodes[8] = offset + cell.entities(0)[2];
1495
offset = offset + mesh.topology().size(0);
1496
nodes[9] = offset + cell.entities(1)[0];
1497
nodes[10] = offset + cell.entities(1)[1];
1498
nodes[11] = offset + cell.entities(1)[2];
1501
void pointmap(Point points[], unsigned int components[], const AffineMap& map) const
1503
points[0] = map(0.000000000000000e+00, 0.000000000000000e+00);
1504
points[1] = map(1.000000000000000e+00, 0.000000000000000e+00);
1505
points[2] = map(0.000000000000000e+00, 1.000000000000000e+00);
1506
points[3] = map(5.000000000000000e-01, 5.000000000000000e-01);
1507
points[4] = map(0.000000000000000e+00, 5.000000000000000e-01);
1508
points[5] = map(5.000000000000000e-01, 0.000000000000000e+00);
1509
points[6] = map(0.000000000000000e+00, 0.000000000000000e+00);
1510
points[7] = map(1.000000000000000e+00, 0.000000000000000e+00);
1511
points[8] = map(0.000000000000000e+00, 1.000000000000000e+00);
1512
points[9] = map(5.000000000000000e-01, 5.000000000000000e-01);
1513
points[10] = map(0.000000000000000e+00, 5.000000000000000e-01);
1514
points[11] = map(5.000000000000000e-01, 0.000000000000000e+00);
1529
void vertexeval(uint vertex_nodes[], unsigned int vertex, const Mesh& mesh) const
1531
// FIXME: Temporary fix for Lagrange elements
1532
vertex_nodes[0] = vertex;
1533
int offset = mesh.topology().size(0) + mesh.topology().size(1);
1534
vertex_nodes[1] = offset + vertex;
1537
const FiniteElement& operator[] (unsigned int i) const
1542
FiniteElement& operator[] (unsigned int i)
1547
FiniteElementSpec spec() const
1549
FiniteElementSpec s("Vector Lagrange", "triangle", 2, 2);
1555
unsigned int* tensordims;
1556
FiniteElement** subelements;
1560
LinearForm::LinearForm(Function& w0) : dolfin::LinearForm(1)
1562
// Create finite element for test space
1563
_test = new TestElement();
1566
initFunction(0, w0, new FunctionElement_0());
1569
// Contribution from the interior
1570
bool LinearForm::interior_contribution() const { return true; }
1572
void LinearForm::eval(real block[], const AffineMap& map, real det) const
1574
// Compute coefficients
1575
const real c0_0 = c[0][0];
1576
const real c0_1 = c[0][1];
1577
const real c0_2 = c[0][2];
1578
const real c0_3 = c[0][3];
1579
const real c0_4 = c[0][4];
1580
const real c0_5 = c[0][5];
1581
const real c0_6 = c[0][6];
1582
const real c0_7 = c[0][7];
1583
const real c0_8 = c[0][8];
1584
const real c0_9 = c[0][9];
1585
const real c0_10 = c[0][10];
1586
const real c0_11 = c[0][11];
1588
// Compute geometry tensors
1589
const real G0_0 = det*c0_0;
1590
const real G0_1 = det*c0_1;
1591
const real G0_2 = det*c0_2;
1592
const real G0_3 = det*c0_3;
1593
const real G0_4 = det*c0_4;
1594
const real G0_5 = det*c0_5;
1595
const real G1_6 = det*c0_6;
1596
const real G1_7 = det*c0_7;
1597
const real G1_8 = det*c0_8;
1598
const real G1_9 = det*c0_9;
1599
const real G1_10 = det*c0_10;
1600
const real G1_11 = det*c0_11;
1602
// Compute element tensor
1603
block[0] = 1.666666666666665e-02*G0_0 - 2.777777777777774e-03*G0_1 - 2.777777777777775e-03*G0_2 - 1.111111111111110e-02*G0_3;
1604
block[1] = -2.777777777777774e-03*G0_0 + 1.666666666666665e-02*G0_1 - 2.777777777777776e-03*G0_2 - 1.111111111111111e-02*G0_4;
1605
block[2] = -2.777777777777775e-03*G0_0 - 2.777777777777776e-03*G0_1 + 1.666666666666666e-02*G0_2 - 1.111111111111111e-02*G0_5;
1606
block[3] = -1.111111111111110e-02*G0_0 + 8.888888888888882e-02*G0_3 + 4.444444444444443e-02*G0_4 + 4.444444444444443e-02*G0_5;
1607
block[4] = -1.111111111111111e-02*G0_1 + 4.444444444444443e-02*G0_3 + 8.888888888888884e-02*G0_4 + 4.444444444444442e-02*G0_5;
1608
block[5] = -1.111111111111111e-02*G0_2 + 4.444444444444443e-02*G0_3 + 4.444444444444443e-02*G0_4 + 8.888888888888882e-02*G0_5;
1609
block[6] = 1.666666666666665e-02*G1_6 - 2.777777777777774e-03*G1_7 - 2.777777777777774e-03*G1_8 - 1.111111111111109e-02*G1_9;
1610
block[7] = -2.777777777777774e-03*G1_6 + 1.666666666666665e-02*G1_7 - 2.777777777777775e-03*G1_8 - 1.111111111111111e-02*G1_10;
1611
block[8] = -2.777777777777774e-03*G1_6 - 2.777777777777775e-03*G1_7 + 1.666666666666666e-02*G1_8 - 1.111111111111111e-02*G1_11;
1612
block[9] = -1.111111111111109e-02*G1_6 + 8.888888888888882e-02*G1_9 + 4.444444444444443e-02*G1_10 + 4.444444444444443e-02*G1_11;
1613
block[10] = -1.111111111111111e-02*G1_7 + 4.444444444444443e-02*G1_9 + 8.888888888888884e-02*G1_10 + 4.444444444444442e-02*G1_11;
1614
block[11] = -1.111111111111111e-02*G1_8 + 4.444444444444443e-02*G1_9 + 4.444444444444443e-02*G1_10 + 8.888888888888882e-02*G1_11;
1615
block[12] = 0.000000000000000e+00;
1616
block[13] = 0.000000000000000e+00;
1617
block[14] = 0.000000000000000e+00;
1620
// No contribution from the boundary
1621
bool LinearForm::boundary_contribution() const { return false; }
1623
void LinearForm::eval(real block[], const AffineMap& map, real det, unsigned int facet) const {}
1625
// No contribution from interior boundaries
1626
bool LinearForm::interior_boundary_contribution() const { return false; }
1628
void LinearForm::eval(real block[], const AffineMap& map0, const AffineMap& map1, real det, unsigned int facet0, unsigned int facet1, unsigned int alignment) const {}