Skip to content

Commit bb13670

Browse files
authored
Merge pull request #3642 from farscape-project/rt_opt
Optimise RT orientation code dealing w/ cyclic permutations
2 parents da8c922 + 86515ce commit bb13670

2 files changed

Lines changed: 37 additions & 32 deletions

File tree

examples/vector_fe/vector_fe_ex6/vector_fe_ex6.C

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,10 @@
3131
// The solver packages supported by libMesh.
3232
#include "libmesh/enum_solver_package.h"
3333

34-
// The mesh object and mesh generation utilities.
34+
// The mesh object and mesh generation and modification utilities.
3535
#include "libmesh/mesh.h"
3636
#include "libmesh/mesh_generation.h"
37+
#include "libmesh/mesh_modification.h"
3738

3839
// Matrix and vector types.
3940
#include "libmesh/dense_matrix.h"
@@ -131,6 +132,9 @@ int main (int argc, char ** argv)
131132
-1., 1.,
132133
Utility::string_to_enum<ElemType>(elem_str));
133134

135+
// Make sure the code is robust against nodal reorderings.
136+
MeshTools::Modification::permute_elements(mesh);
137+
134138
// Print information about the mesh to the screen.
135139
mesh.print_info();
136140

src/fe/fe_raviart_shape_3D.C

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,11 @@ namespace libMesh
2525
{
2626

2727

28-
bool orientation(std::vector<Point> & arr)
28+
template<size_t N>
29+
bool orientation(std::array<Point, N> & arr)
2930
{
30-
while (std::min_element(arr.begin(), arr.end()) != arr.begin())
31-
std::rotate(arr.begin(), arr.begin() + 1, arr.end());
31+
if (N % 2 == 0)
32+
std::rotate(arr.begin(), std::min_element(arr.begin(), arr.end()), arr.end());
3233

3334
size_t cnt = 0;
3435
for(size_t i = 0; i < arr.size(); i++)
@@ -76,47 +77,47 @@ RealGradient FE<3,RAVIART_THOMAS>::shape(const Elem * elem,
7677
{
7778
case 0:
7879
{
79-
std::vector<Point> arr = {elem->point(1), elem->point(0), elem->point(3), elem->point(2)};
80+
std::array<Point, 4> arr = {elem->point(1), elem->point(0), elem->point(3), elem->point(2)};
8081
if (orientation(arr))
8182
return RealGradient( 0.0, 0.0, 0.125*(zeta-1.0) );
8283
else
8384
return RealGradient( 0.0, 0.0, -0.125*(zeta-1.0) );
8485
}
8586
case 1:
8687
{
87-
std::vector<Point> arr = {elem->point(4), elem->point(0), elem->point(1), elem->point(5)};
88+
std::array<Point, 4> arr = {elem->point(4), elem->point(0), elem->point(1), elem->point(5)};
8889
if (orientation(arr))
8990
return RealGradient( 0.0, 0.125*(eta-1.0), 0.0 );
9091
else
9192
return RealGradient( 0.0, -0.125*(eta-1.0), 0.0 );
9293
}
9394
case 2:
9495
{
95-
std::vector<Point> arr = {elem->point(6), elem->point(5), elem->point(1), elem->point(2)};
96+
std::array<Point, 4> arr = {elem->point(6), elem->point(5), elem->point(1), elem->point(2)};
9697
if (orientation(arr))
9798
return RealGradient( 0.125*(xi+1.0), 0.0, 0.0 );
9899
else
99100
return RealGradient( -0.125*(xi+1.0), 0.0, 0.0 );
100101
}
101102
case 3:
102103
{
103-
std::vector<Point> arr = {elem->point(7), elem->point(6), elem->point(2), elem->point(3)};
104+
std::array<Point, 4> arr = {elem->point(7), elem->point(6), elem->point(2), elem->point(3)};
104105
if (orientation(arr))
105106
return RealGradient( 0.0, 0.125*(1.0+eta), 0.0 );
106107
else
107108
return RealGradient( 0.0, -0.125*(1.0+eta), 0.0 );
108109
}
109110
case 4:
110111
{
111-
std::vector<Point> arr = {elem->point(7), elem->point(3), elem->point(0), elem->point(4)};
112+
std::array<Point, 4> arr = {elem->point(7), elem->point(3), elem->point(0), elem->point(4)};
112113
if (orientation(arr))
113114
return RealGradient( 0.125*(xi-1.0), 0.0, 0.0 );
114115
else
115116
return RealGradient( -0.125*(xi-1.0), 0.0, 0.0 );
116117
}
117118
case 5:
118119
{
119-
std::vector<Point> arr = {elem->point(5), elem->point(6), elem->point(7), elem->point(4)};
120+
std::array<Point, 4> arr = {elem->point(5), elem->point(6), elem->point(7), elem->point(4)};
120121
if (orientation(arr))
121122
return RealGradient( 0.0, 0.0, 0.125*(1.0+zeta) );
122123
else
@@ -141,31 +142,31 @@ RealGradient FE<3,RAVIART_THOMAS>::shape(const Elem * elem,
141142
{
142143
case 0:
143144
{
144-
std::vector<Point> arr = {elem->point(0), elem->point(2), elem->point(1)};
145+
std::array<Point, 3> arr = {elem->point(0), elem->point(2), elem->point(1)};
145146
if (orientation(arr))
146147
return RealGradient( 2.0*xi, 2.0*eta, 2.0*zeta-2.0 );
147148
else
148149
return RealGradient( -2.0*xi, -2.0*eta, -2.0*zeta+2.0 );
149150
}
150151
case 1:
151152
{
152-
std::vector<Point> arr = {elem->point(1), elem->point(3), elem->point(0)};
153+
std::array<Point, 3> arr = {elem->point(1), elem->point(3), elem->point(0)};
153154
if (orientation(arr))
154155
return RealGradient( 2.0*xi, 2.0*eta-2.0, 2.0*zeta );
155156
else
156157
return RealGradient( -2.0*xi, -2.0*eta+2.0, -2.0*zeta );
157158
}
158159
case 2:
159160
{
160-
std::vector<Point> arr = {elem->point(1), elem->point(2), elem->point(3)};
161+
std::array<Point, 3> arr = {elem->point(1), elem->point(2), elem->point(3)};
161162
if (orientation(arr))
162163
return RealGradient( 2.0*xi, 2.0*eta, 2.0*zeta );
163164
else
164165
return RealGradient( -2.0*xi, -2.0*eta, -2.0*zeta );
165166
}
166167
case 3:
167168
{
168-
std::vector<Point> arr = {elem->point(0), elem->point(3), elem->point(2)};
169+
std::array<Point, 3> arr = {elem->point(0), elem->point(3), elem->point(2)};
169170
if (orientation(arr))
170171
return RealGradient( 2.0*xi-2.0, 2.0*eta, 2.0*zeta );
171172
else
@@ -257,15 +258,15 @@ RealGradient FE<3,RAVIART_THOMAS>::shape_deriv(const Elem * elem,
257258
return RealGradient();
258259
case 2:
259260
{
260-
std::vector<Point> arr = {elem->point(6), elem->point(5), elem->point(1), elem->point(2)};
261+
std::array<Point, 4> arr = {elem->point(6), elem->point(5), elem->point(1), elem->point(2)};
261262
if (orientation(arr))
262263
return RealGradient( 0.125, 0.0, 0.0 );
263264
else
264265
return RealGradient( -0.125, 0.0, 0.0 );
265266
}
266267
case 4:
267268
{
268-
std::vector<Point> arr = {elem->point(7), elem->point(3), elem->point(0), elem->point(4)};
269+
std::array<Point, 4> arr = {elem->point(7), elem->point(3), elem->point(0), elem->point(4)};
269270
if (orientation(arr))
270271
return RealGradient( 0.125, 0.0, 0.0 );
271272
else
@@ -289,15 +290,15 @@ RealGradient FE<3,RAVIART_THOMAS>::shape_deriv(const Elem * elem,
289290
return RealGradient();
290291
case 1:
291292
{
292-
std::vector<Point> arr = {elem->point(4), elem->point(0), elem->point(1), elem->point(5)};
293+
std::array<Point, 4> arr = {elem->point(4), elem->point(0), elem->point(1), elem->point(5)};
293294
if (orientation(arr))
294295
return RealGradient( 0.0, 0.125, 0.0 );
295296
else
296297
return RealGradient( 0.0, -0.125, 0.0 );
297298
}
298299
case 3:
299300
{
300-
std::vector<Point> arr = {elem->point(7), elem->point(6), elem->point(2), elem->point(3)};
301+
std::array<Point, 4> arr = {elem->point(7), elem->point(6), elem->point(2), elem->point(3)};
301302
if (orientation(arr))
302303
return RealGradient( 0.0, 0.125, 0.0 );
303304
else
@@ -321,15 +322,15 @@ RealGradient FE<3,RAVIART_THOMAS>::shape_deriv(const Elem * elem,
321322
return RealGradient();
322323
case 0:
323324
{
324-
std::vector<Point> arr = {elem->point(1), elem->point(0), elem->point(3), elem->point(2)};
325+
std::array<Point, 4> arr = {elem->point(1), elem->point(0), elem->point(3), elem->point(2)};
325326
if (orientation(arr))
326327
return RealGradient( 0.0, 0.0, 0.125 );
327328
else
328329
return RealGradient( 0.0, 0.0, -0.125 );
329330
}
330331
case 5:
331332
{
332-
std::vector<Point> arr = {elem->point(5), elem->point(6), elem->point(7), elem->point(4)};
333+
std::array<Point, 4> arr = {elem->point(5), elem->point(6), elem->point(7), elem->point(4)};
333334
if (orientation(arr))
334335
return RealGradient( 0.0, 0.0, 0.125 );
335336
else
@@ -361,31 +362,31 @@ RealGradient FE<3,RAVIART_THOMAS>::shape_deriv(const Elem * elem,
361362
{
362363
case 0:
363364
{
364-
std::vector<Point> arr = {elem->point(0), elem->point(2), elem->point(1)};
365+
std::array<Point, 3> arr = {elem->point(0), elem->point(2), elem->point(1)};
365366
if (orientation(arr))
366367
return RealGradient( 2.0, 0.0, 0.0 );
367368
else
368369
return RealGradient( -2.0, 0.0, 0.0 );
369370
}
370371
case 1:
371372
{
372-
std::vector<Point> arr = {elem->point(1), elem->point(3), elem->point(0)};
373+
std::array<Point, 3> arr = {elem->point(1), elem->point(3), elem->point(0)};
373374
if (orientation(arr))
374375
return RealGradient( 2.0, 0.0, 0.0 );
375376
else
376377
return RealGradient( -2.0, 0.0, 0.0 );
377378
}
378379
case 2:
379380
{
380-
std::vector<Point> arr = {elem->point(1), elem->point(2), elem->point(3)};
381+
std::array<Point, 3> arr = {elem->point(1), elem->point(2), elem->point(3)};
381382
if (orientation(arr))
382383
return RealGradient( 2.0, 0.0, 0.0 );
383384
else
384385
return RealGradient( -2.0, 0.0, 0.0 );
385386
}
386387
case 3:
387388
{
388-
std::vector<Point> arr = {elem->point(0), elem->point(3), elem->point(2)};
389+
std::array<Point, 3> arr = {elem->point(0), elem->point(3), elem->point(2)};
389390
if (orientation(arr))
390391
return RealGradient( 2.0, 0.0, 0.0 );
391392
else
@@ -404,31 +405,31 @@ RealGradient FE<3,RAVIART_THOMAS>::shape_deriv(const Elem * elem,
404405
{
405406
case 0:
406407
{
407-
std::vector<Point> arr = {elem->point(0), elem->point(2), elem->point(1)};
408+
std::array<Point, 3> arr = {elem->point(0), elem->point(2), elem->point(1)};
408409
if (orientation(arr))
409410
return RealGradient( 0.0, 2.0, 0.0 );
410411
else
411412
return RealGradient( 0.0, -2.0, 0.0 );
412413
}
413414
case 1:
414415
{
415-
std::vector<Point> arr = {elem->point(1), elem->point(3), elem->point(0)};
416+
std::array<Point, 3> arr = {elem->point(1), elem->point(3), elem->point(0)};
416417
if (orientation(arr))
417418
return RealGradient( 0.0, 2.0, 0.0 );
418419
else
419420
return RealGradient( 0.0, -2.0, 0.0 );
420421
}
421422
case 2:
422423
{
423-
std::vector<Point> arr = {elem->point(1), elem->point(2), elem->point(3)};
424+
std::array<Point, 3> arr = {elem->point(1), elem->point(2), elem->point(3)};
424425
if (orientation(arr))
425426
return RealGradient( 0.0, 2.0, 0.0 );
426427
else
427428
return RealGradient( 0.0, -2.0, 0.0 );
428429
}
429430
case 3:
430431
{
431-
std::vector<Point> arr = {elem->point(0), elem->point(3), elem->point(2)};
432+
std::array<Point, 3> arr = {elem->point(0), elem->point(3), elem->point(2)};
432433
if (orientation(arr))
433434
return RealGradient( 0.0, 2.0, 0.0 );
434435
else
@@ -447,31 +448,31 @@ RealGradient FE<3,RAVIART_THOMAS>::shape_deriv(const Elem * elem,
447448
{
448449
case 0:
449450
{
450-
std::vector<Point> arr = {elem->point(0), elem->point(2), elem->point(1)};
451+
std::array<Point, 3> arr = {elem->point(0), elem->point(2), elem->point(1)};
451452
if (orientation(arr))
452453
return RealGradient( 0.0, 0.0, 2.0 );
453454
else
454455
return RealGradient( 0.0, 0.0, -2.0 );
455456
}
456457
case 1:
457458
{
458-
std::vector<Point> arr = {elem->point(1), elem->point(3), elem->point(0)};
459+
std::array<Point, 3> arr = {elem->point(1), elem->point(3), elem->point(0)};
459460
if (orientation(arr))
460461
return RealGradient( 0.0, 0.0, 2.0 );
461462
else
462463
return RealGradient( 0.0, 0.0, -2.0 );
463464
}
464465
case 2:
465466
{
466-
std::vector<Point> arr = {elem->point(1), elem->point(2), elem->point(3)};
467+
std::array<Point, 3> arr = {elem->point(1), elem->point(2), elem->point(3)};
467468
if (orientation(arr))
468469
return RealGradient( 0.0, 0.0, 2.0 );
469470
else
470471
return RealGradient( 0.0, 0.0, -2.0 );
471472
}
472473
case 3:
473474
{
474-
std::vector<Point> arr = {elem->point(0), elem->point(3), elem->point(2)};
475+
std::array<Point, 3> arr = {elem->point(0), elem->point(3), elem->point(2)};
475476
if (orientation(arr))
476477
return RealGradient( 0.0, 0.0, 2.0 );
477478
else

0 commit comments

Comments
 (0)