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{
44
48{
49 std::array<SpatialDomains::PointGeom *, 2> vertices = {v0, v1};
51 new SpatialDomains::SegGeom(id, 3, vertices));
52 return result;
53}
54
56 std::array<SpatialDomains::PointGeom *, 4> v,
57 std::array<SpatialDomains::SegGeomUniquePtr, 6> &segVec,
58 std::array<SpatialDomains::TriGeomUniquePtr, 4> &faceVec)
59{
60 std::array<std::array<int, 2>, 6> edgeVerts = {
61 {{{0, 1}}, {{1, 2}}, {{0, 2}}, {{0, 3}}, {{1, 3}}, {{2, 3}}}};
62 std::array<std::array<int, 3>, 4> faceEdges = {
63 {{{0, 1, 2}}, {{0, 4, 3}}, {{1, 5, 4}}, {{2, 5, 3}}}};
64
65 // Create segments from vertices
66 for (int i = 0; i < 6; ++i)
67 {
68 segVec[i] = CreateSegGeom(i, v[edgeVerts[i][0]], v[edgeVerts[i][1]]);
69 }
70
71 // Create faces from edges
72 std::array<SpatialDomains::TriGeom *, 4> faces;
73 for (int i = 0; i < 4; ++i)
74 {
75 std::array<SpatialDomains::SegGeom *, 3> face;
76 for (int j = 0; j < 3; ++j)
77 {
78 face[j] = segVec[faceEdges[i][j]].get();
79 }
81 new SpatialDomains::TriGeom(i, face));
82 faces[i] = faceVec[i].get();
83 }
84
86 new SpatialDomains::TetGeom(0, faces));
87 return tetGeom;
88}
89
90BOOST_AUTO_TEST_CASE(TestTetBwdTrans_IterPerExp_UniformP)
91{
93 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
95 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
97 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
99 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
100
101 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
102 v2.get(), v3.get()};
103 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
104 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
105 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
106
107 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
109 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
110 triPointsTypeDir1);
111 Nektar::LibUtilities::BasisType basisTypeDir1 =
113 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
114 triPointsKeyDir1);
115
116 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
117 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
118 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(4,
119 triPointsTypeDir2);
120 Nektar::LibUtilities::BasisType basisTypeDir2 =
122 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
123 triPointsKeyDir2);
124
125 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
126 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
127 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(4,
128 triPointsTypeDir3);
129 Nektar::LibUtilities::BasisType basisTypeDir3 =
131 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
132 triPointsKeyDir3);
133
136 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
137
138 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
139 CollExp.push_back(Exp);
140
142 Collections::CollectionOptimisation colOpt(dummySession, 3,
144 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
145 Collections::Collection c(CollExp, impTypes);
147
148 Array<OneD, NekDouble> coeffs(Exp->GetNcoeffs(), 1.0), tmp;
149 for (int i = 0; i < coeffs.size(); ++i)
150 {
151 coeffs[i] = i + 1; // make values distinct
152 }
153 Array<OneD, NekDouble> phys1(Exp->GetTotPoints());
154 Array<OneD, NekDouble> phys2(Exp->GetTotPoints());
155
156 Exp->BwdTrans(coeffs, phys1);
157 c.ApplyOperator(Collections::eBwdTrans, coeffs, phys2);
158
159 double epsilon = 1.0e-8;
160 for (int i = 0; i < phys1.size(); ++i)
161 {
162 BOOST_CHECK_CLOSE(phys1[i], phys2[i], epsilon);
163 }
164}
165
166BOOST_AUTO_TEST_CASE(TestTetBwdTrans_IterPerExp_VariableP_MultiElmt)
167{
169 new SpatialDomains::PointGeom(3u, 0u, -1.5, -1.5, -1.5));
171 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
173 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
175 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
176
177 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
178 v2.get(), v3.get()};
179 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
180 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
181 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
182
183 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
185 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
186 triPointsTypeDir1);
187 Nektar::LibUtilities::BasisType basisTypeDir1 =
189 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
190 triPointsKeyDir1);
191
192 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
193 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
194 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(7,
195 triPointsTypeDir2);
196 Nektar::LibUtilities::BasisType basisTypeDir2 =
198 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 6,
199 triPointsKeyDir2);
200
201 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
202 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
203 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(9,
204 triPointsTypeDir3);
205 Nektar::LibUtilities::BasisType basisTypeDir3 =
207 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
208 triPointsKeyDir3);
209
212 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
213
214 int nelmts = 10;
215
216 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
217 for (int i = 0; i < nelmts; ++i)
218 {
219 CollExp.push_back(Exp);
220 }
221
223 Collections::CollectionOptimisation colOpt(dummySession, 3,
225 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
226 Collections::Collection c(CollExp, impTypes);
228
229 Array<OneD, NekDouble> coeffs(nelmts * Exp->GetNcoeffs(), 1.0), tmp;
230 for (int i = 0; i < coeffs.size(); ++i)
231 {
232 coeffs[i] = i + 1;
233 }
234 Array<OneD, NekDouble> phys1(nelmts * Exp->GetTotPoints());
235 Array<OneD, NekDouble> phys2(nelmts * Exp->GetTotPoints());
236
237 for (int i = 0; i < nelmts; ++i)
238 {
239 Exp->BwdTrans(coeffs + i * Exp->GetNcoeffs(),
240 tmp = phys1 + i * Exp->GetTotPoints());
241 }
242
243 c.ApplyOperator(Collections::eBwdTrans, coeffs, phys2);
244
245 double epsilon = 1.0e-8;
246 for (int i = 0; i < phys1.size(); ++i)
247 {
248 BOOST_CHECK_CLOSE(phys1[i], phys2[i], epsilon);
249 }
250}
251
252BOOST_AUTO_TEST_CASE(TestTetIProductWRTBase_IterPerExp_UniformP)
253{
255 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
257 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
259 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
261 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
262
263 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
264 v2.get(), v3.get()};
265 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
266 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
267 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
268
269 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
271 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
272 triPointsTypeDir1);
273 Nektar::LibUtilities::BasisType basisTypeDir1 =
275 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
276 triPointsKeyDir1);
277
278 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
279 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
280 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(4,
281 triPointsTypeDir2);
282 Nektar::LibUtilities::BasisType basisTypeDir2 =
284 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
285 triPointsKeyDir2);
286
287 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
288 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
289 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(4,
290 triPointsTypeDir3);
291 Nektar::LibUtilities::BasisType basisTypeDir3 =
293 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
294 triPointsKeyDir3);
295
298 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
299
300 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
301 CollExp.push_back(Exp);
302
304 Collections::CollectionOptimisation colOpt(dummySession, 3,
306 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
307 Collections::Collection c(CollExp, impTypes);
309
310 const int nq = Exp->GetTotPoints();
311 Array<OneD, NekDouble> phys(nq);
312 Array<OneD, NekDouble> coeffs1(Exp->GetNcoeffs());
313 Array<OneD, NekDouble> coeffs2(Exp->GetNcoeffs());
314
315 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
316
317 Exp->GetCoords(xc, yc, zc);
318
319 for (int i = 0; i < nq; ++i)
320 {
321 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
322 }
323
324 Exp->IProductWRTBase(phys, coeffs1);
326
327 double epsilon = 1.0e-8;
328 for (int i = 0; i < coeffs1.size(); ++i)
329 {
330 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
331 }
332}
333
334BOOST_AUTO_TEST_CASE(TestTetIProductWRTBase_IterPerExp_VariableP_MultiElmt)
335{
337 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
339 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
341 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
343 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
344
345 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
346 v2.get(), v3.get()};
347 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
348 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
349 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
350
351 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
353 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
354 triPointsTypeDir1);
355 Nektar::LibUtilities::BasisType basisTypeDir1 =
357 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
358 triPointsKeyDir1);
359
360 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
361 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
362 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(6,
363 triPointsTypeDir2);
364 Nektar::LibUtilities::BasisType basisTypeDir2 =
366 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
367 triPointsKeyDir2);
368 // const Nektar::LibUtilities::BasisKey
369 // basisKeyDir2(basisTypeDir2,5,triPointsKeyDir2);
370
371 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
372 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
373 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(9,
374 triPointsTypeDir3);
375 Nektar::LibUtilities::BasisType basisTypeDir3 =
377 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
378 triPointsKeyDir3);
379
382 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
383
384 int nelmts = 10;
385
386 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
387 for (int i = 0; i < nelmts; ++i)
388 {
389 CollExp.push_back(Exp);
390 }
391
393 Collections::CollectionOptimisation colOpt(dummySession, 3,
395 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
396 Collections::Collection c(CollExp, impTypes);
398
399 const int nq = Exp->GetTotPoints();
400 Array<OneD, NekDouble> phys(nelmts * nq), tmp;
401 Array<OneD, NekDouble> coeffs1(nelmts * Exp->GetNcoeffs());
402 Array<OneD, NekDouble> coeffs2(nelmts * Exp->GetNcoeffs());
403
404 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
405
406 Exp->GetCoords(xc, yc, zc);
407
408 for (int i = 0; i < nq; ++i)
409 {
410 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
411 }
412 Exp->IProductWRTBase(phys, coeffs1);
413
414 for (int i = 1; i < nelmts; ++i)
415 {
416 Vmath::Vcopy(nq, &phys[0], 1, &phys[i * nq], 1);
417 Exp->IProductWRTBase(phys + i * nq,
418 tmp = coeffs1 + i * Exp->GetNcoeffs());
419 }
421
422 double epsilon = 1.0e-4;
423 for (int i = 0; i < coeffs1.size(); ++i)
424 {
425 // clamp values below 1e-14 to zero
426 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
427 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
428 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
429 }
430}
431
432BOOST_AUTO_TEST_CASE(TestTetBwdTrans_StdMat_UniformP)
433{
435 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
437 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
439 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
441 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
442
443 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
444 v2.get(), v3.get()};
445 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
446 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
447 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
448
449 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
451 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
452 triPointsTypeDir1);
453 Nektar::LibUtilities::BasisType basisTypeDir1 =
455 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
456 triPointsKeyDir1);
457
458 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
459 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
460 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(4,
461 triPointsTypeDir2);
462 Nektar::LibUtilities::BasisType basisTypeDir2 =
464 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
465 triPointsKeyDir2);
466
467 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
468 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
469 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(4,
470 triPointsTypeDir3);
471 Nektar::LibUtilities::BasisType basisTypeDir3 =
473 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
474 triPointsKeyDir3);
475
478 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
479
480 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
481 CollExp.push_back(Exp);
482
484 Collections::CollectionOptimisation colOpt(dummySession, 3,
486 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
487 Collections::Collection c(CollExp, impTypes);
489
490 Array<OneD, NekDouble> coeffs(Exp->GetNcoeffs(), 1.0), tmp;
491 for (int i = 0; i < coeffs.size(); ++i)
492 {
493 coeffs[i] = i + 1; // make values distinct
494 }
495 Array<OneD, NekDouble> phys1(Exp->GetTotPoints());
496 Array<OneD, NekDouble> phys2(Exp->GetTotPoints());
497
498 Exp->BwdTrans(coeffs, phys1);
499 c.ApplyOperator(Collections::eBwdTrans, coeffs, phys2);
500
501 double epsilon = 1.0e-8;
502 for (int i = 0; i < phys1.size(); ++i)
503 {
504 BOOST_CHECK_CLOSE(phys1[i], phys2[i], epsilon);
505 }
506}
507
508BOOST_AUTO_TEST_CASE(TestTetBwdTrans_StdMat_VariableP_MultiElmt)
509{
511 new SpatialDomains::PointGeom(3u, 0u, -1.5, -1.5, -1.5));
513 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
515 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
517 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
518
519 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
520 v2.get(), v3.get()};
521 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
522 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
523 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
524
525 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
527 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
528 triPointsTypeDir1);
529 Nektar::LibUtilities::BasisType basisTypeDir1 =
531 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
532 triPointsKeyDir1);
533
534 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
535 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
536 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(7,
537 triPointsTypeDir2);
538 Nektar::LibUtilities::BasisType basisTypeDir2 =
540 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
541 triPointsKeyDir2);
542
543 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
544 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
545 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(9,
546 triPointsTypeDir3);
547 Nektar::LibUtilities::BasisType basisTypeDir3 =
549 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
550 triPointsKeyDir3);
551
554 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
555
556 int nelmts = 10;
557
558 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
559 for (int i = 0; i < nelmts; ++i)
560 {
561 CollExp.push_back(Exp);
562 }
563
565 Collections::CollectionOptimisation colOpt(dummySession, 3,
567 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
568 Collections::Collection c(CollExp, impTypes);
570
571 Array<OneD, NekDouble> coeffs(nelmts * Exp->GetNcoeffs(), 1.0), tmp;
572 for (int i = 0; i < coeffs.size(); ++i)
573 {
574 coeffs[i] = i + 1;
575 }
576 Array<OneD, NekDouble> phys1(nelmts * Exp->GetTotPoints());
577 Array<OneD, NekDouble> phys2(nelmts * Exp->GetTotPoints());
578
579 for (int i = 0; i < nelmts; ++i)
580 {
581 Exp->BwdTrans(coeffs + i * Exp->GetNcoeffs(),
582 tmp = phys1 + i * Exp->GetTotPoints());
583 }
584
585 c.ApplyOperator(Collections::eBwdTrans, coeffs, phys2);
586
587 double epsilon = 1.0e-8;
588 for (int i = 0; i < phys1.size(); ++i)
589 {
590 BOOST_CHECK_CLOSE(phys1[i], phys2[i], epsilon);
591 }
592}
593
594BOOST_AUTO_TEST_CASE(TestTetBwdTrans_SumFac_UniformP)
595{
597 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
599 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
601 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
603 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
604
605 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
606 v2.get(), v3.get()};
607 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
608 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
609 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
610
611 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
613 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
614 triPointsTypeDir1);
615 Nektar::LibUtilities::BasisType basisTypeDir1 =
617 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
618 triPointsKeyDir1);
619
620 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
621 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
622 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(4,
623 triPointsTypeDir2);
624 Nektar::LibUtilities::BasisType basisTypeDir2 =
626 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
627 triPointsKeyDir2);
628
629 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
630 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
631 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(4,
632 triPointsTypeDir3);
633 Nektar::LibUtilities::BasisType basisTypeDir3 =
635 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
636 triPointsKeyDir3);
637
640 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
641
642 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
643 CollExp.push_back(Exp);
644
646 Collections::CollectionOptimisation colOpt(dummySession, 3,
648 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
649 Collections::Collection c(CollExp, impTypes);
651
652 Array<OneD, NekDouble> coeffs(Exp->GetNcoeffs(), 1.0), tmp;
653 for (int i = 0; i < coeffs.size(); ++i)
654 {
655 coeffs[i] = i + 1; // make values distinct
656 }
657 Array<OneD, NekDouble> phys1(Exp->GetTotPoints());
658 Array<OneD, NekDouble> phys2(Exp->GetTotPoints());
659
660 Exp->BwdTrans(coeffs, phys1);
661 c.ApplyOperator(Collections::eBwdTrans, coeffs, phys2);
662
663 double epsilon = 1.0e-8;
664 for (int i = 0; i < phys1.size(); ++i)
665 {
666 BOOST_CHECK_CLOSE(phys1[i], phys2[i], epsilon);
667 }
668}
669
670BOOST_AUTO_TEST_CASE(TestTetBwdTrans_SumFac_MultiElmt)
671{
673 new SpatialDomains::PointGeom(3u, 0u, -1.5, -1.5, -1.5));
675 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
677 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
679 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
680
681 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
682 v2.get(), v3.get()};
683 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
684 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
685 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
686
687 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
689 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
690 triPointsTypeDir1);
691 Nektar::LibUtilities::BasisType basisTypeDir1 =
693 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
694 triPointsKeyDir1);
695
696 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
697 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
698 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(4,
699 triPointsTypeDir2);
700 Nektar::LibUtilities::BasisType basisTypeDir2 =
702 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
703 triPointsKeyDir2);
704
705 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
706 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
707 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(4,
708 triPointsTypeDir3);
709 Nektar::LibUtilities::BasisType basisTypeDir3 =
711 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
712 triPointsKeyDir3);
713
716 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
717
718 int nelmts = 10;
719
720 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
721 for (int i = 0; i < nelmts; ++i)
722 {
723 CollExp.push_back(Exp);
724 }
725
727 Collections::CollectionOptimisation colOpt(dummySession, 3,
729 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
730 Collections::Collection c(CollExp, impTypes);
732
733 Array<OneD, NekDouble> coeffs(nelmts * Exp->GetNcoeffs(), 1.0), tmp;
734 for (int i = 0; i < coeffs.size(); ++i)
735 {
736 coeffs[i] = i + 1;
737 }
738 Array<OneD, NekDouble> phys1(nelmts * Exp->GetTotPoints());
739 Array<OneD, NekDouble> phys2(nelmts * Exp->GetTotPoints());
740
741 for (int i = 0; i < nelmts; ++i)
742 {
743 Exp->BwdTrans(coeffs + i * Exp->GetNcoeffs(),
744 tmp = phys1 + i * Exp->GetTotPoints());
745 }
746
747 c.ApplyOperator(Collections::eBwdTrans, coeffs, phys2);
748
749 double epsilon = 1.0e-8;
750 for (int i = 0; i < phys1.size(); ++i)
751 {
752 BOOST_CHECK_CLOSE(phys1[i], phys2[i], epsilon);
753 }
754}
755
756BOOST_AUTO_TEST_CASE(TestTetBwdTrans_SumFac_MultiElmt_VariableP)
757{
759 new SpatialDomains::PointGeom(3u, 0u, -1.5, -1.5, -1.5));
761 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
763 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
765 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
766
767 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
768 v2.get(), v3.get()};
769 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
770 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
771 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
772
773 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
775 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
776 triPointsTypeDir1);
777 Nektar::LibUtilities::BasisType basisTypeDir1 =
779 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
780 triPointsKeyDir1);
781
782 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
783 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
784 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(6,
785 triPointsTypeDir2);
786 Nektar::LibUtilities::BasisType basisTypeDir2 =
788 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 6,
789 triPointsKeyDir2);
790
791 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
792 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
793 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(9,
794 triPointsTypeDir3);
795 Nektar::LibUtilities::BasisType basisTypeDir3 =
797 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
798 triPointsKeyDir3);
799
802 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
803
804 int nelmts = 1;
805
806 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
807 for (int i = 0; i < nelmts; ++i)
808 {
809 CollExp.push_back(Exp);
810 }
811
813 Collections::CollectionOptimisation colOpt(dummySession, 3,
815 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
816 Collections::Collection c(CollExp, impTypes);
818
819 Array<OneD, NekDouble> coeffs(nelmts * Exp->GetNcoeffs(), 1.0), tmp;
820 for (int i = 0; i < coeffs.size(); ++i)
821 {
822 coeffs[i] = i + 1;
823 }
824 Array<OneD, NekDouble> phys1(nelmts * Exp->GetTotPoints());
825 Array<OneD, NekDouble> phys2(nelmts * Exp->GetTotPoints());
826
827 for (int i = 0; i < nelmts; ++i)
828 {
829 Exp->BwdTrans(coeffs + i * Exp->GetNcoeffs(),
830 tmp = phys1 + i * Exp->GetTotPoints());
831 }
832
833 c.ApplyOperator(Collections::eBwdTrans, coeffs, phys2);
834
835 double epsilon = 1.0e-8;
836 for (int i = 0; i < phys1.size(); ++i)
837 {
838 BOOST_CHECK_CLOSE(phys1[i], phys2[i], epsilon);
839 }
840}
841
842BOOST_AUTO_TEST_CASE(TestTetBwdTrans_MatrixFree_UniformP)
843{
845 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
847 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
849 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
851 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
852
853 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
854 v2.get(), v3.get()};
855 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
856 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
857 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
858
859 unsigned int numQuadPoints = 5;
860 unsigned int numModes = 4;
861
862 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
864 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
865 triPointsTypeDir1);
866 Nektar::LibUtilities::BasisType basisTypeDir1 =
868 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
869 triPointsKeyDir1);
870
871 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
872 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
873 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
874 triPointsTypeDir2);
875 Nektar::LibUtilities::BasisType basisTypeDir2 =
877 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
878 triPointsKeyDir2);
879
880 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
881 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
882 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
883 triPointsTypeDir3);
884 Nektar::LibUtilities::BasisType basisTypeDir3 =
886 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
887 triPointsKeyDir3);
888
891 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
892
893 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
894 CollExp.push_back(Exp);
895
897 Collections::CollectionOptimisation colOpt(dummySession, 2,
899 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
900 // ... only one op at the time ...
902 Collections::Collection c(CollExp, impTypes);
904
905 Array<OneD, NekDouble> coeffs(Exp->GetNcoeffs(), 1.0), tmp;
906 for (int i = 0; i < coeffs.size(); ++i)
907 {
908 coeffs[i] = i + 1; // make values distinct
909 }
910 Array<OneD, NekDouble> physRef(Exp->GetTotPoints());
911 Array<OneD, NekDouble> phys(Exp->GetTotPoints());
912
913 Exp->BwdTrans(coeffs, physRef);
914 c.ApplyOperator(Collections::eBwdTrans, coeffs, phys);
915
916 double epsilon = 1.0e-8;
917 for (int i = 0; i < physRef.size(); ++i)
918 {
919 BOOST_CHECK_CLOSE(physRef[i], phys[i], epsilon);
920 }
921}
922
923BOOST_AUTO_TEST_CASE(TestTetBwdTrans_MatrixFree_UniformP_OverInt)
924{
926 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
928 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
930 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
932 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
933
934 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
935 v2.get(), v3.get()};
936 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
937 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
938 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
939
940 unsigned int numQuadPoints = 8;
941 unsigned int numModes = 4;
942
943 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
945 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
946 triPointsTypeDir1);
947 Nektar::LibUtilities::BasisType basisTypeDir1 =
949 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
950 triPointsKeyDir1);
951
952 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
953 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
954 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
955 triPointsTypeDir2);
956 Nektar::LibUtilities::BasisType basisTypeDir2 =
958 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
959 triPointsKeyDir2);
960
961 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
962 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
963 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
964 triPointsTypeDir3);
965 Nektar::LibUtilities::BasisType basisTypeDir3 =
967 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
968 triPointsKeyDir3);
969
972 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
973
974 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
975 CollExp.push_back(Exp);
976
978 Collections::CollectionOptimisation colOpt(dummySession, 2,
980 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
981 // ... only one op at the time ...
983 Collections::Collection c(CollExp, impTypes);
985
986 Array<OneD, NekDouble> coeffs(Exp->GetNcoeffs(), 1.0), tmp;
987 for (int i = 0; i < coeffs.size(); ++i)
988 {
989 coeffs[i] = i + 1; // make values distinct
990 }
991 Array<OneD, NekDouble> physRef(Exp->GetTotPoints());
992 Array<OneD, NekDouble> phys(Exp->GetTotPoints());
993
994 Exp->BwdTrans(coeffs, physRef);
995 c.ApplyOperator(Collections::eBwdTrans, coeffs, phys);
996
997 double epsilon = 1.0e-8;
998 for (int i = 0; i < physRef.size(); ++i)
999 {
1000 BOOST_CHECK_CLOSE(physRef[i], phys[i], epsilon);
1001 }
1002}
1003
1004BOOST_AUTO_TEST_CASE(TestTetIProductWRTBase_StdMat_UniformP)
1005{
1007 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1009 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1011 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
1013 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
1014
1015 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
1016 v2.get(), v3.get()};
1017 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
1018 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
1019 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
1020
1021 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
1023 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
1024 triPointsTypeDir1);
1025 Nektar::LibUtilities::BasisType basisTypeDir1 =
1027 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
1028 triPointsKeyDir1);
1029
1030 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
1031 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
1032 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(4,
1033 triPointsTypeDir2);
1034 Nektar::LibUtilities::BasisType basisTypeDir2 =
1036 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
1037 triPointsKeyDir2);
1038
1039 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
1040 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1041 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(4,
1042 triPointsTypeDir3);
1043 Nektar::LibUtilities::BasisType basisTypeDir3 =
1045 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
1046 triPointsKeyDir3);
1047
1050 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
1051
1052 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
1053 CollExp.push_back(Exp);
1054
1056 Collections::CollectionOptimisation colOpt(dummySession, 3,
1058 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1059 Collections::Collection c(CollExp, impTypes);
1061
1062 const int nq = Exp->GetTotPoints();
1063 Array<OneD, NekDouble> phys(nq);
1064 Array<OneD, NekDouble> coeffs1(Exp->GetNcoeffs());
1065 Array<OneD, NekDouble> coeffs2(Exp->GetNcoeffs());
1066
1067 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1068
1069 Exp->GetCoords(xc, yc, zc);
1070
1071 for (int i = 0; i < nq; ++i)
1072 {
1073 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1074 }
1075
1076 Exp->IProductWRTBase(phys, coeffs1);
1078
1079 double epsilon = 1.0e-8;
1080 for (int i = 0; i < coeffs1.size(); ++i)
1081 {
1082 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
1083 }
1084}
1085
1086BOOST_AUTO_TEST_CASE(TestTetIProductWRTBase_StdMat_VariableP_MultiElmt)
1087{
1089 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1091 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1093 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
1095 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
1096
1097 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
1098 v2.get(), v3.get()};
1099 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
1100 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
1101 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
1102
1103 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
1105 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
1106 triPointsTypeDir1);
1107 Nektar::LibUtilities::BasisType basisTypeDir1 =
1109 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
1110 triPointsKeyDir1);
1111
1112 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
1113 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
1114 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(7,
1115 triPointsTypeDir2);
1116 Nektar::LibUtilities::BasisType basisTypeDir2 =
1118 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
1119 triPointsKeyDir2);
1120
1121 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
1122 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1123 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(9,
1124 triPointsTypeDir3);
1125 Nektar::LibUtilities::BasisType basisTypeDir3 =
1127 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
1128 triPointsKeyDir3);
1129
1132 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
1133
1134 int nelmts = 10;
1135
1136 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
1137 for (int i = 0; i < nelmts; ++i)
1138 {
1139 CollExp.push_back(Exp);
1140 }
1141
1143 Collections::CollectionOptimisation colOpt(dummySession, 3,
1145 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1146 Collections::Collection c(CollExp, impTypes);
1148
1149 const int nq = Exp->GetTotPoints();
1150 Array<OneD, NekDouble> phys(nelmts * nq), tmp;
1151 Array<OneD, NekDouble> coeffs1(nelmts * Exp->GetNcoeffs());
1152 Array<OneD, NekDouble> coeffs2(nelmts * Exp->GetNcoeffs());
1153
1154 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1155
1156 Exp->GetCoords(xc, yc, zc);
1157
1158 for (int i = 0; i < nq; ++i)
1159 {
1160 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1161 }
1162 Exp->IProductWRTBase(phys, coeffs1);
1163
1164 for (int i = 1; i < nelmts; ++i)
1165 {
1166 Vmath::Vcopy(nq, &phys[0], 1, &phys[i * nq], 1);
1167 Exp->IProductWRTBase(phys + i * nq,
1168 tmp = coeffs1 + i * Exp->GetNcoeffs());
1169 }
1171
1172 double epsilon = 1.0e-4;
1173 for (int i = 0; i < coeffs1.size(); ++i)
1174 {
1175 // clamp values below 1e-14 to zero
1176 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
1177 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
1178 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
1179 }
1180}
1181
1182BOOST_AUTO_TEST_CASE(TestTetIProductWRTBase_SumFac_UniformP)
1183{
1185 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1187 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1189 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
1191 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
1192
1193 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
1194 v2.get(), v3.get()};
1195 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
1196 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
1197 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
1198
1199 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
1201 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
1202 triPointsTypeDir1);
1203 Nektar::LibUtilities::BasisType basisTypeDir1 =
1205 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
1206 triPointsKeyDir1);
1207
1208 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
1209 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
1210 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(4,
1211 triPointsTypeDir2);
1212 Nektar::LibUtilities::BasisType basisTypeDir2 =
1214 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
1215 triPointsKeyDir2);
1216
1217 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
1218 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1219 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(4,
1220 triPointsTypeDir3);
1221 Nektar::LibUtilities::BasisType basisTypeDir3 =
1223 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
1224 triPointsKeyDir3);
1225
1228 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
1229
1230 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
1231 CollExp.push_back(Exp);
1232
1234 Collections::CollectionOptimisation colOpt(dummySession, 3,
1236 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1237 Collections::Collection c(CollExp, impTypes);
1239
1240 const int nq = Exp->GetTotPoints();
1241 Array<OneD, NekDouble> phys(nq);
1242 Array<OneD, NekDouble> coeffs1(Exp->GetNcoeffs());
1243 Array<OneD, NekDouble> coeffs2(Exp->GetNcoeffs());
1244
1245 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1246
1247 Exp->GetCoords(xc, yc, zc);
1248
1249 for (int i = 0; i < nq; ++i)
1250 {
1251 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1252 }
1253
1254 Exp->IProductWRTBase(phys, coeffs1);
1256
1257 double epsilon = 1.0e-8;
1258 for (int i = 0; i < coeffs1.size(); ++i)
1259 {
1260 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
1261 }
1262}
1263
1264BOOST_AUTO_TEST_CASE(TestTetIProductWRTBase_SumFac_VariableP_MultiElmt)
1265{
1267 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1269 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1271 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
1273 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
1274
1275 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
1276 v2.get(), v3.get()};
1277 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
1278 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
1279 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
1280
1281 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
1283 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
1284 triPointsTypeDir1);
1285 Nektar::LibUtilities::BasisType basisTypeDir1 =
1287 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
1288 triPointsKeyDir1);
1289
1290 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
1291 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
1292 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(7,
1293 triPointsTypeDir2);
1294 Nektar::LibUtilities::BasisType basisTypeDir2 =
1296 // const Nektar::LibUtilities::BasisKey
1297 // basisKeyDir2(basisTypeDir2,6,triPointsKeyDir2);
1298 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
1299 triPointsKeyDir2);
1300
1301 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
1302 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1303 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(9,
1304 triPointsTypeDir3);
1305 Nektar::LibUtilities::BasisType basisTypeDir3 =
1307 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
1308 triPointsKeyDir3);
1309
1312 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
1313
1314 int nelmts = 10;
1315
1316 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
1317 for (int i = 0; i < nelmts; ++i)
1318 {
1319 CollExp.push_back(Exp);
1320 }
1321
1323 Collections::CollectionOptimisation colOpt(dummySession, 3,
1325 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1326 Collections::Collection c(CollExp, impTypes);
1328
1329 const int nq = Exp->GetTotPoints();
1330 Array<OneD, NekDouble> phys(nelmts * nq), tmp;
1331 Array<OneD, NekDouble> coeffs1(nelmts * Exp->GetNcoeffs());
1332 Array<OneD, NekDouble> coeffs2(nelmts * Exp->GetNcoeffs());
1333
1334 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1335
1336 Exp->GetCoords(xc, yc, zc);
1337
1338 for (int i = 0; i < nq; ++i)
1339 {
1340 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1341 }
1342 Exp->IProductWRTBase(phys, coeffs1);
1343
1344 for (int i = 1; i < nelmts; ++i)
1345 {
1346 Vmath::Vcopy(nq, &phys[0], 1, &phys[i * nq], 1);
1347 Exp->IProductWRTBase(phys + i * nq,
1348 tmp = coeffs1 + i * Exp->GetNcoeffs());
1349 }
1351
1352 double epsilon = 1.0e-4;
1353 for (int i = 0; i < coeffs1.size(); ++i)
1354 {
1355 // clamp values below 1e-14 to zero
1356 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
1357 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
1358 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
1359 }
1360}
1361
1362BOOST_AUTO_TEST_CASE(TestTetIProductWRTBase_MatrixFree_UniformP_Undeformed)
1363{
1365 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1367 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1369 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
1371 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
1372
1373 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
1374 v2.get(), v3.get()};
1375 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
1376 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
1377 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
1378
1379 unsigned int numQuadPoints = 5;
1380 unsigned int numModes = 4;
1381
1382 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
1384 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
1385 triPointsTypeDir1);
1386 Nektar::LibUtilities::BasisType basisTypeDir1 =
1388 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
1389 triPointsKeyDir1);
1390
1391 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
1392 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
1393 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
1394 triPointsTypeDir2);
1395 Nektar::LibUtilities::BasisType basisTypeDir2 =
1397 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
1398 triPointsKeyDir2);
1399
1400 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
1401 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1402 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
1403 triPointsTypeDir3);
1404 Nektar::LibUtilities::BasisType basisTypeDir3 =
1406 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
1407 triPointsKeyDir3);
1408
1411 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
1412
1413 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
1414 CollExp.push_back(Exp);
1415
1417 Collections::CollectionOptimisation colOpt(dummySession, 2,
1419 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1420 // ... only one op at the time ...
1422 Collections::Collection c(CollExp, impTypes);
1424
1425 const int nq = Exp->GetTotPoints();
1426 Array<OneD, NekDouble> phys(nq);
1427 Array<OneD, NekDouble> coeffsRef(Exp->GetNcoeffs());
1428 Array<OneD, NekDouble> coeffs(Exp->GetNcoeffs());
1429
1430 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1431
1432 Exp->GetCoords(xc, yc, zc);
1433
1434 for (int i = 0; i < nq; ++i)
1435 {
1436 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1437 }
1438
1439 Exp->IProductWRTBase(phys, coeffsRef);
1441
1442 double epsilon = 1.0e-8;
1443 for (int i = 0; i < coeffsRef.size(); ++i)
1444 {
1445 BOOST_CHECK_CLOSE(coeffsRef[i], coeffs[i], epsilon);
1446 }
1447}
1448
1449BOOST_AUTO_TEST_CASE(TestTetIProductWRTBase_MatrixFree_UniformP_Deformed)
1450{
1452 new SpatialDomains::PointGeom(3u, 0u, -2.0, -3.0, -4.0));
1454 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1456 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
1458 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
1459
1460 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
1461 v2.get(), v3.get()};
1462 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
1463 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
1464 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
1465
1466 unsigned int numQuadPoints = 5;
1467 unsigned int numModes = 4;
1468
1469 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
1471 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
1472 triPointsTypeDir1);
1473 Nektar::LibUtilities::BasisType basisTypeDir1 =
1475 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
1476 triPointsKeyDir1);
1477
1478 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
1479 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
1480 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
1481 triPointsTypeDir2);
1482 Nektar::LibUtilities::BasisType basisTypeDir2 =
1484 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
1485 triPointsKeyDir2);
1486
1487 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
1488 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1489 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
1490 triPointsTypeDir3);
1491 Nektar::LibUtilities::BasisType basisTypeDir3 =
1493 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
1494 triPointsKeyDir3);
1495
1498 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
1499
1500 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
1501 CollExp.push_back(Exp);
1502
1504 Collections::CollectionOptimisation colOpt(dummySession, 2,
1506 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1507 // ... only one op at the time ...
1509 Collections::Collection c(CollExp, impTypes);
1511
1512 const int nq = Exp->GetTotPoints();
1513 Array<OneD, NekDouble> phys(nq);
1514 Array<OneD, NekDouble> coeffsRef(Exp->GetNcoeffs());
1515 Array<OneD, NekDouble> coeffs(Exp->GetNcoeffs());
1516
1517 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1518
1519 Exp->GetCoords(xc, yc, zc);
1520
1521 for (int i = 0; i < nq; ++i)
1522 {
1523 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1524 }
1525
1526 Exp->IProductWRTBase(phys, coeffsRef);
1528
1529 double epsilon = 1.0e-8;
1530 for (int i = 0; i < coeffsRef.size(); ++i)
1531 {
1532 BOOST_CHECK_CLOSE(coeffsRef[i], coeffs[i], epsilon);
1533 }
1534}
1535
1537 TestTetIProductWRTBase_MatrixFree_UniformP_Deformed_OverInt)
1538{
1540 new SpatialDomains::PointGeom(3u, 0u, -2.0, -3.0, -4.0));
1542 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1544 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
1546 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
1547
1548 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
1549 v2.get(), v3.get()};
1550 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
1551 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
1552 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
1553
1554 unsigned int numQuadPoints = 8;
1555 unsigned int numModes = 4;
1556
1557 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
1559 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
1560 triPointsTypeDir1);
1561 Nektar::LibUtilities::BasisType basisTypeDir1 =
1563 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
1564 triPointsKeyDir1);
1565
1566 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
1567 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
1568 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
1569 triPointsTypeDir2);
1570 Nektar::LibUtilities::BasisType basisTypeDir2 =
1572 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
1573 triPointsKeyDir2);
1574
1575 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
1576 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1577 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
1578 triPointsTypeDir3);
1579 Nektar::LibUtilities::BasisType basisTypeDir3 =
1581 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
1582 triPointsKeyDir3);
1583
1586 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
1587
1588 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
1589 CollExp.push_back(Exp);
1590
1592 Collections::CollectionOptimisation colOpt(dummySession, 2,
1594 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1595 // ... only one op at the time ...
1597 Collections::Collection c(CollExp, impTypes);
1599
1600 const int nq = Exp->GetTotPoints();
1601 Array<OneD, NekDouble> phys(nq);
1602 Array<OneD, NekDouble> coeffsRef(Exp->GetNcoeffs());
1603 Array<OneD, NekDouble> coeffs(Exp->GetNcoeffs());
1604
1605 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1606
1607 Exp->GetCoords(xc, yc, zc);
1608
1609 for (int i = 0; i < nq; ++i)
1610 {
1611 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1612 }
1613
1614 Exp->IProductWRTBase(phys, coeffsRef);
1616
1617 double epsilon = 1.0e-8;
1618 for (int i = 0; i < coeffsRef.size(); ++i)
1619 {
1620 BOOST_CHECK_CLOSE(coeffsRef[i], coeffs[i], epsilon);
1621 }
1622}
1623
1624BOOST_AUTO_TEST_CASE(TestTetPhysDeriv_IterPerExp_UniformP)
1625{
1627 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1629 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1631 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
1633 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
1634
1635 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
1636 v2.get(), v3.get()};
1637 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
1638 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
1639 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
1640
1641 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
1643 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
1644 triPointsTypeDir1);
1645 Nektar::LibUtilities::BasisType basisTypeDir1 =
1647 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
1648 triPointsKeyDir1);
1649
1650 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
1651 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
1652 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(4,
1653 triPointsTypeDir2);
1654 Nektar::LibUtilities::BasisType basisTypeDir2 =
1656 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
1657 triPointsKeyDir2);
1658
1659 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
1660 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1661 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(4,
1662 triPointsTypeDir3);
1663 Nektar::LibUtilities::BasisType basisTypeDir3 =
1665 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
1666 triPointsKeyDir3);
1667
1670 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
1671
1672 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
1673 CollExp.push_back(Exp);
1674
1676 Collections::CollectionOptimisation colOpt(dummySession, 3,
1678 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1679 Collections::Collection c(CollExp, impTypes);
1681
1682 const int nq = Exp->GetTotPoints();
1683 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1684 Array<OneD, NekDouble> phys(nq), tmp, tmp1, tmp2;
1685 Array<OneD, NekDouble> diff1(3 * nq);
1686 Array<OneD, NekDouble> diff2(3 * nq);
1687
1688 Exp->GetCoords(xc, yc, zc);
1689
1690 for (int i = 0; i < nq; ++i)
1691 {
1692 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1693 }
1694
1695 Exp->PhysDeriv(phys, diff1, tmp = diff1 + nq, tmp1 = diff1 + 2 * nq);
1696 c.ApplyOperator(Collections::ePhysDeriv, phys, diff2, tmp = diff2 + nq,
1697 tmp2 = diff2 + 2 * nq);
1698
1699 double epsilon = 1.0e-8;
1700 for (int i = 0; i < diff1.size(); ++i)
1701 {
1702 BOOST_CHECK_CLOSE(diff1[i], diff2[i], epsilon);
1703 }
1704}
1705
1706BOOST_AUTO_TEST_CASE(TestTetPhysDeriv_IterPerExp_VariableP_MultiElmt)
1707{
1709 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1711 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1713 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
1715 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
1716
1717 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
1718 v2.get(), v3.get()};
1719 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
1720 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
1721 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
1722
1723 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
1725 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
1726 triPointsTypeDir1);
1727 Nektar::LibUtilities::BasisType basisTypeDir1 =
1729 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
1730 triPointsKeyDir1);
1731
1732 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
1733 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
1734 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(7,
1735 triPointsTypeDir2);
1736 Nektar::LibUtilities::BasisType basisTypeDir2 =
1738 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 6,
1739 triPointsKeyDir2);
1740
1741 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
1742 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1743 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(9,
1744 triPointsTypeDir3);
1745 Nektar::LibUtilities::BasisType basisTypeDir3 =
1747 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
1748 triPointsKeyDir3);
1749
1752 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
1753
1754 int nelmts = 10;
1755
1756 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
1757 for (int i = 0; i < nelmts; ++i)
1758 {
1759 CollExp.push_back(Exp);
1760 }
1761
1763 Collections::CollectionOptimisation colOpt(dummySession, 3,
1765 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1766 Collections::Collection c(CollExp, impTypes);
1768
1769 const int nq = Exp->GetTotPoints();
1770 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1771 Array<OneD, NekDouble> phys(nelmts * nq), tmp, tmp1, tmp2;
1772 Array<OneD, NekDouble> diff1(3 * nelmts * nq);
1773 Array<OneD, NekDouble> diff2(3 * nelmts * nq);
1774
1775 Exp->GetCoords(xc, yc, zc);
1776
1777 for (int i = 0; i < nq; ++i)
1778 {
1779 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1780 }
1781 Exp->PhysDeriv(phys, diff1, tmp1 = diff1 + (nelmts)*nq,
1782 tmp2 = diff1 + (2 * nelmts) * nq);
1783
1784 for (int i = 1; i < nelmts; ++i)
1785 {
1786 Vmath::Vcopy(nq, phys, 1, tmp = phys + i * nq, 1);
1787 Exp->PhysDeriv(phys, tmp = diff1 + i * nq,
1788 tmp1 = diff1 + (nelmts + i) * nq,
1789 tmp2 = diff1 + (2 * nelmts + i) * nq);
1790 }
1791
1793 tmp = diff2 + nelmts * nq, tmp2 = diff2 + 2 * nelmts * nq);
1794
1795 double epsilon = 1.0e-8;
1796 for (int i = 0; i < diff1.size(); ++i)
1797 {
1798 BOOST_CHECK_CLOSE(diff1[i], diff2[i], epsilon);
1799 }
1800}
1801
1802BOOST_AUTO_TEST_CASE(TestTetPhysDeriv_StdMat_UniformP)
1803{
1805 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1807 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1809 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
1811 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
1812
1813 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
1814 v2.get(), v3.get()};
1815 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
1816 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
1817 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
1818
1819 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
1821 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
1822 triPointsTypeDir1);
1823 Nektar::LibUtilities::BasisType basisTypeDir1 =
1825 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
1826 triPointsKeyDir1);
1827
1828 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
1829 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
1830 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(4,
1831 triPointsTypeDir2);
1832 Nektar::LibUtilities::BasisType basisTypeDir2 =
1834 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
1835 triPointsKeyDir2);
1836
1837 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
1838 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1839 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(4,
1840 triPointsTypeDir3);
1841 Nektar::LibUtilities::BasisType basisTypeDir3 =
1843 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
1844 triPointsKeyDir3);
1845
1848 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
1849
1850 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
1851 CollExp.push_back(Exp);
1852
1854 Collections::CollectionOptimisation colOpt(dummySession, 3,
1856 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1857 Collections::Collection c(CollExp, impTypes);
1859
1860 const int nq = Exp->GetTotPoints();
1861 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1862 Array<OneD, NekDouble> phys(nq), tmp, tmp1, tmp2;
1863 Array<OneD, NekDouble> diff1(3 * nq);
1864 Array<OneD, NekDouble> diff2(3 * nq);
1865
1866 Exp->GetCoords(xc, yc, zc);
1867
1868 for (int i = 0; i < nq; ++i)
1869 {
1870 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1871 }
1872
1873 Exp->PhysDeriv(phys, diff1, tmp = diff1 + nq, tmp1 = diff1 + 2 * nq);
1874 c.ApplyOperator(Collections::ePhysDeriv, phys, diff2, tmp = diff2 + nq,
1875 tmp2 = diff2 + 2 * nq);
1876
1877 double epsilon = 1.0e-8;
1878 for (int i = 0; i < diff1.size(); ++i)
1879 {
1880 BOOST_CHECK_CLOSE(diff1[i], diff2[i], epsilon);
1881 }
1882}
1883
1884BOOST_AUTO_TEST_CASE(TestTetPhysDeriv_StdMat_VariableP_MultiElmt)
1885{
1887 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1889 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1891 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
1893 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
1894
1895 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
1896 v2.get(), v3.get()};
1897 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
1898 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
1899 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
1900
1901 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
1903 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
1904 triPointsTypeDir1);
1905 Nektar::LibUtilities::BasisType basisTypeDir1 =
1907 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
1908 triPointsKeyDir1);
1909
1910 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
1911 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
1912 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(7,
1913 triPointsTypeDir2);
1914 Nektar::LibUtilities::BasisType basisTypeDir2 =
1916 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 6,
1917 triPointsKeyDir2);
1918
1919 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
1920 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
1921 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(9,
1922 triPointsTypeDir3);
1923 Nektar::LibUtilities::BasisType basisTypeDir3 =
1925 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
1926 triPointsKeyDir3);
1927
1930 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
1931
1932 int nelmts = 10;
1933
1934 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
1935 for (int i = 0; i < nelmts; ++i)
1936 {
1937 CollExp.push_back(Exp);
1938 }
1939
1941 Collections::CollectionOptimisation colOpt(dummySession, 3,
1943 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
1944 Collections::Collection c(CollExp, impTypes);
1946
1947 const int nq = Exp->GetTotPoints();
1948 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
1949 Array<OneD, NekDouble> phys(nelmts * nq), tmp, tmp1, tmp2;
1950 Array<OneD, NekDouble> diff1(3 * nelmts * nq);
1951 Array<OneD, NekDouble> diff2(3 * nelmts * nq);
1952
1953 Exp->GetCoords(xc, yc, zc);
1954
1955 for (int i = 0; i < nq; ++i)
1956 {
1957 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
1958 }
1959 Exp->PhysDeriv(phys, diff1, tmp1 = diff1 + (nelmts)*nq,
1960 tmp2 = diff1 + (2 * nelmts) * nq);
1961
1962 for (int i = 1; i < nelmts; ++i)
1963 {
1964 Vmath::Vcopy(nq, phys, 1, tmp = phys + i * nq, 1);
1965 Exp->PhysDeriv(phys, tmp = diff1 + i * nq,
1966 tmp1 = diff1 + (nelmts + i) * nq,
1967 tmp2 = diff1 + (2 * nelmts + i) * nq);
1968 }
1969
1971 tmp = diff2 + nelmts * nq, tmp2 = diff2 + 2 * nelmts * nq);
1972
1973 double epsilon = 1.0e-8;
1974 for (int i = 0; i < diff1.size(); ++i)
1975 {
1976 BOOST_CHECK_CLOSE(diff1[i], diff2[i], epsilon);
1977 }
1978}
1979
1980BOOST_AUTO_TEST_CASE(TestTetPhysDeriv_SumFac_UniformP)
1981{
1983 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
1985 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
1987 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
1989 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
1990
1991 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
1992 v2.get(), v3.get()};
1993 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
1994 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
1995 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
1996
1997 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
1999 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
2000 triPointsTypeDir1);
2001 Nektar::LibUtilities::BasisType basisTypeDir1 =
2003 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
2004 triPointsKeyDir1);
2005
2006 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
2007 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
2008 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(4,
2009 triPointsTypeDir2);
2010 Nektar::LibUtilities::BasisType basisTypeDir2 =
2012 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
2013 triPointsKeyDir2);
2014
2015 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
2016 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2017 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(4,
2018 triPointsTypeDir3);
2019 Nektar::LibUtilities::BasisType basisTypeDir3 =
2021 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
2022 triPointsKeyDir3);
2023
2026 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
2027
2028 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
2029 CollExp.push_back(Exp);
2030
2032 Collections::CollectionOptimisation colOpt(dummySession, 3,
2034 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2035 Collections::Collection c(CollExp, impTypes);
2037
2038 const int nq = Exp->GetTotPoints();
2039 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
2040 Array<OneD, NekDouble> phys(nq), tmp, tmp1, tmp2;
2041 Array<OneD, NekDouble> diff1(3 * nq);
2042 Array<OneD, NekDouble> diff2(3 * nq);
2043
2044 Exp->GetCoords(xc, yc, zc);
2045
2046 for (int i = 0; i < nq; ++i)
2047 {
2048 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
2049 }
2050
2051 Exp->PhysDeriv(phys, diff1, tmp = diff1 + nq, tmp1 = diff1 + 2 * nq);
2052 c.ApplyOperator(Collections::ePhysDeriv, phys, diff2, tmp = diff2 + nq,
2053 tmp2 = diff2 + 2 * nq);
2054
2055 double epsilon = 1.0e-8;
2056 for (int i = 0; i < diff1.size(); ++i)
2057 {
2058 BOOST_CHECK_CLOSE(diff1[i], diff2[i], epsilon);
2059 }
2060}
2061
2062BOOST_AUTO_TEST_CASE(TestTetPhysDeriv_SumFac_VariableP_MultiElmt)
2063{
2065 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
2067 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2069 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
2071 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
2072
2073 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
2074 v2.get(), v3.get()};
2075 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
2076 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
2077 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
2078
2079 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
2081 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
2082 triPointsTypeDir1);
2083 Nektar::LibUtilities::BasisType basisTypeDir1 =
2085 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
2086 triPointsKeyDir1);
2087
2088 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
2089 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
2090 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(7,
2091 triPointsTypeDir2);
2092 Nektar::LibUtilities::BasisType basisTypeDir2 =
2094 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 6,
2095 triPointsKeyDir2);
2096
2097 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
2098 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2099 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(9,
2100 triPointsTypeDir3);
2101 Nektar::LibUtilities::BasisType basisTypeDir3 =
2103 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
2104 triPointsKeyDir3);
2105
2108 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
2109
2110 int nelmts = 10;
2111
2112 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
2113 for (int i = 0; i < nelmts; ++i)
2114 {
2115 CollExp.push_back(Exp);
2116 }
2117
2119 Collections::CollectionOptimisation colOpt(dummySession, 3,
2121 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2122 Collections::Collection c(CollExp, impTypes);
2124
2125 const int nq = Exp->GetTotPoints();
2126 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
2127 Array<OneD, NekDouble> phys(nelmts * nq), tmp, tmp1, tmp2;
2128 Array<OneD, NekDouble> diff1(3 * nelmts * nq);
2129 Array<OneD, NekDouble> diff2(3 * nelmts * nq);
2130
2131 Exp->GetCoords(xc, yc, zc);
2132
2133 for (int i = 0; i < nq; ++i)
2134 {
2135 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
2136 }
2137 Exp->PhysDeriv(phys, diff1, tmp1 = diff1 + (nelmts)*nq,
2138 tmp2 = diff1 + (2 * nelmts) * nq);
2139
2140 for (int i = 1; i < nelmts; ++i)
2141 {
2142 Vmath::Vcopy(nq, phys, 1, tmp = phys + i * nq, 1);
2143 Exp->PhysDeriv(phys, tmp = diff1 + i * nq,
2144 tmp1 = diff1 + (nelmts + i) * nq,
2145 tmp2 = diff1 + (2 * nelmts + i) * nq);
2146 }
2147
2149 tmp = diff2 + nelmts * nq, tmp2 = diff2 + 2 * nelmts * nq);
2150
2151 double epsilon = 1.0e-8;
2152 for (int i = 0; i < diff1.size(); ++i)
2153 {
2154 BOOST_CHECK_CLOSE(diff1[i], diff2[i], epsilon);
2155 }
2156}
2157
2158BOOST_AUTO_TEST_CASE(TestTetPhysDeriv_MatrixFree_UniformP)
2159{
2161 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
2163 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2165 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
2167 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
2168
2169 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
2170 v2.get(), v3.get()};
2171 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
2172 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
2173 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
2174
2175 unsigned int numQuadPoints = 5;
2176 unsigned int numModes = 4;
2177
2178 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
2180 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
2181 triPointsTypeDir1);
2182 Nektar::LibUtilities::BasisType basisTypeDir1 =
2184 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
2185 triPointsKeyDir1);
2186
2187 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
2188 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
2189 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
2190 triPointsTypeDir2);
2191 Nektar::LibUtilities::BasisType basisTypeDir2 =
2193 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
2194 triPointsKeyDir2);
2195
2196 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
2197 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2198 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
2199 triPointsTypeDir3);
2200 Nektar::LibUtilities::BasisType basisTypeDir3 =
2202 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
2203 triPointsKeyDir3);
2204
2207 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
2208
2209 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
2210 CollExp.push_back(Exp);
2211
2213 Collections::CollectionOptimisation colOpt(dummySession, 2,
2215 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2216 // ... only one op at the time ...
2218 Collections::Collection c(CollExp, impTypes);
2220
2221 const int nq = Exp->GetTotPoints();
2222 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
2223 Array<OneD, NekDouble> phys(nq), tmp, tmp1, tmp2;
2224 Array<OneD, NekDouble> diffRef(3 * nq);
2225 Array<OneD, NekDouble> diff(3 * nq);
2226
2227 Exp->GetCoords(xc, yc, zc);
2228
2229 for (int i = 0; i < nq; ++i)
2230 {
2231 phys[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
2232 }
2233
2234 Exp->PhysDeriv(phys, diffRef, tmp = diffRef + nq, tmp1 = diffRef + 2 * nq);
2235 c.ApplyOperator(Collections::ePhysDeriv, phys, diff, tmp = diff + nq,
2236 tmp2 = diff + 2 * nq);
2237
2238 double epsilon = 1.0e-8;
2239 for (int i = 0; i < diffRef.size(); ++i)
2240 {
2241 BOOST_CHECK_CLOSE(diffRef[i], diff[i], epsilon);
2242 }
2243}
2244
2245BOOST_AUTO_TEST_CASE(TestTetIProductWRTDerivBase_IterPerExp_UniformP)
2246{
2248 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
2250 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2252 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
2254 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
2255
2256 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
2257 v2.get(), v3.get()};
2258 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
2259 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
2260 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
2261
2262 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
2264 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
2265 triPointsTypeDir1);
2266 Nektar::LibUtilities::BasisType basisTypeDir1 =
2268 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
2269 triPointsKeyDir1);
2270
2271 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
2272 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
2273 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(4,
2274 triPointsTypeDir2);
2275 Nektar::LibUtilities::BasisType basisTypeDir2 =
2277 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
2278 triPointsKeyDir2);
2279
2280 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
2281 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2282 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(4,
2283 triPointsTypeDir3);
2284 Nektar::LibUtilities::BasisType basisTypeDir3 =
2286 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
2287 triPointsKeyDir3);
2288
2291 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
2292
2293 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
2294 CollExp.push_back(Exp);
2295
2297 Collections::CollectionOptimisation colOpt(dummySession, 3,
2299 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2300 Collections::Collection c(CollExp, impTypes);
2302
2303 const int nq = Exp->GetTotPoints();
2304 const int nm = Exp->GetNcoeffs();
2305 Array<OneD, NekDouble> phys1(nq);
2306 Array<OneD, NekDouble> phys2(nq);
2307 Array<OneD, NekDouble> phys3(nq);
2308 Array<OneD, NekDouble> coeffs1(nm);
2309 Array<OneD, NekDouble> coeffs2(nm);
2310
2311 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
2312
2313 Exp->GetCoords(xc, yc, zc);
2314
2315 for (int i = 0; i < nq; ++i)
2316 {
2317 phys1[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
2318 phys2[i] = cos(xc[i]) * sin(yc[i]) * cos(zc[i]);
2319 phys3[i] = cos(xc[i]) * sin(yc[i]) * sin(zc[i]);
2320 }
2321
2322 // Standard routines
2323 Exp->IProductWRTDerivBase(0, phys1, coeffs1);
2324 Exp->IProductWRTDerivBase(1, phys2, coeffs2);
2325 Vmath::Vadd(nm, coeffs1, 1, coeffs2, 1, coeffs1, 1);
2326 Exp->IProductWRTDerivBase(2, phys3, coeffs2);
2327 Vmath::Vadd(nm, coeffs1, 1, coeffs2, 1, coeffs1, 1);
2328
2330 coeffs2);
2331
2332 double epsilon = 1.0e-8;
2333 for (int i = 0; i < coeffs1.size(); ++i)
2334 {
2335 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
2336 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
2337 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
2338 }
2339}
2340
2341BOOST_AUTO_TEST_CASE(TestTetIProductWRTDerivBase_IterPerExp_VariableP_MultiElmt)
2342{
2344 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
2346 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2348 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
2350 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
2351
2352 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
2353 v2.get(), v3.get()};
2354 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
2355 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
2356 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
2357
2358 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
2360 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
2361 triPointsTypeDir1);
2362 Nektar::LibUtilities::BasisType basisTypeDir1 =
2364 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
2365 triPointsKeyDir1);
2366
2367 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
2368 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
2369 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(6,
2370 triPointsTypeDir2);
2371 Nektar::LibUtilities::BasisType basisTypeDir2 =
2373 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
2374 triPointsKeyDir2);
2375 // const Nektar::LibUtilities::BasisKey
2376 // basisKeyDir2(basisTypeDir2,5,triPointsKeyDir2);
2377
2378 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
2379 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2380 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(9,
2381 triPointsTypeDir3);
2382 Nektar::LibUtilities::BasisType basisTypeDir3 =
2384 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
2385 triPointsKeyDir3);
2386
2389 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
2390
2391 int nelmts = 1;
2392
2393 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
2394 for (int i = 0; i < nelmts; ++i)
2395 {
2396 CollExp.push_back(Exp);
2397 }
2398
2400 Collections::CollectionOptimisation colOpt(dummySession, 3,
2402 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2403 Collections::Collection c(CollExp, impTypes);
2405
2406 const int nq = Exp->GetTotPoints();
2407 const int nm = Exp->GetNcoeffs();
2408 Array<OneD, NekDouble> phys1(nelmts * nq), tmp;
2409 Array<OneD, NekDouble> phys2(nelmts * nq);
2410 Array<OneD, NekDouble> phys3(nelmts * nq);
2411 Array<OneD, NekDouble> coeffs1(nelmts * nm);
2412 Array<OneD, NekDouble> coeffs2(nelmts * nm);
2413
2414 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
2415
2416 Exp->GetCoords(xc, yc, zc);
2417
2418 for (int i = 0; i < nq; ++i)
2419 {
2420 phys1[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
2421 phys2[i] = cos(xc[i]) * sin(yc[i]) * cos(zc[i]);
2422 phys3[i] = cos(xc[i]) * sin(yc[i]) * sin(zc[i]);
2423 }
2424 for (int i = 1; i < nelmts; ++i)
2425 {
2426 Vmath::Vcopy(nq, phys1, 1, tmp = phys1 + i * nq, 1);
2427 Vmath::Vcopy(nq, phys2, 1, tmp = phys2 + i * nq, 1);
2428 Vmath::Vcopy(nq, phys3, 1, tmp = phys3 + i * nq, 1);
2429 }
2430
2431 // Standard routines
2432 for (int i = 0; i < nelmts; ++i)
2433 {
2434 Exp->IProductWRTDerivBase(0, phys1 + i * nq, tmp = coeffs1 + i * nm);
2435 Exp->IProductWRTDerivBase(1, phys2 + i * nq, tmp = coeffs2 + i * nm);
2436 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
2437 tmp = coeffs1 + i * nm, 1);
2438 Exp->IProductWRTDerivBase(2, phys3 + i * nq, tmp = coeffs2 + i * nm);
2439 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
2440 tmp = coeffs1 + i * nm, 1);
2441 }
2442
2444 coeffs2);
2445
2446 double epsilon = 1.0e-8;
2447 for (int i = 0; i < coeffs1.size(); ++i)
2448 {
2449 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
2450 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
2451 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
2452 }
2453}
2454
2455BOOST_AUTO_TEST_CASE(TestTetIProductWRTDerivBase_StdMat_UniformP)
2456{
2458 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
2460 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2462 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
2464 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
2465
2466 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
2467 v2.get(), v3.get()};
2468 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
2469 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
2470 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
2471
2472 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
2474 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
2475 triPointsTypeDir1);
2476 Nektar::LibUtilities::BasisType basisTypeDir1 =
2478 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
2479 triPointsKeyDir1);
2480
2481 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
2482 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
2483 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(4,
2484 triPointsTypeDir2);
2485 Nektar::LibUtilities::BasisType basisTypeDir2 =
2487 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
2488 triPointsKeyDir2);
2489
2490 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
2491 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2492 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(4,
2493 triPointsTypeDir3);
2494 Nektar::LibUtilities::BasisType basisTypeDir3 =
2496 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
2497 triPointsKeyDir3);
2498
2501 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
2502
2503 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
2504 CollExp.push_back(Exp);
2505
2507 Collections::CollectionOptimisation colOpt(dummySession, 3,
2509 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2510 Collections::Collection c(CollExp, impTypes);
2512
2513 const int nq = Exp->GetTotPoints();
2514 const int nm = Exp->GetNcoeffs();
2515 Array<OneD, NekDouble> phys1(nq);
2516 Array<OneD, NekDouble> phys2(nq);
2517 Array<OneD, NekDouble> phys3(nq);
2518 Array<OneD, NekDouble> coeffs1(nm);
2519 Array<OneD, NekDouble> coeffs2(nm);
2520
2521 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
2522
2523 Exp->GetCoords(xc, yc, zc);
2524
2525 for (int i = 0; i < nq; ++i)
2526 {
2527 phys1[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
2528 phys2[i] = cos(xc[i]) * sin(yc[i]) * cos(zc[i]);
2529 phys3[i] = cos(xc[i]) * sin(yc[i]) * sin(zc[i]);
2530 }
2531
2532 // Standard routines
2533 Exp->IProductWRTDerivBase(0, phys1, coeffs1);
2534 Exp->IProductWRTDerivBase(1, phys2, coeffs2);
2535 Vmath::Vadd(nm, coeffs1, 1, coeffs2, 1, coeffs1, 1);
2536 Exp->IProductWRTDerivBase(2, phys3, coeffs2);
2537 Vmath::Vadd(nm, coeffs1, 1, coeffs2, 1, coeffs1, 1);
2538
2540 coeffs2);
2541
2542 double epsilon = 1.0e-8;
2543 for (int i = 0; i < coeffs1.size(); ++i)
2544 {
2545 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
2546 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
2547 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
2548 }
2549}
2550
2551BOOST_AUTO_TEST_CASE(TestTetIProductWRTDerivBase_StdMat_VariableP_MultiElmt)
2552{
2554 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
2556 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2558 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
2560 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
2561
2562 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
2563 v2.get(), v3.get()};
2564 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
2565 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
2566 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
2567
2568 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
2570 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
2571 triPointsTypeDir1);
2572 Nektar::LibUtilities::BasisType basisTypeDir1 =
2574 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
2575 triPointsKeyDir1);
2576
2577 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
2578 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
2579 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(6,
2580 triPointsTypeDir2);
2581 Nektar::LibUtilities::BasisType basisTypeDir2 =
2583 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
2584 triPointsKeyDir2);
2585 // const Nektar::LibUtilities::BasisKey
2586 // basisKeyDir2(basisTypeDir2,5,triPointsKeyDir2);
2587
2588 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
2589 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2590 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(9,
2591 triPointsTypeDir3);
2592 Nektar::LibUtilities::BasisType basisTypeDir3 =
2594 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
2595 triPointsKeyDir3);
2596
2599 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
2600
2601 int nelmts = 1;
2602
2603 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
2604 for (int i = 0; i < nelmts; ++i)
2605 {
2606 CollExp.push_back(Exp);
2607 }
2608
2610 Collections::CollectionOptimisation colOpt(dummySession, 3,
2612 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2613 Collections::Collection c(CollExp, impTypes);
2615
2616 const int nq = Exp->GetTotPoints();
2617 const int nm = Exp->GetNcoeffs();
2618 Array<OneD, NekDouble> phys1(nelmts * nq), tmp;
2619 Array<OneD, NekDouble> phys2(nelmts * nq);
2620 Array<OneD, NekDouble> phys3(nelmts * nq);
2621 Array<OneD, NekDouble> coeffs1(nelmts * nm);
2622 Array<OneD, NekDouble> coeffs2(nelmts * nm);
2623
2624 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
2625
2626 Exp->GetCoords(xc, yc, zc);
2627
2628 for (int i = 0; i < nq; ++i)
2629 {
2630 phys1[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
2631 phys2[i] = cos(xc[i]) * sin(yc[i]) * cos(zc[i]);
2632 phys3[i] = cos(xc[i]) * sin(yc[i]) * sin(zc[i]);
2633 }
2634 for (int i = 1; i < nelmts; ++i)
2635 {
2636 Vmath::Vcopy(nq, phys1, 1, tmp = phys1 + i * nq, 1);
2637 Vmath::Vcopy(nq, phys2, 1, tmp = phys2 + i * nq, 1);
2638 Vmath::Vcopy(nq, phys3, 1, tmp = phys3 + i * nq, 1);
2639 }
2640
2641 // Standard routines
2642 for (int i = 0; i < nelmts; ++i)
2643 {
2644 Exp->IProductWRTDerivBase(0, phys1 + i * nq, tmp = coeffs1 + i * nm);
2645 Exp->IProductWRTDerivBase(1, phys2 + i * nq, tmp = coeffs2 + i * nm);
2646 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
2647 tmp = coeffs1 + i * nm, 1);
2648 Exp->IProductWRTDerivBase(2, phys3 + i * nq, tmp = coeffs2 + i * nm);
2649 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
2650 tmp = coeffs1 + i * nm, 1);
2651 }
2652
2654 coeffs2);
2655
2656 double epsilon = 1.0e-8;
2657 for (int i = 0; i < coeffs1.size(); ++i)
2658 {
2659 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
2660 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
2661 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
2662 }
2663}
2664
2665BOOST_AUTO_TEST_CASE(TestTetIProductWRTDerivBase_SumFac_UniformP)
2666{
2668 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
2670 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2672 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
2674 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
2675
2676 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
2677 v2.get(), v3.get()};
2678 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
2679 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
2680 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
2681
2682 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
2684 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
2685 triPointsTypeDir1);
2686 Nektar::LibUtilities::BasisType basisTypeDir1 =
2688 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
2689 triPointsKeyDir1);
2690
2691 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
2692 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
2693 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(4,
2694 triPointsTypeDir2);
2695 Nektar::LibUtilities::BasisType basisTypeDir2 =
2697 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
2698 triPointsKeyDir2);
2699
2700 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
2701 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2702 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(4,
2703 triPointsTypeDir3);
2704 Nektar::LibUtilities::BasisType basisTypeDir3 =
2706 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 4,
2707 triPointsKeyDir3);
2708
2711 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
2712
2713 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
2714 CollExp.push_back(Exp);
2715
2717 Collections::CollectionOptimisation colOpt(dummySession, 3,
2719 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2720 Collections::Collection c(CollExp, impTypes);
2722
2723 const int nq = Exp->GetTotPoints();
2724 const int nm = Exp->GetNcoeffs();
2725 Array<OneD, NekDouble> phys1(nq);
2726 Array<OneD, NekDouble> phys2(nq);
2727 Array<OneD, NekDouble> phys3(nq);
2728 Array<OneD, NekDouble> coeffs1(nm);
2729 Array<OneD, NekDouble> coeffs2(nm);
2730
2731 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
2732
2733 Exp->GetCoords(xc, yc, zc);
2734
2735 for (int i = 0; i < nq; ++i)
2736 {
2737 phys1[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
2738 phys2[i] = cos(xc[i]) * sin(yc[i]) * cos(zc[i]);
2739 phys3[i] = cos(xc[i]) * sin(yc[i]) * sin(zc[i]);
2740 }
2741
2742 // Standard routines
2743 Exp->IProductWRTDerivBase(0, phys1, coeffs1);
2744 Exp->IProductWRTDerivBase(1, phys2, coeffs2);
2745 Vmath::Vadd(nm, coeffs1, 1, coeffs2, 1, coeffs1, 1);
2746 Exp->IProductWRTDerivBase(2, phys3, coeffs2);
2747 Vmath::Vadd(nm, coeffs1, 1, coeffs2, 1, coeffs1, 1);
2748
2750 coeffs2);
2751
2752 double epsilon = 1.0e-7;
2753 for (int i = 0; i < coeffs1.size(); ++i)
2754 {
2755 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
2756 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
2757 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
2758 }
2759}
2760
2761BOOST_AUTO_TEST_CASE(TestTetIProductWRTDerivBase_SumFac_VariableP_MultiElmt)
2762{
2764 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
2766 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2768 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
2770 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
2771
2772 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
2773 v2.get(), v3.get()};
2774 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
2775 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
2776 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
2777
2778 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
2780 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(5,
2781 triPointsTypeDir1);
2782 Nektar::LibUtilities::BasisType basisTypeDir1 =
2784 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, 4,
2785 triPointsKeyDir1);
2786
2787 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
2788 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
2789 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(6,
2790 triPointsTypeDir2);
2791 Nektar::LibUtilities::BasisType basisTypeDir2 =
2793 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, 4,
2794 triPointsKeyDir2);
2795 // const Nektar::LibUtilities::BasisKey
2796 // basisKeyDir2(basisTypeDir2,5,triPointsKeyDir2);
2797
2798 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
2799 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2800 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(9,
2801 triPointsTypeDir3);
2802 Nektar::LibUtilities::BasisType basisTypeDir3 =
2804 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, 8,
2805 triPointsKeyDir3);
2806
2809 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
2810
2811 int nelmts = 1;
2812
2813 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
2814 for (int i = 0; i < nelmts; ++i)
2815 {
2816 CollExp.push_back(Exp);
2817 }
2818
2820 Collections::CollectionOptimisation colOpt(dummySession, 3,
2822 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
2823 Collections::Collection c(CollExp, impTypes);
2825
2826 const int nq = Exp->GetTotPoints();
2827 const int nm = Exp->GetNcoeffs();
2828 Array<OneD, NekDouble> phys1(nelmts * nq), tmp;
2829 Array<OneD, NekDouble> phys2(nelmts * nq);
2830 Array<OneD, NekDouble> phys3(nelmts * nq);
2831 Array<OneD, NekDouble> coeffs1(nelmts * nm);
2832 Array<OneD, NekDouble> coeffs2(nelmts * nm);
2833
2834 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
2835
2836 Exp->GetCoords(xc, yc, zc);
2837
2838 for (int i = 0; i < nq; ++i)
2839 {
2840 phys1[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
2841 phys2[i] = cos(xc[i]) * sin(yc[i]) * cos(zc[i]);
2842 phys3[i] = cos(xc[i]) * sin(yc[i]) * sin(zc[i]);
2843 }
2844 for (int i = 1; i < nelmts; ++i)
2845 {
2846 Vmath::Vcopy(nq, phys1, 1, tmp = phys1 + i * nq, 1);
2847 Vmath::Vcopy(nq, phys2, 1, tmp = phys2 + i * nq, 1);
2848 Vmath::Vcopy(nq, phys3, 1, tmp = phys3 + i * nq, 1);
2849 }
2850
2851 // Standard routines
2852 for (int i = 0; i < nelmts; ++i)
2853 {
2854 Exp->IProductWRTDerivBase(0, phys1 + i * nq, tmp = coeffs1 + i * nm);
2855 Exp->IProductWRTDerivBase(1, phys2 + i * nq, tmp = coeffs2 + i * nm);
2856 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
2857 tmp = coeffs1 + i * nm, 1);
2858 Exp->IProductWRTDerivBase(2, phys3 + i * nq, tmp = coeffs2 + i * nm);
2859 Vmath::Vadd(nm, coeffs1 + i * nm, 1, coeffs2 + i * nm, 1,
2860 tmp = coeffs1 + i * nm, 1);
2861 }
2862
2864 coeffs2);
2865
2866 double epsilon = 1.0e-7;
2867 for (int i = 0; i < coeffs1.size(); ++i)
2868 {
2869 coeffs1[i] = (fabs(coeffs1[i]) < 1e-14) ? 0.0 : coeffs1[i];
2870 coeffs2[i] = (fabs(coeffs2[i]) < 1e-14) ? 0.0 : coeffs2[i];
2871 BOOST_CHECK_CLOSE(coeffs1[i], coeffs2[i], epsilon);
2872 }
2873}
2874
2875BOOST_AUTO_TEST_CASE(TestTetmHelmholtz_IterPerExp_UniformP_ConstVarDiff)
2876{
2878 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
2880 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2882 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
2884 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
2885
2886 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
2887 v2.get(), v3.get()};
2888 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
2889 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
2890 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
2891
2892 unsigned int numQuadPoints = 5;
2893 unsigned int numModes = 4;
2894
2895 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
2897 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
2898 triPointsTypeDir1);
2899 Nektar::LibUtilities::BasisType basisTypeDir1 =
2901 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
2902 triPointsKeyDir1);
2903
2904 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
2905 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
2906 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
2907 triPointsTypeDir2);
2908 Nektar::LibUtilities::BasisType basisTypeDir2 =
2910 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
2911 triPointsKeyDir2);
2912
2913 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
2914 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
2915 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
2916 triPointsTypeDir3);
2917 Nektar::LibUtilities::BasisType basisTypeDir3 =
2919 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
2920 triPointsKeyDir3);
2921
2924 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
2925
2928 basisKeyDir1, basisKeyDir2, basisKeyDir3);
2929
2930 int nelmts = 10;
2931
2932 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
2933 for (int i = 0; i < nelmts; ++i)
2934 {
2935 CollExp.push_back(Exp);
2936 }
2937
2939 Collections::CollectionOptimisation colOpt(dummySession, 2,
2941 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(stdExp);
2942 Collections::Collection c(CollExp, impTypes);
2944 factors[StdRegions::eFactorLambda] = 0.0;
2945 factors[StdRegions::eFactorCoeffD00] = 1.25;
2946 factors[StdRegions::eFactorCoeffD01] = 0.25;
2947 factors[StdRegions::eFactorCoeffD11] = 1.25;
2948 factors[StdRegions::eFactorCoeffD02] = 0.25;
2949 factors[StdRegions::eFactorCoeffD12] = 0.25;
2950 factors[StdRegions::eFactorCoeffD22] = 1.25;
2951
2953
2954 const int nm = Exp->GetNcoeffs();
2955 Array<OneD, NekDouble> coeffsIn(nelmts * nm);
2956 Array<OneD, NekDouble> coeffsRef(nelmts * nm);
2957 Array<OneD, NekDouble> coeffs(nelmts * nm), tmp;
2958
2959 for (int i = 0; i < nm; ++i)
2960 {
2961 coeffsIn[i] = 1.0 + i;
2962 }
2963
2964 for (int i = 1; i < nelmts; ++i)
2965 {
2966 Vmath::Vcopy(nm, coeffsIn, 1, tmp = coeffsIn + i * nm, 1);
2967 }
2968
2969 StdRegions::StdMatrixKey mkey(StdRegions::eHelmholtz, Exp->DetShapeType(),
2970 *Exp, factors);
2971
2972 for (int i = 0; i < nelmts; ++i)
2973 {
2974 // Standard routines
2975 Exp->GeneralMatrixOp(coeffsIn + i * nm, tmp = coeffsRef + i * nm, mkey);
2976 }
2977
2978 c.ApplyOperator(Collections::eHelmholtz, coeffsIn, coeffs);
2979
2980 double epsilon = 1.0e-8;
2981 for (int i = 0; i < coeffsRef.size(); ++i)
2982 {
2983 coeffsRef[i] = (std::abs(coeffsRef[i]) < 1e-14) ? 0.0 : coeffsRef[i];
2984 coeffs[i] = (std::abs(coeffs[i]) < 1e-14) ? 0.0 : coeffs[i];
2985 BOOST_CHECK_CLOSE(coeffsRef[i], coeffs[i], epsilon);
2986 }
2987}
2988
2989BOOST_AUTO_TEST_CASE(TestTetmHelmholtz_MatrixFree_UniformP)
2990{
2992 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
2994 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
2996 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
2998 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
2999
3000 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
3001 v2.get(), v3.get()};
3002 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
3003 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
3004 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
3005
3006 unsigned int numQuadPoints = 5;
3007 unsigned int numModes = 4;
3008
3009 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
3011 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
3012 triPointsTypeDir1);
3013 Nektar::LibUtilities::BasisType basisTypeDir1 =
3015 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
3016 triPointsKeyDir1);
3017
3018 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
3019 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
3020 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
3021 triPointsTypeDir2);
3022 Nektar::LibUtilities::BasisType basisTypeDir2 =
3024 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
3025 triPointsKeyDir2);
3026
3027 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
3028 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
3029 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
3030 triPointsTypeDir3);
3031 Nektar::LibUtilities::BasisType basisTypeDir3 =
3033 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
3034 triPointsKeyDir3);
3035
3038 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
3039
3042 basisKeyDir1, basisKeyDir2, basisKeyDir3);
3043
3044 int nelmts = 10;
3045
3046 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
3047 for (int i = 0; i < nelmts; ++i)
3048 {
3049 CollExp.push_back(Exp);
3050 }
3051
3053 Collections::CollectionOptimisation colOpt(dummySession, 2,
3055 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(stdExp);
3056 Collections::Collection c(CollExp, impTypes);
3058 factors[StdRegions::eFactorLambda] = 0.0;
3059
3061
3062 const int nm = Exp->GetNcoeffs();
3063 Array<OneD, NekDouble> coeffsIn(nelmts * nm);
3064 Array<OneD, NekDouble> coeffsRef(nelmts * nm);
3065 Array<OneD, NekDouble> coeffs(nelmts * nm), tmp;
3066
3067 for (int i = 0; i < nm; ++i)
3068 {
3069 coeffsIn[i] = 1.0 + i;
3070 }
3071
3072 for (int i = 1; i < nelmts; ++i)
3073 {
3074 Vmath::Vcopy(nm, coeffsIn, 1, tmp = coeffsIn + i * nm, 1);
3075 }
3076
3077 StdRegions::StdMatrixKey mkey(StdRegions::eHelmholtz, Exp->DetShapeType(),
3078 *Exp, factors);
3079
3080 for (int i = 0; i < nelmts; ++i)
3081 {
3082 // Standard routines
3083 Exp->GeneralMatrixOp(coeffsIn + i * nm, tmp = coeffsRef + i * nm, mkey);
3084 }
3085
3086 c.ApplyOperator(Collections::eHelmholtz, coeffsIn, coeffs);
3087
3088 double epsilon = 1.0e-8;
3089 for (int i = 0; i < coeffsRef.size(); ++i)
3090 {
3091 coeffsRef[i] = (std::abs(coeffsRef[i]) < 1e-14) ? 0.0 : coeffsRef[i];
3092 coeffs[i] = (std::abs(coeffs[i]) < 1e-14) ? 0.0 : coeffs[i];
3093 BOOST_CHECK_CLOSE(coeffsRef[i], coeffs[i], epsilon);
3094 }
3095}
3096
3097BOOST_AUTO_TEST_CASE(TestTetmHelmholtz_MatrixFree_Deformed_OverInt)
3098{
3100 new SpatialDomains::PointGeom(3u, 0u, -2.0, -3.0, -4.0));
3102 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
3104 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
3106 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
3107
3108 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
3109 v2.get(), v3.get()};
3110 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
3111 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
3112 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
3113
3114 unsigned int numQuadPoints = 8;
3115 unsigned int numModes = 4;
3116
3117 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
3119 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
3120 triPointsTypeDir1);
3121 Nektar::LibUtilities::BasisType basisTypeDir1 =
3123 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
3124 triPointsKeyDir1);
3125
3126 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
3127 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
3128 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
3129 triPointsTypeDir2);
3130 Nektar::LibUtilities::BasisType basisTypeDir2 =
3132 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
3133 triPointsKeyDir2);
3134
3135 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
3136 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
3137 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
3138 triPointsTypeDir3);
3139 Nektar::LibUtilities::BasisType basisTypeDir3 =
3141 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
3142 triPointsKeyDir3);
3143
3146 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
3147
3150 basisKeyDir1, basisKeyDir2, basisKeyDir3);
3151
3152 int nelmts = 10;
3153
3154 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
3155 for (int i = 0; i < nelmts; ++i)
3156 {
3157 CollExp.push_back(Exp);
3158 }
3159
3161 Collections::CollectionOptimisation colOpt(dummySession, 2,
3163 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(stdExp);
3164 Collections::Collection c(CollExp, impTypes);
3166 factors[StdRegions::eFactorLambda] = 0.0;
3167
3169
3170 const int nm = Exp->GetNcoeffs();
3171 Array<OneD, NekDouble> coeffsIn(nelmts * nm);
3172 Array<OneD, NekDouble> coeffsRef(nelmts * nm);
3173 Array<OneD, NekDouble> coeffs(nelmts * nm), tmp;
3174
3175 for (int i = 0; i < nm; ++i)
3176 {
3177 coeffsIn[i] = 1.0 + i;
3178 }
3179
3180 for (int i = 1; i < nelmts; ++i)
3181 {
3182 Vmath::Vcopy(nm, coeffsIn, 1, tmp = coeffsIn + i * nm, 1);
3183 }
3184
3185 StdRegions::StdMatrixKey mkey(StdRegions::eHelmholtz, Exp->DetShapeType(),
3186 *Exp, factors);
3187
3188 for (int i = 0; i < nelmts; ++i)
3189 {
3190 // Standard routines
3191 Exp->GeneralMatrixOp(coeffsIn + i * nm, tmp = coeffsRef + i * nm, mkey);
3192 }
3193
3194 c.ApplyOperator(Collections::eHelmholtz, coeffsIn, coeffs);
3195
3196 double epsilon = 1.0e-8;
3197 for (int i = 0; i < coeffsRef.size(); ++i)
3198 {
3199 coeffsRef[i] = (std::abs(coeffsRef[i]) < 1e-14) ? 0.0 : coeffsRef[i];
3200 coeffs[i] = (std::abs(coeffs[i]) < 1e-14) ? 0.0 : coeffs[i];
3201 BOOST_CHECK_CLOSE(coeffsRef[i], coeffs[i], epsilon);
3202 }
3203}
3204
3205BOOST_AUTO_TEST_CASE(TestTetIProductWRTDerivBase_MatrixFree_UniformP_Undeformed)
3206{
3208 new SpatialDomains::PointGeom(3u, 0u, -2.0, -3.0, -4.0));
3210 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
3212 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
3214 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
3215
3216 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
3217 v2.get(), v3.get()};
3218 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
3219 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
3220 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
3221
3222 unsigned int numQuadPoints = 5;
3223 unsigned int numModes = 4;
3224
3225 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
3227 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
3228 triPointsTypeDir1);
3229 Nektar::LibUtilities::BasisType basisTypeDir1 =
3231 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
3232 triPointsKeyDir1);
3233
3234 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
3235 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
3236 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
3237 triPointsTypeDir2);
3238 Nektar::LibUtilities::BasisType basisTypeDir2 =
3240 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
3241 triPointsKeyDir2);
3242
3243 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
3244 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
3245 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
3246 triPointsTypeDir3);
3247 Nektar::LibUtilities::BasisType basisTypeDir3 =
3249 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
3250 triPointsKeyDir3);
3251
3254 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
3255
3256 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
3257 CollExp.push_back(Exp);
3258
3260 Collections::CollectionOptimisation colOpt(dummySession, 2,
3262 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
3263 // ... only one op at the time ...
3265 Collections::Collection c(CollExp, impTypes);
3267
3268 const int nq = Exp->GetTotPoints();
3269 const int nm = Exp->GetNcoeffs();
3270 Array<OneD, NekDouble> phys1(nq);
3271 Array<OneD, NekDouble> phys2(nq);
3272 Array<OneD, NekDouble> phys3(nq);
3273 Array<OneD, NekDouble> coeffsRef(nm);
3274 Array<OneD, NekDouble> coeffs(nm);
3275
3276 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
3277
3278 Exp->GetCoords(xc, yc, zc);
3279
3280 for (int i = 0; i < nq; ++i)
3281 {
3282 phys1[i] = sin(xc[i]) * cos(yc[i]) * sin(zc[i]);
3283 phys2[i] = cos(xc[i]) * sin(yc[i]) * cos(zc[i]);
3284 phys3[i] = cos(xc[i]) * sin(yc[i]) * sin(zc[i]);
3285 }
3286
3287 // Standard routines
3288 Exp->IProductWRTDerivBase(0, phys1, coeffsRef);
3289 Exp->IProductWRTDerivBase(1, phys2, coeffs);
3290 Vmath::Vadd(nm, coeffsRef, 1, coeffs, 1, coeffsRef, 1);
3291 Exp->IProductWRTDerivBase(2, phys3, coeffs);
3292 Vmath::Vadd(nm, coeffsRef, 1, coeffs, 1, coeffsRef, 1);
3293
3295 coeffs);
3296
3297 double epsilon = 1.0e-7;
3298 for (int i = 0; i < coeffsRef.size(); ++i)
3299 {
3300 coeffsRef[i] = (std::abs(coeffsRef[i]) < 1e-14) ? 0.0 : coeffsRef[i];
3301 coeffs[i] = (std::abs(coeffs[i]) < 1e-14) ? 0.0 : coeffs[i];
3302 BOOST_CHECK_CLOSE(coeffsRef[i], coeffs[i], epsilon);
3303 }
3304}
3305
3306BOOST_AUTO_TEST_CASE(TestTetmHelmholtz_MatrixFree_UniformP_ConstVarDiff)
3307{
3309 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
3311 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
3313 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
3315 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
3316
3317 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
3318 v2.get(), v3.get()};
3319 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
3320 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
3321 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
3322
3323 unsigned int numQuadPoints = 5;
3324 unsigned int numModes = 4;
3325
3326 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
3328 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
3329 triPointsTypeDir1);
3330 Nektar::LibUtilities::BasisType basisTypeDir1 =
3332 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
3333 triPointsKeyDir1);
3334
3335 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
3336 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
3337 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
3338 triPointsTypeDir2);
3339 Nektar::LibUtilities::BasisType basisTypeDir2 =
3341 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
3342 triPointsKeyDir2);
3343
3344 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
3345 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
3346 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
3347 triPointsTypeDir3);
3348 Nektar::LibUtilities::BasisType basisTypeDir3 =
3350 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
3351 triPointsKeyDir3);
3352
3355 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
3356
3359 basisKeyDir1, basisKeyDir2, basisKeyDir3);
3360
3361 int nelmts = 10;
3362
3363 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
3364 for (int i = 0; i < nelmts; ++i)
3365 {
3366 CollExp.push_back(Exp);
3367 }
3368
3370 Collections::CollectionOptimisation colOpt(dummySession, 2,
3372 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(stdExp);
3373 Collections::Collection c(CollExp, impTypes);
3375 factors[StdRegions::eFactorLambda] = 0.0;
3376 factors[StdRegions::eFactorCoeffD00] = 1.25;
3377 factors[StdRegions::eFactorCoeffD01] = 0.25;
3378 factors[StdRegions::eFactorCoeffD11] = 1.25;
3379 factors[StdRegions::eFactorCoeffD02] = 0.25;
3380 factors[StdRegions::eFactorCoeffD12] = 0.25;
3381 factors[StdRegions::eFactorCoeffD22] = 1.25;
3382
3384
3385 const int nm = Exp->GetNcoeffs();
3386 Array<OneD, NekDouble> coeffsIn(nelmts * nm);
3387 Array<OneD, NekDouble> coeffsRef(nelmts * nm);
3388 Array<OneD, NekDouble> coeffs(nelmts * nm), tmp;
3389
3390 for (int i = 0; i < nm; ++i)
3391 {
3392 coeffsIn[i] = 1.0 + i;
3393 }
3394
3395 for (int i = 1; i < nelmts; ++i)
3396 {
3397 Vmath::Vcopy(nm, coeffsIn, 1, tmp = coeffsIn + i * nm, 1);
3398 }
3399
3400 StdRegions::StdMatrixKey mkey(StdRegions::eHelmholtz, Exp->DetShapeType(),
3401 *Exp, factors);
3402
3403 for (int i = 0; i < nelmts; ++i)
3404 {
3405 // Standard routines
3406 Exp->GeneralMatrixOp(coeffsIn + i * nm, tmp = coeffsRef + i * nm, mkey);
3407 }
3408
3409 c.ApplyOperator(Collections::eHelmholtz, coeffsIn, coeffs);
3410
3411 double epsilon = 1.0e-8;
3412 for (int i = 0; i < coeffsRef.size(); ++i)
3413 {
3414 coeffsRef[i] = (std::abs(coeffsRef[i]) < 1e-14) ? 0.0 : coeffsRef[i];
3415 coeffs[i] = (std::abs(coeffs[i]) < 1e-14) ? 0.0 : coeffs[i];
3416 BOOST_CHECK_CLOSE(coeffsRef[i], coeffs[i], epsilon);
3417 }
3418}
3419
3420BOOST_AUTO_TEST_CASE(TestTetPhysInterp1D_NoCollections_UniformP)
3421{
3422
3424 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
3426 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
3428 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
3430 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
3431
3432 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
3433 v2.get(), v3.get()};
3434 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
3435 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
3436 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
3437
3438 unsigned int numQuadPoints = 5;
3439 unsigned int numModes = 4;
3440
3441 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
3443 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
3444 triPointsTypeDir1);
3445 Nektar::LibUtilities::BasisType basisTypeDir1 =
3447 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
3448 triPointsKeyDir1);
3449
3450 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
3451 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
3452 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
3453 triPointsTypeDir2);
3454 Nektar::LibUtilities::BasisType basisTypeDir2 =
3456 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
3457 triPointsKeyDir2);
3458
3459 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
3460 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
3461 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
3462 triPointsTypeDir3);
3463 Nektar::LibUtilities::BasisType basisTypeDir3 =
3465 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
3466 triPointsKeyDir3);
3467
3470 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
3471
3472 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
3473 CollExp.push_back(Exp);
3474
3476 Collections::CollectionOptimisation colOpt(dummySession, 3,
3478 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
3479 Collections::Collection c(CollExp, impTypes);
3480
3482 factors[StdRegions::eFactorConst] = 1.5;
3484
3485 const int nq = Exp->GetTotPoints();
3486
3487 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
3488 Array<OneD, NekDouble> phys(nq);
3489
3490 Exp->GetCoords(xc, yc, zc);
3491
3492 for (int i = 0; i < nq; ++i)
3493 {
3494 phys[i] = pow(xc[i], 3) + pow(yc[i], 3) + pow(zc[i], 3);
3495 }
3496
3498 Array<OneD, NekDouble> xc1(nq1);
3499 Array<OneD, NekDouble> yc1(nq1);
3500 Array<OneD, NekDouble> zc1(nq1);
3501 Array<OneD, NekDouble> phys1(nq1);
3502
3507
3508 double epsilon = 1.0e-8;
3509 // since solution is a polynomial should be able to compare soln directly
3510 for (int i = 0; i < nq1; ++i)
3511 {
3512 NekDouble exact = pow(xc1[i], 3) + pow(yc1[i], 3) + pow(zc1[i], 3);
3513 phys1[i] = (fabs(phys1[i]) < 1e-14) ? 0.0 : phys1[i];
3514 exact = (fabs(exact) < 1e-14) ? 0.0 : exact;
3515 BOOST_CHECK_CLOSE(phys1[i], exact, epsilon);
3516 }
3517}
3518
3519BOOST_AUTO_TEST_CASE(TestTetPhysInterp1D_MatrixFree_UniformP)
3520{
3521
3523 new SpatialDomains::PointGeom(3u, 0u, -1.0, -1.0, -1.0));
3525 new SpatialDomains::PointGeom(3u, 1u, 1.0, -1.0, -1.0));
3527 new SpatialDomains::PointGeom(3u, 2u, -1.0, 1.0, -1.0));
3529 new SpatialDomains::PointGeom(3u, 3u, -1.0, -1.0, 1.0));
3530
3531 std::array<SpatialDomains::PointGeom *, 4> v = {v0.get(), v1.get(),
3532 v2.get(), v3.get()};
3533 std::array<SpatialDomains::SegGeomUniquePtr, 6> segVec;
3534 std::array<SpatialDomains::TriGeomUniquePtr, 4> faceVec;
3535 SpatialDomains::TetGeomUniquePtr tetGeom = CreateTet(v, segVec, faceVec);
3536
3537 unsigned int numQuadPoints = 5;
3538 unsigned int numModes = 4;
3539
3540 Nektar::LibUtilities::PointsType triPointsTypeDir1 =
3542 const Nektar::LibUtilities::PointsKey triPointsKeyDir1(numQuadPoints,
3543 triPointsTypeDir1);
3544 Nektar::LibUtilities::BasisType basisTypeDir1 =
3546 const Nektar::LibUtilities::BasisKey basisKeyDir1(basisTypeDir1, numModes,
3547 triPointsKeyDir1);
3548
3549 Nektar::LibUtilities::PointsType triPointsTypeDir2 =
3550 Nektar::LibUtilities::eGaussRadauMAlpha1Beta0;
3551 const Nektar::LibUtilities::PointsKey triPointsKeyDir2(numQuadPoints - 1,
3552 triPointsTypeDir2);
3553 Nektar::LibUtilities::BasisType basisTypeDir2 =
3555 const Nektar::LibUtilities::BasisKey basisKeyDir2(basisTypeDir2, numModes,
3556 triPointsKeyDir2);
3557
3558 Nektar::LibUtilities::PointsType triPointsTypeDir3 =
3559 Nektar::LibUtilities::eGaussRadauMAlpha2Beta0;
3560 const Nektar::LibUtilities::PointsKey triPointsKeyDir3(numQuadPoints - 1,
3561 triPointsTypeDir3);
3562 Nektar::LibUtilities::BasisType basisTypeDir3 =
3564 const Nektar::LibUtilities::BasisKey basisKeyDir3(basisTypeDir3, numModes,
3565 triPointsKeyDir3);
3566
3569 basisKeyDir1, basisKeyDir2, basisKeyDir3, tetGeom.get());
3570
3571 std::vector<StdRegions::StdExpansionSharedPtr> CollExp;
3572 CollExp.push_back(Exp);
3573
3575 Collections::CollectionOptimisation colOpt(dummySession, 3,
3577 Collections::OperatorImpMap impTypes = colOpt.GetOperatorImpMap(Exp);
3578 Collections::Collection c(CollExp, impTypes);
3579
3581 factors[StdRegions::eFactorConst] = 1.5;
3583
3584 const int nq = Exp->GetTotPoints();
3585
3586 Array<OneD, NekDouble> xc(nq), yc(nq), zc(nq);
3587 Array<OneD, NekDouble> phys(nq);
3588
3589 Exp->GetCoords(xc, yc, zc);
3590
3591 for (int i = 0; i < nq; ++i)
3592 {
3593 phys[i] = pow(xc[i], 3) + pow(yc[i], 3) + pow(zc[i], 3);
3594 }
3595
3597 Array<OneD, NekDouble> xc1(nq1);
3598 Array<OneD, NekDouble> yc1(nq1);
3599 Array<OneD, NekDouble> zc1(nq1);
3600 Array<OneD, NekDouble> phys1(nq1);
3601
3606
3607 double epsilon = 1.0e-8;
3608 // since solution is a polynomial should be able to compare soln directly
3609 for (int i = 0; i < nq1; ++i)
3610 {
3611 NekDouble exact = pow(xc1[i], 3) + pow(yc1[i], 3) + pow(zc1[i], 3);
3612 phys1[i] = (fabs(phys1[i]) < 1e-14) ? 0.0 : phys1[i];
3613 exact = (fabs(exact) < 1e-14) ? 0.0 : exact;
3614 BOOST_CHECK_CLOSE(phys1[i], exact, epsilon);
3615 }
3616}
3617} // namespace Nektar::TetCollectionTests
COLLECTIONS_EXPORT void Initialise(const OperatorType opType, StdRegions::FactorMap factors=StdRegions::NullFactorMap)
void ApplyOperator(const OperatorType &op, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &output)
Definition Collection.h:138
int GetOutputSize(const OperatorType &op, bool defaultOut=true)
Definition Collection.h:112
COLLECTIONS_EXPORT OperatorImpMap GetOperatorImpMap(StdRegions::StdExpansionSharedPtr pExp)
Get Operator Implementation Map from XMl or using default;.
Describes the specification for a Basis.
Definition Basis.h:45
Defines a specification for a set of points.
Definition Points.h:50
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
std::map< OperatorType, ImplementationType > OperatorImpMap
Definition Operator.h:131
std::shared_ptr< SessionReader > SessionReaderSharedPtr
@ eGaussLobattoLegendre
1D Gauss-Lobatto-Legendre quadrature points
Definition PointsType.h:51
@ 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:212
unique_ptr_objpool< SegGeom > SegGeomUniquePtr
Definition MeshGraph.h:98
unique_ptr_objpool< PointGeom > PointGeomUniquePtr
Definition MeshGraph.h:93
unique_ptr_objpool< TriGeom > TriGeomUniquePtr
Definition MeshGraph.h:99
unique_ptr_objpool< TetGeom > TetGeomUniquePtr
Definition MeshGraph.h:101
std::shared_ptr< StdTetExp > StdTetExpSharedPtr
Definition StdTetExp.h:224
std::map< ConstFactorType, NekDouble > ConstFactorMap
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