Nektar++
ExpListHomogeneous2D.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: ExpListHomogeneous2D.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: An ExpList which is homogeneous in 2-directions
32//
33///////////////////////////////////////////////////////////////////////////////
34
35#include <boost/core/ignore_unused.hpp>
36
37#include <LibUtilities/Foundations/ManagerAccess.h> // for PointsManager, etc
42
43using namespace std;
44
45namespace Nektar
46{
47namespace MultiRegions
48{
49// Forward declaration for typedefs
51 : ExpList(type), m_homogeneousBasis_y(LibUtilities::NullBasisSharedPtr),
52 m_homogeneousBasis_z(LibUtilities::NullBasisSharedPtr), m_lhom_y(1),
53 m_lhom_z(1), m_homogeneous2DBlockMat(
54 MemoryManager<Homo2DBlockMatrixMap>::AllocateSharedPtr())
55{
56}
57
59 const ExpansionType type,
61 const LibUtilities::BasisKey &HomoBasis_y,
62 const LibUtilities::BasisKey &HomoBasis_z, const NekDouble lhom_y,
63 const NekDouble lhom_z, const bool useFFT, const bool dealiasing)
64 : ExpList(type), m_useFFT(useFFT), m_lhom_y(lhom_y), m_lhom_z(lhom_z),
65 m_homogeneous2DBlockMat(
66 MemoryManager<Homo2DBlockMatrixMap>::AllocateSharedPtr()),
67 m_dealiasing(dealiasing)
68{
69 m_session = pSession;
70 m_comm = pSession->GetComm();
71
73 "Homogeneous Basis in y direction is a null basis");
75 "Homogeneous Basis in z direction is a null basis");
76
79
82 HomoBasis_y, HomoBasis_z, m_comm->GetColumnComm());
83
84 m_Ycomm = m_comm->GetColumnComm()->GetRowComm();
85 m_Zcomm = m_comm->GetColumnComm()->GetRowComm();
86
87 m_ny = m_homogeneousBasis_y->GetNumPoints() / m_Ycomm->GetSize();
88 m_nz = m_homogeneousBasis_z->GetNumPoints() / m_Zcomm->GetSize();
89
91
92 if (m_useFFT)
93 {
94 m_FFT_y =
96 m_FFT_z =
98 }
99
100 if (m_dealiasing)
101 {
102 ASSERTL0(m_comm->GetColumnComm()->GetSize() == 1,
103 "Remove dealiasing if you want to run in parallel");
105 }
106}
107
108/**
109 * @param In ExpListHomogeneous2D object to copy.
110 */
112 : ExpList(In, false), m_useFFT(In.m_useFFT), m_FFT_y(In.m_FFT_y),
113 m_FFT_z(In.m_FFT_z), m_transposition(In.m_transposition),
114 m_Ycomm(In.m_Ycomm), m_Zcomm(In.m_Ycomm),
115 m_homogeneousBasis_y(In.m_homogeneousBasis_y),
116 m_homogeneousBasis_z(In.m_homogeneousBasis_z), m_lhom_y(In.m_lhom_y),
117 m_lhom_z(In.m_lhom_z),
118 m_homogeneous2DBlockMat(In.m_homogeneous2DBlockMat), m_ny(In.m_ny),
119 m_nz(In.m_nz), m_dealiasing(In.m_dealiasing), m_padsize_y(In.m_padsize_y),
120 m_padsize_z(In.m_padsize_z), MatFwdPAD(In.MatFwdPAD),
121 MatBwdPAD(In.MatBwdPAD)
122{
124}
125
127 const ExpListHomogeneous2D &In, const std::vector<unsigned int> &eIDs)
128 : ExpList(In, eIDs, false), m_useFFT(In.m_useFFT), m_FFT_y(In.m_FFT_y),
129 m_FFT_z(In.m_FFT_z), m_transposition(In.m_transposition),
130 m_Ycomm(In.m_Ycomm), m_Zcomm(In.m_Ycomm),
131 m_homogeneousBasis_y(In.m_homogeneousBasis_y),
132 m_homogeneousBasis_z(In.m_homogeneousBasis_z), m_lhom_y(In.m_lhom_y),
133 m_lhom_z(In.m_lhom_z),
134 m_homogeneous2DBlockMat(
135 MemoryManager<Homo2DBlockMatrixMap>::AllocateSharedPtr()),
136 m_ny(In.m_ny), m_nz(In.m_nz), m_dealiasing(In.m_dealiasing),
137 m_padsize_y(In.m_padsize_y), m_padsize_z(In.m_padsize_z),
138 MatFwdPAD(In.MatFwdPAD), MatBwdPAD(In.MatBwdPAD)
139{
141}
142
143/**
144 * Destructor
145 */
147{
148}
149
151 const int npts, const Array<OneD, const NekDouble> &inarray,
152 Array<OneD, NekDouble> &outarray, bool Shuff, bool UnShuff)
153{
154 // Forwards trans
155 Homogeneous2DTrans(npts, inarray, outarray, true, Shuff, UnShuff);
156}
157
159 const int npts, const Array<OneD, const NekDouble> &inarray,
160 Array<OneD, NekDouble> &outarray, bool Shuff, bool UnShuff)
161{
162 // Backwards trans
163 Homogeneous2DTrans(npts, inarray, outarray, false, Shuff, UnShuff);
164}
165
167 const int npoints, const Array<OneD, NekDouble> &inarray1,
168 const Array<OneD, NekDouble> &inarray2, Array<OneD, NekDouble> &outarray)
169{
170 // int npoints = outarray.size(); // number of total physical points
171 int nlines =
172 m_lines.size(); // number of lines == number of Fourier modes = number
173 // of Fourier coeff = number of points per slab
174 int nslabs = npoints /
175 nlines; // number of slabs = numebr of physical points per line
176
177 Array<OneD, NekDouble> V1(npoints);
178 Array<OneD, NekDouble> V2(npoints);
179 Array<OneD, NekDouble> V1V2(npoints);
180 Array<OneD, NekDouble> ShufV1(npoints);
181 Array<OneD, NekDouble> ShufV2(npoints);
182 Array<OneD, NekDouble> ShufV1V2(npoints);
183
184 if (m_WaveSpace)
185 {
186 V1 = inarray1;
187 V2 = inarray2;
188 }
189 else
190 {
191 HomogeneousFwdTrans(npoints, inarray1, V1);
192 HomogeneousFwdTrans(npoints, inarray2, V2);
193 }
194
195 m_transposition->Transpose(npoints, V1, ShufV1, false,
197 m_transposition->Transpose(npoints, V2, ShufV2, false,
199
200 Array<OneD, NekDouble> PadV1_slab_coeff(m_padsize_y * m_padsize_z, 0.0);
201 Array<OneD, NekDouble> PadV2_slab_coeff(m_padsize_y * m_padsize_z, 0.0);
202 Array<OneD, NekDouble> PadRe_slab_coeff(m_padsize_y * m_padsize_z, 0.0);
203
204 Array<OneD, NekDouble> PadV1_slab_phys(m_padsize_y * m_padsize_z, 0.0);
205 Array<OneD, NekDouble> PadV2_slab_phys(m_padsize_y * m_padsize_z, 0.0);
206 Array<OneD, NekDouble> PadRe_slab_phys(m_padsize_y * m_padsize_z, 0.0);
207
208 NekVector<NekDouble> PadIN_V1(m_padsize_y * m_padsize_z, PadV1_slab_coeff,
209 eWrapper);
210 NekVector<NekDouble> PadOUT_V1(m_padsize_y * m_padsize_z, PadV1_slab_phys,
211 eWrapper);
212
213 NekVector<NekDouble> PadIN_V2(m_padsize_y * m_padsize_z, PadV2_slab_coeff,
214 eWrapper);
215 NekVector<NekDouble> PadOUT_V2(m_padsize_y * m_padsize_z, PadV2_slab_phys,
216 eWrapper);
217
218 NekVector<NekDouble> PadIN_Re(m_padsize_y * m_padsize_z, PadRe_slab_phys,
219 eWrapper);
220 NekVector<NekDouble> PadOUT_Re(m_padsize_y * m_padsize_z, PadRe_slab_coeff,
221 eWrapper);
222
223 // Looping on the slabs
224 for (int j = 0; j < nslabs; j++)
225 {
226 // Copying the j-th slab of size N*M into a bigger slab of lenght 2*N*M
227 // We are in Fourier space
228 for (int i = 0; i < m_nz; i++)
229 {
230 Vmath::Vcopy(m_ny, &(ShufV1[i * m_ny + j * nlines]), 1,
231 &(PadV1_slab_coeff[i * 2 * m_ny]), 1);
232 Vmath::Vcopy(m_ny, &(ShufV2[i * m_ny + j * nlines]), 1,
233 &(PadV2_slab_coeff[i * 2 * m_ny]), 1);
234 }
235
236 // Moving to physical space using the padded system
237 PadOUT_V1 = (*MatBwdPAD) * PadIN_V1;
238 PadOUT_V2 = (*MatBwdPAD) * PadIN_V2;
239
240 // Perfroming the vectors multiplication in physical
241 // space on the padded system
242 Vmath::Vmul(m_padsize_y * m_padsize_z, PadV1_slab_phys, 1,
243 PadV2_slab_phys, 1, PadRe_slab_phys, 1);
244
245 // Moving back the result (V1*V2)_phys in Fourier
246 // space, padded system
247 PadOUT_Re = (*MatFwdPAD) * PadIN_Re;
248
249 // Copying the first half of the padded pencil in the
250 // full vector (Fourier space)
251 for (int i = 0; i < m_nz; i++)
252 {
253 Vmath::Vcopy(m_ny, &(PadRe_slab_coeff[i * 2 * m_ny]), 1,
254 &(ShufV1V2[i * m_ny + j * nlines]), 1);
255 }
256 }
257
258 if (m_WaveSpace)
259 {
260 m_transposition->Transpose(npoints, ShufV1V2, outarray, false,
262 }
263 else
264 {
265 m_transposition->Transpose(npoints, ShufV1V2, V1V2, false,
267
268 // Moving the results in physical space for the output
269 HomogeneousBwdTrans(npoints, V1V2, outarray);
270 }
271}
272
274 const int npts, const Array<OneD, Array<OneD, NekDouble>> &inarray1,
275 const Array<OneD, Array<OneD, NekDouble>> &inarray2,
277{
278 // TODO Proper implementation of this
279 size_t ndim = inarray1.size();
280 ASSERTL1(inarray2.size() % ndim == 0,
281 "Wrong dimensions for DealiasedDotProd.");
282
283 size_t nvec = inarray2.size() % ndim;
284
285 Array<OneD, NekDouble> out(npts);
286 for (size_t i = 0; i < nvec; i++)
287 {
288 Vmath::Zero(npts, outarray[i], 1);
289 for (size_t j = 0; j < ndim; j++)
290 {
291 DealiasedProd(npts, inarray1[j], inarray2[i * ndim + j], out);
292 Vmath::Vadd(npts, outarray[i], 1, out, 1, outarray[i], 1);
293 }
294 }
295}
296
298 const Array<OneD, const NekDouble> &inarray,
299 Array<OneD, NekDouble> &outarray)
300{
301 size_t cnt = 0, cnt1 = 0;
302 Array<OneD, NekDouble> tmparray;
303 size_t nlines = m_lines.size();
304
305 for (size_t n = 0; n < nlines; ++n)
306 {
307 m_lines[n]->FwdTrans(inarray + cnt, tmparray = outarray + cnt1);
308 cnt += m_lines[n]->GetTotPoints();
309 cnt1 += m_lines[n]->GetNcoeffs();
310 }
311 if (!m_WaveSpace)
312 {
313 HomogeneousFwdTrans(cnt1, outarray, outarray);
314 }
315}
316
318 const Array<OneD, const NekDouble> &inarray,
319 Array<OneD, NekDouble> &outarray)
320{
321 size_t cnt = 0, cnt1 = 0;
322 Array<OneD, NekDouble> tmparray;
323 size_t nlines = m_lines.size();
324
325 for (size_t n = 0; n < nlines; ++n)
326 {
327 m_lines[n]->FwdTransLocalElmt(inarray + cnt,
328 tmparray = outarray + cnt1);
329
330 cnt += m_lines[n]->GetTotPoints();
331 cnt1 += m_lines[n]->GetNcoeffs();
332 }
333 if (!m_WaveSpace)
334 {
335 HomogeneousFwdTrans(cnt1, outarray, outarray);
336 }
337}
338
340 const Array<OneD, const NekDouble> &inarray,
341 Array<OneD, NekDouble> &outarray)
342{
343 int cnt = 0, cnt1 = 0;
344 Array<OneD, NekDouble> tmparray;
345 int nlines = m_lines.size();
346
347 for (int n = 0; n < nlines; ++n)
348 {
349 m_lines[n]->FwdTransBndConstrained(inarray + cnt,
350 tmparray = outarray + cnt1);
351
352 cnt += m_lines[n]->GetTotPoints();
353 cnt1 += m_lines[n]->GetNcoeffs();
354 }
355 if (!m_WaveSpace)
356 {
357 HomogeneousFwdTrans(cnt1, outarray, outarray);
358 }
359}
360
362 const Array<OneD, const NekDouble> &inarray,
363 Array<OneD, NekDouble> &outarray)
364{
365 size_t cnt = 0, cnt1 = 0;
366 Array<OneD, NekDouble> tmparray;
367 size_t nlines = m_lines.size();
368
369 for (size_t n = 0; n < nlines; ++n)
370 {
371 m_lines[n]->BwdTrans(inarray + cnt, tmparray = outarray + cnt1);
372 cnt += m_lines[n]->GetNcoeffs();
373 cnt1 += m_lines[n]->GetTotPoints();
374 }
375 if (!m_WaveSpace)
376 {
377 HomogeneousBwdTrans(cnt1, outarray, outarray);
378 }
379}
380
382 const Array<OneD, const NekDouble> &inarray,
383 Array<OneD, NekDouble> &outarray)
384{
385 size_t cnt = 0, cnt1 = 0;
386 Array<OneD, NekDouble> tmparray;
387 size_t nlines = m_lines.size();
388
389 for (size_t n = 0; n < nlines; ++n)
390 {
391 m_lines[n]->IProductWRTBase(inarray + cnt, tmparray = outarray + cnt1);
392
393 cnt += m_lines[n]->GetNcoeffs();
394 cnt1 += m_lines[n]->GetTotPoints();
395 }
396}
397
399 const int num_dofs, const Array<OneD, const NekDouble> &inarray,
400 Array<OneD, NekDouble> &outarray, bool IsForwards, bool Shuff, bool UnShuff)
401{
402 boost::ignore_unused(Shuff, UnShuff);
403
404 if (m_useFFT)
405 {
406
407 int n = m_lines.size(); // number of Fourier points in the Fourier
408 // directions (x-z grid)
409 int p =
410 num_dofs /
411 n; // number of points per line = n of Fourier transform required
412
413 Array<OneD, NekDouble> fft_in(num_dofs);
414 Array<OneD, NekDouble> fft_out(num_dofs);
415
416 m_transposition->Transpose(num_dofs, inarray, fft_in, false,
418
419 if (IsForwards)
420 {
421 for (int i = 0; i < (p * m_nz); i++)
422 {
423 m_FFT_y->FFTFwdTrans(m_tmpIN = fft_in + i * m_ny,
424 m_tmpOUT = fft_out + i * m_ny);
425 }
426 }
427 else
428 {
429 for (int i = 0; i < (p * m_nz); i++)
430 {
431 m_FFT_y->FFTBwdTrans(m_tmpIN = fft_in + i * m_ny,
432 m_tmpOUT = fft_out + i * m_ny);
433 }
434 }
435
436 m_transposition->Transpose(num_dofs, fft_out, fft_in, false,
438
439 if (IsForwards)
440 {
441 for (int i = 0; i < (p * m_ny); i++)
442 {
443 m_FFT_z->FFTFwdTrans(m_tmpIN = fft_in + i * m_nz,
444 m_tmpOUT = fft_out + i * m_nz);
445 }
446 }
447 else
448 {
449 for (int i = 0; i < (p * m_ny); i++)
450 {
451 m_FFT_z->FFTBwdTrans(m_tmpIN = fft_in + i * m_nz,
452 m_tmpOUT = fft_out + i * m_nz);
453 }
454 }
455
456 // TODO: required ZYtoX routine
457 m_transposition->Transpose(num_dofs, fft_out, fft_in, false,
459
460 m_transposition->Transpose(num_dofs, fft_in, outarray, false,
462 }
463 else
464 {
465 DNekBlkMatSharedPtr blkmatY;
466 DNekBlkMatSharedPtr blkmatZ;
467
468 if (num_dofs == m_npoints) // transform phys space
469 {
470 if (IsForwards)
471 {
474 }
475 else
476 {
479 }
480 }
481 else
482 {
483 if (IsForwards)
484 {
487 }
488 else
489 {
492 }
493 }
494
495 int nrowsY = blkmatY->GetRows();
496 int ncolsY = blkmatY->GetColumns();
497
498 Array<OneD, NekDouble> sortedinarrayY(ncolsY);
499 Array<OneD, NekDouble> sortedoutarrayY(nrowsY);
500
501 int nrowsZ = blkmatZ->GetRows();
502 int ncolsZ = blkmatZ->GetColumns();
503
504 Array<OneD, NekDouble> sortedinarrayZ(ncolsZ);
505 Array<OneD, NekDouble> sortedoutarrayZ(nrowsZ);
506
507 NekVector<NekDouble> inY(ncolsY, sortedinarrayY, eWrapper);
508 NekVector<NekDouble> outY(nrowsY, sortedoutarrayY, eWrapper);
509
510 NekVector<NekDouble> inZ(ncolsZ, sortedinarrayZ, eWrapper);
511 NekVector<NekDouble> outZ(nrowsZ, sortedoutarrayZ, eWrapper);
512
513 m_transposition->Transpose(num_dofs, inarray, sortedinarrayY,
514 !IsForwards, LibUtilities::eXtoYZ);
515
516 outY = (*blkmatY) * inY;
517
518 m_transposition->Transpose(sortedoutarrayY.size(), sortedoutarrayY,
519 sortedinarrayZ, false,
521
522 outZ = (*blkmatZ) * inZ;
523
524 m_transposition->Transpose(sortedoutarrayZ.size(), sortedoutarrayZ,
525 sortedoutarrayY, false,
527
528 m_transposition->Transpose(sortedoutarrayY.size(), sortedoutarrayY,
529 outarray, false, LibUtilities::eYZtoX);
530 }
531}
532
534 Homogeneous2DMatType mattype) const
535{
536 auto matrixIter = m_homogeneous2DBlockMat->find(mattype);
537
538 if (matrixIter == m_homogeneous2DBlockMat->end())
539 {
540 return ((*m_homogeneous2DBlockMat)[mattype] =
542 }
543 else
544 {
545 return matrixIter->second;
546 }
547}
548
550 Homogeneous2DMatType mattype) const
551{
552 int i;
553 int n_exp = 0;
554
555 DNekMatSharedPtr loc_mat;
556 DNekBlkMatSharedPtr BlkMatrix;
557
559
560 int NumPoints = 0;
561 int NumModes = 0;
562 int NumPencils = 0;
563
564 if ((mattype == eForwardsCoeffSpaceY1D) ||
565 (mattype == eBackwardsCoeffSpaceY1D) ||
566 (mattype == eForwardsPhysSpaceY1D) ||
567 (mattype == eBackwardsPhysSpaceY1D))
568 {
570 NumPoints = m_homogeneousBasis_y->GetNumModes();
571 NumModes = m_homogeneousBasis_y->GetNumPoints();
572 NumPencils = m_homogeneousBasis_z->GetNumPoints();
573 }
574 else
575 {
577 NumPoints = m_homogeneousBasis_z->GetNumModes();
578 NumModes = m_homogeneousBasis_z->GetNumPoints();
579 NumPencils = m_homogeneousBasis_y->GetNumPoints();
580 }
581
582 if ((mattype == eForwardsCoeffSpaceY1D) ||
583 (mattype == eForwardsCoeffSpaceZ1D) ||
584 (mattype == eBackwardsCoeffSpaceY1D) ||
585 (mattype == eBackwardsCoeffSpaceZ1D))
586 {
587 n_exp = m_lines[0]->GetNcoeffs();
588 }
589 else
590 {
591 n_exp = m_lines[0]->GetTotPoints(); // will operatore on m_phys
592 }
593
594 Array<OneD, unsigned int> nrows(n_exp);
595 Array<OneD, unsigned int> ncols(n_exp);
596
597 if ((mattype == eForwardsCoeffSpaceY1D) ||
598 (mattype == eForwardsPhysSpaceY1D) ||
599 (mattype == eForwardsCoeffSpaceZ1D) ||
600 (mattype == eForwardsPhysSpaceZ1D))
601 {
602 nrows = Array<OneD, unsigned int>(n_exp * NumPencils, NumModes);
603 ncols = Array<OneD, unsigned int>(n_exp * NumPencils, NumPoints);
604 }
605 else
606 {
607 nrows = Array<OneD, unsigned int>(n_exp * NumPencils, NumPoints);
608 ncols = Array<OneD, unsigned int>(n_exp * NumPencils, NumModes);
609 }
610
611 MatrixStorage blkmatStorage = eDIAGONAL;
612 BlkMatrix = MemoryManager<DNekBlkMat>::AllocateSharedPtr(nrows, ncols,
613 blkmatStorage);
614
616
617 if ((mattype == eForwardsCoeffSpaceY1D) ||
618 (mattype == eForwardsPhysSpaceY1D) ||
619 (mattype == eForwardsCoeffSpaceZ1D) ||
620 (mattype == eForwardsPhysSpaceZ1D))
621 {
623 StdSeg.DetShapeType(), StdSeg);
624
625 loc_mat = StdSeg.GetStdMatrix(matkey);
626 }
627 else
628 {
630 StdSeg.DetShapeType(), StdSeg);
631
632 loc_mat = StdSeg.GetStdMatrix(matkey);
633 }
634
635 // set up array of block matrices.
636 for (i = 0; i < (n_exp * NumPencils); ++i)
637 {
638 BlkMatrix->SetBlock(i, i, loc_mat);
639 }
640
641 return BlkMatrix;
642}
643
644std::vector<LibUtilities::FieldDefinitionsSharedPtr> ExpListHomogeneous2D::
646{
647 std::vector<LibUtilities::FieldDefinitionsSharedPtr> returnval;
648 // Set up Homogeneous length details.
650 HomoBasis[0] = m_homogeneousBasis_y;
651 HomoBasis[1] = m_homogeneousBasis_z;
652
653 std::vector<NekDouble> HomoLen(2);
654 HomoLen[0] = m_lhom_y;
655 HomoLen[1] = m_lhom_z;
656
657 int nhom_modes_y = m_homogeneousBasis_y->GetNumModes();
658 int nhom_modes_z = m_homogeneousBasis_z->GetNumModes();
659
660 std::vector<unsigned int> sIDs = LibUtilities::NullUnsignedIntVector;
661
662 std::vector<unsigned int> yIDs;
663 std::vector<unsigned int> zIDs;
664
665 for (int n = 0; n < nhom_modes_z; ++n)
666 {
667 for (int m = 0; m < nhom_modes_y; ++m)
668 {
669 zIDs.push_back(n);
670 yIDs.push_back(m);
671 }
672 }
673
674 m_lines[0]->GeneralGetFieldDefinitions(returnval, 2, HomoBasis, HomoLen,
675 false, sIDs, zIDs, yIDs);
676 return returnval;
677}
678
680 std::vector<LibUtilities::FieldDefinitionsSharedPtr> &fielddef)
681{
682 // Set up Homogeneous length details.
684 HomoBasis[0] = m_homogeneousBasis_y;
685 HomoBasis[1] = m_homogeneousBasis_z;
686 std::vector<NekDouble> HomoLen(2);
687 HomoLen[0] = m_lhom_y;
688 HomoLen[1] = m_lhom_z;
689
690 int nhom_modes_y = m_homogeneousBasis_y->GetNumModes();
691 int nhom_modes_z = m_homogeneousBasis_z->GetNumModes();
692
693 std::vector<unsigned int> sIDs = LibUtilities::NullUnsignedIntVector;
694
695 std::vector<unsigned int> yIDs;
696 std::vector<unsigned int> zIDs;
697
698 for (int n = 0; n < nhom_modes_z; ++n)
699 {
700 for (int m = 0; m < nhom_modes_y; ++m)
701 {
702 zIDs.push_back(n);
703 yIDs.push_back(m);
704 }
705 }
706
707 // enforce NumHomoDir == 1 by direct call
708 m_lines[0]->GeneralGetFieldDefinitions(fielddef, 2, HomoBasis, HomoLen,
709 false, sIDs, zIDs, yIDs);
710}
711
714 std::vector<NekDouble> &fielddata, Array<OneD, NekDouble> &coeffs)
715{
716 int i, k;
717
718 int NumMod_y = m_homogeneousBasis_y->GetNumModes();
719 int NumMod_z = m_homogeneousBasis_z->GetNumModes();
720
721 int ncoeffs_per_line = m_lines[0]->GetNcoeffs();
722
723 // Determine mapping from element ids to location in
724 // expansion list
725 map<int, int> ElmtID_to_ExpID;
726 for (i = 0; i < m_lines[0]->GetExpSize(); ++i)
727 {
728 ElmtID_to_ExpID[(*m_exp)[i]->GetGeom()->GetGlobalID()] = i;
729 }
730
731 for (i = 0; i < fielddef->m_elementIDs.size(); ++i)
732 {
733 int eid = ElmtID_to_ExpID[fielddef->m_elementIDs[i]];
734 int datalen = (*m_exp)[eid]->GetNcoeffs();
735
736 for (k = 0; k < (NumMod_y * NumMod_z); ++k)
737 {
738 fielddata.insert(
739 fielddata.end(),
740 &coeffs[m_coeff_offset[eid] + k * ncoeffs_per_line],
741 &coeffs[m_coeff_offset[eid] + k * ncoeffs_per_line] + datalen);
742 }
743 }
744}
745
748 std::vector<NekDouble> &fielddata)
749{
750 v_AppendFieldData(fielddef, fielddata, m_coeffs);
751}
752// Extract the data in fielddata into the m_coeff list
755 std::vector<NekDouble> &fielddata, std::string &field,
756 Array<OneD, NekDouble> &coeffs, std::unordered_map<int, int> zIdToPlane)
757{
758 boost::ignore_unused(zIdToPlane);
759 int i, k;
760 int offset = 0;
761 int datalen = fielddata.size() / fielddef->m_fields.size();
762 int ncoeffs_per_line = m_lines[0]->GetNcoeffs();
763 int NumMod_y = m_homogeneousBasis_y->GetNumModes();
764 int NumMod_z = m_homogeneousBasis_z->GetNumModes();
765 // Find data location according to field definition
766 for (i = 0; i < fielddef->m_fields.size(); ++i)
767 {
768 if (fielddef->m_fields[i] == field)
769 {
770 break;
771 }
772 offset += datalen;
773 }
774 ASSERTL0(i != fielddef->m_fields.size(), "Field not found in data file");
775 // Determine mapping from element ids to location in
776 // expansion list
777 map<int, int> ElmtID_to_ExpID;
778 for (i = 0; i < m_lines[0]->GetExpSize(); ++i)
779 {
780 ElmtID_to_ExpID[(*m_exp)[i]->GetGeom()->GetGlobalID()] = i;
781 }
782 for (i = 0; i < fielddef->m_elementIDs.size(); ++i)
783 {
784 int eid = ElmtID_to_ExpID[fielddef->m_elementIDs[i]];
785 int datalen = (*m_exp)[eid]->GetNcoeffs();
786 for (k = 0; k < (NumMod_y * NumMod_z); ++k)
787 {
788 Vmath::Vcopy(datalen, &fielddata[offset], 1,
789 &coeffs[m_coeff_offset[eid] + k * ncoeffs_per_line],
790 1);
791 offset += datalen;
792 }
793 }
794}
796 int expansion, std::string var)
797{
798 int i;
799 int nq = (*m_exp)[expansion]->GetTotPoints();
800 int npoints_per_line = m_lines[0]->GetTotPoints();
801
802 // printing the fields of that zone
803 outfile << " <DataArray type=\"Float64\" Name=\"" << var << "\">"
804 << endl;
805 outfile << " ";
806 for (int n = 0; n < m_lines.size(); ++n)
807 {
808 const Array<OneD, NekDouble> phys =
809 m_phys + m_phys_offset[expansion] + n * npoints_per_line;
810
811 for (i = 0; i < nq; ++i)
812 {
813 outfile << (fabs(phys[i]) < NekConstants::kNekZeroTol ? 0 : phys[i])
814 << " ";
815 }
816 }
817 outfile << endl;
818 outfile << " </DataArray>" << endl;
819}
820
824
825{
826 int nyzlines = m_lines.size(); // number of Fourier points in the Fourier
827 // directions (nF_pts)
828 int n_points_line = m_npoints / nyzlines; // number of points per line
829
836
837 for (int i = 0; i < nyzlines; i++)
838 {
839 m_lines[i]->PhysDeriv(tmp1 = inarray + i * n_points_line,
840 tmp2 = out_d0 + i * n_points_line);
841 }
842
843 if (m_homogeneousBasis_y->GetBasisType() == LibUtilities::eFourier &&
845 {
846 if (m_WaveSpace)
847 {
848 temparray = inarray;
849 }
850 else
851 {
852 HomogeneousFwdTrans(m_npoints, inarray, temparray);
853 }
854 NekDouble sign = -1.0;
856
857 // along y
858 for (int i = 0; i < m_ny; i++)
859 {
860 beta = -sign * 2 * M_PI * (i / 2) / m_lhom_y;
861
862 for (int j = 0; j < m_nz; j++)
863 {
864 Vmath::Smul(n_points_line, beta,
865 tmp1 = temparray + n_points_line * (i + j * m_ny),
866 1,
867 tmp2 = temparray1 +
868 n_points_line * ((i - int(sign)) + j * m_ny),
869 1);
870 }
871
872 sign = -1.0 * sign;
873 }
874
875 // along z
876 sign = -1.0;
877 for (int i = 0; i < m_nz; i++)
878 {
879 beta = -sign * 2 * M_PI * (i / 2) / m_lhom_z;
881 m_ny * n_points_line, beta,
882 tmp1 = temparray + i * m_ny * n_points_line, 1,
883 tmp2 = temparray2 + (i - int(sign)) * m_ny * n_points_line, 1);
884 sign = -1.0 * sign;
885 }
886 if (m_WaveSpace)
887 {
888 out_d1 = temparray1;
889 out_d2 = temparray2;
890 }
891 else
892 {
893 HomogeneousBwdTrans(m_npoints, temparray1, out_d1);
894 HomogeneousBwdTrans(m_npoints, temparray2, out_d2);
895 }
896 }
897 else
898 {
899 if (m_WaveSpace)
900 {
901 ASSERTL0(false, "Semi-phyisical time-stepping not implemented yet "
902 "for non-Fourier basis")
903 }
904 else
905 {
906 StdRegions::StdQuadExp StdQuad(m_homogeneousBasis_y->GetBasisKey(),
907 m_homogeneousBasis_z->GetBasisKey());
908
909 m_transposition->Transpose(m_npoints, inarray, temparray, false,
911
912 for (int i = 0; i < n_points_line; i++)
913 {
914 StdQuad.PhysDeriv(tmp1 = temparray + i * nyzlines,
915 tmp2 = temparray1 + i * nyzlines,
916 tmp3 = temparray2 + i * nyzlines);
917 }
918
919 m_transposition->Transpose(m_npoints, temparray1, out_d1, false,
921 m_transposition->Transpose(m_npoints, temparray2, out_d2, false,
923 Vmath::Smul(m_npoints, 2.0 / m_lhom_y, out_d1, 1, out_d1, 1);
924 Vmath::Smul(m_npoints, 2.0 / m_lhom_z, out_d2, 1, out_d2, 1);
925 }
926 }
927}
928
930 Direction edir, const Array<OneD, const NekDouble> &inarray,
932
933{
934 int nyzlines = m_lines.size(); // number of Fourier points in the Fourier
935 // directions (nF_pts)
936 int n_points_line = m_npoints / nyzlines; // number of points per line
937 // convert enum into int
938 int dir = (int)edir;
939
946
947 if (dir < 1)
948 {
949 for (int i = 0; i < nyzlines; i++)
950 {
951 m_lines[i]->PhysDeriv(tmp1 = inarray + i * n_points_line,
952 tmp2 = out_d + i * n_points_line);
953 }
954 }
955 else
956 {
957 if (m_homogeneousBasis_y->GetBasisType() == LibUtilities::eFourier &&
959 {
960 if (m_WaveSpace)
961 {
962 temparray = inarray;
963 }
964 else
965 {
966 HomogeneousFwdTrans(m_npoints, inarray, temparray);
967 }
968 NekDouble sign = -1.0;
970
971 if (dir == 1)
972 {
973 // along y
974 for (int i = 0; i < m_ny; i++)
975 {
976 beta = -sign * 2 * M_PI * (i / 2) / m_lhom_y;
977
978 for (int j = 0; j < m_nz; j++)
979 {
981 n_points_line, beta,
982 tmp1 = temparray + n_points_line * (i + j * m_ny),
983 1,
984 tmp2 = temparray1 +
985 n_points_line * ((i - int(sign)) + j * m_ny),
986 1);
987 }
988 sign = -1.0 * sign;
989 }
990 if (m_WaveSpace)
991 {
992 out_d = temparray1;
993 }
994 else
995 {
996 HomogeneousBwdTrans(m_npoints, temparray1, out_d);
997 }
998 }
999 else
1000 {
1001 // along z
1002 for (int i = 0; i < m_nz; i++)
1003 {
1004 beta = -sign * 2 * M_PI * (i / 2) / m_lhom_z;
1005 Vmath::Smul(m_ny * n_points_line, beta,
1006 tmp1 = temparray + i * m_ny * n_points_line, 1,
1007 tmp2 = temparray2 +
1008 (i - int(sign)) * m_ny * n_points_line,
1009 1);
1010 sign = -1.0 * sign;
1011 }
1012 if (m_WaveSpace)
1013 {
1014 out_d = temparray2;
1015 }
1016 else
1017 {
1018 HomogeneousBwdTrans(m_npoints, temparray2, out_d);
1019 }
1020 }
1021 }
1022 else
1023 {
1024 if (m_WaveSpace)
1025 {
1026 ASSERTL0(false, "Semi-phyisical time-stepping not implemented "
1027 "yet for non-Fourier basis")
1028 }
1029 else
1030 {
1031 StdRegions::StdQuadExp StdQuad(
1032 m_homogeneousBasis_y->GetBasisKey(),
1033 m_homogeneousBasis_z->GetBasisKey());
1034
1035 m_transposition->Transpose(m_npoints, inarray, temparray, false,
1037
1038 for (int i = 0; i < n_points_line; i++)
1039 {
1040 StdQuad.PhysDeriv(tmp1 = temparray + i * nyzlines,
1041 tmp2 = temparray1 + i * nyzlines,
1042 tmp3 = temparray2 + i * nyzlines);
1043 }
1044
1045 if (dir == 1)
1046 {
1047 m_transposition->Transpose(m_npoints, temparray1, out_d,
1048 false, LibUtilities::eYZtoX);
1049 Vmath::Smul(m_npoints, 2.0 / m_lhom_y, out_d, 1, out_d, 1);
1050 }
1051 else
1052 {
1053 m_transposition->Transpose(m_npoints, temparray2, out_d,
1054 false, LibUtilities::eYZtoX);
1055 Vmath::Smul(m_npoints, 2.0 / m_lhom_z, out_d, 1, out_d, 1);
1056 }
1057 }
1058 }
1059 }
1060}
1061
1065
1066{
1067 v_PhysDeriv(inarray, out_d0, out_d1, out_d2);
1068}
1069
1071 Direction edir, const Array<OneD, const NekDouble> &inarray,
1073{
1074 // convert int into enum
1075 v_PhysDeriv(edir, inarray, out_d);
1076}
1077
1079{
1080 NekDouble size_y = 1.5 * m_ny;
1081 NekDouble size_z = 1.5 * m_nz;
1082 m_padsize_y = int(size_y);
1083 m_padsize_z = int(size_z);
1084
1088 Ppad_y);
1089
1093 Ppad_z);
1094
1097
1098 StdRegions::StdQuadExp StdQuad(m_paddingBasis_y->GetBasisKey(),
1099 m_paddingBasis_z->GetBasisKey());
1100
1102 StdQuad.DetShapeType(), StdQuad);
1104 StdQuad.DetShapeType(), StdQuad);
1105
1106 MatFwdPAD = StdQuad.GetStdMatrix(matkey1);
1107 MatBwdPAD = StdQuad.GetStdMatrix(matkey2);
1108}
1109} // namespace MultiRegions
1110} // namespace Nektar
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:249
#define ASSERTL2(condition, msg)
Assert Level 2 – Debugging which is used FULLDEBUG compilation mode. This level assert is designed to...
Definition: ErrorUtil.hpp:272
#define sign(a, b)
return the sign(b)*a
Definition: Polylib.cpp:49
Represents a basis of a given type.
Definition: Basis.h:200
const BasisKey GetBasisKey() const
Returns the specification for the Basis.
Definition: Basis.h:315
Describes the specification for a Basis.
Definition: Basis.h:47
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:144
Defines a specification for a set of points.
Definition: Points.h:55
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
Abstraction of a two-dimensional multi-elemental expansion which is merely a collection of local expa...
virtual void v_DealiasedProd(const int num_dofs, const Array< OneD, NekDouble > &inarray1, const Array< OneD, NekDouble > &inarray2, Array< OneD, NekDouble > &outarray) override
virtual void v_FwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
virtual void v_DealiasedDotProd(const int num_dofs, const Array< OneD, Array< OneD, NekDouble > > &inarray1, const Array< OneD, Array< OneD, NekDouble > > &inarray2, Array< OneD, Array< OneD, NekDouble > > &outarray) override
virtual void v_FwdTransLocalElmt(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
virtual std::vector< LibUtilities::FieldDefinitionsSharedPtr > v_GetFieldDefinitions(void) override
DNekBlkMatSharedPtr GenHomogeneous2DBlockMatrix(Homogeneous2DMatType mattype) const
virtual void v_FwdTransBndConstrained(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
LibUtilities::NektarFFTSharedPtr m_FFT_y
ExpListHomogeneous2D(const ExpansionType type)
Default constructor.
int m_nz
Number of modes = number of poitns in z direction.
LibUtilities::NektarFFTSharedPtr m_FFT_z
LibUtilities::BasisSharedPtr m_homogeneousBasis_y
Definition of the total number of degrees of freedom and quadrature points. Sets up the storage for m...
NekDouble m_lhom_z
Width of homogeneous direction z.
int m_ny
Number of modes = number of poitns in y direction.
void PhysDeriv(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_d0, Array< OneD, NekDouble > &out_d1, Array< OneD, NekDouble > &out_d2)
virtual void v_HomogeneousFwdTrans(const int npts, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool Shuff=true, bool UnShuff=true) override
virtual void v_IProductWRTBase(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
virtual void v_WriteVtkPieceData(std::ostream &outfile, int expansion, std::string var) override
LibUtilities::TranspositionSharedPtr m_transposition
Array< OneD, ExpListSharedPtr > m_lines
Vector of ExpList, will be filled with ExpList1D.
LibUtilities::BasisSharedPtr m_homogeneousBasis_z
Base expansion in z direction.
LibUtilities::BasisSharedPtr m_paddingBasis_z
Base expansion in z direction.
virtual void v_AppendFieldData(LibUtilities::FieldDefinitionsSharedPtr &fielddef, std::vector< NekDouble > &fielddata) override
virtual void v_ExtractDataToCoeffs(LibUtilities::FieldDefinitionsSharedPtr &fielddef, std::vector< NekDouble > &fielddata, std::string &field, Array< OneD, NekDouble > &coeffs, std::unordered_map< int, int > zIdToPlane) override
Extract data from raw field data into expansion list.
void Homogeneous2DTrans(const int npts, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool IsForwards, bool Shuff=true, bool UnShuff=true)
DNekBlkMatSharedPtr GetHomogeneous2DBlockMatrix(Homogeneous2DMatType mattype) const
virtual void v_BwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
LibUtilities::BasisSharedPtr m_paddingBasis_y
Base expansion in y direction.
virtual void v_PhysDeriv(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_d0, Array< OneD, NekDouble > &out_d1, Array< OneD, NekDouble > &out_d2) override
NekDouble m_lhom_y
Width of homogeneous direction y.
virtual void v_HomogeneousBwdTrans(const int npts, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool Shuff=true, bool UnShuff=true) override
Base class for all multi-elemental spectral/hp expansions.
Definition: ExpList.h:102
Array< OneD, NekDouble > m_coeffs
Concatenation of all local expansion coefficients.
Definition: ExpList.h:1092
Array< OneD, int > m_coeff_offset
Offset of elemental data into the array m_coeffs.
Definition: ExpList.h:1136
void DealiasedProd(const int num_dofs, const Array< OneD, NekDouble > &inarray1, const Array< OneD, NekDouble > &inarray2, Array< OneD, NekDouble > &outarray)
Definition: ExpList.h:1881
LibUtilities::CommSharedPtr m_comm
Communicator.
Definition: ExpList.h:1065
void HomogeneousBwdTrans(const int npts, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool Shuff=true, bool UnShuff=true)
Definition: ExpList.h:1872
LibUtilities::SessionReaderSharedPtr m_session
Session.
Definition: ExpList.h:1067
Array< OneD, int > m_phys_offset
Offset of elemental data into the array m_phys.
Definition: ExpList.h:1138
Array< OneD, NekDouble > m_phys
The global expansion evaluated at the quadrature points.
Definition: ExpList.h:1108
void HomogeneousFwdTrans(const int npts, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool Shuff=true, bool UnShuff=true)
Definition: ExpList.h:1863
DNekMatSharedPtr GetStdMatrix(const StdMatrixKey &mkey)
Definition: StdExpansion.h:609
LibUtilities::ShapeType DetShapeType() const
This function returns the shape of the expansion domain.
Definition: StdExpansion.h:373
void PhysDeriv(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_d0, Array< OneD, NekDouble > &out_d1=NullNekDouble1DArray, Array< OneD, NekDouble > &out_d2=NullNekDouble1DArray)
Definition: StdExpansion.h:855
Class representing a segment element in reference space All interface of this class sits in StdExpans...
Definition: StdSegExp.h:48
static BasisSharedPtr NullBasisSharedPtr
Definition: Basis.h:352
static std::vector< unsigned int > NullUnsignedIntVector
BasisManagerT & BasisManager(void)
std::shared_ptr< Basis > BasisSharedPtr
NektarFFTFactory & GetNektarFFTFactory()
Definition: NektarFFT.cpp:69
static const BasisKey NullBasisKey(eNoBasisType, 0, NullPointsKey)
Defines a null basis with no type or points.
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< FieldDefinitions > FieldDefinitionsSharedPtr
Definition: FieldIO.h:186
@ beta
Gauss Radau pinned at x=-1,.
Definition: PointsType.h:61
@ eFourierEvenlySpaced
1D Evenly-spaced points using Fourier Fit
Definition: PointsType.h:76
@ eFourier
Fourier Expansion .
Definition: BasisType.h:57
std::map< Homogeneous2DMatType, DNekBlkMatSharedPtr > Homo2DBlockMatrixMap
A map between homo matrix keys and their associated block matrices.
static const NekDouble kNekZeroTol
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
std::shared_ptr< DNekBlkMat > DNekBlkMatSharedPtr
Definition: NekTypeDefs.hpp:77
std::shared_ptr< DNekMat > DNekMatSharedPtr
Definition: NekTypeDefs.hpp:75
double NekDouble
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.
Definition: Vmath.cpp:207
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.cpp:354
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
Definition: Vmath.cpp:245
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:487
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1191