Nektar++
Loading...
Searching...
No Matches
TestPyrCollection.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: TestPyrCollection.cpp
4//
5// For more information, please see: http://www.nektar.info
6//
7// The MIT License
8//
9// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// Permission is hereby granted, free of charge, to any person obtaining a
14// copy of this software and associated documentation files (the "Software"),
15// to deal in the Software without restriction, including without limitation
16// the rights to use, copy, modify, merge, publish, distribute, sublicense,
17// and/or sell copies of the Software, and to permit persons to whom the
18// Software is furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29// DEALINGS IN THE SOFTWARE.
30//
31// Description:
32//
33///////////////////////////////////////////////////////////////////////////////
34
39#include <LocalRegions/PyrExp.h>
41#include <boost/test/tools/floating_point_comparison.hpp>
42#include <boost/test/unit_test.hpp>
43
45{
46#define NELMTS 10
47
51{
52 std::array<SpatialDomains::PointGeom *, 2> vertices = {v0, v1};
54 new SpatialDomains::SegGeom(id, 3, vertices));
55 return result;
56}
57
59 std::array<SpatialDomains::PointGeom *, 5> v,
60 std::array<SpatialDomains::SegGeomUniquePtr, 8> &segVec,
61 std::array<SpatialDomains::TriGeomUniquePtr, 4> &triVec,
62 std::array<SpatialDomains::QuadGeomUniquePtr, 1> &quadVec)
63{
64 std::array<std::array<int, 2>, 8> edgeVerts = {{{{0, 1}},
65 {{1, 2}},
66 {{3, 2}},
67 {{0, 3}},
68 {{0, 4}},
69 {{1, 4}},
70 {{2, 4}},
71 {{3, 4}}}};
72 std::array<std::array<int, 4>, 5> faceEdges = {{{{0, 1, 2, 3}},
73 {{0, 5, 4, -1}},
74 {{1, 6, 5, -1}},
75 {{2, 7, 6, -1}},
76 {{3, 7, 4, -1}}}};
77
78 // Create segments from vertices
79 for (int i = 0; i < 8; ++i)
80 {
81 segVec[i] = CreateSegGeom(i, v[edgeVerts[i][0]], v[edgeVerts[i][1]]);
82 }
83
84 // Create faces from edges
85 std::array<SpatialDomains::Geometry2D *, 5> faces;
86 for (int i = 0; i < 5; ++i)
87 {
88 if (i == 0)
89 {
90 // Quad faces
91 std::array<SpatialDomains::SegGeom *, 4> face;
92 for (int j = 0; j < 4; ++j)
93 {
94 face[j] = segVec[faceEdges[i][j]].get();
95 }
97 new SpatialDomains::QuadGeom(i, face));
98 faces[i] = quadVec[0].get();
99 }
100 else
101 {
102 // Tri faces
103 std::array<SpatialDomains::SegGeom *, 3> face;
104 for (int j = 0; j < 3; ++j)
105 {
106 face[j] = segVec[faceEdges[i][j]].get();
107 }
108 triVec[i - 1] = SpatialDomains::TriGeomUniquePtr(
109 new SpatialDomains::TriGeom(i, face));
110 faces[i] = triVec[i - 1].get();
111 }
112 }
113
115 new SpatialDomains::PyrGeom(0, faces));
116 return pyrGeom;
117}
118
119BOOST_AUTO_TEST_CASE(TestPyrBwdTrans_IterPerExp_UniformP_MultiElmt)
120{
122 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
124 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
126 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
128 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
130 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
131
132 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
133 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
134 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
135 std::array<SpatialDomains::PointGeom *, 5> v = {
136 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
138 CreatePyr(v, segVec, triVec, quadVec);
139
140 Nektar::LibUtilities::PointsType PointsTypeDir1 =
142 const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1);
143 Nektar::LibUtilities::BasisType basisTypeDir1 =
145 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
146 PointsKeyDir1);
147
148 Nektar::LibUtilities::PointsType PointsTypeDir2 =
150 const Nektar::LibUtilities::PointsKey PointsKeyDir2(5, PointsTypeDir2);
151 Nektar::LibUtilities::BasisType basisTypeDir2 =
153 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
154 PointsKeyDir2);
155
156 Nektar::LibUtilities::PointsType PointsTypeDir3 =
157 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
158 const Nektar::LibUtilities::PointsKey PointsKeyDir3(4, PointsTypeDir3);
159 Nektar::LibUtilities::BasisType basisTypeDir3 =
161 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
162 PointsKeyDir3);
163
166 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
167
168 int nelmts = NELMTS;
169
170 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
171 for (int i = 0; i < nelmts; ++i)
172 {
173 CollExp.push_back(Exp);
174 }
175
177 Collections::CollectionOptimisation colOpt(dummySession, 3,
179 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
180 Collections::Collection c(CollExp, impTypes);
182
183 Array<OneD, NekDouble> coeffs(nelmts * Exp->GetNcoeffs(), 1.0), tmp;
184 for (int i = 0; i < coeffs.size(); ++i)
185 {
186 coeffs[i] = i + 1;
187 }
188 Array<OneD, NekDouble> phys1(nelmts * Exp->GetTotPoints());
189 Array<OneD, NekDouble> phys2(nelmts * Exp->GetTotPoints());
190
191 for (int i = 0; i < nelmts; ++i)
192 {
193 Exp->BwdTrans(coeffs + i * Exp->GetNcoeffs(),
194 tmp = phys1 + i * Exp->GetTotPoints());
195 }
196
198 timer.Start();
199 c.ApplyOperator(Collections::eBwdTrans, coeffs, phys2);
200 timer.Stop();
201 timer.AccumulateRegion("Pyr BwdTrans IterPerExp");
202
203 double epsilon = 1.0e-8;
204 for (int i = 0; i < phys1.size(); ++i)
205 {
206 BOOST_CHECK_CLOSE(phys1[i], phys2[i], epsilon);
207 }
208}
209
210BOOST_AUTO_TEST_CASE(TestPyrBwdTrans_StdMat_UniformP_MultiElmt)
211{
213 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
215 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
217 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
219 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
221 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
222
223 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
224 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
225 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
226 std::array<SpatialDomains::PointGeom *, 5> v = {
227 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
229 CreatePyr(v, segVec, triVec, quadVec);
230
231 Nektar::LibUtilities::PointsType PointsTypeDir1 =
233 const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1);
234 Nektar::LibUtilities::BasisType basisTypeDir1 =
236 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
237 PointsKeyDir1);
238
239 Nektar::LibUtilities::PointsType PointsTypeDir2 =
241 const Nektar::LibUtilities::PointsKey PointsKeyDir2(5, PointsTypeDir2);
242 Nektar::LibUtilities::BasisType basisTypeDir2 =
244 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
245 PointsKeyDir2);
246
247 Nektar::LibUtilities::PointsType PointsTypeDir3 =
248 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
249 const Nektar::LibUtilities::PointsKey PointsKeyDir3(5, PointsTypeDir3);
250 Nektar::LibUtilities::BasisType basisTypeDir3 =
252 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
253 PointsKeyDir3);
254
257 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
258
259 int nelmts = 10;
260
261 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
262 for (int i = 0; i < nelmts; ++i)
263 {
264 CollExp.push_back(Exp);
265 }
266
268 Collections::CollectionOptimisation colOpt(dummySession, 3,
270 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
271 Collections::Collection c(CollExp, impTypes);
273
274 Array<OneD, NekDouble> coeffs(nelmts * Exp->GetNcoeffs(), 1.0);
275 for (int i = 0; i < coeffs.size(); ++i)
276 {
277 coeffs[i] = i + 1;
278 }
279 Array<OneD, NekDouble> phys1(nelmts * Exp->GetTotPoints(), 0.0);
280 Array<OneD, NekDouble> phys2(nelmts * Exp->GetTotPoints(), 0.0);
282
283 for (int i = 0; i < nelmts; ++i)
284 {
285 Exp->BwdTrans(coeffs + i * Exp->GetNcoeffs(),
286 tmp = phys1 + i * Exp->GetTotPoints());
287 }
288 c.ApplyOperator(Collections::eBwdTrans, coeffs, phys2);
289
290 double epsilon = 1.0e-8;
291 for (int i = 0; i < phys1.size(); ++i)
292 {
293 BOOST_CHECK_CLOSE(phys1[i], phys2[i], epsilon);
294 }
295}
296
297BOOST_AUTO_TEST_CASE(TestPyrBwdTrans_SumFac_UniformP_MultiElmt)
298{
300 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
302 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
304 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
306 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
308 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
309
310 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
311 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
312 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
313 std::array<SpatialDomains::PointGeom *, 5> v = {
314 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
316 CreatePyr(v, segVec, triVec, quadVec);
317
318 Nektar::LibUtilities::PointsType PointsTypeDir1 =
320 const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1);
321 Nektar::LibUtilities::BasisType basisTypeDir1 =
323 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
324 PointsKeyDir1);
325
326 Nektar::LibUtilities::PointsType PointsTypeDir2 =
328 const Nektar::LibUtilities::PointsKey PointsKeyDir2(5, PointsTypeDir2);
329 Nektar::LibUtilities::BasisType basisTypeDir2 =
331 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
332 PointsKeyDir2);
333
334 Nektar::LibUtilities::PointsType PointsTypeDir3 =
335 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
336 const Nektar::LibUtilities::PointsKey PointsKeyDir3(5, PointsTypeDir3);
337 Nektar::LibUtilities::BasisType basisTypeDir3 =
339 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
340 PointsKeyDir3);
341
344 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
345
346 int nelmts = NELMTS;
347
348 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
349 for (int i = 0; i < nelmts; ++i)
350 {
351 CollExp.push_back(Exp);
352 }
353
355 Collections::CollectionOptimisation colOpt(dummySession, 3,
359 Collections::Collection c(CollExp, impTypes);
361
362 Array<OneD, NekDouble> coeffs(nelmts * Exp->GetNcoeffs(), 1.0);
363 for (int i = 0; i < coeffs.size(); ++i)
364 {
365 coeffs[i] = i + 1;
366 }
367 Array<OneD, NekDouble> phys1(nelmts * Exp->GetTotPoints(), 0.0);
368 Array<OneD, NekDouble> phys2(nelmts * Exp->GetTotPoints(), 0.0);
370
371 for (int i = 0; i < nelmts; ++i)
372 {
373 Exp->BwdTrans(coeffs + i * Exp->GetNcoeffs(),
374 tmp = phys1 + i * Exp->GetTotPoints());
375 }
376
378 timer.Start();
379 c.ApplyOperator(Collections::eBwdTrans, coeffs, phys2);
380 timer.Stop();
381 timer.AccumulateRegion("Pyr BwdTrans SumFactor");
382
383 double epsilon = 1.0e-8;
384 for (int i = 0; i < phys1.size(); ++i)
385 {
386 BOOST_CHECK_CLOSE(phys1[i], phys2[i], epsilon);
387 }
388}
389
390BOOST_AUTO_TEST_CASE(TestPyrBwdTrans_IterPerExp_VariableP_MultiElmt)
391{
393 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
395 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
397 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
399 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
401 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
402
403 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
404 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
405 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
406 std::array<SpatialDomains::PointGeom *, 5> v = {
407 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
409 CreatePyr(v, segVec, triVec, quadVec);
410
411 Nektar::LibUtilities::PointsType PointsTypeDir1 =
413 const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1);
414 Nektar::LibUtilities::BasisType basisTypeDir1 =
416 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
417 PointsKeyDir1);
418
419 Nektar::LibUtilities::PointsType PointsTypeDir2 =
421 const Nektar::LibUtilities::PointsKey PointsKeyDir2(7, PointsTypeDir2);
422 Nektar::LibUtilities::BasisType basisTypeDir2 =
424 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 6,
425 PointsKeyDir2);
426
427 Nektar::LibUtilities::PointsType PointsTypeDir3 =
428 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
429 const Nektar::LibUtilities::PointsKey PointsKeyDir3(8, PointsTypeDir3);
430 Nektar::LibUtilities::BasisType basisTypeDir3 =
432 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
433 PointsKeyDir3);
434
437 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
438 int nelmts = 10;
439
440 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
441 for (int i = 0; i < nelmts; ++i)
442 {
443 CollExp.push_back(Exp);
444 }
445
447 Collections::CollectionOptimisation colOpt(dummySession, 3,
449 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
450 Collections::Collection c(CollExp, impTypes);
452
453 Array<OneD, NekDouble> coeffs(nelmts * Exp->GetNcoeffs(), 1.0);
454 for (int i = 0; i < coeffs.size(); ++i)
455 {
456 coeffs[i] = i + 1;
457 }
458 Array<OneD, NekDouble> phys1(nelmts * Exp->GetTotPoints(), 0.0);
459 Array<OneD, NekDouble> phys2(nelmts * Exp->GetTotPoints(), 0.0);
461
462 for (int i = 0; i < nelmts; ++i)
463 {
464 Exp->BwdTrans(coeffs + i * Exp->GetNcoeffs(),
465 tmp = phys1 + i * Exp->GetTotPoints());
466 }
467 c.ApplyOperator(Collections::eBwdTrans, coeffs, phys2);
468
469 double epsilon = 1.0e-8;
470 for (int i = 0; i < phys1.size(); ++i)
471 {
472 BOOST_CHECK_CLOSE(phys1[i], phys2[i], epsilon);
473 }
474}
475
476BOOST_AUTO_TEST_CASE(TestPyrBwdTrans_StdMat_VariableP_MultiElmt)
477{
479 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
481 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
483 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
485 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
487 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
488
489 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
490 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
491 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
492 std::array<SpatialDomains::PointGeom *, 5> v = {
493 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
495 CreatePyr(v, segVec, triVec, quadVec);
496
497 Nektar::LibUtilities::PointsType PointsTypeDir1 =
499 const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1);
500 Nektar::LibUtilities::BasisType basisTypeDir1 =
502 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
503 PointsKeyDir1);
504
505 Nektar::LibUtilities::PointsType PointsTypeDir2 =
507 const Nektar::LibUtilities::PointsKey PointsKeyDir2(7, PointsTypeDir2);
508 Nektar::LibUtilities::BasisType basisTypeDir2 =
510 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 6,
511 PointsKeyDir2);
512
513 Nektar::LibUtilities::PointsType PointsTypeDir3 =
514 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
515 const Nektar::LibUtilities::PointsKey PointsKeyDir3(8, PointsTypeDir3);
516 Nektar::LibUtilities::BasisType basisTypeDir3 =
518 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
519 PointsKeyDir3);
520
523 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
524
525 int nelmts = 10;
526
527 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
528 for (int i = 0; i < nelmts; ++i)
529 {
530 CollExp.push_back(Exp);
531 }
532
534 Collections::CollectionOptimisation colOpt(dummySession, 3,
536 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
537 Collections::Collection c(CollExp, impTypes);
539
540 Array<OneD, NekDouble> coeffs(nelmts * Exp->GetNcoeffs(), 1.0);
541 for (int i = 0; i < coeffs.size(); ++i)
542 {
543 coeffs[i] = i + 1;
544 }
545 Array<OneD, NekDouble> phys1(nelmts * Exp->GetTotPoints(), 0.0);
546 Array<OneD, NekDouble> phys2(nelmts * Exp->GetTotPoints(), 0.0);
548
549 for (int i = 0; i < nelmts; ++i)
550 {
551 Exp->BwdTrans(coeffs + i * Exp->GetNcoeffs(),
552 tmp = phys1 + i * Exp->GetTotPoints());
553 }
554 c.ApplyOperator(Collections::eBwdTrans, coeffs, phys2);
555
556 double epsilon = 1.0e-8;
557 for (int i = 0; i < phys1.size(); ++i)
558 {
559 BOOST_CHECK_CLOSE(phys1[i], phys2[i], epsilon);
560 }
561}
562
563BOOST_AUTO_TEST_CASE(TestPyrBwdTrans_SumFac_VariableP_MultiElmt)
564{
566 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
568 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
570 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
572 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
574 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
575
576 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
577 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
578 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
579 std::array<SpatialDomains::PointGeom *, 5> v = {
580 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
582 CreatePyr(v, segVec, triVec, quadVec);
583
584 Nektar::LibUtilities::PointsType PointsTypeDir1 =
586 const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1);
587 Nektar::LibUtilities::BasisType basisTypeDir1 =
589 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
590 PointsKeyDir1);
591
592 Nektar::LibUtilities::PointsType PointsTypeDir2 =
594 const Nektar::LibUtilities::PointsKey PointsKeyDir2(7, PointsTypeDir2);
595 Nektar::LibUtilities::BasisType basisTypeDir2 =
597 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 6,
598 PointsKeyDir2);
599
600 Nektar::LibUtilities::PointsType PointsTypeDir3 =
602 const Nektar::LibUtilities::PointsKey PointsKeyDir3(8, PointsTypeDir3);
603 Nektar::LibUtilities::BasisType basisTypeDir3 =
605 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
606 PointsKeyDir3);
607
610 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
611
612 int nelmts = 10;
613
614 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
615 for (int i = 0; i < nelmts; ++i)
616 {
617 CollExp.push_back(Exp);
618 }
619
621 Collections::CollectionOptimisation colOpt(dummySession, 3,
625 Collections::Collection c(CollExp, impTypes);
627
628 Array<OneD, NekDouble> coeffs(nelmts * Exp->GetNcoeffs(), 1.0);
629 for (int i = 0; i < coeffs.size(); ++i)
630 {
631 coeffs[i] = i + 1;
632 }
633 Array<OneD, NekDouble> phys1(nelmts * Exp->GetTotPoints(), 0.0);
634 Array<OneD, NekDouble> phys2(nelmts * Exp->GetTotPoints(), 0.0);
636
637 for (int i = 0; i < nelmts; ++i)
638 {
639 Exp->BwdTrans(coeffs + i * Exp->GetNcoeffs(),
640 tmp = phys1 + i * Exp->GetTotPoints());
641 }
642 c.ApplyOperator(Collections::eBwdTrans, coeffs, phys2);
643
644 double epsilon = 1.0e-8;
645 for (int i = 0; i < phys1.size(); ++i)
646 {
647 BOOST_CHECK_CLOSE(phys1[i], phys2[i], epsilon);
648 }
649}
650
651BOOST_AUTO_TEST_CASE(TestPyrPhysDeriv_IterPerExp_UniformP_MultiElmt)
652{
654 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
656 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
658 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
660 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
662 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
663
664 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
665 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
666 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
667 std::array<SpatialDomains::PointGeom *, 5> v = {
668 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
670 CreatePyr(v, segVec, triVec, quadVec);
671
672 Nektar::LibUtilities::PointsType PointsTypeDir1 =
674 const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1);
675 Nektar::LibUtilities::BasisType basisTypeDir1 =
677 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
678 PointsKeyDir1);
679
680 Nektar::LibUtilities::PointsType PointsTypeDir2 =
682 const Nektar::LibUtilities::PointsKey PointsKeyDir2(5, PointsTypeDir2);
683 Nektar::LibUtilities::BasisType basisTypeDir2 =
685 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
686 PointsKeyDir2);
687
688 Nektar::LibUtilities::PointsType PointsTypeDir3 =
689 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
690 const Nektar::LibUtilities::PointsKey PointsKeyDir3(4, PointsTypeDir3);
691 Nektar::LibUtilities::BasisType basisTypeDir3 =
693 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
694 PointsKeyDir3);
695
698 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
699 int nelmts = NELMTS;
700
701 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
702 for (int i = 0; i < nelmts; ++i)
703 {
704 CollExp.push_back(Exp);
705 }
706
708 Collections::CollectionOptimisation colOpt(dummySession, 3,
710 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
711 Collections::Collection c(CollExp, impTypes);
713
714 const int nq = Exp->GetTotPoints();
715 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
716 Array<OneD, NekDouble> phys(nelmts * nq), tmp, tmp1, tmp2;
717 Array<OneD, NekDouble> diff1(3 * nelmts * nq);
718 Array<OneD, NekDouble> diff2(3 * nelmts * nq);
719
720 Exp->GetCoords(xc, yc, zc);
721
722 for (int i = 0; i < nq; ++i)
723 {
724 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
725 }
726 Exp->PhysDeriv(phys, diff1, tmp1 = diff1 + (nelmts)*nq,
727 tmp2 = diff1 + (2 * nelmts) * nq);
728
729 for (int i = 1; i < nelmts; ++i)
730 {
731 Vmath::Vcopy(nq, phys, 1, tmp = phys + i * nq, 1);
732 Exp->PhysDeriv(phys, tmp = diff1 + i * nq,
733 tmp1 = diff1 + (nelmts + i) * nq,
734 tmp2 = diff1 + (2 * nelmts + i) * nq);
735 }
736
738 timer.Start();
740 tmp = diff2 + nelmts * nq, tmp2 = diff2 + 2 * nelmts * nq);
741 timer.Stop();
742 timer.AccumulateRegion("Pyr PhysDeriv IterPerExp");
743
744 double epsilon = 1.0e-8;
745 for (int i = 0; i < diff1.size(); ++i)
746 {
747 BOOST_CHECK_CLOSE(diff1[i], diff2[i], epsilon);
748 }
749}
750
751BOOST_AUTO_TEST_CASE(TestPyrPhysDeriv_StdMat_UniformP_MultiElmt)
752{
754 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
756 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
758 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
760 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
762 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
763
764 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
765 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
766 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
767 std::array<SpatialDomains::PointGeom *, 5> v = {
768 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
770 CreatePyr(v, segVec, triVec, quadVec);
771
772 Nektar::LibUtilities::PointsType PointsTypeDir1 =
774 const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1);
775 Nektar::LibUtilities::BasisType basisTypeDir1 =
777 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
778 PointsKeyDir1);
779
780 Nektar::LibUtilities::PointsType PointsTypeDir2 =
782 const Nektar::LibUtilities::PointsKey PointsKeyDir2(5, PointsTypeDir2);
783 Nektar::LibUtilities::BasisType basisTypeDir2 =
785 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
786 PointsKeyDir2);
787
788 Nektar::LibUtilities::PointsType PointsTypeDir3 =
789 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
790 const Nektar::LibUtilities::PointsKey PointsKeyDir3(4, PointsTypeDir3);
791 Nektar::LibUtilities::BasisType basisTypeDir3 =
793 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
794 PointsKeyDir3);
795
798 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
799
800 int nelmts = 10;
801
802 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
803 for (int i = 0; i < nelmts; ++i)
804 {
805 CollExp.push_back(Exp);
806 }
807
809 Collections::CollectionOptimisation colOpt(dummySession, 3,
811 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
812 Collections::Collection c(CollExp, impTypes);
814
815 const int nq = Exp->GetTotPoints();
816 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
817 Array<OneD, NekDouble> phys(nelmts * nq), tmp, tmp1, tmp2;
818 Array<OneD, NekDouble> diff1(3 * nelmts * nq);
819 Array<OneD, NekDouble> diff2(3 * nelmts * nq);
820
821 Exp->GetCoords(xc, yc, zc);
822
823 for (int i = 0; i < nq; ++i)
824 {
825 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
826 }
827 Exp->PhysDeriv(phys, diff1, tmp1 = diff1 + (nelmts)*nq,
828 tmp2 = diff1 + (2 * nelmts) * nq);
829
830 for (int i = 1; i < nelmts; ++i)
831 {
832 Vmath::Vcopy(nq, phys, 1, tmp = phys + i * nq, 1);
833 Exp->PhysDeriv(phys, tmp = diff1 + i * nq,
834 tmp1 = diff1 + (nelmts + i) * nq,
835 tmp2 = diff1 + (2 * nelmts + i) * nq);
836 }
837
839 tmp = diff2 + nelmts * nq, tmp2 = diff2 + 2 * nelmts * nq);
840
841 double epsilon = 1.0e-8;
842 for (int i = 0; i < diff1.size(); ++i)
843 {
844 // clamp values below 1e-14 to zero
845 diff1[i] = (fabs(diff1[i]) < 1e-14) ? 0.0 : diff1[i];
846 diff2[i] = (fabs(diff2[i]) < 1e-14) ? 0.0 : diff2[i];
847 BOOST_CHECK_CLOSE(diff1[i], diff2[i], epsilon);
848 }
849}
850
851BOOST_AUTO_TEST_CASE(TestPyrPhysDeriv_SumFac_UniformP_MultiElmt)
852{
854 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
856 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
858 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
860 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
862 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
863
864 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
865 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
866 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
867 std::array<SpatialDomains::PointGeom *, 5> v = {
868 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
870 CreatePyr(v, segVec, triVec, quadVec);
871
872 Nektar::LibUtilities::PointsType PointsTypeDir1 =
874 const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1);
875 Nektar::LibUtilities::BasisType basisTypeDir1 =
877 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
878 PointsKeyDir1);
879
880 Nektar::LibUtilities::PointsType PointsTypeDir2 =
882 const Nektar::LibUtilities::PointsKey PointsKeyDir2(5, PointsTypeDir2);
883 Nektar::LibUtilities::BasisType basisTypeDir2 =
885 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
886 PointsKeyDir2);
887
888 Nektar::LibUtilities::PointsType PointsTypeDir3 =
889 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
890 const Nektar::LibUtilities::PointsKey PointsKeyDir3(4, PointsTypeDir3);
891 Nektar::LibUtilities::BasisType basisTypeDir3 =
893 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
894 PointsKeyDir3);
895
898 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
899 int nelmts = NELMTS;
900
901 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
902 for (int i = 0; i < nelmts; ++i)
903 {
904 CollExp.push_back(Exp);
905 }
906
908 Collections::CollectionOptimisation colOpt(dummySession, 3,
912 Collections::Collection c(CollExp, impTypes);
914
915 const int nq = Exp->GetTotPoints();
916 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
917 Array<OneD, NekDouble> phys(nelmts * nq), tmp, tmp1, tmp2;
918 Array<OneD, NekDouble> diff1(3 * nelmts * nq);
919 Array<OneD, NekDouble> diff2(3 * nelmts * nq);
920
921 Exp->GetCoords(xc, yc, zc);
922
923 for (int i = 0; i < nq; ++i)
924 {
925 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
926 }
927 Exp->PhysDeriv(phys, diff1, tmp1 = diff1 + (nelmts)*nq,
928 tmp2 = diff1 + (2 * nelmts) * nq);
929
930 for (int i = 1; i < nelmts; ++i)
931 {
932 Vmath::Vcopy(nq, phys, 1, tmp = phys + i * nq, 1);
933 Exp->PhysDeriv(phys, tmp = diff1 + i * nq,
934 tmp1 = diff1 + (nelmts + i) * nq,
935 tmp2 = diff1 + (2 * nelmts + i) * nq);
936 }
937
939 timer.Start();
941 tmp = diff2 + nelmts * nq, tmp2 = diff2 + 2 * nelmts * nq);
942 timer.Stop();
943 timer.AccumulateRegion("Pyr PhysDeriv SumFactor");
944
945 double epsilon = 1.0e-8;
946 for (int i = 0; i < diff1.size(); ++i)
947 {
948 // clamp values below 1e-14 to zero
949 diff1[i] = (fabs(diff1[i]) < 1e-14) ? 0.0 : diff1[i];
950 diff2[i] = (fabs(diff2[i]) < 1e-14) ? 0.0 : diff2[i];
951 BOOST_CHECK_CLOSE(diff1[i], diff2[i], epsilon);
952 }
953}
954
955BOOST_AUTO_TEST_CASE(TestPyrPhysDeriv_IterPerExp_VariableP_MultiElmt)
956{
958 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
960 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
962 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
964 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
966 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
967
968 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
969 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
970 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
971 std::array<SpatialDomains::PointGeom *, 5> v = {
972 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
974 CreatePyr(v, segVec, triVec, quadVec);
975
976 Nektar::LibUtilities::PointsType PointsTypeDir1 =
978 const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1);
979 Nektar::LibUtilities::BasisType basisTypeDir1 =
981 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
982 PointsKeyDir1);
983
984 Nektar::LibUtilities::PointsType PointsTypeDir2 =
986 const Nektar::LibUtilities::PointsKey PointsKeyDir2(7, PointsTypeDir2);
987 Nektar::LibUtilities::BasisType basisTypeDir2 =
989 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 6,
990 PointsKeyDir2);
991
992 Nektar::LibUtilities::PointsType PointsTypeDir3 =
993 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
994 const Nektar::LibUtilities::PointsKey PointsKeyDir3(8, PointsTypeDir3);
995 Nektar::LibUtilities::BasisType basisTypeDir3 =
997 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
998 PointsKeyDir3);
999
1002 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
1003
1004 int nelmts = 10;
1005
1006 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
1007 for (int i = 0; i < nelmts; ++i)
1008 {
1009 CollExp.push_back(Exp);
1010 }
1011
1013 Collections::CollectionOptimisation colOpt(dummySession, 3,
1015 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1016 Collections::Collection c(CollExp, impTypes);
1018
1019 const int nq = Exp->GetTotPoints();
1020 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1021 Array<OneD, NekDouble> phys(nelmts * nq), tmp, tmp1, tmp2;
1022 Array<OneD, NekDouble> diff1(3 * nelmts * nq);
1023 Array<OneD, NekDouble> diff2(3 * nelmts * nq);
1024
1025 Exp->GetCoords(xc, yc, zc);
1026
1027 for (int i = 0; i < nq; ++i)
1028 {
1029 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1030 }
1031 Exp->PhysDeriv(phys, diff1, tmp1 = diff1 + (nelmts)*nq,
1032 tmp2 = diff1 + (2 * nelmts) * nq);
1033
1034 for (int i = 1; i < nelmts; ++i)
1035 {
1036 Vmath::Vcopy(nq, phys, 1, tmp = phys + i * nq, 1);
1037 Exp->PhysDeriv(phys, tmp = diff1 + i * nq,
1038 tmp1 = diff1 + (nelmts + i) * nq,
1039 tmp2 = diff1 + (2 * nelmts + i) * nq);
1040 }
1041
1043 tmp = diff2 + nelmts * nq, tmp2 = diff2 + 2 * nelmts * nq);
1044
1045 double epsilon = 1.0e-8;
1046 for (int i = 0; i < diff1.size(); ++i)
1047 {
1048 // clamp values below 1e-14 to zero
1049 diff1[i] = (fabs(diff1[i]) < 1e-14) ? 0.0 : diff1[i];
1050 diff2[i] = (fabs(diff2[i]) < 1e-14) ? 0.0 : diff2[i];
1051 BOOST_CHECK_CLOSE(diff1[i], diff2[i], epsilon);
1052 }
1053}
1054
1055BOOST_AUTO_TEST_CASE(TestPyrPhysDeriv_SumFac_VariableP_MultiElmt)
1056{
1058 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1060 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1062 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
1064 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
1066 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
1067
1068 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
1069 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
1070 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
1071 std::array<SpatialDomains::PointGeom *, 5> v = {
1072 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
1074 CreatePyr(v, segVec, triVec, quadVec);
1075
1076 Nektar::LibUtilities::PointsType PointsTypeDir1 =
1078 const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1);
1079 Nektar::LibUtilities::BasisType basisTypeDir1 =
1081 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
1082 PointsKeyDir1);
1083
1084 Nektar::LibUtilities::PointsType PointsTypeDir2 =
1086 const Nektar::LibUtilities::PointsKey PointsKeyDir2(7, PointsTypeDir2);
1087 Nektar::LibUtilities::BasisType basisTypeDir2 =
1089 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 6,
1090 PointsKeyDir2);
1091
1092 Nektar::LibUtilities::PointsType PointsTypeDir3 =
1093 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1094 const Nektar::LibUtilities::PointsKey PointsKeyDir3(8, PointsTypeDir3);
1095 Nektar::LibUtilities::BasisType basisTypeDir3 =
1097 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
1098 PointsKeyDir3);
1099
1102 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
1103
1104 int nelmts = 10;
1105
1106 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
1107 for (int i = 0; i < nelmts; ++i)
1108 {
1109 CollExp.push_back(Exp);
1110 }
1111
1113 Collections::CollectionOptimisation colOpt(dummySession, 3,
1117
1118 Collections::Collection c(CollExp, impTypes);
1120
1121 const int nq = Exp->GetTotPoints();
1122 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1123 Array<OneD, NekDouble> phys(nelmts * nq), tmp, tmp1, tmp2;
1124 Array<OneD, NekDouble> diff1(3 * nelmts * nq);
1125 Array<OneD, NekDouble> diff2(3 * nelmts * nq);
1126
1127 Exp->GetCoords(xc, yc, zc);
1128
1129 for (int i = 0; i < nq; ++i)
1130 {
1131 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1132 }
1133 Exp->PhysDeriv(phys, tmp = diff1, tmp1 = diff1 + (nelmts)*nq,
1134 tmp2 = diff1 + (2 * nelmts) * nq);
1135 for (int i = 1; i < nelmts; ++i)
1136 {
1137 Vmath::Vcopy(nq, phys, 1, tmp = phys + i * nq, 1);
1138 Exp->PhysDeriv(phys, tmp = diff1 + i * nq,
1139 tmp1 = diff1 + (nelmts + i) * nq,
1140 tmp2 = diff1 + (2 * nelmts + i) * nq);
1141 }
1142
1144 tmp = diff2 + nelmts * nq, tmp2 = diff2 + 2 * nelmts * nq);
1145
1146 double epsilon = 1.0e-8;
1147 for (int i = 0; i < diff1.size(); ++i)
1148 {
1149 // clamp values below 1e-14 to zero
1150 diff1[i] = (fabs(diff1[i]) < 1e-14) ? 0.0 : diff1[i];
1151 diff2[i] = (fabs(diff2[i]) < 1e-14) ? 0.0 : diff2[i];
1152 BOOST_CHECK_CLOSE(diff1[i], diff2[i], epsilon);
1153 }
1154}
1155
1156BOOST_AUTO_TEST_CASE(TestPyrPhysDeriv_MatrixFree_UniformP_MultiElmt)
1157{
1159 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1161 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1163 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
1165 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
1167 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
1168
1169 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
1170 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
1171 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
1172 std::array<SpatialDomains::PointGeom *, 5> v = {
1173 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
1175 CreatePyr(v, segVec, triVec, quadVec);
1176
1177 unsigned int numQuadPoints = 5;
1178 unsigned int numModes = 2;
1179
1180 Nektar::LibUtilities::PointsType PointsTypeDir1 =
1182 const Nektar::LibUtilities::PointsKey PointsKeyDir1(numQuadPoints,
1183 PointsTypeDir1);
1184 Nektar::LibUtilities::BasisType basisTypeDir1 =
1186 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
1187 PointsKeyDir1);
1188
1189 Nektar::LibUtilities::PointsType PointsTypeDir2 =
1191 const Nektar::LibUtilities::PointsKey PointsKeyDir2(numQuadPoints,
1192 PointsTypeDir2);
1193 Nektar::LibUtilities::BasisType basisTypeDir2 =
1195 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
1196 PointsKeyDir2);
1197
1198 Nektar::LibUtilities::PointsType PointsTypeDir3 =
1199 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1200 const Nektar::LibUtilities::PointsKey PointsKeyDir3(numQuadPoints - 1,
1201 PointsTypeDir3);
1202 Nektar::LibUtilities::BasisType basisTypeDir3 =
1204 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
1205 PointsKeyDir3);
1206
1209 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
1210
1211 int nelmts = NELMTS;
1212
1213 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
1214 for (int i = 0; i < nelmts; ++i)
1215 {
1216 CollExp.push_back(Exp);
1217 }
1218
1220 Collections::CollectionOptimisation colOpt(dummySession, 2,
1222 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1223
1225 Collections::Collection c(CollExp, impTypes);
1227
1228 const int nq = Exp->GetTotPoints();
1229 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1230 Array<OneD, NekDouble> phys(nelmts * nq), tmp, tmp1, tmp2;
1231 Array<OneD, NekDouble> diff1(3 * nelmts * nq);
1232 Array<OneD, NekDouble> diff2(3 * nelmts * nq);
1233
1234 Exp->GetCoords(xc, yc, zc);
1235
1236 for (int i = 0; i < nq; ++i)
1237 {
1238 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1239 }
1240 Exp->PhysDeriv(phys, diff1, tmp1 = diff1 + (nelmts)*nq,
1241 tmp2 = diff1 + (2 * nelmts) * nq);
1242
1243 for (int i = 1; i < nelmts; ++i)
1244 {
1245 Vmath::Vcopy(nq, phys, 1, tmp = phys + i * nq, 1);
1246 Exp->PhysDeriv(phys, tmp = diff1 + i * nq,
1247 tmp1 = diff1 + (nelmts + i) * nq,
1248 tmp2 = diff1 + (2 * nelmts + i) * nq);
1249 }
1250
1251 LibUtilities::Timer timer;
1252 timer.Start();
1254 tmp = diff2 + nelmts * nq, tmp2 = diff2 + 2 * nelmts * nq);
1255 timer.Stop();
1256 timer.AccumulateRegion("Pyr PhysDeriv MatrixFree");
1257
1258 double epsilon = 1.0e-8;
1259 for (int i = 0; i < diff1.size(); ++i)
1260 {
1261 // clamp values below 1e-14 to zero
1262 diff1[i] = (fabs(diff1[i]) < 1e-14) ? 0.0 : diff1[i];
1263 diff2[i] = (fabs(diff2[i]) < 1e-14) ? 0.0 : diff2[i];
1264 BOOST_CHECK_CLOSE(diff1[i], diff2[i], epsilon);
1265 }
1266}
1267
1268BOOST_AUTO_TEST_CASE(TestPyrIProductWRTBase_IterPerExp_UniformP_MultiElmt)
1269{
1271 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1273 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1275 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
1277 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
1279 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
1280
1281 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
1282 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
1283 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
1284 std::array<SpatialDomains::PointGeom *, 5> v = {
1285 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
1287 CreatePyr(v, segVec, triVec, quadVec);
1288
1289 Nektar::LibUtilities::PointsType PointsTypeDir1 =
1291 const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1);
1292 Nektar::LibUtilities::BasisType basisTypeDir1 =
1294 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
1295 PointsKeyDir1);
1296
1297 Nektar::LibUtilities::PointsType PointsTypeDir2 =
1299 const Nektar::LibUtilities::PointsKey PointsKeyDir2(5, PointsTypeDir2);
1300 Nektar::LibUtilities::BasisType basisTypeDir2 =
1302 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
1303 PointsKeyDir2);
1304
1305 Nektar::LibUtilities::PointsType PointsTypeDir3 =
1306 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1307 const Nektar::LibUtilities::PointsKey PointsKeyDir3(4, PointsTypeDir3);
1308 Nektar::LibUtilities::BasisType basisTypeDir3 =
1310 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
1311 PointsKeyDir3);
1312
1315 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
1316
1317 int nelmts = NELMTS;
1318
1319 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
1320 for (int i = 0; i < nelmts; ++i)
1321 {
1322 CollExp.push_back(Exp);
1323 }
1324
1326 Collections::CollectionOptimisation colOpt(dummySession, 3,
1328 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1329 Collections::Collection c(CollExp, impTypes);
1331
1332 const int nq = Exp->GetTotPoints();
1333 Array<OneD, NekDouble> phys(nelmts * nq, 0.0);
1334 Array<OneD, NekDouble> coeffs1(nelmts * Exp->GetNcoeffs(), 0.0);
1335 Array<OneD, NekDouble> coeffs2(nelmts * Exp->GetNcoeffs(), 0.0);
1337 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1338
1339 Exp->GetCoords(xc, yc, zc);
1340
1341 for (int i = 0; i < nq; ++i)
1342 {
1343 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1344 }
1345 Exp->IProductWRTBase(phys, coeffs1);
1346
1347 for (int i = 1; i < nelmts; ++i)
1348 {
1349 Vmath::Vcopy(nq, &phys[0], 1, &phys[i * nq], 1);
1350 Exp->IProductWRTBase(phys + i * nq,
1351 tmp = coeffs1 + i * Exp->GetNcoeffs());
1352 }
1353
1354 LibUtilities::Timer timer;
1355 timer.Start();
1357 timer.Stop();
1358 timer.AccumulateRegion("Pyr IProdWRTB IterPerExp");
1359
1360 double epsilon = 1.0e-8;
1361 for (int i = 0; i < coeffs1.size(); ++i)
1362 {
1363 // clamp values below 1e-14 to zero
1364 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
1365 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
1366 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
1367 }
1368}
1369
1370BOOST_AUTO_TEST_CASE(TestPyrIProductWRTBase_StdMat_UniformP_MultiElmt)
1371{
1373 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1375 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1377 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
1379 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
1381 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
1382
1383 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
1384 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
1385 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
1386 std::array<SpatialDomains::PointGeom *, 5> v = {
1387 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
1389 CreatePyr(v, segVec, triVec, quadVec);
1390
1391 Nektar::LibUtilities::PointsType PointsTypeDir1 =
1393 const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1);
1394 Nektar::LibUtilities::BasisType basisTypeDir1 =
1396 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
1397 PointsKeyDir1);
1398
1399 Nektar::LibUtilities::PointsType PointsTypeDir2 =
1401 const Nektar::LibUtilities::PointsKey PointsKeyDir2(5, PointsTypeDir2);
1402 Nektar::LibUtilities::BasisType basisTypeDir2 =
1404 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
1405 PointsKeyDir2);
1406
1407 Nektar::LibUtilities::PointsType PointsTypeDir3 =
1408 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1409 const Nektar::LibUtilities::PointsKey PointsKeyDir3(4, PointsTypeDir3);
1410 Nektar::LibUtilities::BasisType basisTypeDir3 =
1412 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
1413 PointsKeyDir3);
1414
1417 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
1418
1419 int nelmts = 10;
1420
1421 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
1422 for (int i = 0; i < nelmts; ++i)
1423 {
1424 CollExp.push_back(Exp);
1425 }
1426
1428 Collections::CollectionOptimisation colOpt(dummySession, 3,
1430 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1431 Collections::Collection c(CollExp, impTypes);
1433
1434 const int nq = Exp->GetTotPoints();
1435 Array<OneD, NekDouble> phys(nelmts * nq, 0.0);
1436 Array<OneD, NekDouble> coeffs1(nelmts * Exp->GetNcoeffs(), 0.0);
1437 Array<OneD, NekDouble> coeffs2(nelmts * Exp->GetNcoeffs(), 0.0);
1439 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1440
1441 Exp->GetCoords(xc, yc, zc);
1442
1443 for (int i = 0; i < nq; ++i)
1444 {
1445 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1446 }
1447 Exp->IProductWRTBase(phys, coeffs1);
1448
1449 for (int i = 1; i < nelmts; ++i)
1450 {
1451 Vmath::Vcopy(nq, &phys[0], 1, &phys[i * nq], 1);
1452 Exp->IProductWRTBase(phys + i * nq,
1453 tmp = coeffs1 + i * Exp->GetNcoeffs());
1454 }
1455
1457
1458 double epsilon = 1.0e-8;
1459 for (int i = 0; i < coeffs1.size(); ++i)
1460 {
1461 // clamp values below 1e-14 to zero
1462 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
1463 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
1464 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
1465 }
1466}
1467
1468BOOST_AUTO_TEST_CASE(TestPyrIProductWRTBase_SumFac_UniformP_MultiElmt)
1469{
1471 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1473 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1475 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
1477 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
1479 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
1480
1481 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
1482 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
1483 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
1484 std::array<SpatialDomains::PointGeom *, 5> v = {
1485 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
1487 CreatePyr(v, segVec, triVec, quadVec);
1488
1489 Nektar::LibUtilities::PointsType PointsTypeDir1 =
1491 const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1);
1492 Nektar::LibUtilities::BasisType basisTypeDir1 =
1494 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
1495 PointsKeyDir1);
1496
1497 Nektar::LibUtilities::PointsType PointsTypeDir2 =
1499 const Nektar::LibUtilities::PointsKey PointsKeyDir2(5, PointsTypeDir2);
1500 Nektar::LibUtilities::BasisType basisTypeDir2 =
1502 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
1503 PointsKeyDir2);
1504
1505 Nektar::LibUtilities::PointsType PointsTypeDir3 =
1506 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1507 const Nektar::LibUtilities::PointsKey PointsKeyDir3(4, PointsTypeDir3);
1508 Nektar::LibUtilities::BasisType basisTypeDir3 =
1510 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
1511 PointsKeyDir3);
1512
1515 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
1516
1517 int nelmts = NELMTS;
1518
1519 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
1520 for (int i = 0; i < nelmts; ++i)
1521 {
1522 CollExp.push_back(Exp);
1523 }
1524
1526 Collections::CollectionOptimisation colOpt(dummySession, 3,
1530 Collections::Collection c(CollExp, impTypes);
1532
1533 const int nq = Exp->GetTotPoints();
1534 Array<OneD, NekDouble> phys(nelmts * nq, 0.0);
1535 Array<OneD, NekDouble> coeffs1(nelmts * Exp->GetNcoeffs(), 0.0);
1536 Array<OneD, NekDouble> coeffs2(nelmts * Exp->GetNcoeffs(), 0.0);
1538 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1539
1540 Exp->GetCoords(xc, yc, zc);
1541
1542 for (int i = 0; i < nq; ++i)
1543 {
1544 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1545 }
1546 Exp->IProductWRTBase(phys, coeffs1);
1547
1548 for (int i = 1; i < nelmts; ++i)
1549 {
1550 Vmath::Vcopy(nq, &phys[0], 1, &phys[i * nq], 1);
1551 Exp->IProductWRTBase(phys + i * nq,
1552 tmp = coeffs1 + i * Exp->GetNcoeffs());
1553 }
1554
1555 LibUtilities::Timer timer;
1556 timer.Start();
1558 timer.Stop();
1559 timer.AccumulateRegion("Pyr IProdWRTB SumFactor");
1560
1561 double epsilon = 1.0e-8;
1562 for (int i = 0; i < coeffs1.size(); ++i)
1563 {
1564 // clamp values below 1e-14 to zero
1565 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
1566 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
1567 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
1568 }
1569}
1570
1571BOOST_AUTO_TEST_CASE(TestPyrIProductWRTBase_IterPerExp_VariableP_MultiElmt)
1572{
1574 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1576 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1578 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
1580 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
1582 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
1583
1584 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
1585 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
1586 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
1587 std::array<SpatialDomains::PointGeom *, 5> v = {
1588 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
1590 CreatePyr(v, segVec, triVec, quadVec);
1591
1592 Nektar::LibUtilities::PointsType PointsTypeDir1 =
1594 const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1);
1595 Nektar::LibUtilities::BasisType basisTypeDir1 =
1597 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
1598 PointsKeyDir1);
1599
1600 Nektar::LibUtilities::PointsType PointsTypeDir2 =
1602 const Nektar::LibUtilities::PointsKey PointsKeyDir2(7, PointsTypeDir2);
1603 Nektar::LibUtilities::BasisType basisTypeDir2 =
1605 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 6,
1606 PointsKeyDir2);
1607
1608 Nektar::LibUtilities::PointsType PointsTypeDir3 =
1609 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1610 const Nektar::LibUtilities::PointsKey PointsKeyDir3(8, PointsTypeDir3);
1611 Nektar::LibUtilities::BasisType basisTypeDir3 =
1613 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
1614 PointsKeyDir3);
1615
1618 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
1619
1620 int nelmts = 10;
1621
1622 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
1623 for (int i = 0; i < nelmts; ++i)
1624 {
1625 CollExp.push_back(Exp);
1626 }
1627
1629 Collections::CollectionOptimisation colOpt(dummySession, 3,
1631 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1632 Collections::Collection c(CollExp, impTypes);
1634
1635 const int nq = Exp->GetTotPoints();
1636 Array<OneD, NekDouble> phys(nelmts * nq, 0.0);
1637 Array<OneD, NekDouble> coeffs1(nelmts * Exp->GetNcoeffs(), 0.0);
1638 Array<OneD, NekDouble> coeffs2(nelmts * Exp->GetNcoeffs(), 0.0);
1640 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1641
1642 Exp->GetCoords(xc, yc, zc);
1643
1644 for (int i = 0; i < nq; ++i)
1645 {
1646 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1647 }
1648 Exp->IProductWRTBase(phys, coeffs1);
1649
1650 for (int i = 1; i < nelmts; ++i)
1651 {
1652 Vmath::Vcopy(nq, &phys[0], 1, &phys[i * nq], 1);
1653 Exp->IProductWRTBase(phys + i * nq,
1654 tmp = coeffs1 + i * Exp->GetNcoeffs());
1655 }
1656
1658
1659 double epsilon = 1.0e-8;
1660 for (int i = 0; i < coeffs1.size(); ++i)
1661 {
1662 // clamp values below 1e-14 to zero
1663 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
1664 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
1665 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
1666 }
1667}
1668
1669BOOST_AUTO_TEST_CASE(TestPyrIProductWRTBase_StdMat_VariableP_MultiElmt)
1670{
1672 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1674 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1676 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
1678 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
1680 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
1681
1682 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
1683 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
1684 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
1685 std::array<SpatialDomains::PointGeom *, 5> v = {
1686 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
1688 CreatePyr(v, segVec, triVec, quadVec);
1689
1690 Nektar::LibUtilities::PointsType PointsTypeDir1 =
1692 const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1);
1693 Nektar::LibUtilities::BasisType basisTypeDir1 =
1695 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
1696 PointsKeyDir1);
1697
1698 Nektar::LibUtilities::PointsType PointsTypeDir2 =
1700 const Nektar::LibUtilities::PointsKey PointsKeyDir2(7, PointsTypeDir2);
1701 Nektar::LibUtilities::BasisType basisTypeDir2 =
1703 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 6,
1704 PointsKeyDir2);
1705
1706 Nektar::LibUtilities::PointsType PointsTypeDir3 =
1707 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1708 const Nektar::LibUtilities::PointsKey PointsKeyDir3(8, PointsTypeDir3);
1709 Nektar::LibUtilities::BasisType basisTypeDir3 =
1711 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
1712 PointsKeyDir3);
1713
1716 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
1717
1718 int nelmts = 10;
1719
1720 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
1721 for (int i = 0; i < nelmts; ++i)
1722 {
1723 CollExp.push_back(Exp);
1724 }
1725
1727 Collections::CollectionOptimisation colOpt(dummySession, 3,
1729 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1730 Collections::Collection c(CollExp, impTypes);
1732
1733 const int nq = Exp->GetTotPoints();
1734 Array<OneD, NekDouble> phys(nelmts * nq, 0.0);
1735 Array<OneD, NekDouble> coeffs1(nelmts * Exp->GetNcoeffs(), 0.0);
1736 Array<OneD, NekDouble> coeffs2(nelmts * Exp->GetNcoeffs(), 0.0);
1738 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1739
1740 Exp->GetCoords(xc, yc, zc);
1741
1742 for (int i = 0; i < nq; ++i)
1743 {
1744 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1745 }
1746 Exp->IProductWRTBase(phys, coeffs1);
1747
1748 for (int i = 1; i < nelmts; ++i)
1749 {
1750 Vmath::Vcopy(nq, &phys[0], 1, &phys[i * nq], 1);
1751 Exp->IProductWRTBase(phys + i * nq,
1752 tmp = coeffs1 + i * Exp->GetNcoeffs());
1753 }
1754
1756
1757 double epsilon = 1.0e-8;
1758 for (int i = 0; i < coeffs1.size(); ++i)
1759 {
1760 // clamp values below 1e-14 to zero
1761 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
1762 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
1763 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
1764 }
1765}
1766
1767BOOST_AUTO_TEST_CASE(TestPyrIProductWRTBase_SumFac_VariableP_MultiElmt)
1768{
1770 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1772 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1774 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
1776 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
1778 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
1779
1780 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
1781 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
1782 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
1783 std::array<SpatialDomains::PointGeom *, 5> v = {
1784 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
1786 CreatePyr(v, segVec, triVec, quadVec);
1787
1788 Nektar::LibUtilities::PointsType PointsTypeDir1 =
1790 const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1);
1791 Nektar::LibUtilities::BasisType basisTypeDir1 =
1793 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
1794 PointsKeyDir1);
1795
1796 Nektar::LibUtilities::PointsType PointsTypeDir2 =
1798 const Nektar::LibUtilities::PointsKey PointsKeyDir2(7, PointsTypeDir2);
1799 Nektar::LibUtilities::BasisType basisTypeDir2 =
1801 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 6,
1802 PointsKeyDir2);
1803
1804 Nektar::LibUtilities::PointsType PointsTypeDir3 =
1805 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1806 const Nektar::LibUtilities::PointsKey PointsKeyDir3(8, PointsTypeDir3);
1807 Nektar::LibUtilities::BasisType basisTypeDir3 =
1809 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
1810 PointsKeyDir3);
1811
1814 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
1815
1816 int nelmts = 10;
1817
1818 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
1819 for (int i = 0; i < nelmts; ++i)
1820 {
1821 CollExp.push_back(Exp);
1822 }
1823
1825 Collections::CollectionOptimisation colOpt(dummySession, 3,
1829 Collections::Collection c(CollExp, impTypes);
1831
1832 const int nq = Exp->GetTotPoints();
1833 Array<OneD, NekDouble> phys(nelmts * nq, 0.0);
1834 Array<OneD, NekDouble> coeffs1(nelmts * Exp->GetNcoeffs(), 0.0);
1835 Array<OneD, NekDouble> coeffs2(nelmts * Exp->GetNcoeffs(), 0.0);
1837 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1838
1839 Exp->GetCoords(xc, yc, zc);
1840
1841 for (int i = 0; i < nq; ++i)
1842 {
1843 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1844 }
1845 Exp->IProductWRTBase(phys, coeffs1);
1846
1847 for (int i = 1; i < nelmts; ++i)
1848 {
1849 Vmath::Vcopy(nq, &phys[0], 1, &phys[i * nq], 1);
1850 Exp->IProductWRTBase(phys + i * nq,
1851 tmp = coeffs1 + i * Exp->GetNcoeffs());
1852 }
1853
1855
1856 double epsilon = 1.0e-8;
1857 for (int i = 0; i < coeffs1.size(); ++i)
1858 {
1859 // clamp values below 1e-14 to zero
1860 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
1861 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
1862 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
1863 }
1864}
1865
1866BOOST_AUTO_TEST_CASE(TestPyrIProductWRTBase_MatrixFree_UniformP_MultiElmt)
1867{
1869 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1871 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1873 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
1875 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
1877 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
1878
1879 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
1880 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
1881 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
1882 std::array<SpatialDomains::PointGeom *, 5> v = {
1883 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
1885 CreatePyr(v, segVec, triVec, quadVec);
1886
1887 unsigned int numQuadPoints = 5;
1888 unsigned int numModes = 4;
1889
1890 Nektar::LibUtilities::PointsType PointsTypeDir1 =
1892 const Nektar::LibUtilities::PointsKey PointsKeyDir1(numQuadPoints,
1893 PointsTypeDir1);
1894 Nektar::LibUtilities::BasisType basisTypeDir1 =
1896 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
1897 PointsKeyDir1);
1898
1899 Nektar::LibUtilities::PointsType PointsTypeDir2 =
1901 const Nektar::LibUtilities::PointsKey PointsKeyDir2(numQuadPoints,
1902 PointsTypeDir2);
1903 Nektar::LibUtilities::BasisType basisTypeDir2 =
1905 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
1906 PointsKeyDir2);
1907
1908 Nektar::LibUtilities::PointsType PointsTypeDir3 =
1909 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1910 const Nektar::LibUtilities::PointsKey PointsKeyDir3(numQuadPoints - 1,
1911 PointsTypeDir3);
1912 Nektar::LibUtilities::BasisType basisTypeDir3 =
1914 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
1915 PointsKeyDir3);
1916
1919 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
1920
1921 int nelmts = NELMTS;
1922
1923 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
1924 for (int i = 0; i < nelmts; ++i)
1925 {
1926 CollExp.push_back(Exp);
1927 }
1928
1930 Collections::CollectionOptimisation colOpt(dummySession, 2,
1934 Collections::Collection c(CollExp, impTypes);
1936
1937 const int nq = Exp->GetTotPoints();
1938 Array<OneD, NekDouble> phys(nelmts * nq, 0.0);
1939 Array<OneD, NekDouble> coeffs1(nelmts * Exp->GetNcoeffs(), 0.0);
1940 Array<OneD, NekDouble> coeffs2(nelmts * Exp->GetNcoeffs(), 0.0);
1942 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1943
1944 Exp->GetCoords(xc, yc, zc);
1945
1946 for (int i = 0; i < nq; ++i)
1947 {
1948 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1949 }
1950 Exp->IProductWRTBase(phys, coeffs1);
1951
1952 for (int i = 1; i < nelmts; ++i)
1953 {
1954 Vmath::Vcopy(nq, &phys[0], 1, &phys[i * nq], 1);
1955 Exp->IProductWRTBase(phys + i * nq,
1956 tmp = coeffs1 + i * Exp->GetNcoeffs());
1957 }
1958
1959 LibUtilities::Timer timer;
1960 timer.Start();
1962 timer.Stop();
1963 timer.AccumulateRegion("Pyr IProdWRTB MatrixFree");
1964
1965 double epsilon = 1.0e-8;
1966 for (int i = 0; i < coeffs1.size(); ++i)
1967 {
1968 // clamp values below 1e-14 to zero
1969 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
1970 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
1971 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
1972 }
1973}
1974
1975BOOST_AUTO_TEST_CASE(TestPyrIProductWRTBase_MatrixFree_Deformed_MultiElmt)
1976{
1978 new SpatialDomains::PointGeom(3u, 0u, -2.0, -3.0, -4.0));
1980 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1982 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
1984 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
1986 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
1987
1988 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
1989 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
1990 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
1991 std::array<SpatialDomains::PointGeom *, 5> v = {
1992 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
1994 CreatePyr(v, segVec, triVec, quadVec);
1995
1996 unsigned int numQuadPoints = 5;
1997 unsigned int numModes = 4;
1998
1999 Nektar::LibUtilities::PointsType PointsTypeDir1 =
2001 const Nektar::LibUtilities::PointsKey PointsKeyDir1(numQuadPoints,
2002 PointsTypeDir1);
2003 Nektar::LibUtilities::BasisType basisTypeDir1 =
2005 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
2006 PointsKeyDir1);
2007
2008 Nektar::LibUtilities::PointsType PointsTypeDir2 =
2010 const Nektar::LibUtilities::PointsKey PointsKeyDir2(numQuadPoints,
2011 PointsTypeDir2);
2012 Nektar::LibUtilities::BasisType basisTypeDir2 =
2014 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
2015 PointsKeyDir2);
2016
2017 Nektar::LibUtilities::PointsType PointsTypeDir3 =
2018 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2019 const Nektar::LibUtilities::PointsKey PointsKeyDir3(numQuadPoints - 1,
2020 PointsTypeDir3);
2021 Nektar::LibUtilities::BasisType basisTypeDir3 =
2023 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
2024 PointsKeyDir3);
2025
2028 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
2029
2030 int nelmts = 5;
2031
2032 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
2033 for (int i = 0; i < nelmts; ++i)
2034 {
2035 CollExp.push_back(Exp);
2036 }
2037
2039 Collections::CollectionOptimisation colOpt(dummySession, 2,
2042
2044 Collections::Collection c(CollExp, impTypes);
2046
2047 const int nq = Exp->GetTotPoints();
2048 Array<OneD, NekDouble> phys(nelmts * nq, 0.0);
2049 Array<OneD, NekDouble> coeffs1(nelmts * Exp->GetNcoeffs(), 0.0);
2050 Array<OneD, NekDouble> coeffs2(nelmts * Exp->GetNcoeffs(), 0.0);
2052 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
2053
2054 Exp->GetCoords(xc, yc, zc);
2055
2056 for (int i = 0; i < nq; ++i)
2057 {
2058 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
2059 }
2060 Exp->IProductWRTBase(phys, coeffs1);
2061
2062 for (int i = 1; i < nelmts; ++i)
2063 {
2064 Vmath::Vcopy(nq, &phys[0], 1, &phys[i * nq], 1);
2065 Exp->IProductWRTBase(phys + i * nq,
2066 tmp = coeffs1 + i * Exp->GetNcoeffs());
2067 }
2068
2070
2071 double epsilon = 1.0e-8;
2072 for (int i = 0; i < coeffs1.size(); ++i)
2073 {
2074 // clamp values below 1e-14 to zero
2075 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
2076 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
2077 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
2078 }
2079}
2080
2081BOOST_AUTO_TEST_CASE(TestPyrIProductWRTDerivBase_IterPerExp_UniformP_MultiElmt)
2082{
2084 new SpatialDomains::PointGeom(3u, 0u, -1.5, -1.5, -1.5));
2086 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2088 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
2090 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
2092 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
2093
2094 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
2095 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
2096 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
2097 std::array<SpatialDomains::PointGeom *, 5> v = {
2098 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
2100 CreatePyr(v, segVec, triVec, quadVec);
2101
2102 Nektar::LibUtilities::PointsType PointsTypeDir1 =
2104 const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1);
2105 Nektar::LibUtilities::BasisType basisTypeDir1 =
2107 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
2108 PointsKeyDir1);
2109
2110 Nektar::LibUtilities::PointsType PointsTypeDir2 =
2112 const Nektar::LibUtilities::PointsKey PointsKeyDir2(5, PointsTypeDir2);
2113 Nektar::LibUtilities::BasisType basisTypeDir2 =
2115 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
2116 PointsKeyDir2);
2117
2118 Nektar::LibUtilities::PointsType PointsTypeDir3 =
2119 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2120 const Nektar::LibUtilities::PointsKey PointsKeyDir3(4, PointsTypeDir3);
2121 Nektar::LibUtilities::BasisType basisTypeDir3 =
2123 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
2124 PointsKeyDir3);
2125
2128 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
2129
2130 int nelmts = NELMTS;
2131
2132 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
2133 for (int i = 0; i < nelmts; ++i)
2134 {
2135 CollExp.push_back(Exp);
2136 }
2137
2139 Collections::CollectionOptimisation colOpt(dummySession, 3,
2141 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2142 Collections::Collection c(CollExp, impTypes);
2144
2145 const int nq = Exp->GetTotPoints();
2146 const int nm = Exp->GetNcoeffs();
2147 Array<OneD, NekDouble> phys1(nelmts * nq), tmp;
2148 Array<OneD, NekDouble> phys2(nelmts * nq);
2149 Array<OneD, NekDouble> phys3(nelmts * nq);
2150 Array<OneD, NekDouble> coeffs1(nelmts * nm);
2151 Array<OneD, NekDouble> coeffs2(nelmts * nm);
2152
2153 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
2154
2155 Exp->GetCoords(xc, yc, zc);
2156
2157 for (int i = 0; i < nq; ++i)
2158 {
2159 phys1[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
2160 phys2[i] = cos(xc[i]) * sin(yc[i]) * cos(zc[i]);
2161 phys3[i] = cos(xc[i]) * sin(yc[i]) * sin(zc[i]);
2162 }
2163 for (int i = 1; i < nelmts; ++i)
2164 {
2165 Vmath::Vcopy(nq, phys1, 1, tmp = phys1 + i * nq, 1);
2166 Vmath::Vcopy(nq, phys2, 1, tmp = phys2 + i * nq, 1);
2167 Vmath::Vcopy(nq, phys3, 1, tmp = phys3 + i * nq, 1);
2168 }
2169
2170 // Standard routines
2171 for (int i = 0; i < nelmts; ++i)
2172 {
2173 Exp->IProductWRTDerivBase(0, phys1 + i * nq, tmp = coeffs1 + i * nm);
2174 Exp->IProductWRTDerivBase(1, phys2 + i * nq, tmp = coeffs2 + i * nm);
2175 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
2176 tmp = coeffs1 + i * nm, 1);
2177 Exp->IProductWRTDerivBase(2, phys3 + i * nq, tmp = coeffs2 + i * nm);
2178 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
2179 tmp = coeffs1 + i * nm, 1);
2180 }
2181
2182 LibUtilities::Timer timer;
2183 timer.Start();
2185 coeffs2);
2186 timer.Stop();
2187 timer.AccumulateRegion("Pyr IProdWRTDB IterPerExp");
2188
2189 double epsilon = 1.0e-8;
2190 for (int i = 0; i < coeffs1.size(); ++i)
2191 {
2192 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
2193 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
2194 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
2195 }
2196}
2197
2198BOOST_AUTO_TEST_CASE(TestPyrIProductWRTDerivBase_StdMat_UniformP_MultiElmt)
2199{
2201 new SpatialDomains::PointGeom(3u, 0u, -1.5, -1.5, -1.5));
2203 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2205 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
2207 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
2209 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
2210
2211 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
2212 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
2213 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
2214 std::array<SpatialDomains::PointGeom *, 5> v = {
2215 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
2217 CreatePyr(v, segVec, triVec, quadVec);
2218
2219 Nektar::LibUtilities::PointsType PointsTypeDir1 =
2221 const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1);
2222 Nektar::LibUtilities::BasisType basisTypeDir1 =
2224 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
2225 PointsKeyDir1);
2226
2227 Nektar::LibUtilities::PointsType PointsTypeDir2 =
2229 const Nektar::LibUtilities::PointsKey PointsKeyDir2(5, PointsTypeDir2);
2230 Nektar::LibUtilities::BasisType basisTypeDir2 =
2232 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
2233 PointsKeyDir2);
2234
2235 Nektar::LibUtilities::PointsType PointsTypeDir3 =
2236 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2237 const Nektar::LibUtilities::PointsKey PointsKeyDir3(4, PointsTypeDir3);
2238 Nektar::LibUtilities::BasisType basisTypeDir3 =
2240 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
2241 PointsKeyDir3);
2242
2245 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
2246
2247 int nelmts = 10;
2248
2249 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
2250 for (int i = 0; i < nelmts; ++i)
2251 {
2252 CollExp.push_back(Exp);
2253 }
2254
2256 Collections::CollectionOptimisation colOpt(dummySession, 3,
2258 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2259 Collections::Collection c(CollExp, impTypes);
2261
2262 const int nq = Exp->GetTotPoints();
2263 const int nm = Exp->GetNcoeffs();
2264 Array<OneD, NekDouble> phys1(nelmts * nq), tmp;
2265 Array<OneD, NekDouble> phys2(nelmts * nq);
2266 Array<OneD, NekDouble> phys3(nelmts * nq);
2267 Array<OneD, NekDouble> coeffs1(nelmts * nm);
2268 Array<OneD, NekDouble> coeffs2(nelmts * nm);
2269
2270 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
2271
2272 Exp->GetCoords(xc, yc, zc);
2273
2274 for (int i = 0; i < nq; ++i)
2275 {
2276 phys1[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
2277 phys2[i] = cos(xc[i]) * sin(yc[i]) * cos(zc[i]);
2278 phys3[i] = cos(xc[i]) * sin(yc[i]) * sin(zc[i]);
2279 }
2280 for (int i = 1; i < nelmts; ++i)
2281 {
2282 Vmath::Vcopy(nq, phys1, 1, tmp = phys1 + i * nq, 1);
2283 Vmath::Vcopy(nq, phys2, 1, tmp = phys2 + i * nq, 1);
2284 Vmath::Vcopy(nq, phys3, 1, tmp = phys3 + i * nq, 1);
2285 }
2286
2287 // Standard routines
2288 for (int i = 0; i < nelmts; ++i)
2289 {
2290 Exp->IProductWRTDerivBase(0, phys1 + i * nq, tmp = coeffs1 + i * nm);
2291 Exp->IProductWRTDerivBase(1, phys2 + i * nq, tmp = coeffs2 + i * nm);
2292 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
2293 tmp = coeffs1 + i * nm, 1);
2294 Exp->IProductWRTDerivBase(2, phys3 + i * nq, tmp = coeffs2 + i * nm);
2295 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
2296 tmp = coeffs1 + i * nm, 1);
2297 }
2298
2300 coeffs2);
2301
2302 double epsilon = 1.0e-8;
2303 for (int i = 0; i < coeffs1.size(); ++i)
2304 {
2305 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
2306 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
2307 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
2308 }
2309}
2310
2311BOOST_AUTO_TEST_CASE(TestPyrIProductWRTDerivBase_SumFac_UniformP_MultiElmt)
2312{
2314 new SpatialDomains::PointGeom(3u, 0u, -1.5, -1.5, -1.5));
2316 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2318 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
2320 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
2322 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
2323
2324 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
2325 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
2326 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
2327 std::array<SpatialDomains::PointGeom *, 5> v = {
2328 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
2330 CreatePyr(v, segVec, triVec, quadVec);
2331
2332 Nektar::LibUtilities::PointsType PointsTypeDir1 =
2334 const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1);
2335 Nektar::LibUtilities::BasisType basisTypeDir1 =
2337 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
2338 PointsKeyDir1);
2339
2340 Nektar::LibUtilities::PointsType PointsTypeDir2 =
2342 const Nektar::LibUtilities::PointsKey PointsKeyDir2(5, PointsTypeDir2);
2343 Nektar::LibUtilities::BasisType basisTypeDir2 =
2345 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
2346 PointsKeyDir2);
2347
2348 Nektar::LibUtilities::PointsType PointsTypeDir3 =
2349 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2350 const Nektar::LibUtilities::PointsKey PointsKeyDir3(4, PointsTypeDir3);
2351 Nektar::LibUtilities::BasisType basisTypeDir3 =
2353 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
2354 PointsKeyDir3);
2355
2358 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
2359
2360 int nelmts = NELMTS;
2361
2362 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
2363 for (int i = 0; i < nelmts; ++i)
2364 {
2365 CollExp.push_back(Exp);
2366 }
2367
2369 Collections::CollectionOptimisation colOpt(dummySession, 3,
2371 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2372 Collections::Collection c(CollExp, impTypes);
2374
2375 const int nq = Exp->GetTotPoints();
2376 const int nm = Exp->GetNcoeffs();
2377 Array<OneD, NekDouble> phys1(nelmts * nq), tmp;
2378 Array<OneD, NekDouble> phys2(nelmts * nq);
2379 Array<OneD, NekDouble> phys3(nelmts * nq);
2380 Array<OneD, NekDouble> coeffs1(nelmts * nm);
2381 Array<OneD, NekDouble> coeffs2(nelmts * nm);
2382
2383 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
2384
2385 Exp->GetCoords(xc, yc, zc);
2386
2387 for (int i = 0; i < nq; ++i)
2388 {
2389 phys1[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
2390 phys2[i] = cos(xc[i]) * sin(yc[i]) * cos(zc[i]);
2391 phys3[i] = cos(xc[i]) * sin(yc[i]) * sin(zc[i]);
2392 }
2393 for (int i = 1; i < nelmts; ++i)
2394 {
2395 Vmath::Vcopy(nq, phys1, 1, tmp = phys1 + i * nq, 1);
2396 Vmath::Vcopy(nq, phys2, 1, tmp = phys2 + i * nq, 1);
2397 Vmath::Vcopy(nq, phys3, 1, tmp = phys3 + i * nq, 1);
2398 }
2399
2400 // Standard routines
2401 for (int i = 0; i < nelmts; ++i)
2402 {
2403 Exp->IProductWRTDerivBase(0, phys1 + i * nq, tmp = coeffs1 + i * nm);
2404 Exp->IProductWRTDerivBase(1, phys2 + i * nq, tmp = coeffs2 + i * nm);
2405 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
2406 tmp = coeffs1 + i * nm, 1);
2407 Exp->IProductWRTDerivBase(2, phys3 + i * nq, tmp = coeffs2 + i * nm);
2408 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
2409 tmp = coeffs1 + i * nm, 1);
2410 }
2411
2412 LibUtilities::Timer timer;
2413 timer.Start();
2415 coeffs2);
2416 timer.Stop();
2417 timer.AccumulateRegion("Pyr IProdWRTDB SumFactor");
2418
2419 double epsilon = 1.0e-8;
2420 for (int i = 0; i < coeffs1.size(); ++i)
2421 {
2422 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
2423 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
2424 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
2425 }
2426}
2427
2428BOOST_AUTO_TEST_CASE(TestPyrIProductWRTDerivBase_IterPerExp_VariableP_MultiElmt)
2429{
2431 new SpatialDomains::PointGeom(3u, 0u, -1.5, -1.5, -1.5));
2433 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2435 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
2437 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
2439 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
2440
2441 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
2442 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
2443 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
2444 std::array<SpatialDomains::PointGeom *, 5> v = {
2445 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
2447 CreatePyr(v, segVec, triVec, quadVec);
2448
2449 Nektar::LibUtilities::PointsType PointsTypeDir1 =
2451 const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1);
2452 Nektar::LibUtilities::BasisType basisTypeDir1 =
2454 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
2455 PointsKeyDir1);
2456
2457 Nektar::LibUtilities::PointsType PointsTypeDir2 =
2459 const Nektar::LibUtilities::PointsKey PointsKeyDir2(7, PointsTypeDir2);
2460 Nektar::LibUtilities::BasisType basisTypeDir2 =
2462 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 6,
2463 PointsKeyDir2);
2464
2465 Nektar::LibUtilities::PointsType PointsTypeDir3 =
2466 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2467 const Nektar::LibUtilities::PointsKey PointsKeyDir3(8, PointsTypeDir3);
2468 Nektar::LibUtilities::BasisType basisTypeDir3 =
2470 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
2471 PointsKeyDir3);
2472
2475 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
2476
2477 int nelmts = 10;
2478
2479 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
2480 for (int i = 0; i < nelmts; ++i)
2481 {
2482 CollExp.push_back(Exp);
2483 }
2484
2486 Collections::CollectionOptimisation colOpt(dummySession, 3,
2488 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2489 Collections::Collection c(CollExp, impTypes);
2491
2492 const int nq = Exp->GetTotPoints();
2493 const int nm = Exp->GetNcoeffs();
2494 Array<OneD, NekDouble> phys1(nelmts * nq), tmp;
2495 Array<OneD, NekDouble> phys2(nelmts * nq);
2496 Array<OneD, NekDouble> phys3(nelmts * nq);
2497 Array<OneD, NekDouble> coeffs1(nelmts * nm);
2498 Array<OneD, NekDouble> coeffs2(nelmts * nm);
2499
2500 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
2501
2502 Exp->GetCoords(xc, yc, zc);
2503
2504 for (int i = 0; i < nq; ++i)
2505 {
2506 phys1[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
2507 phys2[i] = cos(xc[i]) * sin(yc[i]) * cos(zc[i]);
2508 phys3[i] = cos(xc[i]) * sin(yc[i]) * sin(zc[i]);
2509 }
2510 for (int i = 1; i < nelmts; ++i)
2511 {
2512 Vmath::Vcopy(nq, phys1, 1, tmp = phys1 + i * nq, 1);
2513 Vmath::Vcopy(nq, phys2, 1, tmp = phys2 + i * nq, 1);
2514 Vmath::Vcopy(nq, phys3, 1, tmp = phys3 + i * nq, 1);
2515 }
2516
2517 // Standard routines
2518 for (int i = 0; i < nelmts; ++i)
2519 {
2520 Exp->IProductWRTDerivBase(0, phys1 + i * nq, tmp = coeffs1 + i * nm);
2521 Exp->IProductWRTDerivBase(1, phys2 + i * nq, tmp = coeffs2 + i * nm);
2522 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
2523 tmp = coeffs1 + i * nm, 1);
2524 Exp->IProductWRTDerivBase(2, phys3 + i * nq, tmp = coeffs2 + i * nm);
2525 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
2526 tmp = coeffs1 + i * nm, 1);
2527 }
2528
2530 coeffs2);
2531
2532 double epsilon = 1.0e-8;
2533 for (int i = 0; i < coeffs1.size(); ++i)
2534 {
2535 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
2536 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
2537 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
2538 }
2539}
2540
2541BOOST_AUTO_TEST_CASE(TestPyrIProductWRTDerivBase_MatrixFree_Deformed_MultiElmt)
2542{
2544 new SpatialDomains::PointGeom(3u, 0u, -1.5, -1.5, -1.5));
2546 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2548 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
2550 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
2552 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
2553
2554 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
2555 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
2556 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
2557 std::array<SpatialDomains::PointGeom *, 5> v = {
2558 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
2560 CreatePyr(v, segVec, triVec, quadVec);
2561
2562 unsigned int numQuadPoints = 5;
2563 unsigned int numModes = 4;
2564
2565 Nektar::LibUtilities::PointsType PointsTypeDir1 =
2567 const Nektar::LibUtilities::PointsKey PointsKeyDir1(numQuadPoints,
2568 PointsTypeDir1);
2569 Nektar::LibUtilities::BasisType basisTypeDir1 =
2571 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
2572 PointsKeyDir1);
2573
2574 Nektar::LibUtilities::PointsType PointsTypeDir2 =
2576 const Nektar::LibUtilities::PointsKey PointsKeyDir2(numQuadPoints,
2577 PointsTypeDir2);
2578 Nektar::LibUtilities::BasisType basisTypeDir2 =
2580 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
2581 PointsKeyDir2);
2582
2583 Nektar::LibUtilities::PointsType PointsTypeDir3 =
2584 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2585 const Nektar::LibUtilities::PointsKey PointsKeyDir3(numQuadPoints - 1,
2586 PointsTypeDir3);
2587 Nektar::LibUtilities::BasisType basisTypeDir3 =
2589 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
2590 PointsKeyDir3);
2591
2594 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
2595
2596 int nelmts = NELMTS;
2597
2598 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
2599 for (int i = 0; i < nelmts; ++i)
2600 {
2601 CollExp.push_back(Exp);
2602 }
2603
2605 Collections::CollectionOptimisation colOpt(dummySession, 2,
2607 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2608 Collections::Collection c(CollExp, impTypes);
2610
2611 const int nq = Exp->GetTotPoints();
2612 const int nm = Exp->GetNcoeffs();
2613 Array<OneD, NekDouble> phys1(nelmts * nq), tmp;
2614 Array<OneD, NekDouble> phys2(nelmts * nq);
2615 Array<OneD, NekDouble> phys3(nelmts * nq);
2616 Array<OneD, NekDouble> coeffs1(nelmts * nm);
2617 Array<OneD, NekDouble> coeffs2(nelmts * nm);
2618
2619 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
2620 Exp->GetCoords(xc, yc, zc);
2621
2622 for (int i = 0; i < nq; ++i)
2623 {
2624 phys1[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
2625 phys2[i] = cos(xc[i]) * sin(yc[i]) * cos(zc[i]);
2626 phys3[i] = cos(xc[i]) * sin(yc[i]) * sin(zc[i]);
2627 }
2628 for (int i = 1; i < nelmts; ++i)
2629 {
2630 Vmath::Vcopy(nq, phys1, 1, tmp = phys1 + i * nq, 1);
2631 Vmath::Vcopy(nq, phys2, 1, tmp = phys2 + i * nq, 1);
2632 Vmath::Vcopy(nq, phys3, 1, tmp = phys3 + i * nq, 1);
2633 }
2634
2635 // Standard routines
2636 for (int i = 0; i < nelmts; ++i)
2637 {
2638 Exp->IProductWRTDerivBase(0, phys1 + i * nq, tmp = coeffs1 + i * nm);
2639 Exp->IProductWRTDerivBase(1, phys2 + i * nq, tmp = coeffs2 + i * nm);
2640 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
2641 tmp = coeffs1 + i * nm, 1);
2642 Exp->IProductWRTDerivBase(2, phys3 + i * nq, tmp = coeffs2 + i * nm);
2643 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
2644 tmp = coeffs1 + i * nm, 1);
2645 }
2646
2647 LibUtilities::Timer timer;
2648 timer.Start();
2650 coeffs2);
2651 timer.Stop();
2652 timer.AccumulateRegion("Pyr IProdWRTDB MatrixFree");
2653
2654 double epsilon = 1.0e-8;
2655 for (int i = 0; i < coeffs1.size(); ++i)
2656 {
2657 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
2658 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
2659 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
2660 }
2661}
2663 TestPyrIProductWRTDerivBase_MatrixFree_Deformed_MultiElmt_OverInt)
2664{
2666 new SpatialDomains::PointGeom(3u, 0u, -1.5, -1.5, -1.5));
2668 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2670 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
2672 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
2674 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
2675
2676 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
2677 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
2678 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
2679 std::array<SpatialDomains::PointGeom *, 5> v = {
2680 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
2682 CreatePyr(v, segVec, triVec, quadVec);
2683
2684 unsigned int numQuadPoints = 8;
2685 unsigned int numModes = 4;
2686
2687 Nektar::LibUtilities::PointsType PointsTypeDir1 =
2689 const Nektar::LibUtilities::PointsKey PointsKeyDir1(numQuadPoints,
2690 PointsTypeDir1);
2691 Nektar::LibUtilities::BasisType basisTypeDir1 =
2693 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
2694 PointsKeyDir1);
2695
2696 Nektar::LibUtilities::PointsType PointsTypeDir2 =
2698 const Nektar::LibUtilities::PointsKey PointsKeyDir2(numQuadPoints,
2699 PointsTypeDir2);
2700 Nektar::LibUtilities::BasisType basisTypeDir2 =
2702 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
2703 PointsKeyDir2);
2704
2705 Nektar::LibUtilities::PointsType PointsTypeDir3 =
2706 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2707 const Nektar::LibUtilities::PointsKey PointsKeyDir3(numQuadPoints - 1,
2708 PointsTypeDir3);
2709 Nektar::LibUtilities::BasisType basisTypeDir3 =
2711 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
2712 PointsKeyDir3);
2713
2716 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
2717
2718 int nelmts = 5;
2719
2720 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
2721 for (int i = 0; i < nelmts; ++i)
2722 {
2723 CollExp.push_back(Exp);
2724 }
2725
2727 Collections::CollectionOptimisation colOpt(dummySession, 2,
2729 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2730 Collections::Collection c(CollExp, impTypes);
2732
2733 const int nq = Exp->GetTotPoints();
2734 const int nm = Exp->GetNcoeffs();
2735 Array<OneD, NekDouble> phys1(nelmts * nq), tmp;
2736 Array<OneD, NekDouble> phys2(nelmts * nq);
2737 Array<OneD, NekDouble> phys3(nelmts * nq);
2738 Array<OneD, NekDouble> coeffs1(nelmts * nm);
2739 Array<OneD, NekDouble> coeffs2(nelmts * nm);
2740
2741 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
2742 Exp->GetCoords(xc, yc, zc);
2743
2744 for (int i = 0; i < nq; ++i)
2745 {
2746 phys1[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
2747 phys2[i] = cos(xc[i]) * sin(yc[i]) * cos(zc[i]);
2748 phys3[i] = cos(xc[i]) * sin(yc[i]) * sin(zc[i]);
2749 }
2750 for (int i = 1; i < nelmts; ++i)
2751 {
2752 Vmath::Vcopy(nq, phys1, 1, tmp = phys1 + i * nq, 1);
2753 Vmath::Vcopy(nq, phys2, 1, tmp = phys2 + i * nq, 1);
2754 Vmath::Vcopy(nq, phys3, 1, tmp = phys3 + i * nq, 1);
2755 }
2756
2757 // Standard routines
2758 for (int i = 0; i < nelmts; ++i)
2759 {
2760 Exp->IProductWRTDerivBase(0, phys1 + i * nq, tmp = coeffs1 + i * nm);
2761 Exp->IProductWRTDerivBase(1, phys2 + i * nq, tmp = coeffs2 + i * nm);
2762 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
2763 tmp = coeffs1 + i * nm, 1);
2764 Exp->IProductWRTDerivBase(2, phys3 + i * nq, tmp = coeffs2 + i * nm);
2765 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
2766 tmp = coeffs1 + i * nm, 1);
2767 }
2768
2770 coeffs2);
2771
2772 double epsilon = 1.0e-8;
2773 for (int i = 0; i < coeffs1.size(); ++i)
2774 {
2775 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
2776 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
2777 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
2778 }
2779}
2780
2781BOOST_AUTO_TEST_CASE(TestPyrBwdTrans_MatrixFree_UniformP_MultiElmt)
2782{
2784 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
2786 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2788 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
2790 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
2792 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
2793
2794 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
2795 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
2796 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
2797 std::array<SpatialDomains::PointGeom *, 5> v = {
2798 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
2800 CreatePyr(v, segVec, triVec, quadVec);
2801
2802 unsigned int numQuadPoints = 5;
2803 unsigned int numModes = 4;
2804
2805 Nektar::LibUtilities::PointsType PointsTypeDir1 =
2807 const Nektar::LibUtilities::PointsKey PointsKeyDir1(numQuadPoints,
2808 PointsTypeDir1);
2809 Nektar::LibUtilities::BasisType basisTypeDir1 =
2811 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
2812 PointsKeyDir1);
2813
2814 Nektar::LibUtilities::PointsType PointsTypeDir2 =
2816 const Nektar::LibUtilities::PointsKey PointsKeyDir2(numQuadPoints,
2817 PointsTypeDir2);
2818 Nektar::LibUtilities::BasisType basisTypeDir2 =
2820 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
2821 PointsKeyDir2);
2822
2823 Nektar::LibUtilities::PointsType PointsTypeDir3 =
2824 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2825 const Nektar::LibUtilities::PointsKey PointsKeyDir3(numQuadPoints - 1,
2826 PointsTypeDir3);
2827 Nektar::LibUtilities::BasisType basisTypeDir3 =
2829 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
2830 PointsKeyDir3);
2831
2834 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
2835
2836 unsigned int nelmts = NELMTS;
2837
2838 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
2839 for (unsigned int i = 0; i < nelmts; ++i)
2840 {
2841 CollExp.push_back(Exp);
2842 }
2843
2845 Collections::CollectionOptimisation colOpt(dummySession, 2,
2847 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2848
2849 // ... only one op at the time ...
2851 Collections::Collection c(CollExp, impTypes);
2853
2854 Array<OneD, NekDouble> coeffs(nelmts * Exp->GetNcoeffs(), 1.0);
2855 for (int i = 0; i < coeffs.size(); ++i)
2856 {
2857 coeffs[i] = i + 1;
2858 }
2859 Array<OneD, NekDouble> physRef(nelmts * Exp->GetTotPoints(), 0.0);
2860 Array<OneD, NekDouble> phys(nelmts * Exp->GetTotPoints(), 0.0);
2862
2863 for (unsigned int i = 0; i < nelmts; ++i)
2864 {
2865 Exp->BwdTrans(coeffs + i * Exp->GetNcoeffs(),
2866 tmp = physRef + i * Exp->GetTotPoints());
2867 }
2868 LibUtilities::Timer timer;
2869 timer.Start();
2870 c.ApplyOperator(Collections::eBwdTrans, coeffs, phys);
2871 timer.Stop();
2872 timer.AccumulateRegion("Pyr BwdTrans MatrixFree");
2873
2874 double epsilon = 1.0e-8;
2875 for (unsigned int i = 0; i < physRef.size(); ++i)
2876 {
2877 BOOST_CHECK_CLOSE(physRef[i], phys[i], epsilon);
2878 }
2879}
2880
2881BOOST_AUTO_TEST_CASE(TestPyrBwdTrans_MatrixFree_UniformP_OverInt_MultiElmt)
2882{
2884 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
2886 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2888 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
2890 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
2892 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
2893
2894 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
2895 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
2896 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
2897 std::array<SpatialDomains::PointGeom *, 5> v = {
2898 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
2900 CreatePyr(v, segVec, triVec, quadVec);
2901
2902 unsigned int numQuadPoints = 8;
2903 unsigned int numModes = 4;
2904
2905 Nektar::LibUtilities::PointsType PointsTypeDir1 =
2907 const Nektar::LibUtilities::PointsKey PointsKeyDir1(numQuadPoints,
2908 PointsTypeDir1);
2909 Nektar::LibUtilities::BasisType basisTypeDir1 =
2911 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
2912 PointsKeyDir1);
2913
2914 Nektar::LibUtilities::PointsType PointsTypeDir2 =
2916 const Nektar::LibUtilities::PointsKey PointsKeyDir2(numQuadPoints,
2917 PointsTypeDir2);
2918 Nektar::LibUtilities::BasisType basisTypeDir2 =
2920 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
2921 PointsKeyDir2);
2922
2923 Nektar::LibUtilities::PointsType PointsTypeDir3 =
2924 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2925 const Nektar::LibUtilities::PointsKey PointsKeyDir3(numQuadPoints - 1,
2926 PointsTypeDir3);
2927 Nektar::LibUtilities::BasisType basisTypeDir3 =
2929 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
2930 PointsKeyDir3);
2931
2934 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
2935
2936 unsigned int nelmts = 10;
2937
2938 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
2939 for (unsigned int i = 0; i < nelmts; ++i)
2940 {
2941 CollExp.push_back(Exp);
2942 }
2943
2945 Collections::CollectionOptimisation colOpt(dummySession, 2,
2947 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2948
2949 // ... only one op at the time ...
2951 Collections::Collection c(CollExp, impTypes);
2953
2954 Array<OneD, NekDouble> coeffs(nelmts * Exp->GetNcoeffs(), 1.0);
2955 for (int i = 0; i < coeffs.size(); ++i)
2956 {
2957 coeffs[i] = i + 1;
2958 }
2959 Array<OneD, NekDouble> physRef(nelmts * Exp->GetTotPoints(), 0.0);
2960 Array<OneD, NekDouble> phys(nelmts * Exp->GetTotPoints(), 0.0);
2962
2963 for (unsigned int i = 0; i < nelmts; ++i)
2964 {
2965 Exp->BwdTrans(coeffs + i * Exp->GetNcoeffs(),
2966 tmp = physRef + i * Exp->GetTotPoints());
2967 }
2968 c.ApplyOperator(Collections::eBwdTrans, coeffs, phys);
2969
2970 double epsilon = 1.0e-8;
2971 for (unsigned int i = 0; i < physRef.size(); ++i)
2972 {
2973 BOOST_CHECK_CLOSE(physRef[i], phys[i], epsilon);
2974 }
2975}
2976
2977BOOST_AUTO_TEST_CASE(TestPyrIProductWRTDerivBase_StdMat_VariableP_MultiElmt)
2978{
2980 new SpatialDomains::PointGeom(3u, 0u, -1.5, -1.5, -1.5));
2982 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2984 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
2986 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
2988 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
2989
2990 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
2991 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
2992 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
2993 std::array<SpatialDomains::PointGeom *, 5> v = {
2994 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
2996 CreatePyr(v, segVec, triVec, quadVec);
2997
2998 Nektar::LibUtilities::PointsType PointsTypeDir1 =
3000 const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1);
3001 Nektar::LibUtilities::BasisType basisTypeDir1 =
3003 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
3004 PointsKeyDir1);
3005
3006 Nektar::LibUtilities::PointsType PointsTypeDir2 =
3008 const Nektar::LibUtilities::PointsKey PointsKeyDir2(7, PointsTypeDir2);
3009 Nektar::LibUtilities::BasisType basisTypeDir2 =
3011 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 6,
3012 PointsKeyDir2);
3013
3014 Nektar::LibUtilities::PointsType PointsTypeDir3 =
3015 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
3016 const Nektar::LibUtilities::PointsKey PointsKeyDir3(8, PointsTypeDir3);
3017 Nektar::LibUtilities::BasisType basisTypeDir3 =
3019 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
3020 PointsKeyDir3);
3021
3024 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
3025
3026 int nelmts = 10;
3027
3028 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
3029 for (int i = 0; i < nelmts; ++i)
3030 {
3031 CollExp.push_back(Exp);
3032 }
3033
3035 Collections::CollectionOptimisation colOpt(dummySession, 3,
3037 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
3038 Collections::Collection c(CollExp, impTypes);
3040
3041 const int nq = Exp->GetTotPoints();
3042 const int nm = Exp->GetNcoeffs();
3043 Array<OneD, NekDouble> phys1(nelmts * nq), tmp;
3044 Array<OneD, NekDouble> phys2(nelmts * nq);
3045 Array<OneD, NekDouble> phys3(nelmts * nq);
3046 Array<OneD, NekDouble> coeffs1(nelmts * nm);
3047 Array<OneD, NekDouble> coeffs2(nelmts * nm);
3048
3049 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
3050
3051 Exp->GetCoords(xc, yc, zc);
3052
3053 for (int i = 0; i < nq; ++i)
3054 {
3055 phys1[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
3056 phys2[i] = cos(xc[i]) * sin(yc[i]) * cos(zc[i]);
3057 phys3[i] = cos(xc[i]) * sin(yc[i]) * sin(zc[i]);
3058 }
3059 for (int i = 1; i < nelmts; ++i)
3060 {
3061 Vmath::Vcopy(nq, phys1, 1, tmp = phys1 + i * nq, 1);
3062 Vmath::Vcopy(nq, phys2, 1, tmp = phys2 + i * nq, 1);
3063 Vmath::Vcopy(nq, phys3, 1, tmp = phys3 + i * nq, 1);
3064 }
3065
3066 // Standard routines
3067 for (int i = 0; i < nelmts; ++i)
3068 {
3069 Exp->IProductWRTDerivBase(0, phys1 + i * nq, tmp = coeffs1 + i * nm);
3070 Exp->IProductWRTDerivBase(1, phys2 + i * nq, tmp = coeffs2 + i * nm);
3071 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
3072 tmp = coeffs1 + i * nm, 1);
3073 Exp->IProductWRTDerivBase(2, phys3 + i * nq, tmp = coeffs2 + i * nm);
3074 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
3075 tmp = coeffs1 + i * nm, 1);
3076 }
3077
3079 coeffs2);
3080
3081 double epsilon = 1.0e-8;
3082 for (int i = 0; i < coeffs1.size(); ++i)
3083 {
3084 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
3085 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
3086 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
3087 }
3088}
3089
3090BOOST_AUTO_TEST_CASE(TestPyrIProductWRTDerivBase_SumFac_VariableP_MultiElmt)
3091{
3093 new SpatialDomains::PointGeom(3u, 0u, -1.5, -1.5, -1.5));
3095 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
3097 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
3099 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
3101 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
3102
3103 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
3104 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
3105 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
3106 std::array<SpatialDomains::PointGeom *, 5> v = {
3107 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
3109 CreatePyr(v, segVec, triVec, quadVec);
3110
3111 Nektar::LibUtilities::PointsType PointsTypeDir1 =
3113 const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1);
3114 Nektar::LibUtilities::BasisType basisTypeDir1 =
3116 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
3117 PointsKeyDir1);
3118
3119 Nektar::LibUtilities::PointsType PointsTypeDir2 =
3121 const Nektar::LibUtilities::PointsKey PointsKeyDir2(7, PointsTypeDir2);
3122 Nektar::LibUtilities::BasisType basisTypeDir2 =
3124 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 6,
3125 PointsKeyDir2);
3126
3127 Nektar::LibUtilities::PointsType PointsTypeDir3 =
3128 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
3129 const Nektar::LibUtilities::PointsKey PointsKeyDir3(8, PointsTypeDir3);
3130 Nektar::LibUtilities::BasisType basisTypeDir3 =
3132 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
3133 PointsKeyDir3);
3134
3137 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
3138
3139 int nelmts = 10;
3140
3141 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
3142 for (int i = 0; i < nelmts; ++i)
3143 {
3144 CollExp.push_back(Exp);
3145 }
3146
3148 Collections::CollectionOptimisation colOpt(dummySession, 3,
3150 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
3151 Collections::Collection c(CollExp, impTypes);
3153
3154 const int nq = Exp->GetTotPoints();
3155 const int nm = Exp->GetNcoeffs();
3156 Array<OneD, NekDouble> phys1(nelmts * nq), tmp;
3157 Array<OneD, NekDouble> phys2(nelmts * nq);
3158 Array<OneD, NekDouble> phys3(nelmts * nq);
3159 Array<OneD, NekDouble> coeffs1(nelmts * nm);
3160 Array<OneD, NekDouble> coeffs2(nelmts * nm);
3161
3162 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
3163
3164 Exp->GetCoords(xc, yc, zc);
3165
3166 for (int i = 0; i < nq; ++i)
3167 {
3168 phys1[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
3169 phys2[i] = cos(xc[i]) * sin(yc[i]) * cos(zc[i]);
3170 phys3[i] = cos(xc[i]) * sin(yc[i]) * sin(zc[i]);
3171 }
3172 for (int i = 1; i < nelmts; ++i)
3173 {
3174 Vmath::Vcopy(nq, phys1, 1, tmp = phys1 + i * nq, 1);
3175 Vmath::Vcopy(nq, phys2, 1, tmp = phys2 + i * nq, 1);
3176 Vmath::Vcopy(nq, phys3, 1, tmp = phys3 + i * nq, 1);
3177 }
3178
3179 // Standard routines
3180 for (int i = 0; i < nelmts; ++i)
3181 {
3182 Exp->IProductWRTDerivBase(0, phys1 + i * nq, tmp = coeffs1 + i * nm);
3183 Exp->IProductWRTDerivBase(1, phys2 + i * nq, tmp = coeffs2 + i * nm);
3184 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
3185 tmp = coeffs1 + i * nm, 1);
3186 Exp->IProductWRTDerivBase(2, phys3 + i * nq, tmp = coeffs2 + i * nm);
3187 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
3188 tmp = coeffs1 + i * nm, 1);
3189 }
3190
3192 coeffs2);
3193
3194 double epsilon = 1.0e-8;
3195 for (int i = 0; i < coeffs1.size(); ++i)
3196 {
3197 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
3198 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
3199 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
3200 }
3201}
3202
3203BOOST_AUTO_TEST_CASE(TestPyrHelmholtz_IterPerExp_UniformP_ConstVarDiff)
3204{
3206 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
3208 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
3210 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
3212 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
3214 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
3215
3216 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
3217 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
3218 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
3219 std::array<SpatialDomains::PointGeom *, 5> v = {
3220 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
3222 CreatePyr(v, segVec, triVec, quadVec);
3223
3224 unsigned int numQuadPoints = 5;
3225 unsigned int numModes = 4;
3226
3227 Nektar::LibUtilities::PointsType PointsTypeDir1 =
3229 const Nektar::LibUtilities::PointsKey PointsKeyDir1(numQuadPoints,
3230 PointsTypeDir1);
3231 Nektar::LibUtilities::BasisType basisTypeDir1 =
3233 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
3234 PointsKeyDir1);
3235
3236 Nektar::LibUtilities::PointsType PointsTypeDir2 =
3238 const Nektar::LibUtilities::PointsKey PointsKeyDir2(numQuadPoints,
3239 PointsTypeDir2);
3240 Nektar::LibUtilities::BasisType basisTypeDir2 =
3242 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
3243 PointsKeyDir2);
3244
3245 Nektar::LibUtilities::PointsType PointsTypeDir3 =
3246 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
3247 const Nektar::LibUtilities::PointsKey PointsKeyDir3(numQuadPoints - 1,
3248 PointsTypeDir3);
3249 Nektar::LibUtilities::BasisType basisTypeDir3 =
3251 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
3252 PointsKeyDir3);
3253
3256 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
3257
3258 int nelmts = 10;
3259
3260 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
3261 for (int i = 0; i < nelmts; ++i)
3262 {
3263 CollExp.push_back(Exp);
3264 }
3265
3267 Collections::CollectionOptimisation colOpt(dummySession, 2,
3269 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
3270 Collections::Collection c(CollExp, impTypes);
3272 factors[StdRegions::eFactorLambda] = 1.5;
3273 factors[StdRegions::eFactorCoeffD00] = 1.25;
3274 factors[StdRegions::eFactorCoeffD01] = 0.25;
3275 factors[StdRegions::eFactorCoeffD11] = 1.25;
3276 factors[StdRegions::eFactorCoeffD02] = 0.25;
3277 factors[StdRegions::eFactorCoeffD12] = 0.25;
3278 factors[StdRegions::eFactorCoeffD22] = 1.25;
3279
3281
3282 const int nm = Exp->GetNcoeffs();
3283 Array<OneD, NekDouble> coeffsIn(nelmts * nm);
3284 Array<OneD, NekDouble> coeffsRef(nelmts * nm);
3285 Array<OneD, NekDouble> coeffs(nelmts * nm), tmp;
3286
3287 for (int i = 0; i < nm; ++i)
3288 {
3289 coeffsIn[i] = 1.0;
3290 }
3291
3292 for (int i = 1; i < nelmts; ++i)
3293 {
3294 Vmath::Vcopy(nm, coeffsIn, 1, tmp = coeffsIn + i * nm, 1);
3295 }
3296
3297 StdRegions::StdMatrixKey mkey(StdRegions::eHelmholtz, Exp->DetShapeType(),
3298 *Exp, factors);
3299
3300 for (int i = 0; i < nelmts; ++i)
3301 {
3302 // Standard routines
3303 Exp->GeneralMatrixOp(coeffsIn + i * nm, tmp = coeffsRef + i * nm, mkey);
3304 }
3305
3306 c.ApplyOperator(Collections::eHelmholtz, coeffsIn, coeffs);
3307
3308 double epsilon = 1.0e-8;
3309 for (int i = 0; i < coeffsRef.size(); ++i)
3310 {
3311 coeffsRef[i] = (std::abs(coeffsRef[i]) < 1e-14) ? 0.0 : coeffsRef[i];
3312 coeffs[i] = (std::abs(coeffs[i]) < 1e-14) ? 0.0 : coeffs[i];
3313 BOOST_CHECK_CLOSE(coeffsRef[i], coeffs[i], epsilon);
3314 }
3315}
3316
3317BOOST_AUTO_TEST_CASE(TestPyrHelmholtz_MatrixFree_UniformP)
3318{
3320 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
3322 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
3324 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
3326 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
3328 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
3329
3330 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
3331 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
3332 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
3333 std::array<SpatialDomains::PointGeom *, 5> v = {
3334 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
3336 CreatePyr(v, segVec, triVec, quadVec);
3337
3338 unsigned int numQuadPoints = 5;
3339 unsigned int numModes = 4;
3340
3341 Nektar::LibUtilities::PointsType PointsTypeDir1 =
3343 const Nektar::LibUtilities::PointsKey PointsKeyDir1(numQuadPoints,
3344 PointsTypeDir1);
3345 Nektar::LibUtilities::BasisType basisTypeDir1 =
3347 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
3348 PointsKeyDir1);
3349
3350 Nektar::LibUtilities::PointsType PointsTypeDir2 =
3352 const Nektar::LibUtilities::PointsKey PointsKeyDir2(numQuadPoints,
3353 PointsTypeDir2);
3354 Nektar::LibUtilities::BasisType basisTypeDir2 =
3356 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
3357 PointsKeyDir2);
3358
3359 Nektar::LibUtilities::PointsType PointsTypeDir3 =
3360 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
3361 const Nektar::LibUtilities::PointsKey PointsKeyDir3(numQuadPoints - 1,
3362 PointsTypeDir3);
3363 Nektar::LibUtilities::BasisType basisTypeDir3 =
3365 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
3366 PointsKeyDir3);
3367
3370 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
3371
3372 int nelmts = 10;
3373
3374 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
3375 for (int i = 0; i < nelmts; ++i)
3376 {
3377 CollExp.push_back(Exp);
3378 }
3379
3381 Collections::CollectionOptimisation colOpt(dummySession, 2,
3383 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
3384 Collections::Collection c(CollExp, impTypes);
3386 factors[StdRegions::eFactorLambda] = 1.5;
3387
3389
3390 const int nm = Exp->GetNcoeffs();
3391 Array<OneD, NekDouble> coeffsIn(nelmts * nm);
3392 Array<OneD, NekDouble> coeffsRef(nelmts * nm);
3393 Array<OneD, NekDouble> coeffs(nelmts * nm), tmp;
3394
3395 for (int i = 0; i < nm; ++i)
3396 {
3397 coeffsIn[i] = 1.0;
3398 }
3399
3400 for (int i = 1; i < nelmts; ++i)
3401 {
3402 Vmath::Vcopy(nm, coeffsIn, 1, tmp = coeffsIn + i * nm, 1);
3403 }
3404
3405 StdRegions::StdMatrixKey mkey(StdRegions::eHelmholtz, Exp->DetShapeType(),
3406 *Exp, factors);
3407
3408 for (int i = 0; i < nelmts; ++i)
3409 {
3410 // Standard routines
3411 Exp->GeneralMatrixOp(coeffsIn + i * nm, tmp = coeffsRef + i * nm, mkey);
3412 }
3413
3414 c.ApplyOperator(Collections::eHelmholtz, coeffsIn, coeffs);
3415
3416 double epsilon = 1.0e-8;
3417 for (int i = 0; i < coeffsRef.size(); ++i)
3418 {
3419 coeffsRef[i] = (std::abs(coeffsRef[i]) < 1e-14) ? 0.0 : coeffsRef[i];
3420 coeffs[i] = (std::abs(coeffs[i]) < 1e-14) ? 0.0 : coeffs[i];
3421 BOOST_CHECK_CLOSE(coeffsRef[i], coeffs[i], epsilon);
3422 }
3423}
3424
3425BOOST_AUTO_TEST_CASE(TestPyrHelmholtz_MatrixFree_Deformed_overInt)
3426{
3428 new SpatialDomains::PointGeom(3u, 0u, -1.5, -1.5, -1.5));
3430 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
3432 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
3434 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
3436 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
3437
3438 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
3439 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
3440 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
3441 std::array<SpatialDomains::PointGeom *, 5> v = {
3442 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
3444 CreatePyr(v, segVec, triVec, quadVec);
3445
3446 unsigned int numQuadPoints = 8;
3447 unsigned int numModes = 4;
3448
3449 Nektar::LibUtilities::PointsType PointsTypeDir1 =
3451 const Nektar::LibUtilities::PointsKey PointsKeyDir1(numQuadPoints,
3452 PointsTypeDir1);
3453 Nektar::LibUtilities::BasisType basisTypeDir1 =
3455 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
3456 PointsKeyDir1);
3457
3458 Nektar::LibUtilities::PointsType PointsTypeDir2 =
3460 const Nektar::LibUtilities::PointsKey PointsKeyDir2(numQuadPoints,
3461 PointsTypeDir2);
3462 Nektar::LibUtilities::BasisType basisTypeDir2 =
3464 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
3465 PointsKeyDir2);
3466
3467 Nektar::LibUtilities::PointsType PointsTypeDir3 =
3468 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
3469 const Nektar::LibUtilities::PointsKey PointsKeyDir3(numQuadPoints - 1,
3470 PointsTypeDir3);
3471 Nektar::LibUtilities::BasisType basisTypeDir3 =
3473 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
3474 PointsKeyDir3);
3475
3478 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
3479
3480 int nelmts = 10;
3481
3482 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
3483 for (int i = 0; i < nelmts; ++i)
3484 {
3485 CollExp.push_back(Exp);
3486 }
3487
3489 Collections::CollectionOptimisation colOpt(dummySession, 2,
3491 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
3492 Collections::Collection c(CollExp, impTypes);
3494 factors[StdRegions::eFactorLambda] = 1.5;
3495
3497
3498 const int nm = Exp->GetNcoeffs();
3499 Array<OneD, NekDouble> coeffsIn(nelmts * nm);
3500 Array<OneD, NekDouble> coeffsRef(nelmts * nm);
3501 Array<OneD, NekDouble> coeffs(nelmts * nm), tmp;
3502
3503 for (int i = 0; i < nm; ++i)
3504 {
3505 coeffsIn[i] = 1.0;
3506 }
3507
3508 for (int i = 1; i < nelmts; ++i)
3509 {
3510 Vmath::Vcopy(nm, coeffsIn, 1, tmp = coeffsIn + i * nm, 1);
3511 }
3512
3513 StdRegions::StdMatrixKey mkey(StdRegions::eHelmholtz, Exp->DetShapeType(),
3514 *Exp, factors);
3515
3516 for (int i = 0; i < nelmts; ++i)
3517 {
3518 // Standard routines
3519 Exp->GeneralMatrixOp(coeffsIn + i * nm, tmp = coeffsRef + i * nm, mkey);
3520 }
3521
3522 c.ApplyOperator(Collections::eHelmholtz, coeffsIn, coeffs);
3523
3524 double epsilon = 1.0e-8;
3525 for (int i = 0; i < coeffsRef.size(); ++i)
3526 {
3527 coeffsRef[i] = (std::abs(coeffsRef[i]) < 1e-14) ? 0.0 : coeffsRef[i];
3528 coeffs[i] = (std::abs(coeffs[i]) < 1e-14) ? 0.0 : coeffs[i];
3529 BOOST_CHECK_CLOSE(coeffsRef[i], coeffs[i], epsilon);
3530 }
3531}
3532
3533BOOST_AUTO_TEST_CASE(TestPyrHelmholtz_MatrixFree_UniformP_ConstVarDiff)
3534{
3536 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
3538 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
3540 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
3542 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
3544 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
3545
3546 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
3547 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
3548 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
3549 std::array<SpatialDomains::PointGeom *, 5> v = {
3550 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
3552 CreatePyr(v, segVec, triVec, quadVec);
3553
3554 unsigned int numQuadPoints = 5;
3555 unsigned int numModes = 4;
3556
3557 Nektar::LibUtilities::PointsType PointsTypeDir1 =
3559 const Nektar::LibUtilities::PointsKey PointsKeyDir1(numQuadPoints,
3560 PointsTypeDir1);
3561 Nektar::LibUtilities::BasisType basisTypeDir1 =
3563 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
3564 PointsKeyDir1);
3565
3566 Nektar::LibUtilities::PointsType PointsTypeDir2 =
3568 const Nektar::LibUtilities::PointsKey PointsKeyDir2(numQuadPoints,
3569 PointsTypeDir2);
3570 Nektar::LibUtilities::BasisType basisTypeDir2 =
3572 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
3573 PointsKeyDir2);
3574
3575 Nektar::LibUtilities::PointsType PointsTypeDir3 =
3576 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
3577 const Nektar::LibUtilities::PointsKey PointsKeyDir3(numQuadPoints - 1,
3578 PointsTypeDir3);
3579 Nektar::LibUtilities::BasisType basisTypeDir3 =
3581 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
3582 PointsKeyDir3);
3583
3586 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
3587
3588 int nelmts = 10;
3589
3590 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
3591 for (int i = 0; i < nelmts; ++i)
3592 {
3593 CollExp.push_back(Exp);
3594 }
3595
3597 Collections::CollectionOptimisation colOpt(dummySession, 3,
3599 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
3600 Collections::Collection c(CollExp, impTypes);
3602 factors[StdRegions::eFactorLambda] = 1.5;
3603 factors[StdRegions::eFactorCoeffD00] = 1.25;
3604 factors[StdRegions::eFactorCoeffD01] = 0.25;
3605 factors[StdRegions::eFactorCoeffD11] = 1.25;
3606 factors[StdRegions::eFactorCoeffD02] = 0.25;
3607 factors[StdRegions::eFactorCoeffD12] = 0.25;
3608 factors[StdRegions::eFactorCoeffD22] = 1.25;
3609
3611
3612 const int nm = Exp->GetNcoeffs();
3613 Array<OneD, NekDouble> coeffsIn(nelmts * nm);
3614 Array<OneD, NekDouble> coeffsRef(nelmts * nm);
3615 Array<OneD, NekDouble> coeffs(nelmts * nm), tmp;
3616
3617 for (int i = 0; i < nm; ++i)
3618 {
3619 coeffsIn[i] = 1.0;
3620 }
3621
3622 for (int i = 1; i < nelmts; ++i)
3623 {
3624 Vmath::Vcopy(nm, coeffsIn, 1, tmp = coeffsIn + i * nm, 1);
3625 }
3626
3627 StdRegions::StdMatrixKey mkey(StdRegions::eHelmholtz, Exp->DetShapeType(),
3628 *Exp, factors);
3629
3630 for (int i = 0; i < nelmts; ++i)
3631 {
3632 // Standard routines
3633 Exp->GeneralMatrixOp(coeffsIn + i * nm, tmp = coeffsRef + i * nm, mkey);
3634 }
3635
3636 c.ApplyOperator(Collections::eHelmholtz, coeffsIn, coeffs);
3637
3638 double epsilon = 1.0e-8;
3639 for (int i = 0; i < coeffsRef.size(); ++i)
3640 {
3641 coeffsRef[i] = (std::abs(coeffsRef[i]) < 1e-14) ? 0.0 : coeffsRef[i];
3642 coeffs[i] = (std::abs(coeffs[i]) < 1e-14) ? 0.0 : coeffs[i];
3643 BOOST_CHECK_CLOSE(coeffsRef[i], coeffs[i], epsilon);
3644 }
3645}
3646
3647BOOST_AUTO_TEST_CASE(TestPyrPhysInterp1DScaled_NoCollection_UniformP_MultiElmt)
3648{
3650 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
3652 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
3654 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
3656 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
3658 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
3659
3660 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
3661 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
3662 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
3663 std::array<SpatialDomains::PointGeom *, 5> v = {
3664 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
3666 CreatePyr(v, segVec, triVec, quadVec);
3667
3668 Nektar::LibUtilities::PointsType PointsTypeDir1 =
3670 const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1);
3671 Nektar::LibUtilities::BasisType basisTypeDir1 =
3673 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
3674 PointsKeyDir1);
3675
3676 Nektar::LibUtilities::PointsType PointsTypeDir2 =
3678 const Nektar::LibUtilities::PointsKey PointsKeyDir2(5, PointsTypeDir2);
3679 Nektar::LibUtilities::BasisType basisTypeDir2 =
3681 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
3682 PointsKeyDir2);
3683
3684 Nektar::LibUtilities::PointsType PointsTypeDir3 =
3685 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
3686 const Nektar::LibUtilities::PointsKey PointsKeyDir3(4, PointsTypeDir3);
3687 Nektar::LibUtilities::BasisType basisTypeDir3 =
3689 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
3690 PointsKeyDir3);
3691
3694 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
3695
3696 int nelmts = 1;
3697
3698 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
3699 for (int i = 0; i < nelmts; ++i)
3700 {
3701 CollExp.push_back(Exp);
3702 }
3703
3705 Collections::CollectionOptimisation colOpt(dummySession, 3,
3707 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
3708 Collections::Collection c(CollExp, impTypes);
3710 factors[StdRegions::eFactorConst] = 1.5;
3712
3713 const int nq = Exp->GetTotPoints();
3714 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
3715 Array<OneD, NekDouble> phys(nq);
3716
3717 Exp->GetCoords(xc, yc, zc);
3718
3719 for (int i = 0; i < nq; ++i)
3720 {
3721 phys[i] = pow(xc[i], 3) + pow(yc[i], 3) + pow(zc[i], 3);
3722 }
3723
3725 Array<OneD, NekDouble> xc1(nq1);
3726 Array<OneD, NekDouble> yc1(nq1);
3727 Array<OneD, NekDouble> zc1(nq1);
3728 Array<OneD, NekDouble> phys1(nq1);
3729
3734
3735 double epsilon = 2.0e-8;
3736 for (int i = 0; i < nq1; ++i)
3737 {
3738 NekDouble exact = pow(xc1[i], 3) + pow(yc1[i], 3) + pow(zc1[i], 3);
3739 phys1[i] = (fabs(phys1[i]) < 1e-14) ? 0.0 : phys1[i];
3740 exact = (fabs(exact) < 1e-14) ? 0.0 : exact;
3741 BOOST_CHECK_CLOSE(phys1[i], exact, epsilon);
3742 }
3743}
3744
3745BOOST_AUTO_TEST_CASE(TestPyrPhysInterp1DScaled_MatrixFree_UniformP_MultiElmt)
3746{
3748 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
3750 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
3752 new SpatialDomains::PointGeom(3u, 2u, 1.0, 1.0, -1.0));
3754 new SpatialDomains::PointGeom(3u, 3u, -1.0, 1.0, -1.0));
3756 new SpatialDomains::PointGeom(3u, 4u, -1.0, -1.0, 1.0));
3757
3758 std::array<SpatialDomains::SegGeomUniquePtr, 8> segVec;
3759 std::array<SpatialDomains::QuadGeomUniquePtr, 1> quadVec;
3760 std::array<SpatialDomains::TriGeomUniquePtr, 4> triVec;
3761 std::array<SpatialDomains::PointGeom *, 5> v = {
3762 v0.get(), v1.get(), v2.get(), v3.get(), v4.get()};
3764 CreatePyr(v, segVec, triVec, quadVec);
3765
3766 Nektar::LibUtilities::PointsType PointsTypeDir1 =
3768 const Nektar::LibUtilities::PointsKey PointsKeyDir1(5, PointsTypeDir1);
3769 Nektar::LibUtilities::BasisType basisTypeDir1 =
3771 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
3772 PointsKeyDir1);
3773
3774 Nektar::LibUtilities::PointsType PointsTypeDir2 =
3776 const Nektar::LibUtilities::PointsKey PointsKeyDir2(5, PointsTypeDir2);
3777 Nektar::LibUtilities::BasisType basisTypeDir2 =
3779 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
3780 PointsKeyDir2);
3781
3782 Nektar::LibUtilities::PointsType PointsTypeDir3 =
3783 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
3784 const Nektar::LibUtilities::PointsKey PointsKeyDir3(4, PointsTypeDir3);
3785 Nektar::LibUtilities::BasisType basisTypeDir3 =
3787 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
3788 PointsKeyDir3);
3789
3792 basisKeyDir1, basisKeyDir2, basisKeyDir3, pyrGeom.get());
3793
3794 int nelmts = 1;
3795
3796 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
3797 for (int i = 0; i < nelmts; ++i)
3798 {
3799 CollExp.push_back(Exp);
3800 }
3801
3803 Collections::CollectionOptimisation colOpt(dummySession, 3,
3805 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
3806 Collections::Collection c(CollExp, impTypes);
3808 factors[StdRegions::eFactorConst] = 1.5;
3810
3811 const int nq = Exp->GetTotPoints();
3812 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
3813 Array<OneD, NekDouble> phys(nq);
3814
3815 Exp->GetCoords(xc, yc, zc);
3816
3817 for (int i = 0; i < nq; ++i)
3818 {
3819 phys[i] = pow(xc[i], 3) + pow(yc[i], 3) + pow(zc[i], 3);
3820 }
3821
3823 Array<OneD, NekDouble> xc1(nq1);
3824 Array<OneD, NekDouble> yc1(nq1);
3825 Array<OneD, NekDouble> zc1(nq1);
3826 Array<OneD, NekDouble> phys1(nq1);
3827
3832
3833 double epsilon = 2.0e-8;
3834 for (int i = 0; i < nq1; ++i)
3835 {
3836 NekDouble exact = pow(xc1[i], 3) + pow(yc1[i], 3) + pow(zc1[i], 3);
3837 phys1[i] = (fabs(phys1[i]) < 1e-14) ? 0.0 : phys1[i];
3838 exact = (fabs(exact) < 1e-14) ? 0.0 : exact;
3839 BOOST_CHECK_CLOSE(phys1[i], exact, epsilon);
3840 }
3841}
3842
3843} // namespace Nektar::PyrCollectionTests
#define NELMTS
COLLECTIONS_EXPORT void Initialise(const OperatorType opType, StdRegions::FactorMap factors=StdRegions::NullFactorMap)
void ApplyOperator(const OperatorType &op, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &output)
Definition Collection.h:138
int GetOutputSize(const OperatorType &op, bool defaultOut=true)
Definition Collection.h:112
COLLECTIONS_EXPORT OperatorImpMap GetOperatorImpMap(StdRegions::StdExpansionSharedPtr pExp)
Get Operator Implementation Map from XMl or using default;.
Describes the specification for a Basis.
Definition Basis.h:45
Defines a specification for a set of points.
Definition Points.h:50
void AccumulateRegion(std::string, int iolevel=0)
Accumulate elapsed time for a region.
Definition Timer.cpp:70
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
std::map< OperatorType, ImplementationType > OperatorImpMap
Definition Operator.h:131
std::shared_ptr< SessionReader > SessionReaderSharedPtr
@ eGaussLobattoLegendre
1D Gauss-Lobatto-Legendre quadrature points
Definition PointsType.h:51
@ eModifiedPyr_C
Principle Modified Functions.
Definition BasisType.h:53
@ eModified_A
Principle Modified Functions .
Definition BasisType.h:48
std::shared_ptr< PyrExp > PyrExpSharedPtr
Definition PyrExp.h:183
SpatialDomains::SegGeomUniquePtr CreateSegGeom(unsigned int id, SpatialDomains::PointGeom *v0, SpatialDomains::PointGeom *v1)
SpatialDomains::PyrGeomUniquePtr CreatePyr(std::array< SpatialDomains::PointGeom *, 5 > v, std::array< SpatialDomains::SegGeomUniquePtr, 8 > &segVec, std::array< SpatialDomains::TriGeomUniquePtr, 4 > &triVec, std::array< SpatialDomains::QuadGeomUniquePtr, 1 > &quadVec)
BOOST_AUTO_TEST_CASE(TestPyrBwdTrans_IterPerExp_UniformP_MultiElmt)
unique_ptr_objpool< QuadGeom > QuadGeomUniquePtr
Definition MeshGraph.h:100
unique_ptr_objpool< PyrGeom > PyrGeomUniquePtr
Definition MeshGraph.h:102
unique_ptr_objpool< SegGeom > SegGeomUniquePtr
Definition MeshGraph.h:98
unique_ptr_objpool< PointGeom > PointGeomUniquePtr
Definition MeshGraph.h:93
unique_ptr_objpool< TriGeom > TriGeomUniquePtr
Definition MeshGraph.h:99
std::map< ConstFactorType, NekDouble > ConstFactorMap
void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Add vector z = x+y.
Definition Vmath.hpp:180
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition Vmath.hpp:825