Nektar++
Loading...
Searching...
No Matches
TestTetCollection.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: TestTetCollection.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
37#include <LocalRegions/TetExp.h>
39#include <boost/test/tools/floating_point_comparison.hpp>
40#include <boost/test/unit_test.hpp>
41
43{
47{
48 std::array<SpatialDomains::PointGeom *, 2> vertices = {v0, v1};
50 new SpatialDomains::SegGeom(id, 3, vertices));
51 return result;
52}
53
55 std::array<SpatialDomains::PointGeom *, 4> v,
56 std::array<SpatialDomains::SegGeomUniquePtr, 6> &segVec,
57 std::array<SpatialDomains::TriGeomUniquePtr, 4> &faceVec)
58{
59 std::array<std::array<int, 2>, 6> edgeVerts = {
60 {{{0, 1}}, {{1, 2}}, {{0, 2}}, {{0, 3}}, {{1, 3}}, {{2, 3}}}};
61 std::array<std::array<int, 3>, 4> faceEdges = {
62 {{{0, 1, 2}}, {{0, 4, 3}}, {{1, 5, 4}}, {{2, 5, 3}}}};
63
64 // Create segments from vertices
65 for (int i = 0; i < 6; ++i)
66 {
67 segVec[i] = CreateSegGeom(i, v[edgeVerts[i][0]], v[edgeVerts[i][1]]);
68 }
69
70 // Create faces from edges
71 std::array<SpatialDomains::TriGeom *, 4> faces;
72 for (int i = 0; i < 4; ++i)
73 {
74 std::array<SpatialDomains::SegGeom *, 3> face;
75 for (int j = 0; j < 3; ++j)
76 {
77 face[j] = segVec[faceEdges[i][j]].get();
78 }
80 new SpatialDomains::TriGeom(i, face));
81 faces[i] = faceVec[i].get();
82 }
83
85 new SpatialDomains::TetGeom(0, faces));
86 return tetGeom;
87}
88
89BOOST_AUTO_TEST_CASE(TestTetBwdTrans_IterPerExp_UniformP)
90{
92 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
94 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
96 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
98 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
99
100 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
101 v2.get(), v3.get()};
102 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
103 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
104 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
105
106 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
108 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
109 triPointsTypeDir1);
110 Nektar::LibUtilities::BasisType basisTypeDir1 =
112 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
113 triPointsKeyDir1);
114
115 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
116 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
117 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(4,
118 triPointsTypeDir2);
119 Nektar::LibUtilities::BasisType basisTypeDir2 =
121 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
122 triPointsKeyDir2);
123
124 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
125 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
126 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(4,
127 triPointsTypeDir3);
128 Nektar::LibUtilities::BasisType basisTypeDir3 =
130 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
131 triPointsKeyDir3);
132
135 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
136
137 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
138 CollExp.push_back(Exp);
139
141 Collections::CollectionOptimisation colOpt(dummySession, 3,
143 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
144 Collections::Collection c(CollExp, impTypes);
146
147 Array<OneD, NekDouble> coeffs(Exp->GetNcoeffs(), 1.0), tmp;
148 for (int i = 0; i < coeffs.size(); ++i)
149 {
150 coeffs[i] = i + 1; // make values distinct
151 }
152 Array<OneD, NekDouble> phys1(Exp->GetTotPoints());
153 Array<OneD, NekDouble> phys2(Exp->GetTotPoints());
154
155 Exp->BwdTrans(coeffs, phys1);
156 c.ApplyOperator(Collections::eBwdTrans, coeffs, phys2);
157
158 double epsilon = 1.0e-8;
159 for (int i = 0; i < phys1.size(); ++i)
160 {
161 BOOST_CHECK_CLOSE(phys1[i], phys2[i], epsilon);
162 }
163}
164
165BOOST_AUTO_TEST_CASE(TestTetBwdTrans_IterPerExp_VariableP_MultiElmt)
166{
168 new SpatialDomains::PointGeom(3u, 0u, -1.5, -1.5, -1.5));
170 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
172 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
174 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
175
176 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
177 v2.get(), v3.get()};
178 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
179 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
180 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
181
182 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
184 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
185 triPointsTypeDir1);
186 Nektar::LibUtilities::BasisType basisTypeDir1 =
188 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
189 triPointsKeyDir1);
190
191 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
192 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
193 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(7,
194 triPointsTypeDir2);
195 Nektar::LibUtilities::BasisType basisTypeDir2 =
197 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 6,
198 triPointsKeyDir2);
199
200 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
201 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
202 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(9,
203 triPointsTypeDir3);
204 Nektar::LibUtilities::BasisType basisTypeDir3 =
206 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
207 triPointsKeyDir3);
208
211 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
212
213 int nelmts = 10;
214
215 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
216 for (int i = 0; i < nelmts; ++i)
217 {
218 CollExp.push_back(Exp);
219 }
220
222 Collections::CollectionOptimisation colOpt(dummySession, 3,
224 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
225 Collections::Collection c(CollExp, impTypes);
227
228 Array<OneD, NekDouble> coeffs(nelmts * Exp->GetNcoeffs(), 1.0), tmp;
229 for (int i = 0; i < coeffs.size(); ++i)
230 {
231 coeffs[i] = i + 1;
232 }
233 Array<OneD, NekDouble> phys1(nelmts * Exp->GetTotPoints());
234 Array<OneD, NekDouble> phys2(nelmts * Exp->GetTotPoints());
235
236 for (int i = 0; i < nelmts; ++i)
237 {
238 Exp->BwdTrans(coeffs + i * Exp->GetNcoeffs(),
239 tmp = phys1 + i * Exp->GetTotPoints());
240 }
241
242 c.ApplyOperator(Collections::eBwdTrans, coeffs, phys2);
243
244 double epsilon = 1.0e-8;
245 for (int i = 0; i < phys1.size(); ++i)
246 {
247 BOOST_CHECK_CLOSE(phys1[i], phys2[i], epsilon);
248 }
249}
250
251BOOST_AUTO_TEST_CASE(TestTetIProductWRTBase_IterPerExp_UniformP)
252{
254 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
256 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
258 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
260 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
261
262 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
263 v2.get(), v3.get()};
264 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
265 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
266 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
267
268 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
270 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
271 triPointsTypeDir1);
272 Nektar::LibUtilities::BasisType basisTypeDir1 =
274 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
275 triPointsKeyDir1);
276
277 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
278 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
279 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(4,
280 triPointsTypeDir2);
281 Nektar::LibUtilities::BasisType basisTypeDir2 =
283 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
284 triPointsKeyDir2);
285
286 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
287 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
288 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(4,
289 triPointsTypeDir3);
290 Nektar::LibUtilities::BasisType basisTypeDir3 =
292 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
293 triPointsKeyDir3);
294
297 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
298
299 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
300 CollExp.push_back(Exp);
301
303 Collections::CollectionOptimisation colOpt(dummySession, 3,
305 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
306 Collections::Collection c(CollExp, impTypes);
308
309 const int nq = Exp->GetTotPoints();
310 Array<OneD, NekDouble> phys(nq);
311 Array<OneD, NekDouble> coeffs1(Exp->GetNcoeffs());
312 Array<OneD, NekDouble> coeffs2(Exp->GetNcoeffs());
313
314 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
315
316 Exp->GetCoords(xc, yc, zc);
317
318 for (int i = 0; i < nq; ++i)
319 {
320 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
321 }
322
323 Exp->IProductWRTBase(phys, coeffs1);
325
326 double epsilon = 1.0e-8;
327 for (int i = 0; i < coeffs1.size(); ++i)
328 {
329 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
330 }
331}
332
333BOOST_AUTO_TEST_CASE(TestTetIProductWRTBase_IterPerExp_VariableP_MultiElmt)
334{
336 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
338 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
340 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
342 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
343
344 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
345 v2.get(), v3.get()};
346 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
347 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
348 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
349
350 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
352 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
353 triPointsTypeDir1);
354 Nektar::LibUtilities::BasisType basisTypeDir1 =
356 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
357 triPointsKeyDir1);
358
359 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
360 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
361 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(6,
362 triPointsTypeDir2);
363 Nektar::LibUtilities::BasisType basisTypeDir2 =
365 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
366 triPointsKeyDir2);
367 // const Nektar::LibUtilities::BasisKey
368 // basisKeyDir2(basisTypeDir2,5,triPointsKeyDir2);
369
370 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
371 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
372 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(9,
373 triPointsTypeDir3);
374 Nektar::LibUtilities::BasisType basisTypeDir3 =
376 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
377 triPointsKeyDir3);
378
381 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
382
383 int nelmts = 10;
384
385 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
386 for (int i = 0; i < nelmts; ++i)
387 {
388 CollExp.push_back(Exp);
389 }
390
392 Collections::CollectionOptimisation colOpt(dummySession, 3,
394 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
395 Collections::Collection c(CollExp, impTypes);
397
398 const int nq = Exp->GetTotPoints();
399 Array<OneD, NekDouble> phys(nelmts * nq), tmp;
400 Array<OneD, NekDouble> coeffs1(nelmts * Exp->GetNcoeffs());
401 Array<OneD, NekDouble> coeffs2(nelmts * Exp->GetNcoeffs());
402
403 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
404
405 Exp->GetCoords(xc, yc, zc);
406
407 for (int i = 0; i < nq; ++i)
408 {
409 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
410 }
411 Exp->IProductWRTBase(phys, coeffs1);
412
413 for (int i = 1; i < nelmts; ++i)
414 {
415 Vmath::Vcopy(nq, &phys[0], 1, &phys[i * nq], 1);
416 Exp->IProductWRTBase(phys + i * nq,
417 tmp = coeffs1 + i * Exp->GetNcoeffs());
418 }
420
421 double epsilon = 1.0e-4;
422 for (int i = 0; i < coeffs1.size(); ++i)
423 {
424 // clamp values below 1e-14 to zero
425 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
426 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
427 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
428 }
429}
430
431BOOST_AUTO_TEST_CASE(TestTetBwdTrans_StdMat_UniformP)
432{
434 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
436 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
438 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
440 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
441
442 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
443 v2.get(), v3.get()};
444 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
445 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
446 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
447
448 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
450 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
451 triPointsTypeDir1);
452 Nektar::LibUtilities::BasisType basisTypeDir1 =
454 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
455 triPointsKeyDir1);
456
457 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
458 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
459 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(4,
460 triPointsTypeDir2);
461 Nektar::LibUtilities::BasisType basisTypeDir2 =
463 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
464 triPointsKeyDir2);
465
466 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
467 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
468 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(4,
469 triPointsTypeDir3);
470 Nektar::LibUtilities::BasisType basisTypeDir3 =
472 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
473 triPointsKeyDir3);
474
477 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
478
479 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
480 CollExp.push_back(Exp);
481
483 Collections::CollectionOptimisation colOpt(dummySession, 3,
485 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
486 Collections::Collection c(CollExp, impTypes);
488
489 Array<OneD, NekDouble> coeffs(Exp->GetNcoeffs(), 1.0), tmp;
490 for (int i = 0; i < coeffs.size(); ++i)
491 {
492 coeffs[i] = i + 1; // make values distinct
493 }
494 Array<OneD, NekDouble> phys1(Exp->GetTotPoints());
495 Array<OneD, NekDouble> phys2(Exp->GetTotPoints());
496
497 Exp->BwdTrans(coeffs, phys1);
498 c.ApplyOperator(Collections::eBwdTrans, coeffs, phys2);
499
500 double epsilon = 1.0e-8;
501 for (int i = 0; i < phys1.size(); ++i)
502 {
503 BOOST_CHECK_CLOSE(phys1[i], phys2[i], epsilon);
504 }
505}
506
507BOOST_AUTO_TEST_CASE(TestTetBwdTrans_StdMat_VariableP_MultiElmt)
508{
510 new SpatialDomains::PointGeom(3u, 0u, -1.5, -1.5, -1.5));
512 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
514 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
516 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
517
518 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
519 v2.get(), v3.get()};
520 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
521 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
522 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
523
524 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
526 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
527 triPointsTypeDir1);
528 Nektar::LibUtilities::BasisType basisTypeDir1 =
530 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
531 triPointsKeyDir1);
532
533 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
534 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
535 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(7,
536 triPointsTypeDir2);
537 Nektar::LibUtilities::BasisType basisTypeDir2 =
539 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
540 triPointsKeyDir2);
541
542 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
543 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
544 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(9,
545 triPointsTypeDir3);
546 Nektar::LibUtilities::BasisType basisTypeDir3 =
548 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
549 triPointsKeyDir3);
550
553 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
554
555 int nelmts = 10;
556
557 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
558 for (int i = 0; i < nelmts; ++i)
559 {
560 CollExp.push_back(Exp);
561 }
562
564 Collections::CollectionOptimisation colOpt(dummySession, 3,
566 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
567 Collections::Collection c(CollExp, impTypes);
569
570 Array<OneD, NekDouble> coeffs(nelmts * Exp->GetNcoeffs(), 1.0), tmp;
571 for (int i = 0; i < coeffs.size(); ++i)
572 {
573 coeffs[i] = i + 1;
574 }
575 Array<OneD, NekDouble> phys1(nelmts * Exp->GetTotPoints());
576 Array<OneD, NekDouble> phys2(nelmts * Exp->GetTotPoints());
577
578 for (int i = 0; i < nelmts; ++i)
579 {
580 Exp->BwdTrans(coeffs + i * Exp->GetNcoeffs(),
581 tmp = phys1 + i * Exp->GetTotPoints());
582 }
583
584 c.ApplyOperator(Collections::eBwdTrans, coeffs, phys2);
585
586 double epsilon = 1.0e-8;
587 for (int i = 0; i < phys1.size(); ++i)
588 {
589 BOOST_CHECK_CLOSE(phys1[i], phys2[i], epsilon);
590 }
591}
592
593BOOST_AUTO_TEST_CASE(TestTetBwdTrans_SumFac_UniformP)
594{
596 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
598 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
600 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
602 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
603
604 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
605 v2.get(), v3.get()};
606 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
607 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
608 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
609
610 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
612 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
613 triPointsTypeDir1);
614 Nektar::LibUtilities::BasisType basisTypeDir1 =
616 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
617 triPointsKeyDir1);
618
619 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
620 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
621 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(4,
622 triPointsTypeDir2);
623 Nektar::LibUtilities::BasisType basisTypeDir2 =
625 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
626 triPointsKeyDir2);
627
628 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
629 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
630 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(4,
631 triPointsTypeDir3);
632 Nektar::LibUtilities::BasisType basisTypeDir3 =
634 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
635 triPointsKeyDir3);
636
639 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
640
641 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
642 CollExp.push_back(Exp);
643
645 Collections::CollectionOptimisation colOpt(dummySession, 3,
647 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
648 Collections::Collection c(CollExp, impTypes);
650
651 Array<OneD, NekDouble> coeffs(Exp->GetNcoeffs(), 1.0), tmp;
652 for (int i = 0; i < coeffs.size(); ++i)
653 {
654 coeffs[i] = i + 1; // make values distinct
655 }
656 Array<OneD, NekDouble> phys1(Exp->GetTotPoints());
657 Array<OneD, NekDouble> phys2(Exp->GetTotPoints());
658
659 Exp->BwdTrans(coeffs, phys1);
660 c.ApplyOperator(Collections::eBwdTrans, coeffs, phys2);
661
662 double epsilon = 1.0e-8;
663 for (int i = 0; i < phys1.size(); ++i)
664 {
665 BOOST_CHECK_CLOSE(phys1[i], phys2[i], epsilon);
666 }
667}
668
669BOOST_AUTO_TEST_CASE(TestTetBwdTrans_SumFac_MultiElmt)
670{
672 new SpatialDomains::PointGeom(3u, 0u, -1.5, -1.5, -1.5));
674 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
676 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
678 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
679
680 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
681 v2.get(), v3.get()};
682 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
683 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
684 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
685
686 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
688 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
689 triPointsTypeDir1);
690 Nektar::LibUtilities::BasisType basisTypeDir1 =
692 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
693 triPointsKeyDir1);
694
695 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
696 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
697 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(4,
698 triPointsTypeDir2);
699 Nektar::LibUtilities::BasisType basisTypeDir2 =
701 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
702 triPointsKeyDir2);
703
704 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
705 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
706 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(4,
707 triPointsTypeDir3);
708 Nektar::LibUtilities::BasisType basisTypeDir3 =
710 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
711 triPointsKeyDir3);
712
715 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
716
717 int nelmts = 10;
718
719 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
720 for (int i = 0; i < nelmts; ++i)
721 {
722 CollExp.push_back(Exp);
723 }
724
726 Collections::CollectionOptimisation colOpt(dummySession, 3,
728 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
729 Collections::Collection c(CollExp, impTypes);
731
732 Array<OneD, NekDouble> coeffs(nelmts * Exp->GetNcoeffs(), 1.0), tmp;
733 for (int i = 0; i < coeffs.size(); ++i)
734 {
735 coeffs[i] = i + 1;
736 }
737 Array<OneD, NekDouble> phys1(nelmts * Exp->GetTotPoints());
738 Array<OneD, NekDouble> phys2(nelmts * Exp->GetTotPoints());
739
740 for (int i = 0; i < nelmts; ++i)
741 {
742 Exp->BwdTrans(coeffs + i * Exp->GetNcoeffs(),
743 tmp = phys1 + i * Exp->GetTotPoints());
744 }
745
746 c.ApplyOperator(Collections::eBwdTrans, coeffs, phys2);
747
748 double epsilon = 1.0e-8;
749 for (int i = 0; i < phys1.size(); ++i)
750 {
751 BOOST_CHECK_CLOSE(phys1[i], phys2[i], epsilon);
752 }
753}
754
755BOOST_AUTO_TEST_CASE(TestTetBwdTrans_SumFac_MultiElmt_VariableP)
756{
758 new SpatialDomains::PointGeom(3u, 0u, -1.5, -1.5, -1.5));
760 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
762 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
764 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
765
766 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
767 v2.get(), v3.get()};
768 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
769 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
770 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
771
772 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
774 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
775 triPointsTypeDir1);
776 Nektar::LibUtilities::BasisType basisTypeDir1 =
778 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
779 triPointsKeyDir1);
780
781 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
782 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
783 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(6,
784 triPointsTypeDir2);
785 Nektar::LibUtilities::BasisType basisTypeDir2 =
787 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 6,
788 triPointsKeyDir2);
789
790 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
791 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
792 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(9,
793 triPointsTypeDir3);
794 Nektar::LibUtilities::BasisType basisTypeDir3 =
796 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
797 triPointsKeyDir3);
798
801 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
802
803 int nelmts = 1;
804
805 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
806 for (int i = 0; i < nelmts; ++i)
807 {
808 CollExp.push_back(Exp);
809 }
810
812 Collections::CollectionOptimisation colOpt(dummySession, 3,
814 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
815 Collections::Collection c(CollExp, impTypes);
817
818 Array<OneD, NekDouble> coeffs(nelmts * Exp->GetNcoeffs(), 1.0), tmp;
819 for (int i = 0; i < coeffs.size(); ++i)
820 {
821 coeffs[i] = i + 1;
822 }
823 Array<OneD, NekDouble> phys1(nelmts * Exp->GetTotPoints());
824 Array<OneD, NekDouble> phys2(nelmts * Exp->GetTotPoints());
825
826 for (int i = 0; i < nelmts; ++i)
827 {
828 Exp->BwdTrans(coeffs + i * Exp->GetNcoeffs(),
829 tmp = phys1 + i * Exp->GetTotPoints());
830 }
831
832 c.ApplyOperator(Collections::eBwdTrans, coeffs, phys2);
833
834 double epsilon = 1.0e-8;
835 for (int i = 0; i < phys1.size(); ++i)
836 {
837 BOOST_CHECK_CLOSE(phys1[i], phys2[i], epsilon);
838 }
839}
840
841BOOST_AUTO_TEST_CASE(TestTetBwdTrans_MatrixFree_UniformP)
842{
844 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
846 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
848 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
850 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
851
852 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
853 v2.get(), v3.get()};
854 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
855 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
856 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
857
858 unsigned int numQuadPoints = 5;
859 unsigned int numModes = 4;
860
861 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
863 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
864 triPointsTypeDir1);
865 Nektar::LibUtilities::BasisType basisTypeDir1 =
867 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
868 triPointsKeyDir1);
869
870 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
871 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
872 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
873 triPointsTypeDir2);
874 Nektar::LibUtilities::BasisType basisTypeDir2 =
876 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
877 triPointsKeyDir2);
878
879 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
880 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
881 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
882 triPointsTypeDir3);
883 Nektar::LibUtilities::BasisType basisTypeDir3 =
885 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
886 triPointsKeyDir3);
887
890 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
891
892 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
893 CollExp.push_back(Exp);
894
896 Collections::CollectionOptimisation colOpt(dummySession, 2,
898 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
899 // ... only one op at the time ...
901 Collections::Collection c(CollExp, impTypes);
903
904 Array<OneD, NekDouble> coeffs(Exp->GetNcoeffs(), 1.0), tmp;
905 for (int i = 0; i < coeffs.size(); ++i)
906 {
907 coeffs[i] = i + 1; // make values distinct
908 }
909 Array<OneD, NekDouble> physRef(Exp->GetTotPoints());
910 Array<OneD, NekDouble> phys(Exp->GetTotPoints());
911
912 Exp->BwdTrans(coeffs, physRef);
913 c.ApplyOperator(Collections::eBwdTrans, coeffs, phys);
914
915 double epsilon = 1.0e-8;
916 for (int i = 0; i < physRef.size(); ++i)
917 {
918 BOOST_CHECK_CLOSE(physRef[i], phys[i], epsilon);
919 }
920}
921
922BOOST_AUTO_TEST_CASE(TestTetBwdTrans_MatrixFree_UniformP_OverInt)
923{
925 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
927 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
929 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
931 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
932
933 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
934 v2.get(), v3.get()};
935 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
936 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
937 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
938
939 unsigned int numQuadPoints = 8;
940 unsigned int numModes = 4;
941
942 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
944 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
945 triPointsTypeDir1);
946 Nektar::LibUtilities::BasisType basisTypeDir1 =
948 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
949 triPointsKeyDir1);
950
951 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
952 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
953 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
954 triPointsTypeDir2);
955 Nektar::LibUtilities::BasisType basisTypeDir2 =
957 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
958 triPointsKeyDir2);
959
960 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
961 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
962 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
963 triPointsTypeDir3);
964 Nektar::LibUtilities::BasisType basisTypeDir3 =
966 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
967 triPointsKeyDir3);
968
971 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
972
973 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
974 CollExp.push_back(Exp);
975
977 Collections::CollectionOptimisation colOpt(dummySession, 2,
979 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
980 // ... only one op at the time ...
982 Collections::Collection c(CollExp, impTypes);
984
985 Array<OneD, NekDouble> coeffs(Exp->GetNcoeffs(), 1.0), tmp;
986 for (int i = 0; i < coeffs.size(); ++i)
987 {
988 coeffs[i] = i + 1; // make values distinct
989 }
990 Array<OneD, NekDouble> physRef(Exp->GetTotPoints());
991 Array<OneD, NekDouble> phys(Exp->GetTotPoints());
992
993 Exp->BwdTrans(coeffs, physRef);
994 c.ApplyOperator(Collections::eBwdTrans, coeffs, phys);
995
996 double epsilon = 1.0e-8;
997 for (int i = 0; i < physRef.size(); ++i)
998 {
999 BOOST_CHECK_CLOSE(physRef[i], phys[i], epsilon);
1000 }
1001}
1002
1003BOOST_AUTO_TEST_CASE(TestTetIProductWRTBase_StdMat_UniformP)
1004{
1006 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1008 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1010 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
1012 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
1013
1014 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
1015 v2.get(), v3.get()};
1016 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
1017 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
1018 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
1019
1020 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
1022 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
1023 triPointsTypeDir1);
1024 Nektar::LibUtilities::BasisType basisTypeDir1 =
1026 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
1027 triPointsKeyDir1);
1028
1029 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
1030 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
1031 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(4,
1032 triPointsTypeDir2);
1033 Nektar::LibUtilities::BasisType basisTypeDir2 =
1035 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
1036 triPointsKeyDir2);
1037
1038 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
1039 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1040 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(4,
1041 triPointsTypeDir3);
1042 Nektar::LibUtilities::BasisType basisTypeDir3 =
1044 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
1045 triPointsKeyDir3);
1046
1049 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
1050
1051 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
1052 CollExp.push_back(Exp);
1053
1055 Collections::CollectionOptimisation colOpt(dummySession, 3,
1057 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1058 Collections::Collection c(CollExp, impTypes);
1060
1061 const int nq = Exp->GetTotPoints();
1062 Array<OneD, NekDouble> phys(nq);
1063 Array<OneD, NekDouble> coeffs1(Exp->GetNcoeffs());
1064 Array<OneD, NekDouble> coeffs2(Exp->GetNcoeffs());
1065
1066 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1067
1068 Exp->GetCoords(xc, yc, zc);
1069
1070 for (int i = 0; i < nq; ++i)
1071 {
1072 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1073 }
1074
1075 Exp->IProductWRTBase(phys, coeffs1);
1077
1078 double epsilon = 1.0e-8;
1079 for (int i = 0; i < coeffs1.size(); ++i)
1080 {
1081 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
1082 }
1083}
1084
1085BOOST_AUTO_TEST_CASE(TestTetIProductWRTBase_StdMat_VariableP_MultiElmt)
1086{
1088 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1090 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1092 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
1094 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
1095
1096 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
1097 v2.get(), v3.get()};
1098 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
1099 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
1100 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
1101
1102 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
1104 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
1105 triPointsTypeDir1);
1106 Nektar::LibUtilities::BasisType basisTypeDir1 =
1108 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
1109 triPointsKeyDir1);
1110
1111 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
1112 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
1113 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(7,
1114 triPointsTypeDir2);
1115 Nektar::LibUtilities::BasisType basisTypeDir2 =
1117 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
1118 triPointsKeyDir2);
1119
1120 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
1121 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1122 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(9,
1123 triPointsTypeDir3);
1124 Nektar::LibUtilities::BasisType basisTypeDir3 =
1126 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
1127 triPointsKeyDir3);
1128
1131 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
1132
1133 int nelmts = 10;
1134
1135 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
1136 for (int i = 0; i < nelmts; ++i)
1137 {
1138 CollExp.push_back(Exp);
1139 }
1140
1142 Collections::CollectionOptimisation colOpt(dummySession, 3,
1144 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1145 Collections::Collection c(CollExp, impTypes);
1147
1148 const int nq = Exp->GetTotPoints();
1149 Array<OneD, NekDouble> phys(nelmts * nq), tmp;
1150 Array<OneD, NekDouble> coeffs1(nelmts * Exp->GetNcoeffs());
1151 Array<OneD, NekDouble> coeffs2(nelmts * Exp->GetNcoeffs());
1152
1153 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1154
1155 Exp->GetCoords(xc, yc, zc);
1156
1157 for (int i = 0; i < nq; ++i)
1158 {
1159 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1160 }
1161 Exp->IProductWRTBase(phys, coeffs1);
1162
1163 for (int i = 1; i < nelmts; ++i)
1164 {
1165 Vmath::Vcopy(nq, &phys[0], 1, &phys[i * nq], 1);
1166 Exp->IProductWRTBase(phys + i * nq,
1167 tmp = coeffs1 + i * Exp->GetNcoeffs());
1168 }
1170
1171 double epsilon = 1.0e-4;
1172 for (int i = 0; i < coeffs1.size(); ++i)
1173 {
1174 // clamp values below 1e-14 to zero
1175 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
1176 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
1177 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
1178 }
1179}
1180
1181BOOST_AUTO_TEST_CASE(TestTetIProductWRTBase_SumFac_UniformP)
1182{
1184 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1186 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1188 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
1190 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
1191
1192 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
1193 v2.get(), v3.get()};
1194 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
1195 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
1196 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
1197
1198 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
1200 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
1201 triPointsTypeDir1);
1202 Nektar::LibUtilities::BasisType basisTypeDir1 =
1204 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
1205 triPointsKeyDir1);
1206
1207 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
1208 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
1209 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(4,
1210 triPointsTypeDir2);
1211 Nektar::LibUtilities::BasisType basisTypeDir2 =
1213 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
1214 triPointsKeyDir2);
1215
1216 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
1217 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1218 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(4,
1219 triPointsTypeDir3);
1220 Nektar::LibUtilities::BasisType basisTypeDir3 =
1222 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
1223 triPointsKeyDir3);
1224
1227 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
1228
1229 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
1230 CollExp.push_back(Exp);
1231
1233 Collections::CollectionOptimisation colOpt(dummySession, 3,
1235 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1236 Collections::Collection c(CollExp, impTypes);
1238
1239 const int nq = Exp->GetTotPoints();
1240 Array<OneD, NekDouble> phys(nq);
1241 Array<OneD, NekDouble> coeffs1(Exp->GetNcoeffs());
1242 Array<OneD, NekDouble> coeffs2(Exp->GetNcoeffs());
1243
1244 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1245
1246 Exp->GetCoords(xc, yc, zc);
1247
1248 for (int i = 0; i < nq; ++i)
1249 {
1250 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1251 }
1252
1253 Exp->IProductWRTBase(phys, coeffs1);
1255
1256 double epsilon = 1.0e-8;
1257 for (int i = 0; i < coeffs1.size(); ++i)
1258 {
1259 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
1260 }
1261}
1262
1263BOOST_AUTO_TEST_CASE(TestTetIProductWRTBase_SumFac_VariableP_MultiElmt)
1264{
1266 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1268 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1270 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
1272 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
1273
1274 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
1275 v2.get(), v3.get()};
1276 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
1277 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
1278 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
1279
1280 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
1282 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
1283 triPointsTypeDir1);
1284 Nektar::LibUtilities::BasisType basisTypeDir1 =
1286 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
1287 triPointsKeyDir1);
1288
1289 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
1290 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
1291 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(7,
1292 triPointsTypeDir2);
1293 Nektar::LibUtilities::BasisType basisTypeDir2 =
1295 // const Nektar::LibUtilities::BasisKey
1296 // basisKeyDir2(basisTypeDir2,6,triPointsKeyDir2);
1297 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
1298 triPointsKeyDir2);
1299
1300 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
1301 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1302 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(9,
1303 triPointsTypeDir3);
1304 Nektar::LibUtilities::BasisType basisTypeDir3 =
1306 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
1307 triPointsKeyDir3);
1308
1311 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
1312
1313 int nelmts = 10;
1314
1315 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
1316 for (int i = 0; i < nelmts; ++i)
1317 {
1318 CollExp.push_back(Exp);
1319 }
1320
1322 Collections::CollectionOptimisation colOpt(dummySession, 3,
1324 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1325 Collections::Collection c(CollExp, impTypes);
1327
1328 const int nq = Exp->GetTotPoints();
1329 Array<OneD, NekDouble> phys(nelmts * nq), tmp;
1330 Array<OneD, NekDouble> coeffs1(nelmts * Exp->GetNcoeffs());
1331 Array<OneD, NekDouble> coeffs2(nelmts * Exp->GetNcoeffs());
1332
1333 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1334
1335 Exp->GetCoords(xc, yc, zc);
1336
1337 for (int i = 0; i < nq; ++i)
1338 {
1339 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1340 }
1341 Exp->IProductWRTBase(phys, coeffs1);
1342
1343 for (int i = 1; i < nelmts; ++i)
1344 {
1345 Vmath::Vcopy(nq, &phys[0], 1, &phys[i * nq], 1);
1346 Exp->IProductWRTBase(phys + i * nq,
1347 tmp = coeffs1 + i * Exp->GetNcoeffs());
1348 }
1350
1351 double epsilon = 1.0e-4;
1352 for (int i = 0; i < coeffs1.size(); ++i)
1353 {
1354 // clamp values below 1e-14 to zero
1355 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
1356 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
1357 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
1358 }
1359}
1360
1361BOOST_AUTO_TEST_CASE(TestTetIProductWRTBase_MatrixFree_UniformP_Undeformed)
1362{
1364 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1366 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1368 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
1370 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
1371
1372 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
1373 v2.get(), v3.get()};
1374 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
1375 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
1376 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
1377
1378 unsigned int numQuadPoints = 5;
1379 unsigned int numModes = 4;
1380
1381 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
1383 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
1384 triPointsTypeDir1);
1385 Nektar::LibUtilities::BasisType basisTypeDir1 =
1387 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
1388 triPointsKeyDir1);
1389
1390 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
1391 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
1392 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
1393 triPointsTypeDir2);
1394 Nektar::LibUtilities::BasisType basisTypeDir2 =
1396 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
1397 triPointsKeyDir2);
1398
1399 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
1400 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1401 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
1402 triPointsTypeDir3);
1403 Nektar::LibUtilities::BasisType basisTypeDir3 =
1405 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
1406 triPointsKeyDir3);
1407
1410 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
1411
1412 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
1413 CollExp.push_back(Exp);
1414
1416 Collections::CollectionOptimisation colOpt(dummySession, 2,
1418 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1419 // ... only one op at the time ...
1421 Collections::Collection c(CollExp, impTypes);
1423
1424 const int nq = Exp->GetTotPoints();
1425 Array<OneD, NekDouble> phys(nq);
1426 Array<OneD, NekDouble> coeffsRef(Exp->GetNcoeffs());
1427 Array<OneD, NekDouble> coeffs(Exp->GetNcoeffs());
1428
1429 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1430
1431 Exp->GetCoords(xc, yc, zc);
1432
1433 for (int i = 0; i < nq; ++i)
1434 {
1435 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1436 }
1437
1438 Exp->IProductWRTBase(phys, coeffsRef);
1440
1441 double epsilon = 1.0e-8;
1442 for (int i = 0; i < coeffsRef.size(); ++i)
1443 {
1444 BOOST_CHECK_CLOSE(coeffsRef[i], coeffs[i], epsilon);
1445 }
1446}
1447
1448BOOST_AUTO_TEST_CASE(TestTetIProductWRTBase_MatrixFree_UniformP_Deformed)
1449{
1451 new SpatialDomains::PointGeom(3u, 0u, -2.0, -3.0, -4.0));
1453 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1455 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
1457 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
1458
1459 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
1460 v2.get(), v3.get()};
1461 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
1462 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
1463 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
1464
1465 unsigned int numQuadPoints = 5;
1466 unsigned int numModes = 4;
1467
1468 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
1470 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
1471 triPointsTypeDir1);
1472 Nektar::LibUtilities::BasisType basisTypeDir1 =
1474 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
1475 triPointsKeyDir1);
1476
1477 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
1478 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
1479 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
1480 triPointsTypeDir2);
1481 Nektar::LibUtilities::BasisType basisTypeDir2 =
1483 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
1484 triPointsKeyDir2);
1485
1486 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
1487 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1488 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
1489 triPointsTypeDir3);
1490 Nektar::LibUtilities::BasisType basisTypeDir3 =
1492 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
1493 triPointsKeyDir3);
1494
1497 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
1498
1499 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
1500 CollExp.push_back(Exp);
1501
1503 Collections::CollectionOptimisation colOpt(dummySession, 2,
1505 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1506 // ... only one op at the time ...
1508 Collections::Collection c(CollExp, impTypes);
1510
1511 const int nq = Exp->GetTotPoints();
1512 Array<OneD, NekDouble> phys(nq);
1513 Array<OneD, NekDouble> coeffsRef(Exp->GetNcoeffs());
1514 Array<OneD, NekDouble> coeffs(Exp->GetNcoeffs());
1515
1516 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1517
1518 Exp->GetCoords(xc, yc, zc);
1519
1520 for (int i = 0; i < nq; ++i)
1521 {
1522 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1523 }
1524
1525 Exp->IProductWRTBase(phys, coeffsRef);
1527
1528 double epsilon = 1.0e-8;
1529 for (int i = 0; i < coeffsRef.size(); ++i)
1530 {
1531 BOOST_CHECK_CLOSE(coeffsRef[i], coeffs[i], epsilon);
1532 }
1533}
1534
1536 TestTetIProductWRTBase_MatrixFree_UniformP_Deformed_OverInt)
1537{
1539 new SpatialDomains::PointGeom(3u, 0u, -2.0, -3.0, -4.0));
1541 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1543 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
1545 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
1546
1547 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
1548 v2.get(), v3.get()};
1549 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
1550 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
1551 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
1552
1553 unsigned int numQuadPoints = 8;
1554 unsigned int numModes = 4;
1555
1556 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
1558 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
1559 triPointsTypeDir1);
1560 Nektar::LibUtilities::BasisType basisTypeDir1 =
1562 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
1563 triPointsKeyDir1);
1564
1565 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
1566 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
1567 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
1568 triPointsTypeDir2);
1569 Nektar::LibUtilities::BasisType basisTypeDir2 =
1571 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
1572 triPointsKeyDir2);
1573
1574 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
1575 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1576 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
1577 triPointsTypeDir3);
1578 Nektar::LibUtilities::BasisType basisTypeDir3 =
1580 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
1581 triPointsKeyDir3);
1582
1585 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
1586
1587 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
1588 CollExp.push_back(Exp);
1589
1591 Collections::CollectionOptimisation colOpt(dummySession, 2,
1593 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1594 // ... only one op at the time ...
1596 Collections::Collection c(CollExp, impTypes);
1598
1599 const int nq = Exp->GetTotPoints();
1600 Array<OneD, NekDouble> phys(nq);
1601 Array<OneD, NekDouble> coeffsRef(Exp->GetNcoeffs());
1602 Array<OneD, NekDouble> coeffs(Exp->GetNcoeffs());
1603
1604 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1605
1606 Exp->GetCoords(xc, yc, zc);
1607
1608 for (int i = 0; i < nq; ++i)
1609 {
1610 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1611 }
1612
1613 Exp->IProductWRTBase(phys, coeffsRef);
1615
1616 double epsilon = 1.0e-8;
1617 for (int i = 0; i < coeffsRef.size(); ++i)
1618 {
1619 BOOST_CHECK_CLOSE(coeffsRef[i], coeffs[i], epsilon);
1620 }
1621}
1622
1623BOOST_AUTO_TEST_CASE(TestTetPhysDeriv_IterPerExp_UniformP)
1624{
1626 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1628 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1630 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
1632 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
1633
1634 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
1635 v2.get(), v3.get()};
1636 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
1637 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
1638 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
1639
1640 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
1642 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
1643 triPointsTypeDir1);
1644 Nektar::LibUtilities::BasisType basisTypeDir1 =
1646 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
1647 triPointsKeyDir1);
1648
1649 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
1650 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
1651 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(4,
1652 triPointsTypeDir2);
1653 Nektar::LibUtilities::BasisType basisTypeDir2 =
1655 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
1656 triPointsKeyDir2);
1657
1658 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
1659 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1660 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(4,
1661 triPointsTypeDir3);
1662 Nektar::LibUtilities::BasisType basisTypeDir3 =
1664 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
1665 triPointsKeyDir3);
1666
1669 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
1670
1671 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
1672 CollExp.push_back(Exp);
1673
1675 Collections::CollectionOptimisation colOpt(dummySession, 3,
1677 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1678 Collections::Collection c(CollExp, impTypes);
1680
1681 const int nq = Exp->GetTotPoints();
1682 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1683 Array<OneD, NekDouble> phys(nq), tmp, tmp1, tmp2;
1684 Array<OneD, NekDouble> diff1(3 * nq);
1685 Array<OneD, NekDouble> diff2(3 * nq);
1686
1687 Exp->GetCoords(xc, yc, zc);
1688
1689 for (int i = 0; i < nq; ++i)
1690 {
1691 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1692 }
1693
1694 Exp->PhysDeriv(phys, diff1, tmp = diff1 + nq, tmp1 = diff1 + 2 * nq);
1695 c.ApplyOperator(Collections::ePhysDeriv, phys, diff2, tmp = diff2 + nq,
1696 tmp2 = diff2 + 2 * nq);
1697
1698 double epsilon = 1.0e-8;
1699 for (int i = 0; i < diff1.size(); ++i)
1700 {
1701 BOOST_CHECK_CLOSE(diff1[i], diff2[i], epsilon);
1702 }
1703}
1704
1705BOOST_AUTO_TEST_CASE(TestTetPhysDeriv_IterPerExp_VariableP_MultiElmt)
1706{
1708 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1710 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1712 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
1714 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
1715
1716 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
1717 v2.get(), v3.get()};
1718 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
1719 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
1720 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
1721
1722 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
1724 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
1725 triPointsTypeDir1);
1726 Nektar::LibUtilities::BasisType basisTypeDir1 =
1728 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
1729 triPointsKeyDir1);
1730
1731 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
1732 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
1733 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(7,
1734 triPointsTypeDir2);
1735 Nektar::LibUtilities::BasisType basisTypeDir2 =
1737 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 6,
1738 triPointsKeyDir2);
1739
1740 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
1741 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1742 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(9,
1743 triPointsTypeDir3);
1744 Nektar::LibUtilities::BasisType basisTypeDir3 =
1746 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
1747 triPointsKeyDir3);
1748
1751 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
1752
1753 int nelmts = 10;
1754
1755 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
1756 for (int i = 0; i < nelmts; ++i)
1757 {
1758 CollExp.push_back(Exp);
1759 }
1760
1762 Collections::CollectionOptimisation colOpt(dummySession, 3,
1764 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1765 Collections::Collection c(CollExp, impTypes);
1767
1768 const int nq = Exp->GetTotPoints();
1769 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1770 Array<OneD, NekDouble> phys(nelmts * nq), tmp, tmp1, tmp2;
1771 Array<OneD, NekDouble> diff1(3 * nelmts * nq);
1772 Array<OneD, NekDouble> diff2(3 * nelmts * nq);
1773
1774 Exp->GetCoords(xc, yc, zc);
1775
1776 for (int i = 0; i < nq; ++i)
1777 {
1778 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1779 }
1780 Exp->PhysDeriv(phys, diff1, tmp1 = diff1 + (nelmts)*nq,
1781 tmp2 = diff1 + (2 * nelmts) * nq);
1782
1783 for (int i = 1; i < nelmts; ++i)
1784 {
1785 Vmath::Vcopy(nq, phys, 1, tmp = phys + i * nq, 1);
1786 Exp->PhysDeriv(phys, tmp = diff1 + i * nq,
1787 tmp1 = diff1 + (nelmts + i) * nq,
1788 tmp2 = diff1 + (2 * nelmts + i) * nq);
1789 }
1790
1792 tmp = diff2 + nelmts * nq, tmp2 = diff2 + 2 * nelmts * nq);
1793
1794 double epsilon = 1.0e-8;
1795 for (int i = 0; i < diff1.size(); ++i)
1796 {
1797 BOOST_CHECK_CLOSE(diff1[i], diff2[i], epsilon);
1798 }
1799}
1800
1801BOOST_AUTO_TEST_CASE(TestTetPhysDeriv_StdMat_UniformP)
1802{
1804 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1806 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1808 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
1810 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
1811
1812 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
1813 v2.get(), v3.get()};
1814 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
1815 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
1816 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
1817
1818 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
1820 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
1821 triPointsTypeDir1);
1822 Nektar::LibUtilities::BasisType basisTypeDir1 =
1824 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
1825 triPointsKeyDir1);
1826
1827 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
1828 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
1829 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(4,
1830 triPointsTypeDir2);
1831 Nektar::LibUtilities::BasisType basisTypeDir2 =
1833 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
1834 triPointsKeyDir2);
1835
1836 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
1837 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1838 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(4,
1839 triPointsTypeDir3);
1840 Nektar::LibUtilities::BasisType basisTypeDir3 =
1842 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
1843 triPointsKeyDir3);
1844
1847 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
1848
1849 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
1850 CollExp.push_back(Exp);
1851
1853 Collections::CollectionOptimisation colOpt(dummySession, 3,
1855 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1856 Collections::Collection c(CollExp, impTypes);
1858
1859 const int nq = Exp->GetTotPoints();
1860 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1861 Array<OneD, NekDouble> phys(nq), tmp, tmp1, tmp2;
1862 Array<OneD, NekDouble> diff1(3 * nq);
1863 Array<OneD, NekDouble> diff2(3 * nq);
1864
1865 Exp->GetCoords(xc, yc, zc);
1866
1867 for (int i = 0; i < nq; ++i)
1868 {
1869 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1870 }
1871
1872 Exp->PhysDeriv(phys, diff1, tmp = diff1 + nq, tmp1 = diff1 + 2 * nq);
1873 c.ApplyOperator(Collections::ePhysDeriv, phys, diff2, tmp = diff2 + nq,
1874 tmp2 = diff2 + 2 * nq);
1875
1876 double epsilon = 1.0e-8;
1877 for (int i = 0; i < diff1.size(); ++i)
1878 {
1879 BOOST_CHECK_CLOSE(diff1[i], diff2[i], epsilon);
1880 }
1881}
1882
1883BOOST_AUTO_TEST_CASE(TestTetPhysDeriv_StdMat_VariableP_MultiElmt)
1884{
1886 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1888 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1890 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
1892 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
1893
1894 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
1895 v2.get(), v3.get()};
1896 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
1897 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
1898 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
1899
1900 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
1902 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
1903 triPointsTypeDir1);
1904 Nektar::LibUtilities::BasisType basisTypeDir1 =
1906 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
1907 triPointsKeyDir1);
1908
1909 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
1910 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
1911 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(7,
1912 triPointsTypeDir2);
1913 Nektar::LibUtilities::BasisType basisTypeDir2 =
1915 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 6,
1916 triPointsKeyDir2);
1917
1918 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
1919 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1920 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(9,
1921 triPointsTypeDir3);
1922 Nektar::LibUtilities::BasisType basisTypeDir3 =
1924 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
1925 triPointsKeyDir3);
1926
1929 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
1930
1931 int nelmts = 10;
1932
1933 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
1934 for (int i = 0; i < nelmts; ++i)
1935 {
1936 CollExp.push_back(Exp);
1937 }
1938
1940 Collections::CollectionOptimisation colOpt(dummySession, 3,
1942 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1943 Collections::Collection c(CollExp, impTypes);
1945
1946 const int nq = Exp->GetTotPoints();
1947 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1948 Array<OneD, NekDouble> phys(nelmts * nq), tmp, tmp1, tmp2;
1949 Array<OneD, NekDouble> diff1(3 * nelmts * nq);
1950 Array<OneD, NekDouble> diff2(3 * nelmts * nq);
1951
1952 Exp->GetCoords(xc, yc, zc);
1953
1954 for (int i = 0; i < nq; ++i)
1955 {
1956 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1957 }
1958 Exp->PhysDeriv(phys, diff1, tmp1 = diff1 + (nelmts)*nq,
1959 tmp2 = diff1 + (2 * nelmts) * nq);
1960
1961 for (int i = 1; i < nelmts; ++i)
1962 {
1963 Vmath::Vcopy(nq, phys, 1, tmp = phys + i * nq, 1);
1964 Exp->PhysDeriv(phys, tmp = diff1 + i * nq,
1965 tmp1 = diff1 + (nelmts + i) * nq,
1966 tmp2 = diff1 + (2 * nelmts + i) * nq);
1967 }
1968
1970 tmp = diff2 + nelmts * nq, tmp2 = diff2 + 2 * nelmts * nq);
1971
1972 double epsilon = 1.0e-8;
1973 for (int i = 0; i < diff1.size(); ++i)
1974 {
1975 BOOST_CHECK_CLOSE(diff1[i], diff2[i], epsilon);
1976 }
1977}
1978
1979BOOST_AUTO_TEST_CASE(TestTetPhysDeriv_SumFac_UniformP)
1980{
1982 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1984 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1986 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
1988 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
1989
1990 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
1991 v2.get(), v3.get()};
1992 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
1993 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
1994 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
1995
1996 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
1998 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
1999 triPointsTypeDir1);
2000 Nektar::LibUtilities::BasisType basisTypeDir1 =
2002 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
2003 triPointsKeyDir1);
2004
2005 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
2006 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
2007 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(4,
2008 triPointsTypeDir2);
2009 Nektar::LibUtilities::BasisType basisTypeDir2 =
2011 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
2012 triPointsKeyDir2);
2013
2014 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
2015 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2016 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(4,
2017 triPointsTypeDir3);
2018 Nektar::LibUtilities::BasisType basisTypeDir3 =
2020 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
2021 triPointsKeyDir3);
2022
2025 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
2026
2027 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
2028 CollExp.push_back(Exp);
2029
2031 Collections::CollectionOptimisation colOpt(dummySession, 3,
2033 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2034 Collections::Collection c(CollExp, impTypes);
2036
2037 const int nq = Exp->GetTotPoints();
2038 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
2039 Array<OneD, NekDouble> phys(nq), tmp, tmp1, tmp2;
2040 Array<OneD, NekDouble> diff1(3 * nq);
2041 Array<OneD, NekDouble> diff2(3 * nq);
2042
2043 Exp->GetCoords(xc, yc, zc);
2044
2045 for (int i = 0; i < nq; ++i)
2046 {
2047 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
2048 }
2049
2050 Exp->PhysDeriv(phys, diff1, tmp = diff1 + nq, tmp1 = diff1 + 2 * nq);
2051 c.ApplyOperator(Collections::ePhysDeriv, phys, diff2, tmp = diff2 + nq,
2052 tmp2 = diff2 + 2 * nq);
2053
2054 double epsilon = 1.0e-8;
2055 for (int i = 0; i < diff1.size(); ++i)
2056 {
2057 BOOST_CHECK_CLOSE(diff1[i], diff2[i], epsilon);
2058 }
2059}
2060
2061BOOST_AUTO_TEST_CASE(TestTetPhysDeriv_SumFac_VariableP_MultiElmt)
2062{
2064 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
2066 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2068 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
2070 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
2071
2072 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
2073 v2.get(), v3.get()};
2074 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
2075 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
2076 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
2077
2078 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
2080 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
2081 triPointsTypeDir1);
2082 Nektar::LibUtilities::BasisType basisTypeDir1 =
2084 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
2085 triPointsKeyDir1);
2086
2087 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
2088 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
2089 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(7,
2090 triPointsTypeDir2);
2091 Nektar::LibUtilities::BasisType basisTypeDir2 =
2093 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 6,
2094 triPointsKeyDir2);
2095
2096 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
2097 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2098 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(9,
2099 triPointsTypeDir3);
2100 Nektar::LibUtilities::BasisType basisTypeDir3 =
2102 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
2103 triPointsKeyDir3);
2104
2107 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
2108
2109 int nelmts = 10;
2110
2111 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
2112 for (int i = 0; i < nelmts; ++i)
2113 {
2114 CollExp.push_back(Exp);
2115 }
2116
2118 Collections::CollectionOptimisation colOpt(dummySession, 3,
2120 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2121 Collections::Collection c(CollExp, impTypes);
2123
2124 const int nq = Exp->GetTotPoints();
2125 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
2126 Array<OneD, NekDouble> phys(nelmts * nq), tmp, tmp1, tmp2;
2127 Array<OneD, NekDouble> diff1(3 * nelmts * nq);
2128 Array<OneD, NekDouble> diff2(3 * nelmts * nq);
2129
2130 Exp->GetCoords(xc, yc, zc);
2131
2132 for (int i = 0; i < nq; ++i)
2133 {
2134 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
2135 }
2136 Exp->PhysDeriv(phys, diff1, tmp1 = diff1 + (nelmts)*nq,
2137 tmp2 = diff1 + (2 * nelmts) * nq);
2138
2139 for (int i = 1; i < nelmts; ++i)
2140 {
2141 Vmath::Vcopy(nq, phys, 1, tmp = phys + i * nq, 1);
2142 Exp->PhysDeriv(phys, tmp = diff1 + i * nq,
2143 tmp1 = diff1 + (nelmts + i) * nq,
2144 tmp2 = diff1 + (2 * nelmts + i) * nq);
2145 }
2146
2148 tmp = diff2 + nelmts * nq, tmp2 = diff2 + 2 * nelmts * nq);
2149
2150 double epsilon = 1.0e-8;
2151 for (int i = 0; i < diff1.size(); ++i)
2152 {
2153 BOOST_CHECK_CLOSE(diff1[i], diff2[i], epsilon);
2154 }
2155}
2156
2157BOOST_AUTO_TEST_CASE(TestTetPhysDeriv_MatrixFree_UniformP)
2158{
2160 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
2162 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2164 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
2166 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
2167
2168 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
2169 v2.get(), v3.get()};
2170 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
2171 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
2172 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
2173
2174 unsigned int numQuadPoints = 5;
2175 unsigned int numModes = 4;
2176
2177 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
2179 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
2180 triPointsTypeDir1);
2181 Nektar::LibUtilities::BasisType basisTypeDir1 =
2183 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
2184 triPointsKeyDir1);
2185
2186 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
2187 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
2188 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
2189 triPointsTypeDir2);
2190 Nektar::LibUtilities::BasisType basisTypeDir2 =
2192 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
2193 triPointsKeyDir2);
2194
2195 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
2196 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2197 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
2198 triPointsTypeDir3);
2199 Nektar::LibUtilities::BasisType basisTypeDir3 =
2201 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
2202 triPointsKeyDir3);
2203
2206 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
2207
2208 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
2209 CollExp.push_back(Exp);
2210
2212 Collections::CollectionOptimisation colOpt(dummySession, 2,
2214 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2215 // ... only one op at the time ...
2217 Collections::Collection c(CollExp, impTypes);
2219
2220 const int nq = Exp->GetTotPoints();
2221 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
2222 Array<OneD, NekDouble> phys(nq), tmp, tmp1, tmp2;
2223 Array<OneD, NekDouble> diffRef(3 * nq);
2224 Array<OneD, NekDouble> diff(3 * nq);
2225
2226 Exp->GetCoords(xc, yc, zc);
2227
2228 for (int i = 0; i < nq; ++i)
2229 {
2230 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
2231 }
2232
2233 Exp->PhysDeriv(phys, diffRef, tmp = diffRef + nq, tmp1 = diffRef + 2 * nq);
2234 c.ApplyOperator(Collections::ePhysDeriv, phys, diff, tmp = diff + nq,
2235 tmp2 = diff + 2 * nq);
2236
2237 double epsilon = 1.0e-8;
2238 for (int i = 0; i < diffRef.size(); ++i)
2239 {
2240 BOOST_CHECK_CLOSE(diffRef[i], diff[i], epsilon);
2241 }
2242}
2243
2244BOOST_AUTO_TEST_CASE(TestTetIProductWRTDerivBase_IterPerExp_UniformP)
2245{
2247 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
2249 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2251 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
2253 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
2254
2255 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
2256 v2.get(), v3.get()};
2257 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
2258 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
2259 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
2260
2261 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
2263 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
2264 triPointsTypeDir1);
2265 Nektar::LibUtilities::BasisType basisTypeDir1 =
2267 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
2268 triPointsKeyDir1);
2269
2270 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
2271 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
2272 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(4,
2273 triPointsTypeDir2);
2274 Nektar::LibUtilities::BasisType basisTypeDir2 =
2276 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
2277 triPointsKeyDir2);
2278
2279 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
2280 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2281 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(4,
2282 triPointsTypeDir3);
2283 Nektar::LibUtilities::BasisType basisTypeDir3 =
2285 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
2286 triPointsKeyDir3);
2287
2290 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
2291
2292 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
2293 CollExp.push_back(Exp);
2294
2296 Collections::CollectionOptimisation colOpt(dummySession, 3,
2298 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2299 Collections::Collection c(CollExp, impTypes);
2301
2302 const int nq = Exp->GetTotPoints();
2303 const int nm = Exp->GetNcoeffs();
2304 Array<OneD, NekDouble> phys1(nq);
2305 Array<OneD, NekDouble> phys2(nq);
2306 Array<OneD, NekDouble> phys3(nq);
2307 Array<OneD, NekDouble> coeffs1(nm);
2308 Array<OneD, NekDouble> coeffs2(nm);
2309
2310 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
2311
2312 Exp->GetCoords(xc, yc, zc);
2313
2314 for (int i = 0; i < nq; ++i)
2315 {
2316 phys1[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
2317 phys2[i] = cos(xc[i]) * sin(yc[i]) * cos(zc[i]);
2318 phys3[i] = cos(xc[i]) * sin(yc[i]) * sin(zc[i]);
2319 }
2320
2321 // Standard routines
2322 Exp->IProductWRTDerivBase(0, phys1, coeffs1);
2323 Exp->IProductWRTDerivBase(1, phys2, coeffs2);
2324 Vmath::Vadd(nm, coeffs1, 1, coeffs2, 1, coeffs1, 1);
2325 Exp->IProductWRTDerivBase(2, phys3, coeffs2);
2326 Vmath::Vadd(nm, coeffs1, 1, coeffs2, 1, coeffs1, 1);
2327
2329 coeffs2);
2330
2331 double epsilon = 1.0e-8;
2332 for (int i = 0; i < coeffs1.size(); ++i)
2333 {
2334 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
2335 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
2336 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
2337 }
2338}
2339
2340BOOST_AUTO_TEST_CASE(TestTetIProductWRTDerivBase_IterPerExp_VariableP_MultiElmt)
2341{
2343 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
2345 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2347 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
2349 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
2350
2351 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
2352 v2.get(), v3.get()};
2353 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
2354 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
2355 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
2356
2357 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
2359 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
2360 triPointsTypeDir1);
2361 Nektar::LibUtilities::BasisType basisTypeDir1 =
2363 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
2364 triPointsKeyDir1);
2365
2366 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
2367 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
2368 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(6,
2369 triPointsTypeDir2);
2370 Nektar::LibUtilities::BasisType basisTypeDir2 =
2372 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
2373 triPointsKeyDir2);
2374 // const Nektar::LibUtilities::BasisKey
2375 // basisKeyDir2(basisTypeDir2,5,triPointsKeyDir2);
2376
2377 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
2378 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2379 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(9,
2380 triPointsTypeDir3);
2381 Nektar::LibUtilities::BasisType basisTypeDir3 =
2383 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
2384 triPointsKeyDir3);
2385
2388 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
2389
2390 int nelmts = 1;
2391
2392 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
2393 for (int i = 0; i < nelmts; ++i)
2394 {
2395 CollExp.push_back(Exp);
2396 }
2397
2399 Collections::CollectionOptimisation colOpt(dummySession, 3,
2401 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2402 Collections::Collection c(CollExp, impTypes);
2404
2405 const int nq = Exp->GetTotPoints();
2406 const int nm = Exp->GetNcoeffs();
2407 Array<OneD, NekDouble> phys1(nelmts * nq), tmp;
2408 Array<OneD, NekDouble> phys2(nelmts * nq);
2409 Array<OneD, NekDouble> phys3(nelmts * nq);
2410 Array<OneD, NekDouble> coeffs1(nelmts * nm);
2411 Array<OneD, NekDouble> coeffs2(nelmts * nm);
2412
2413 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
2414
2415 Exp->GetCoords(xc, yc, zc);
2416
2417 for (int i = 0; i < nq; ++i)
2418 {
2419 phys1[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
2420 phys2[i] = cos(xc[i]) * sin(yc[i]) * cos(zc[i]);
2421 phys3[i] = cos(xc[i]) * sin(yc[i]) * sin(zc[i]);
2422 }
2423 for (int i = 1; i < nelmts; ++i)
2424 {
2425 Vmath::Vcopy(nq, phys1, 1, tmp = phys1 + i * nq, 1);
2426 Vmath::Vcopy(nq, phys2, 1, tmp = phys2 + i * nq, 1);
2427 Vmath::Vcopy(nq, phys3, 1, tmp = phys3 + i * nq, 1);
2428 }
2429
2430 // Standard routines
2431 for (int i = 0; i < nelmts; ++i)
2432 {
2433 Exp->IProductWRTDerivBase(0, phys1 + i * nq, tmp = coeffs1 + i * nm);
2434 Exp->IProductWRTDerivBase(1, phys2 + i * nq, tmp = coeffs2 + i * nm);
2435 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
2436 tmp = coeffs1 + i * nm, 1);
2437 Exp->IProductWRTDerivBase(2, phys3 + i * nq, tmp = coeffs2 + i * nm);
2438 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
2439 tmp = coeffs1 + i * nm, 1);
2440 }
2441
2443 coeffs2);
2444
2445 double epsilon = 1.0e-8;
2446 for (int i = 0; i < coeffs1.size(); ++i)
2447 {
2448 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
2449 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
2450 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
2451 }
2452}
2453
2454BOOST_AUTO_TEST_CASE(TestTetIProductWRTDerivBase_StdMat_UniformP)
2455{
2457 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
2459 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2461 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
2463 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
2464
2465 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
2466 v2.get(), v3.get()};
2467 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
2468 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
2469 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
2470
2471 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
2473 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
2474 triPointsTypeDir1);
2475 Nektar::LibUtilities::BasisType basisTypeDir1 =
2477 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
2478 triPointsKeyDir1);
2479
2480 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
2481 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
2482 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(4,
2483 triPointsTypeDir2);
2484 Nektar::LibUtilities::BasisType basisTypeDir2 =
2486 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
2487 triPointsKeyDir2);
2488
2489 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
2490 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2491 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(4,
2492 triPointsTypeDir3);
2493 Nektar::LibUtilities::BasisType basisTypeDir3 =
2495 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
2496 triPointsKeyDir3);
2497
2500 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
2501
2502 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
2503 CollExp.push_back(Exp);
2504
2506 Collections::CollectionOptimisation colOpt(dummySession, 3,
2508 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2509 Collections::Collection c(CollExp, impTypes);
2511
2512 const int nq = Exp->GetTotPoints();
2513 const int nm = Exp->GetNcoeffs();
2514 Array<OneD, NekDouble> phys1(nq);
2515 Array<OneD, NekDouble> phys2(nq);
2516 Array<OneD, NekDouble> phys3(nq);
2517 Array<OneD, NekDouble> coeffs1(nm);
2518 Array<OneD, NekDouble> coeffs2(nm);
2519
2520 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
2521
2522 Exp->GetCoords(xc, yc, zc);
2523
2524 for (int i = 0; i < nq; ++i)
2525 {
2526 phys1[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
2527 phys2[i] = cos(xc[i]) * sin(yc[i]) * cos(zc[i]);
2528 phys3[i] = cos(xc[i]) * sin(yc[i]) * sin(zc[i]);
2529 }
2530
2531 // Standard routines
2532 Exp->IProductWRTDerivBase(0, phys1, coeffs1);
2533 Exp->IProductWRTDerivBase(1, phys2, coeffs2);
2534 Vmath::Vadd(nm, coeffs1, 1, coeffs2, 1, coeffs1, 1);
2535 Exp->IProductWRTDerivBase(2, phys3, coeffs2);
2536 Vmath::Vadd(nm, coeffs1, 1, coeffs2, 1, coeffs1, 1);
2537
2539 coeffs2);
2540
2541 double epsilon = 1.0e-8;
2542 for (int i = 0; i < coeffs1.size(); ++i)
2543 {
2544 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
2545 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
2546 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
2547 }
2548}
2549
2550BOOST_AUTO_TEST_CASE(TestTetIProductWRTDerivBase_StdMat_VariableP_MultiElmt)
2551{
2553 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
2555 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2557 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
2559 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
2560
2561 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
2562 v2.get(), v3.get()};
2563 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
2564 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
2565 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
2566
2567 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
2569 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
2570 triPointsTypeDir1);
2571 Nektar::LibUtilities::BasisType basisTypeDir1 =
2573 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
2574 triPointsKeyDir1);
2575
2576 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
2577 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
2578 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(6,
2579 triPointsTypeDir2);
2580 Nektar::LibUtilities::BasisType basisTypeDir2 =
2582 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
2583 triPointsKeyDir2);
2584 // const Nektar::LibUtilities::BasisKey
2585 // basisKeyDir2(basisTypeDir2,5,triPointsKeyDir2);
2586
2587 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
2588 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2589 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(9,
2590 triPointsTypeDir3);
2591 Nektar::LibUtilities::BasisType basisTypeDir3 =
2593 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
2594 triPointsKeyDir3);
2595
2598 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
2599
2600 int nelmts = 1;
2601
2602 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
2603 for (int i = 0; i < nelmts; ++i)
2604 {
2605 CollExp.push_back(Exp);
2606 }
2607
2609 Collections::CollectionOptimisation colOpt(dummySession, 3,
2611 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2612 Collections::Collection c(CollExp, impTypes);
2614
2615 const int nq = Exp->GetTotPoints();
2616 const int nm = Exp->GetNcoeffs();
2617 Array<OneD, NekDouble> phys1(nelmts * nq), tmp;
2618 Array<OneD, NekDouble> phys2(nelmts * nq);
2619 Array<OneD, NekDouble> phys3(nelmts * nq);
2620 Array<OneD, NekDouble> coeffs1(nelmts * nm);
2621 Array<OneD, NekDouble> coeffs2(nelmts * nm);
2622
2623 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
2624
2625 Exp->GetCoords(xc, yc, zc);
2626
2627 for (int i = 0; i < nq; ++i)
2628 {
2629 phys1[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
2630 phys2[i] = cos(xc[i]) * sin(yc[i]) * cos(zc[i]);
2631 phys3[i] = cos(xc[i]) * sin(yc[i]) * sin(zc[i]);
2632 }
2633 for (int i = 1; i < nelmts; ++i)
2634 {
2635 Vmath::Vcopy(nq, phys1, 1, tmp = phys1 + i * nq, 1);
2636 Vmath::Vcopy(nq, phys2, 1, tmp = phys2 + i * nq, 1);
2637 Vmath::Vcopy(nq, phys3, 1, tmp = phys3 + i * nq, 1);
2638 }
2639
2640 // Standard routines
2641 for (int i = 0; i < nelmts; ++i)
2642 {
2643 Exp->IProductWRTDerivBase(0, phys1 + i * nq, tmp = coeffs1 + i * nm);
2644 Exp->IProductWRTDerivBase(1, phys2 + i * nq, tmp = coeffs2 + i * nm);
2645 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
2646 tmp = coeffs1 + i * nm, 1);
2647 Exp->IProductWRTDerivBase(2, phys3 + i * nq, tmp = coeffs2 + i * nm);
2648 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
2649 tmp = coeffs1 + i * nm, 1);
2650 }
2651
2653 coeffs2);
2654
2655 double epsilon = 1.0e-8;
2656 for (int i = 0; i < coeffs1.size(); ++i)
2657 {
2658 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
2659 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
2660 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
2661 }
2662}
2663
2664BOOST_AUTO_TEST_CASE(TestTetIProductWRTDerivBase_SumFac_UniformP)
2665{
2667 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
2669 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2671 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
2673 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
2674
2675 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
2676 v2.get(), v3.get()};
2677 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
2678 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
2679 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
2680
2681 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
2683 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
2684 triPointsTypeDir1);
2685 Nektar::LibUtilities::BasisType basisTypeDir1 =
2687 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
2688 triPointsKeyDir1);
2689
2690 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
2691 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
2692 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(4,
2693 triPointsTypeDir2);
2694 Nektar::LibUtilities::BasisType basisTypeDir2 =
2696 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
2697 triPointsKeyDir2);
2698
2699 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
2700 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2701 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(4,
2702 triPointsTypeDir3);
2703 Nektar::LibUtilities::BasisType basisTypeDir3 =
2705 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
2706 triPointsKeyDir3);
2707
2710 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
2711
2712 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
2713 CollExp.push_back(Exp);
2714
2716 Collections::CollectionOptimisation colOpt(dummySession, 3,
2718 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2719 Collections::Collection c(CollExp, impTypes);
2721
2722 const int nq = Exp->GetTotPoints();
2723 const int nm = Exp->GetNcoeffs();
2724 Array<OneD, NekDouble> phys1(nq);
2725 Array<OneD, NekDouble> phys2(nq);
2726 Array<OneD, NekDouble> phys3(nq);
2727 Array<OneD, NekDouble> coeffs1(nm);
2728 Array<OneD, NekDouble> coeffs2(nm);
2729
2730 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
2731
2732 Exp->GetCoords(xc, yc, zc);
2733
2734 for (int i = 0; i < nq; ++i)
2735 {
2736 phys1[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
2737 phys2[i] = cos(xc[i]) * sin(yc[i]) * cos(zc[i]);
2738 phys3[i] = cos(xc[i]) * sin(yc[i]) * sin(zc[i]);
2739 }
2740
2741 // Standard routines
2742 Exp->IProductWRTDerivBase(0, phys1, coeffs1);
2743 Exp->IProductWRTDerivBase(1, phys2, coeffs2);
2744 Vmath::Vadd(nm, coeffs1, 1, coeffs2, 1, coeffs1, 1);
2745 Exp->IProductWRTDerivBase(2, phys3, coeffs2);
2746 Vmath::Vadd(nm, coeffs1, 1, coeffs2, 1, coeffs1, 1);
2747
2749 coeffs2);
2750
2751 double epsilon = 1.0e-7;
2752 for (int i = 0; i < coeffs1.size(); ++i)
2753 {
2754 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
2755 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
2756 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
2757 }
2758}
2759
2760BOOST_AUTO_TEST_CASE(TestTetIProductWRTDerivBase_SumFac_VariableP_MultiElmt)
2761{
2763 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
2765 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2767 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
2769 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
2770
2771 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
2772 v2.get(), v3.get()};
2773 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
2774 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
2775 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
2776
2777 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
2779 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
2780 triPointsTypeDir1);
2781 Nektar::LibUtilities::BasisType basisTypeDir1 =
2783 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
2784 triPointsKeyDir1);
2785
2786 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
2787 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
2788 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(6,
2789 triPointsTypeDir2);
2790 Nektar::LibUtilities::BasisType basisTypeDir2 =
2792 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
2793 triPointsKeyDir2);
2794 // const Nektar::LibUtilities::BasisKey
2795 // basisKeyDir2(basisTypeDir2,5,triPointsKeyDir2);
2796
2797 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
2798 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2799 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(9,
2800 triPointsTypeDir3);
2801 Nektar::LibUtilities::BasisType basisTypeDir3 =
2803 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
2804 triPointsKeyDir3);
2805
2808 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
2809
2810 int nelmts = 1;
2811
2812 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
2813 for (int i = 0; i < nelmts; ++i)
2814 {
2815 CollExp.push_back(Exp);
2816 }
2817
2819 Collections::CollectionOptimisation colOpt(dummySession, 3,
2821 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2822 Collections::Collection c(CollExp, impTypes);
2824
2825 const int nq = Exp->GetTotPoints();
2826 const int nm = Exp->GetNcoeffs();
2827 Array<OneD, NekDouble> phys1(nelmts * nq), tmp;
2828 Array<OneD, NekDouble> phys2(nelmts * nq);
2829 Array<OneD, NekDouble> phys3(nelmts * nq);
2830 Array<OneD, NekDouble> coeffs1(nelmts * nm);
2831 Array<OneD, NekDouble> coeffs2(nelmts * nm);
2832
2833 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
2834
2835 Exp->GetCoords(xc, yc, zc);
2836
2837 for (int i = 0; i < nq; ++i)
2838 {
2839 phys1[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
2840 phys2[i] = cos(xc[i]) * sin(yc[i]) * cos(zc[i]);
2841 phys3[i] = cos(xc[i]) * sin(yc[i]) * sin(zc[i]);
2842 }
2843 for (int i = 1; i < nelmts; ++i)
2844 {
2845 Vmath::Vcopy(nq, phys1, 1, tmp = phys1 + i * nq, 1);
2846 Vmath::Vcopy(nq, phys2, 1, tmp = phys2 + i * nq, 1);
2847 Vmath::Vcopy(nq, phys3, 1, tmp = phys3 + i * nq, 1);
2848 }
2849
2850 // Standard routines
2851 for (int i = 0; i < nelmts; ++i)
2852 {
2853 Exp->IProductWRTDerivBase(0, phys1 + i * nq, tmp = coeffs1 + i * nm);
2854 Exp->IProductWRTDerivBase(1, phys2 + i * nq, tmp = coeffs2 + i * nm);
2855 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
2856 tmp = coeffs1 + i * nm, 1);
2857 Exp->IProductWRTDerivBase(2, phys3 + i * nq, tmp = coeffs2 + i * nm);
2858 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
2859 tmp = coeffs1 + i * nm, 1);
2860 }
2861
2863 coeffs2);
2864
2865 double epsilon = 1.0e-7;
2866 for (int i = 0; i < coeffs1.size(); ++i)
2867 {
2868 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
2869 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
2870 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
2871 }
2872}
2873
2874BOOST_AUTO_TEST_CASE(TestTetHelmholtz_IterPerExp_UniformP_ConstVarDiff)
2875{
2877 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
2879 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2881 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
2883 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
2884
2885 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
2886 v2.get(), v3.get()};
2887 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
2888 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
2889 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
2890
2891 unsigned int numQuadPoints = 5;
2892 unsigned int numModes = 4;
2893
2894 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
2896 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
2897 triPointsTypeDir1);
2898 Nektar::LibUtilities::BasisType basisTypeDir1 =
2900 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
2901 triPointsKeyDir1);
2902
2903 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
2904 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
2905 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
2906 triPointsTypeDir2);
2907 Nektar::LibUtilities::BasisType basisTypeDir2 =
2909 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
2910 triPointsKeyDir2);
2911
2912 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
2913 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2914 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
2915 triPointsTypeDir3);
2916 Nektar::LibUtilities::BasisType basisTypeDir3 =
2918 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
2919 triPointsKeyDir3);
2920
2923 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
2924
2925 int nelmts = 10;
2926
2927 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
2928 for (int i = 0; i < nelmts; ++i)
2929 {
2930 CollExp.push_back(Exp);
2931 }
2932
2934 Collections::CollectionOptimisation colOpt(dummySession, 2,
2936 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2937 Collections::Collection c(CollExp, impTypes);
2939 factors[StdRegions::eFactorLambda] = 1.5;
2940 factors[StdRegions::eFactorCoeffD00] = 1.25;
2941 factors[StdRegions::eFactorCoeffD01] = 0.25;
2942 factors[StdRegions::eFactorCoeffD11] = 1.25;
2943 factors[StdRegions::eFactorCoeffD02] = 0.25;
2944 factors[StdRegions::eFactorCoeffD12] = 0.25;
2945 factors[StdRegions::eFactorCoeffD22] = 1.25;
2946
2948
2949 const int nm = Exp->GetNcoeffs();
2950 Array<OneD, NekDouble> coeffsIn(nelmts * nm);
2951 Array<OneD, NekDouble> coeffsRef(nelmts * nm);
2952 Array<OneD, NekDouble> coeffs(nelmts * nm), tmp;
2953
2954 for (int i = 0; i < coeffsIn.size(); ++i)
2955 {
2956 coeffsIn[i] = i + 1.0;
2957 }
2958
2959 StdRegions::StdMatrixKey mkey(StdRegions::eHelmholtz, Exp->DetShapeType(),
2960 *Exp, factors);
2961
2962 for (int i = 0; i < nelmts; ++i)
2963 {
2964 // Standard routines
2965 Exp->GeneralMatrixOp(coeffsIn + i * nm, tmp = coeffsRef + i * nm, mkey);
2966 }
2967
2968 c.ApplyOperator(Collections::eHelmholtz, coeffsIn, coeffs);
2969
2970 double epsilon = 1.0e-8;
2971 for (int i = 0; i < coeffsRef.size(); ++i)
2972 {
2973 coeffsRef[i] = (std::abs(coeffsRef[i]) < 1e-14) ? 0.0 : coeffsRef[i];
2974 coeffs[i] = (std::abs(coeffs[i]) < 1e-14) ? 0.0 : coeffs[i];
2975 BOOST_CHECK_CLOSE(coeffsRef[i], coeffs[i], epsilon);
2976 }
2977}
2978
2979BOOST_AUTO_TEST_CASE(TestTetHelmholtz_MatrixFree_UniformP)
2980{
2982 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
2984 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2986 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
2988 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
2989
2990 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
2991 v2.get(), v3.get()};
2992 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
2993 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
2994 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
2995
2996 unsigned int numQuadPoints = 5;
2997 unsigned int numModes = 4;
2998
2999 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
3001 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
3002 triPointsTypeDir1);
3003 Nektar::LibUtilities::BasisType basisTypeDir1 =
3005 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
3006 triPointsKeyDir1);
3007
3008 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
3009 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
3010 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
3011 triPointsTypeDir2);
3012 Nektar::LibUtilities::BasisType basisTypeDir2 =
3014 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
3015 triPointsKeyDir2);
3016
3017 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
3018 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
3019 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
3020 triPointsTypeDir3);
3021 Nektar::LibUtilities::BasisType basisTypeDir3 =
3023 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
3024 triPointsKeyDir3);
3025
3028 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
3029
3030 int nelmts = 10;
3031
3032 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
3033 for (int i = 0; i < nelmts; ++i)
3034 {
3035 CollExp.push_back(Exp);
3036 }
3037
3039 Collections::CollectionOptimisation colOpt(dummySession, 2,
3041 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
3042 Collections::Collection c(CollExp, impTypes);
3044 factors[StdRegions::eFactorLambda] = 1.5;
3045
3047
3048 const int nm = Exp->GetNcoeffs();
3049 Array<OneD, NekDouble> coeffsIn(nelmts * nm);
3050 Array<OneD, NekDouble> coeffsRef(nelmts * nm);
3051 Array<OneD, NekDouble> coeffs(nelmts * nm), tmp;
3052
3053 for (int i = 0; i < coeffsIn.size(); ++i)
3054 {
3055 coeffsIn[i] = i + 1.0;
3056 }
3057
3058 StdRegions::StdMatrixKey mkey(StdRegions::eHelmholtz, Exp->DetShapeType(),
3059 *Exp, factors);
3060
3061 for (int i = 0; i < nelmts; ++i)
3062 {
3063 // Standard routines
3064 Exp->GeneralMatrixOp(coeffsIn + i * nm, tmp = coeffsRef + i * nm, mkey);
3065 }
3066
3067 c.ApplyOperator(Collections::eHelmholtz, coeffsIn, coeffs);
3068
3069 double epsilon = 1.0e-8;
3070 for (int i = 0; i < coeffsRef.size(); ++i)
3071 {
3072 coeffsRef[i] = (std::abs(coeffsRef[i]) < 1e-14) ? 0.0 : coeffsRef[i];
3073 coeffs[i] = (std::abs(coeffs[i]) < 1e-14) ? 0.0 : coeffs[i];
3074 BOOST_CHECK_CLOSE(coeffsRef[i], coeffs[i], epsilon);
3075 }
3076}
3077
3078BOOST_AUTO_TEST_CASE(TestTetHelmholtz_MatrixFree_Deformed_OverInt)
3079{
3081 new SpatialDomains::PointGeom(3u, 0u, -2.0, -3.0, -4.0));
3083 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
3085 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
3087 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
3088
3089 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
3090 v2.get(), v3.get()};
3091 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
3092 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
3093 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
3094
3095 unsigned int numQuadPoints = 8;
3096 unsigned int numModes = 4;
3097
3098 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
3100 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
3101 triPointsTypeDir1);
3102 Nektar::LibUtilities::BasisType basisTypeDir1 =
3104 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
3105 triPointsKeyDir1);
3106
3107 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
3108 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
3109 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
3110 triPointsTypeDir2);
3111 Nektar::LibUtilities::BasisType basisTypeDir2 =
3113 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
3114 triPointsKeyDir2);
3115
3116 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
3117 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
3118 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
3119 triPointsTypeDir3);
3120 Nektar::LibUtilities::BasisType basisTypeDir3 =
3122 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
3123 triPointsKeyDir3);
3124
3127 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
3128
3129 int nelmts = 10;
3130
3131 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
3132 for (int i = 0; i < nelmts; ++i)
3133 {
3134 CollExp.push_back(Exp);
3135 }
3136
3138 Collections::CollectionOptimisation colOpt(dummySession, 2,
3140 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
3141 Collections::Collection c(CollExp, impTypes);
3143 factors[StdRegions::eFactorLambda] = 1.5;
3144
3146
3147 const int nm = Exp->GetNcoeffs();
3148 Array<OneD, NekDouble> coeffsIn(nelmts * nm);
3149 Array<OneD, NekDouble> coeffsRef(nelmts * nm);
3150 Array<OneD, NekDouble> coeffs(nelmts * nm), tmp;
3151
3152 for (int i = 0; i < coeffsIn.size(); ++i)
3153 {
3154 coeffsIn[i] = i + 1.0;
3155 }
3156
3157 StdRegions::StdMatrixKey mkey(StdRegions::eHelmholtz, Exp->DetShapeType(),
3158 *Exp, factors);
3159
3160 for (int i = 0; i < nelmts; ++i)
3161 {
3162 // Standard routines
3163 Exp->GeneralMatrixOp(coeffsIn + i * nm, tmp = coeffsRef + i * nm, mkey);
3164 }
3165
3166 c.ApplyOperator(Collections::eHelmholtz, coeffsIn, coeffs);
3167
3168 double epsilon = 1.0e-8;
3169 for (int i = 0; i < coeffsRef.size(); ++i)
3170 {
3171 coeffsRef[i] = (std::abs(coeffsRef[i]) < 1e-14) ? 0.0 : coeffsRef[i];
3172 coeffs[i] = (std::abs(coeffs[i]) < 1e-14) ? 0.0 : coeffs[i];
3173 BOOST_CHECK_CLOSE(coeffsRef[i], coeffs[i], epsilon);
3174 }
3175}
3176
3177BOOST_AUTO_TEST_CASE(TestTetIProductWRTDerivBase_MatrixFree_UniformP_Undeformed)
3178{
3180 new SpatialDomains::PointGeom(3u, 0u, -2.0, -3.0, -4.0));
3182 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
3184 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
3186 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
3187
3188 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
3189 v2.get(), v3.get()};
3190 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
3191 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
3192 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
3193
3194 unsigned int numQuadPoints = 5;
3195 unsigned int numModes = 4;
3196
3197 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
3199 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
3200 triPointsTypeDir1);
3201 Nektar::LibUtilities::BasisType basisTypeDir1 =
3203 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
3204 triPointsKeyDir1);
3205
3206 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
3207 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
3208 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
3209 triPointsTypeDir2);
3210 Nektar::LibUtilities::BasisType basisTypeDir2 =
3212 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
3213 triPointsKeyDir2);
3214
3215 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
3216 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
3217 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
3218 triPointsTypeDir3);
3219 Nektar::LibUtilities::BasisType basisTypeDir3 =
3221 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
3222 triPointsKeyDir3);
3223
3226 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
3227
3228 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
3229 CollExp.push_back(Exp);
3230
3232 Collections::CollectionOptimisation colOpt(dummySession, 2,
3234 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
3235 // ... only one op at the time ...
3237 Collections::Collection c(CollExp, impTypes);
3239
3240 const int nq = Exp->GetTotPoints();
3241 const int nm = Exp->GetNcoeffs();
3242 Array<OneD, NekDouble> phys1(nq);
3243 Array<OneD, NekDouble> phys2(nq);
3244 Array<OneD, NekDouble> phys3(nq);
3245 Array<OneD, NekDouble> coeffsRef(nm);
3246 Array<OneD, NekDouble> coeffs(nm);
3247
3248 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
3249
3250 Exp->GetCoords(xc, yc, zc);
3251
3252 for (int i = 0; i < nq; ++i)
3253 {
3254 phys1[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
3255 phys2[i] = cos(xc[i]) * sin(yc[i]) * cos(zc[i]);
3256 phys3[i] = cos(xc[i]) * sin(yc[i]) * sin(zc[i]);
3257 }
3258
3259 // Standard routines
3260 Exp->IProductWRTDerivBase(0, phys1, coeffsRef);
3261 Exp->IProductWRTDerivBase(1, phys2, coeffs);
3262 Vmath::Vadd(nm, coeffsRef, 1, coeffs, 1, coeffsRef, 1);
3263 Exp->IProductWRTDerivBase(2, phys3, coeffs);
3264 Vmath::Vadd(nm, coeffsRef, 1, coeffs, 1, coeffsRef, 1);
3265
3267 coeffs);
3268
3269 double epsilon = 1.0e-7;
3270 for (int i = 0; i < coeffsRef.size(); ++i)
3271 {
3272 coeffsRef[i] = (std::abs(coeffsRef[i]) < 1e-14) ? 0.0 : coeffsRef[i];
3273 coeffs[i] = (std::abs(coeffs[i]) < 1e-14) ? 0.0 : coeffs[i];
3274 BOOST_CHECK_CLOSE(coeffsRef[i], coeffs[i], epsilon);
3275 }
3276}
3277
3278BOOST_AUTO_TEST_CASE(TestTetHelmholtz_MatrixFree_UniformP_ConstVarDiff)
3279{
3281 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
3283 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
3285 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
3287 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
3288
3289 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
3290 v2.get(), v3.get()};
3291 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
3292 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
3293 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
3294
3295 unsigned int numQuadPoints = 5;
3296 unsigned int numModes = 4;
3297
3298 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
3300 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
3301 triPointsTypeDir1);
3302 Nektar::LibUtilities::BasisType basisTypeDir1 =
3304 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
3305 triPointsKeyDir1);
3306
3307 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
3308 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
3309 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
3310 triPointsTypeDir2);
3311 Nektar::LibUtilities::BasisType basisTypeDir2 =
3313 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
3314 triPointsKeyDir2);
3315
3316 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
3317 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
3318 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
3319 triPointsTypeDir3);
3320 Nektar::LibUtilities::BasisType basisTypeDir3 =
3322 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
3323 triPointsKeyDir3);
3324
3327 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
3328
3329 int nelmts = 10;
3330
3331 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
3332 for (int i = 0; i < nelmts; ++i)
3333 {
3334 CollExp.push_back(Exp);
3335 }
3336
3338 Collections::CollectionOptimisation colOpt(dummySession, 2,
3340 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
3341 Collections::Collection c(CollExp, impTypes);
3343 factors[StdRegions::eFactorLambda] = 1.5;
3344 factors[StdRegions::eFactorCoeffD00] = 1.25;
3345 factors[StdRegions::eFactorCoeffD01] = 0.25;
3346 factors[StdRegions::eFactorCoeffD11] = 1.25;
3347 factors[StdRegions::eFactorCoeffD02] = 0.25;
3348 factors[StdRegions::eFactorCoeffD12] = 0.25;
3349 factors[StdRegions::eFactorCoeffD22] = 1.25;
3350
3352
3353 const int nm = Exp->GetNcoeffs();
3354 Array<OneD, NekDouble> coeffsIn(nelmts * nm);
3355 Array<OneD, NekDouble> coeffsRef(nelmts * nm);
3356 Array<OneD, NekDouble> coeffs(nelmts * nm), tmp;
3357
3358 for (int i = 0; i < coeffsIn.size(); ++i)
3359 {
3360 coeffsIn[i] = i + 1.0;
3361 }
3362
3363 StdRegions::StdMatrixKey mkey(StdRegions::eHelmholtz, Exp->DetShapeType(),
3364 *Exp, factors);
3365
3366 for (int i = 0; i < nelmts; ++i)
3367 {
3368 // Standard routines
3369 Exp->GeneralMatrixOp(coeffsIn + i * nm, tmp = coeffsRef + i * nm, mkey);
3370 }
3371
3372 c.ApplyOperator(Collections::eHelmholtz, coeffsIn, coeffs);
3373
3374 double epsilon = 1.0e-8;
3375 for (int i = 0; i < coeffsRef.size(); ++i)
3376 {
3377 coeffsRef[i] = (std::abs(coeffsRef[i]) < 1e-14) ? 0.0 : coeffsRef[i];
3378 coeffs[i] = (std::abs(coeffs[i]) < 1e-14) ? 0.0 : coeffs[i];
3379 BOOST_CHECK_CLOSE(coeffsRef[i], coeffs[i], epsilon);
3380 }
3381}
3382
3383BOOST_AUTO_TEST_CASE(TestTetPhysInterp1D_NoCollections_UniformP)
3384{
3385
3387 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
3389 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
3391 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
3393 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
3394
3395 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
3396 v2.get(), v3.get()};
3397 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
3398 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
3399 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
3400
3401 unsigned int numQuadPoints = 5;
3402 unsigned int numModes = 4;
3403
3404 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
3406 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
3407 triPointsTypeDir1);
3408 Nektar::LibUtilities::BasisType basisTypeDir1 =
3410 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
3411 triPointsKeyDir1);
3412
3413 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
3414 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
3415 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
3416 triPointsTypeDir2);
3417 Nektar::LibUtilities::BasisType basisTypeDir2 =
3419 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
3420 triPointsKeyDir2);
3421
3422 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
3423 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
3424 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
3425 triPointsTypeDir3);
3426 Nektar::LibUtilities::BasisType basisTypeDir3 =
3428 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
3429 triPointsKeyDir3);
3430
3433 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
3434
3435 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
3436 CollExp.push_back(Exp);
3437
3439 Collections::CollectionOptimisation colOpt(dummySession, 3,
3441 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
3442 Collections::Collection c(CollExp, impTypes);
3443
3445 factors[StdRegions::eFactorConst] = 1.5;
3447
3448 const int nq = Exp->GetTotPoints();
3449
3450 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
3451 Array<OneD, NekDouble> phys(nq);
3452
3453 Exp->GetCoords(xc, yc, zc);
3454
3455 for (int i = 0; i < nq; ++i)
3456 {
3457 phys[i] = pow(xc[i], 3) + pow(yc[i], 3) + pow(zc[i], 3);
3458 }
3459
3461 Array<OneD, NekDouble> xc1(nq1);
3462 Array<OneD, NekDouble> yc1(nq1);
3463 Array<OneD, NekDouble> zc1(nq1);
3464 Array<OneD, NekDouble> phys1(nq1);
3465
3470
3471 double epsilon = 1.0e-8;
3472 // since solution is a polynomial should be able to compare soln directly
3473 for (int i = 0; i < nq1; ++i)
3474 {
3475 NekDouble exact = pow(xc1[i], 3) + pow(yc1[i], 3) + pow(zc1[i], 3);
3476 phys1[i] = (fabs(phys1[i]) < 1e-14) ? 0.0 : phys1[i];
3477 exact = (fabs(exact) < 1e-14) ? 0.0 : exact;
3478 BOOST_CHECK_CLOSE(phys1[i], exact, epsilon);
3479 }
3480}
3481
3482BOOST_AUTO_TEST_CASE(TestTetPhysInterp1D_MatrixFree_UniformP)
3483{
3484
3486 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
3488 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
3490 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
3492 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
3493
3494 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
3495 v2.get(), v3.get()};
3496 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
3497 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
3498 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
3499
3500 unsigned int numQuadPoints = 5;
3501 unsigned int numModes = 4;
3502
3503 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
3505 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
3506 triPointsTypeDir1);
3507 Nektar::LibUtilities::BasisType basisTypeDir1 =
3509 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
3510 triPointsKeyDir1);
3511
3512 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
3513 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
3514 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
3515 triPointsTypeDir2);
3516 Nektar::LibUtilities::BasisType basisTypeDir2 =
3518 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
3519 triPointsKeyDir2);
3520
3521 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
3522 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
3523 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
3524 triPointsTypeDir3);
3525 Nektar::LibUtilities::BasisType basisTypeDir3 =
3527 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
3528 triPointsKeyDir3);
3529
3532 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
3533
3534 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
3535 CollExp.push_back(Exp);
3536
3538 Collections::CollectionOptimisation colOpt(dummySession, 3,
3540 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
3541 Collections::Collection c(CollExp, impTypes);
3542
3544 factors[StdRegions::eFactorConst] = 1.5;
3546
3547 const int nq = Exp->GetTotPoints();
3548
3549 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
3550 Array<OneD, NekDouble> phys(nq);
3551
3552 Exp->GetCoords(xc, yc, zc);
3553
3554 for (int i = 0; i < nq; ++i)
3555 {
3556 phys[i] = pow(xc[i], 3) + pow(yc[i], 3) + pow(zc[i], 3);
3557 }
3558
3560 Array<OneD, NekDouble> xc1(nq1);
3561 Array<OneD, NekDouble> yc1(nq1);
3562 Array<OneD, NekDouble> zc1(nq1);
3563 Array<OneD, NekDouble> phys1(nq1);
3564
3569
3570 double epsilon = 1.0e-8;
3571 // since solution is a polynomial should be able to compare soln directly
3572 for (int i = 0; i < nq1; ++i)
3573 {
3574 NekDouble exact = pow(xc1[i], 3) + pow(yc1[i], 3) + pow(zc1[i], 3);
3575 phys1[i] = (fabs(phys1[i]) < 1e-14) ? 0.0 : phys1[i];
3576 exact = (fabs(exact) < 1e-14) ? 0.0 : exact;
3577 BOOST_CHECK_CLOSE(phys1[i], exact, epsilon);
3578 }
3579}
3580
3582 TestTetLinearAdvectionDiffusionReaction_IterPerExp_UniformP)
3583{
3585 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
3587 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
3589 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
3591 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
3592
3593 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
3594 v2.get(), v3.get()};
3595 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
3596 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
3597 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
3598
3599 unsigned int numQuadPoints = 5;
3600 unsigned int numModes = 4;
3601
3602 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
3604 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
3605 triPointsTypeDir1);
3606 Nektar::LibUtilities::BasisType basisTypeDir1 =
3608 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
3609 triPointsKeyDir1);
3610
3611 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
3612 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
3613 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
3614 triPointsTypeDir2);
3615 Nektar::LibUtilities::BasisType basisTypeDir2 =
3617 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
3618 triPointsKeyDir2);
3619
3620 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
3621 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
3622 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
3623 triPointsTypeDir3);
3624 Nektar::LibUtilities::BasisType basisTypeDir3 =
3626 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
3627 triPointsKeyDir3);
3628
3631 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
3632
3633 int nelmts = 10;
3634
3635 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
3636 for (int i = 0; i < nelmts; ++i)
3637 {
3638 CollExp.push_back(Exp);
3639 }
3640
3642 Collections::CollectionOptimisation colOpt(dummySession, 2,
3644 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
3645 Collections::Collection c(CollExp, impTypes);
3647 factors[StdRegions::eFactorLambda] = 1.5;
3648
3650
3651 // Add advection velocities via varcoeffs
3652 int npoints = Exp->GetTotPoints() * nelmts;
3653 StdRegions::VarCoeffMap varcoeffs;
3657 for (int i = 0; i < Exp->GetShapeDimension(); i++)
3658 {
3659 varcoeffs[varcoefftypes[i]] = Array<OneD, NekDouble>(npoints, 1.0);
3660 }
3662 varcoeffs);
3663
3664 const int nm = Exp->GetNcoeffs();
3665 Array<OneD, NekDouble> coeffsIn(nelmts * nm);
3666 Array<OneD, NekDouble> coeffsRef(nelmts * nm);
3667 Array<OneD, NekDouble> coeffs(nelmts * nm), tmp;
3668
3669 for (int i = 0; i < coeffsIn.size(); ++i)
3670 {
3671 coeffsIn[i] = i + 1.0;
3672 }
3673
3675 Exp->DetShapeType(), *Exp, factors,
3676 varcoeffs);
3677
3678 for (int i = 0; i < nelmts; ++i)
3679 {
3680 // Standard routines
3681 Exp->GeneralMatrixOp(coeffsIn + i * nm, tmp = coeffsRef + i * nm, mkey);
3682 }
3683
3685 coeffs);
3686
3687 double epsilon = 1.0e-8;
3688 for (int i = 0; i < coeffsRef.size(); ++i)
3689 {
3690 coeffsRef[i] = (std::abs(coeffsRef[i]) < 1e-14) ? 0.0 : coeffsRef[i];
3691 coeffs[i] = (std::abs(coeffs[i]) < 1e-14) ? 0.0 : coeffs[i];
3692 BOOST_CHECK_CLOSE(coeffsRef[i], coeffs[i], epsilon);
3693 }
3694}
3695
3697 TestTetLinearAdvectionDiffusionReaction_MatrixFree_UniformP)
3698{
3700 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
3702 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
3704 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
3706 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
3707
3708 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
3709 v2.get(), v3.get()};
3710 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
3711 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
3712 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
3713
3714 unsigned int numQuadPoints = 5;
3715 unsigned int numModes = 4;
3716
3717 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
3719 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
3720 triPointsTypeDir1);
3721 Nektar::LibUtilities::BasisType basisTypeDir1 =
3723 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
3724 triPointsKeyDir1);
3725
3726 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
3727 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
3728 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
3729 triPointsTypeDir2);
3730 Nektar::LibUtilities::BasisType basisTypeDir2 =
3732 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
3733 triPointsKeyDir2);
3734
3735 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
3736 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
3737 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
3738 triPointsTypeDir3);
3739 Nektar::LibUtilities::BasisType basisTypeDir3 =
3741 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
3742 triPointsKeyDir3);
3743
3746 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
3747
3748 int nelmts = 10;
3749
3750 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
3751 for (int i = 0; i < nelmts; ++i)
3752 {
3753 CollExp.push_back(Exp);
3754 }
3755
3757 Collections::CollectionOptimisation colOpt(dummySession, 2,
3759 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
3760 Collections::Collection c(CollExp, impTypes);
3762 factors[StdRegions::eFactorLambda] = 1.5;
3763
3765
3766 // Add advection velocities via varcoeffs
3767 int npoints = Exp->GetTotPoints() * nelmts;
3768 StdRegions::VarCoeffMap varcoeffs;
3772 for (int i = 0; i < Exp->GetShapeDimension(); i++)
3773 {
3774 varcoeffs[varcoefftypes[i]] = Array<OneD, NekDouble>(npoints, 1.0);
3775 }
3777 varcoeffs);
3778
3779 const int nm = Exp->GetNcoeffs();
3780 Array<OneD, NekDouble> coeffsIn(nelmts * nm);
3781 Array<OneD, NekDouble> coeffsRef(nelmts * nm);
3782 Array<OneD, NekDouble> coeffs(nelmts * nm), tmp;
3783
3784 for (int i = 0; i < coeffsIn.size(); ++i)
3785 {
3786 coeffsIn[i] = i + 1.0;
3787 }
3788
3790 Exp->DetShapeType(), *Exp, factors,
3791 varcoeffs);
3792
3793 for (int i = 0; i < nelmts; ++i)
3794 {
3795 // Standard routines
3796 Exp->GeneralMatrixOp(coeffsIn + i * nm, tmp = coeffsRef + i * nm, mkey);
3797 }
3798
3800 coeffs);
3801
3802 double epsilon = 1.0e-8;
3803 for (int i = 0; i < coeffsRef.size(); ++i)
3804 {
3805 coeffsRef[i] = (std::abs(coeffsRef[i]) < 1e-14) ? 0.0 : coeffsRef[i];
3806 coeffs[i] = (std::abs(coeffs[i]) < 1e-14) ? 0.0 : coeffs[i];
3807 BOOST_CHECK_CLOSE(coeffsRef[i], coeffs[i], epsilon);
3808 }
3809}
3810
3812 TestTetLinearAdvectionDiffusionReaction_MatrixFree_Deformed_OverInt)
3813{
3815 new SpatialDomains::PointGeom(3u, 0u, -2.0, -3.0, -4.0));
3817 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
3819 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
3821 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
3822
3823 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
3824 v2.get(), v3.get()};
3825 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
3826 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
3827 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
3828
3829 unsigned int numQuadPoints = 8;
3830 unsigned int numModes = 4;
3831
3832 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
3834 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
3835 triPointsTypeDir1);
3836 Nektar::LibUtilities::BasisType basisTypeDir1 =
3838 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
3839 triPointsKeyDir1);
3840
3841 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
3842 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
3843 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
3844 triPointsTypeDir2);
3845 Nektar::LibUtilities::BasisType basisTypeDir2 =
3847 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
3848 triPointsKeyDir2);
3849
3850 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
3851 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
3852 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
3853 triPointsTypeDir3);
3854 Nektar::LibUtilities::BasisType basisTypeDir3 =
3856 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
3857 triPointsKeyDir3);
3858
3861 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
3862
3863 int nelmts = 10;
3864
3865 std::vector<LocalRegions::ExpansionSharedPtr> CollExp;
3866 for (int i = 0; i < nelmts; ++i)
3867 {
3868 CollExp.push_back(Exp);
3869 }
3870
3872 Collections::CollectionOptimisation colOpt(dummySession, 2,
3874 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
3875 Collections::Collection c(CollExp, impTypes);
3877 factors[StdRegions::eFactorLambda] = 1.5;
3878
3880
3881 // Add advection velocities via varcoeffs
3882 int npoints = Exp->GetTotPoints() * nelmts;
3883 StdRegions::VarCoeffMap varcoeffs;
3887 for (int i = 0; i < Exp->GetShapeDimension(); i++)
3888 {
3889 varcoeffs[varcoefftypes[i]] = Array<OneD, NekDouble>(npoints, 1.0);
3890 }
3892 varcoeffs);
3893
3894 const int nm = Exp->GetNcoeffs();
3895 Array<OneD, NekDouble> coeffsIn(nelmts * nm);
3896 Array<OneD, NekDouble> coeffsRef(nelmts * nm);
3897 Array<OneD, NekDouble> coeffs(nelmts * nm), tmp;
3898
3899 for (int i = 0; i < coeffsIn.size(); ++i)
3900 {
3901 coeffsIn[i] = i + 1.0;
3902 }
3903
3905 Exp->DetShapeType(), *Exp, factors,
3906 varcoeffs);
3907
3908 for (int i = 0; i < nelmts; ++i)
3909 {
3910 // Standard routines
3911 Exp->GeneralMatrixOp(coeffsIn + i * nm, tmp = coeffsRef + i * nm, mkey);
3912 }
3913
3915 coeffs);
3916
3917 double epsilon = 1.0e-8;
3918 for (int i = 0; i < coeffsRef.size(); ++i)
3919 {
3920 coeffsRef[i] = (std::abs(coeffsRef[i]) < 1e-14) ? 0.0 : coeffsRef[i];
3921 coeffs[i] = (std::abs(coeffs[i]) < 1e-14) ? 0.0 : coeffs[i];
3922 BOOST_CHECK_CLOSE(coeffsRef[i], coeffs[i], epsilon);
3923 std::cout << "i = " << i << "\tdiff = " << coeffsRef[i] - coeffs[i]
3924 << std::endl;
3925 }
3926}
3927
3928} // namespace Nektar::TetCollectionTests
COLLECTIONS_EXPORT void UpdateVarcoeffs(const OperatorType opType, StdRegions::VarCoeffMap &varcoeffs=StdRegions::NullVarCoeffMap)
int GetOutputSize(const OperatorType &op)
Definition Collection.h:112
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:148
COLLECTIONS_EXPORT OperatorImpMap GetOperatorImpMap(LocalRegions::ExpansionSharedPtr 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
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
@ eLinearAdvectionDiffusionReaction
Definition Operator.h:66
std::shared_ptr< SessionReader > SessionReaderSharedPtr
@ eGaussLobattoLegendre
1D Gauss-Lobatto-Legendre quadrature points
Definition PointsType.h:51
@ eModified_B
Principle Modified Functions .
Definition BasisType.h:49
@ eModified_C
Principle Modified Functions .
Definition BasisType.h:50
@ eModified_A
Principle Modified Functions .
Definition BasisType.h:48
std::shared_ptr< TetExp > TetExpSharedPtr
Definition TetExp.h:165
unique_ptr_objpool< SegGeom > SegGeomUniquePtr
Definition MeshGraph.h:102
unique_ptr_objpool< PointGeom > PointGeomUniquePtr
Definition MeshGraph.h:99
unique_ptr_objpool< TriGeom > TriGeomUniquePtr
Definition MeshGraph.h:103
unique_ptr_objpool< TetGeom > TetGeomUniquePtr
Definition MeshGraph.h:105
std::map< ConstFactorType, NekDouble > ConstFactorMap
std::map< StdRegions::VarCoeffType, VarCoeffEntry > VarCoeffMap
The above copyright notice and this permission notice shall be included.
SpatialDomains::SegGeomUniquePtr CreateSegGeom(unsigned int id, SpatialDomains::PointGeom *v0, SpatialDomains::PointGeom *v1)
BOOST_AUTO_TEST_CASE(TestTetBwdTrans_IterPerExp_UniformP)
SpatialDomains::TetGeomUniquePtr CreateTet(std::array< SpatialDomains::PointGeom *, 4 > v, std::array< SpatialDomains::SegGeomUniquePtr, 6 > &segVec, std::array< SpatialDomains::TriGeomUniquePtr, 4 > &faceVec)
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