49 m_lhom(1), m_homogeneous1DBlockMat(
54ExpListHomogeneous1D::ExpListHomogeneous1D(
55 const ExpansionType type,
56 const LibUtilities::SessionReaderSharedPtr &pSession,
57 const LibUtilities::BasisKey &HomoBasis,
const NekDouble lhom,
58 const bool useFFT,
const bool dealiasing)
59 : ExpList(type), m_useFFT(useFFT), m_lhom(lhom),
60 m_homogeneous1DBlockMat(
62 m_dealiasing(dealiasing)
65 m_comm = pSession->GetComm();
67 ASSERTL2(HomoBasis != LibUtilities::NullBasisKey,
68 "Homogeneous Basis is a null basis");
70 m_homogeneousBasis = LibUtilities::BasisManager()[HomoBasis];
72 m_StripZcomm = m_session->DefinesSolverInfo(
"HomoStrip")
73 ? m_comm->GetColumnComm()->GetColumnComm()
74 : m_comm->GetColumnComm();
76 ASSERTL0(m_homogeneousBasis->GetNumPoints() % m_StripZcomm->GetSize() == 0,
77 "HomModesZ should be a multiple of npz.");
79 if ((m_homogeneousBasis->GetBasisType() !=
80 LibUtilities::eFourierHalfModeRe) &&
81 (m_homogeneousBasis->GetBasisType() !=
82 LibUtilities::eFourierHalfModeIm))
85 (m_homogeneousBasis->GetNumPoints() / m_StripZcomm->GetSize()) %
88 "HomModesZ/npz should be an even integer.");
92 MemoryManager<LibUtilities::Transposition>::AllocateSharedPtr(
93 HomoBasis, m_comm, m_StripZcomm);
95 m_planes = Array<OneD, ExpListSharedPtr>(
96 m_homogeneousBasis->GetNumPoints() / m_StripZcomm->GetSize());
100 m_FFT = LibUtilities::GetNektarFFTFactory().CreateInstance(
101 "NekFFTW", m_homogeneousBasis->GetNumPoints());
108 int size = m_homogeneousBasis->GetNumPoints() +
109 m_homogeneousBasis->GetNumPoints() / 2;
110 m_padsize = size + (size % 2);
111 m_FFT_deal = LibUtilities::GetNektarFFTFactory().CreateInstance(
112 "NekFFTW", m_padsize);
116 ASSERTL0(
false,
"Dealiasing available just in combination "
125ExpListHomogeneous1D::ExpListHomogeneous1D(
const ExpListHomogeneous1D &In)
126 : ExpList(In, false), m_transposition(In.m_transposition),
127 m_StripZcomm(In.m_StripZcomm), m_useFFT(In.m_useFFT), m_FFT(In.m_FFT),
128 m_tmpIN(In.m_tmpIN), m_tmpOUT(In.m_tmpOUT),
129 m_homogeneousBasis(In.m_homogeneousBasis), m_lhom(In.m_lhom),
130 m_homogeneous1DBlockMat(In.m_homogeneous1DBlockMat),
131 m_dealiasing(In.m_dealiasing), m_padsize(In.m_padsize)
133 m_planes = Array<OneD, ExpListSharedPtr>(In.m_planes.size());
136ExpListHomogeneous1D::ExpListHomogeneous1D(
137 const ExpListHomogeneous1D &In,
const std::vector<unsigned int> &eIDs,
138 const Collections::ImplementationType ImpType)
139 : ExpList(In, eIDs, false, ImpType), m_transposition(In.m_transposition),
140 m_useFFT(In.m_useFFT), m_FFT(In.m_FFT), m_tmpIN(In.m_tmpIN),
141 m_tmpOUT(In.m_tmpOUT), m_homogeneousBasis(In.m_homogeneousBasis),
143 m_homogeneous1DBlockMat(
145 m_dealiasing(In.m_dealiasing), m_padsize(In.m_padsize)
147 m_planes = Array<OneD, ExpListSharedPtr>(In.m_planes.size());
153ExpListHomogeneous1D::~ExpListHomogeneous1D()
157void ExpListHomogeneous1D::v_HomogeneousFwdTrans(
158 const int npts,
const Array<OneD, const NekDouble> &inarray,
159 Array<OneD, NekDouble> &outarray,
bool Shuff,
bool UnShuff)
162 Homogeneous1DTrans(npts, inarray, outarray,
true, Shuff, UnShuff);
165void ExpListHomogeneous1D::v_HomogeneousBwdTrans(
166 const int npts,
const Array<OneD, const NekDouble> &inarray,
167 Array<OneD, NekDouble> &outarray,
bool Shuff,
bool UnShuff)
170 Homogeneous1DTrans(npts, inarray, outarray,
false, Shuff, UnShuff);
180void ExpListHomogeneous1D::v_DealiasedProd(
181 const int num_dofs,
const Array<OneD, NekDouble> &inarray1,
182 const Array<OneD, NekDouble> &inarray2, Array<OneD, NekDouble> &outarray)
185 int N = m_homogeneousBasis->GetNumPoints();
187 Array<OneD, NekDouble> V1(num_dofs);
188 Array<OneD, NekDouble> V2(num_dofs);
189 Array<OneD, NekDouble> V1V2(num_dofs);
198 HomogeneousFwdTrans(num_dofs, inarray1, V1);
199 HomogeneousFwdTrans(num_dofs, inarray2, V2);
202 int num_points_per_plane = num_dofs / m_planes.size();
204 if (!m_session->DefinesSolverInfo(
"HomoStrip"))
206 num_proc = m_comm->GetColumnComm()->GetSize();
210 num_proc = m_StripZcomm->GetSize();
212 int num_dfts_per_proc =
213 num_points_per_plane / num_proc + (num_points_per_plane % num_proc > 0);
215 Array<OneD, NekDouble> ShufV1(num_dfts_per_proc * N, 0.0);
216 Array<OneD, NekDouble> ShufV2(num_dfts_per_proc * N, 0.0);
217 Array<OneD, NekDouble> ShufV1V2(num_dfts_per_proc * N, 0.0);
219 Array<OneD, NekDouble> ShufV1_PAD_coef(m_padsize, 0.0);
220 Array<OneD, NekDouble> ShufV2_PAD_coef(m_padsize, 0.0);
221 Array<OneD, NekDouble> ShufV1_PAD_phys(m_padsize, 0.0);
222 Array<OneD, NekDouble> ShufV2_PAD_phys(m_padsize, 0.0);
224 Array<OneD, NekDouble> ShufV1V2_PAD_coef(m_padsize, 0.0);
225 Array<OneD, NekDouble> ShufV1V2_PAD_phys(m_padsize, 0.0);
227 m_transposition->Transpose(num_dofs, V1, ShufV1,
false,
228 LibUtilities::eXYtoZ);
229 m_transposition->Transpose(num_dofs, V2, ShufV2,
false,
230 LibUtilities::eXYtoZ);
233 for (
int i = 0; i < num_dfts_per_proc; i++)
237 Vmath::Vcopy(N, &(ShufV1[i * N]), 1, &(ShufV1_PAD_coef[0]), 1);
238 Vmath::Vcopy(N, &(ShufV2[i * N]), 1, &(ShufV2_PAD_coef[0]), 1);
241 m_FFT_deal->FFTBwdTrans(ShufV1_PAD_coef, ShufV1_PAD_phys);
242 m_FFT_deal->FFTBwdTrans(ShufV2_PAD_coef, ShufV2_PAD_phys);
246 Vmath::Vmul(m_padsize, ShufV1_PAD_phys, 1, ShufV2_PAD_phys, 1,
247 ShufV1V2_PAD_phys, 1);
251 m_FFT_deal->FFTFwdTrans(ShufV1V2_PAD_phys, ShufV1V2_PAD_coef);
255 Vmath::Vcopy(N, &(ShufV1V2_PAD_coef[0]), 1, &(ShufV1V2[i * N]), 1);
261 m_transposition->Transpose(num_dofs, ShufV1V2, outarray,
false,
262 LibUtilities::eZtoXY);
266 m_transposition->Transpose(num_dofs, ShufV1V2, V1V2,
false,
267 LibUtilities::eZtoXY);
268 HomogeneousBwdTrans(num_dofs, V1V2, outarray);
281void ExpListHomogeneous1D::v_DealiasedDotProd(
282 const int num_dofs,
const Array<OneD, Array<OneD, NekDouble>> &inarray1,
283 const Array<OneD, Array<OneD, NekDouble>> &inarray2,
284 Array<OneD, Array<OneD, NekDouble>> &outarray)
286 int ndim = inarray1.size();
287 ASSERTL1(inarray2.size() % ndim == 0,
288 "Wrong dimensions for DealiasedDotProd.");
289 int nvec = inarray2.size() / ndim;
292 int N = m_homogeneousBasis->GetNumPoints();
294 int num_points_per_plane = num_dofs / m_planes.size();
296 if (!m_session->DefinesSolverInfo(
"HomoStrip"))
298 num_proc = m_comm->GetColumnComm()->GetSize();
302 num_proc = m_StripZcomm->GetSize();
304 int num_dfts_per_proc =
305 num_points_per_plane / num_proc + (num_points_per_plane % num_proc > 0);
308 Array<OneD, Array<OneD, NekDouble>> V1(ndim);
309 Array<OneD, Array<OneD, NekDouble>> V2(ndim * nvec);
312 for (
int i = 0; i < ndim; i++)
316 for (
int i = 0; i < ndim * nvec; i++)
323 for (
int i = 0; i < ndim; i++)
325 V1[i] = Array<OneD, NekDouble>(num_dofs);
326 HomogeneousFwdTrans(num_dofs, inarray1[i], V1[i]);
328 for (
int i = 0; i < ndim * nvec; i++)
330 V2[i] = Array<OneD, NekDouble>(num_dofs);
331 HomogeneousFwdTrans(num_dofs, inarray2[i], V2[i]);
336 Array<OneD, Array<OneD, NekDouble>> ShufV1(ndim);
337 Array<OneD, NekDouble> ShufV1_PAD_coef(m_padsize, 0.0);
338 Array<OneD, Array<OneD, NekDouble>> ShufV1_PAD_phys(ndim);
339 for (
int i = 0; i < ndim; i++)
341 ShufV1[i] = Array<OneD, NekDouble>(num_dfts_per_proc * N, 0.0);
342 ShufV1_PAD_phys[i] = Array<OneD, NekDouble>(m_padsize, 0.0);
345 Array<OneD, Array<OneD, NekDouble>> ShufV2(ndim * nvec);
346 Array<OneD, NekDouble> ShufV2_PAD_coef(m_padsize, 0.0);
347 Array<OneD, Array<OneD, NekDouble>> ShufV2_PAD_phys(ndim * nvec);
348 for (
int i = 0; i < ndim * nvec; i++)
350 ShufV2[i] = Array<OneD, NekDouble>(num_dfts_per_proc * N, 0.0);
351 ShufV2_PAD_phys[i] = Array<OneD, NekDouble>(m_padsize, 0.0);
354 Array<OneD, Array<OneD, NekDouble>> ShufV1V2(nvec);
355 Array<OneD, NekDouble> ShufV1V2_PAD_coef(m_padsize, 0.0);
356 Array<OneD, NekDouble> ShufV1V2_PAD_phys(m_padsize, 0.0);
357 for (
int i = 0; i < nvec; i++)
359 ShufV1V2[i] = Array<OneD, NekDouble>(num_dfts_per_proc * N, 0.0);
362 for (
int i = 0; i < ndim; i++)
364 m_transposition->Transpose(num_dofs, V1[i], ShufV1[i],
false,
365 LibUtilities::eXYtoZ);
367 for (
int i = 0; i < ndim * nvec; i++)
369 m_transposition->Transpose(num_dofs, V2[i], ShufV2[i],
false,
370 LibUtilities::eXYtoZ);
374 for (
int i = 0; i < num_dfts_per_proc; i++)
376 for (
int j = 0; j < ndim; j++)
380 Vmath::Vcopy(N, &(ShufV1[j][i * N]), 1, &(ShufV1_PAD_coef[0]), 1);
382 m_FFT_deal->FFTBwdTrans(ShufV1_PAD_coef, ShufV1_PAD_phys[j]);
384 for (
int j = 0; j < ndim * nvec; j++)
386 Vmath::Vcopy(N, &(ShufV2[j][i * N]), 1, &(ShufV2_PAD_coef[0]), 1);
387 m_FFT_deal->FFTBwdTrans(ShufV2_PAD_coef, ShufV2_PAD_phys[j]);
392 for (
int j = 0; j < nvec; j++)
395 for (
int k = 0; k < ndim; k++)
398 ShufV2_PAD_phys[j * ndim + k], 1,
399 ShufV1V2_PAD_phys, 1, ShufV1V2_PAD_phys, 1);
403 m_FFT_deal->FFTFwdTrans(ShufV1V2_PAD_phys, ShufV1V2_PAD_coef);
406 Vmath::Vcopy(N, &(ShufV1V2_PAD_coef[0]), 1, &(ShufV1V2[j][i * N]),
414 for (
int j = 0; j < nvec; j++)
416 m_transposition->Transpose(num_dofs, ShufV1V2[j], outarray[j],
417 false, LibUtilities::eZtoXY);
422 Array<OneD, NekDouble> V1V2(num_dofs);
423 for (
int j = 0; j < nvec; j++)
425 m_transposition->Transpose(num_dofs, ShufV1V2[j], V1V2,
false,
426 LibUtilities::eZtoXY);
427 HomogeneousBwdTrans(num_dofs, V1V2, outarray[j]);
435void ExpListHomogeneous1D::v_FwdTrans(
436 const Array<OneD, const NekDouble> &inarray,
437 Array<OneD, NekDouble> &outarray)
439 int cnt = 0, cnt1 = 0;
440 Array<OneD, NekDouble> tmparray;
442 for (
int n = 0; n < m_planes.size(); ++n)
444 m_planes[n]->FwdTrans(inarray + cnt, tmparray = outarray + cnt1);
445 cnt += m_planes[n]->GetTotPoints();
447 cnt1 += m_planes[n]->GetNcoeffs();
451 HomogeneousFwdTrans(cnt1, outarray, outarray);
458void ExpListHomogeneous1D::v_FwdTransLocalElmt(
459 const Array<OneD, const NekDouble> &inarray,
460 Array<OneD, NekDouble> &outarray)
462 int cnt = 0, cnt1 = 0;
463 Array<OneD, NekDouble> tmparray;
466 for (
int n = 0; n < m_planes.size(); ++n)
468 m_planes[n]->FwdTransLocalElmt(inarray + cnt,
469 tmparray = outarray + cnt1);
470 cnt += m_planes[n]->GetTotPoints();
471 cnt1 += m_planes[n]->GetNcoeffs();
475 HomogeneousFwdTrans(cnt1, outarray, outarray);
482void ExpListHomogeneous1D::v_FwdTransBndConstrained(
483 const Array<OneD, const NekDouble> &inarray,
484 Array<OneD, NekDouble> &outarray)
486 int cnt = 0, cnt1 = 0;
487 Array<OneD, NekDouble> tmparray;
490 for (
int n = 0; n < m_planes.size(); ++n)
492 m_planes[n]->FwdTransBndConstrained(inarray + cnt,
493 tmparray = outarray + cnt1);
494 cnt += m_planes[n]->GetTotPoints();
495 cnt1 += m_planes[n]->GetNcoeffs();
499 HomogeneousFwdTrans(cnt1, outarray, outarray);
506void ExpListHomogeneous1D::v_BwdTrans(
507 const Array<OneD, const NekDouble> &inarray,
508 Array<OneD, NekDouble> &outarray)
510 int cnt = 0, cnt1 = 0;
511 Array<OneD, NekDouble> tmparray;
513 for (
int n = 0; n < m_planes.size(); ++n)
515 m_planes[n]->BwdTrans(inarray + cnt, tmparray = outarray + cnt1);
516 cnt += m_planes[n]->GetNcoeffs();
517 cnt1 += m_planes[n]->GetTotPoints();
521 HomogeneousBwdTrans(cnt1, outarray, outarray);
528void ExpListHomogeneous1D::v_IProductWRTBase(
529 const Array<OneD, const NekDouble> &inarray,
530 Array<OneD, NekDouble> &outarray)
532 ASSERTL1(inarray.size() >= m_npoints,
533 "Inarray is not of sufficient length");
534 int cnt = 0, cnt1 = 0;
535 Array<OneD, NekDouble> tmparray, tmpIn;
543 tmpIn = Array<OneD, NekDouble>(m_npoints, 0.0);
544 HomogeneousFwdTrans(m_npoints, inarray, tmpIn);
547 for (
int n = 0; n < m_planes.size(); ++n)
549 m_planes[n]->IProductWRTBase(tmpIn + cnt, tmparray = outarray + cnt1);
551 cnt1 += m_planes[n]->GetNcoeffs();
552 cnt += m_planes[n]->GetTotPoints();
571void ExpListHomogeneous1D::v_IProductWRTDerivBase(
572 const int dir,
const Array<OneD, const NekDouble> &inarray,
573 Array<OneD, NekDouble> &outarray)
575 int nT_pts = m_npoints;
578 nT_pts / m_planes.size();
580 int nT_coeffs = m_planes[0]->GetNcoeffs() * m_planes.size();
581 int nP_coeffs = nT_coeffs / m_planes.size();
583 Array<OneD, NekDouble> tmpIn(nT_pts);
584 Array<OneD, NekDouble> tmp1, tmp2;
593 HomogeneousFwdTrans(m_npoints, inarray, tmpIn);
597 if (dir == 0 || dir == 1)
599 for (
int i = 0; i < m_planes.size(); i++)
602 m_planes[i]->IProductWRTDerivBase(dir, tmpIn + i * nP_pts,
603 tmp1 = outarray + i * nP_coeffs);
609 if (m_homogeneousBasis->GetBasisType() == LibUtilities::eFourier ||
610 m_homogeneousBasis->GetBasisType() ==
611 LibUtilities::eFourierSingleMode ||
612 m_homogeneousBasis->GetBasisType() ==
613 LibUtilities::eFourierHalfModeRe ||
614 m_homogeneousBasis->GetBasisType() ==
615 LibUtilities::eFourierHalfModeIm)
618 Array<OneD, NekDouble> tmpHom(nT_coeffs, 0.0);
624 if (m_homogeneousBasis->GetBasisType() ==
625 LibUtilities::eFourierHalfModeRe)
628 m_planes[0]->IProductWRTBase(tmpIn, tmpHom);
631 beta =
sign * 2 * M_PI * (m_transposition->GetK(0)) / m_lhom;
632 Vmath::Smul(nT_coeffs, beta, tmpHom, 1, tmpHom, 1);
634 else if (m_homogeneousBasis->GetBasisType() ==
635 LibUtilities::eFourierHalfModeIm)
638 m_planes[0]->IProductWRTBase(tmpIn, tmpHom);
641 beta = -
sign * 2 * M_PI * (m_transposition->GetK(0)) / m_lhom;
642 Vmath::Smul(nT_coeffs, beta, tmpHom, 1, tmpHom, 1);
647 Array<OneD, NekDouble> tmpHomTwo(nT_coeffs, 0.0);
648 for (
int i = 0; i < m_planes.size(); i++)
650 if (i != 1 || m_transposition->GetK(i) !=
656 m_planes[i]->IProductWRTBase(tmpIn + i * nP_pts,
663 beta =
sign * 2 * M_PI * (m_transposition->GetK(i)) /
666 nP_coeffs, beta, tmp1 = tmpHomTwo + i * nP_coeffs,
667 1, tmp2 = tmpHom + (i -
int(
sign)) * nP_coeffs, 1);
679 "The IProductWRTDerivBase routine with one homogeneous "
680 "direction is not implemented for the homogeneous basis "
681 "if it is is not of type Fourier "
682 "or FourierSingleMode/HalfModeRe/HalfModeIm");
689 "cannot handle direction give to IProductWRTDerivBase operator."
690 "dir != 0, 1 or 2.");
708void ExpListHomogeneous1D::v_IProductWRTDerivBase(
709 const Array<OneD,
const Array<OneD, NekDouble>> &inarray,
710 Array<OneD, NekDouble> &outarray)
712 int ndim = inarray.size();
714 int nT_coeffs = m_planes[0]->GetNcoeffs() * m_planes.size();
717 v_IProductWRTDerivBase(0, inarray[0], outarray);
721 Array<OneD, NekDouble> tmp(nT_coeffs, 0.0);
722 for (
int dir = 1; dir < ndim; dir++)
724 v_IProductWRTDerivBase(dir, inarray[dir], tmp);
725 Vmath::Vadd(nT_coeffs, tmp, 1, outarray, 1, outarray, 1);
732void ExpListHomogeneous1D::Homogeneous1DTrans(
733 const int num_dofs,
const Array<OneD, const NekDouble> &inarray,
734 Array<OneD, NekDouble> &outarray,
bool IsForwards,
bool Shuff,
bool UnShuff)
739 int num_points_per_plane = num_dofs / m_planes.size();
740 int num_dfts_per_proc;
741 if (!m_session->DefinesSolverInfo(
"HomoStrip"))
743 int nP = m_comm->GetColumnComm()->GetSize();
745 num_points_per_plane / nP + (num_points_per_plane % nP > 0);
749 int nP = m_StripZcomm->GetSize();
751 num_points_per_plane / nP + (num_points_per_plane % nP > 0);
754 Array<OneD, NekDouble> fft_in(
755 num_dfts_per_proc * m_homogeneousBasis->GetNumPoints(), 0.0);
756 Array<OneD, NekDouble> fft_out(
757 num_dfts_per_proc * m_homogeneousBasis->GetNumPoints(), 0.0);
761 m_transposition->Transpose(num_dofs, inarray, fft_in,
false,
762 LibUtilities::eXYtoZ);
766 Vmath::Vcopy(num_dfts_per_proc * m_homogeneousBasis->GetNumPoints(),
767 inarray, 1, fft_in, 1);
772 for (
int i = 0; i < num_dfts_per_proc; i++)
775 m_tmpIN = fft_in + i * m_homogeneousBasis->GetNumPoints(),
777 fft_out + i * m_homogeneousBasis->GetNumPoints());
782 for (
int i = 0; i < num_dfts_per_proc; i++)
785 m_tmpIN = fft_in + i * m_homogeneousBasis->GetNumPoints(),
787 fft_out + i * m_homogeneousBasis->GetNumPoints());
793 m_transposition->Transpose(num_dofs, fft_out, outarray,
false,
794 LibUtilities::eZtoXY);
798 Vmath::Vcopy(num_dfts_per_proc * m_homogeneousBasis->GetNumPoints(),
799 fft_out, 1, outarray, 1);
806 if (num_dofs == m_npoints)
810 blkmat = GetHomogeneous1DBlockMatrix(eForwardsPhysSpace1D);
814 blkmat = GetHomogeneous1DBlockMatrix(eBackwardsPhysSpace1D);
821 blkmat = GetHomogeneous1DBlockMatrix(eForwardsCoeffSpace1D);
825 blkmat = GetHomogeneous1DBlockMatrix(eBackwardsCoeffSpace1D);
829 int nrows = blkmat->GetRows();
830 int ncols = blkmat->GetColumns();
832 Array<OneD, NekDouble> sortedinarray(ncols, 0.0);
833 Array<OneD, NekDouble> sortedoutarray(nrows, 0.0);
837 m_transposition->Transpose(num_dofs, inarray, sortedinarray,
838 !IsForwards, LibUtilities::eXYtoZ);
846 NekVector<NekDouble> in(ncols, sortedinarray, eWrapper);
847 NekVector<NekDouble> out(nrows, sortedoutarray, eWrapper);
850 out = (*blkmat) * in;
854 m_transposition->Transpose(num_dofs, sortedoutarray, outarray,
855 IsForwards, LibUtilities::eZtoXY);
865 Homogeneous1DMatType mattype)
const
867 auto matrixIter = m_homogeneous1DBlockMat->find(mattype);
869 if (matrixIter == m_homogeneous1DBlockMat->end())
871 return ((*m_homogeneous1DBlockMat)[mattype] =
872 GenHomogeneous1DBlockMatrix(mattype));
876 return matrixIter->second;
881 Homogeneous1DMatType mattype)
const
886 int num_trans_per_proc = 0;
888 if ((mattype == eForwardsCoeffSpace1D) ||
889 (mattype == eBackwardsCoeffSpace1D))
891 n_exp = m_planes[0]->GetNcoeffs();
895 n_exp = m_planes[0]->GetTotPoints();
898 num_trans_per_proc = n_exp / m_comm->GetColumnComm()->GetSize() +
899 (n_exp % m_comm->GetColumnComm()->GetSize() > 0);
901 Array<OneD, unsigned int> nrows(num_trans_per_proc);
902 Array<OneD, unsigned int> ncols(num_trans_per_proc);
904 if ((mattype == eForwardsCoeffSpace1D) || (mattype == eForwardsPhysSpace1D))
906 nrows = Array<OneD, unsigned int>(num_trans_per_proc,
907 m_homogeneousBasis->GetNumModes());
908 ncols = Array<OneD, unsigned int>(num_trans_per_proc,
909 m_homogeneousBasis->GetNumPoints());
913 nrows = Array<OneD, unsigned int>(num_trans_per_proc,
914 m_homogeneousBasis->GetNumPoints());
915 ncols = Array<OneD, unsigned int>(num_trans_per_proc,
916 m_homogeneousBasis->GetNumModes());
920 BlkMatrix = MemoryManager<DNekBlkMat>::AllocateSharedPtr(nrows, ncols,
924 if (m_homogeneousBasis->GetBasisType() ==
925 LibUtilities::eFourierHalfModeRe ||
926 m_homogeneousBasis->GetBasisType() == LibUtilities::eFourierHalfModeIm)
928 StdRegions::StdPointExp StdPoint(m_homogeneousBasis->GetBasisKey());
930 if ((mattype == eForwardsCoeffSpace1D) ||
931 (mattype == eForwardsPhysSpace1D))
933 StdRegions::StdMatrixKey matkey(StdRegions::eFwdTrans,
934 StdPoint.DetShapeType(), StdPoint);
936 loc_mat = StdPoint.GetStdMatrix(matkey);
940 StdRegions::StdMatrixKey matkey(StdRegions::eBwdTrans,
941 StdPoint.DetShapeType(), StdPoint);
943 loc_mat = StdPoint.GetStdMatrix(matkey);
949 StdRegions::StdSegExp StdSeg(m_homogeneousBasis->GetBasisKey());
951 if ((mattype == eForwardsCoeffSpace1D) ||
952 (mattype == eForwardsPhysSpace1D))
954 StdRegions::StdMatrixKey matkey(StdRegions::eFwdTrans,
955 StdSeg.DetShapeType(), StdSeg);
957 loc_mat = StdSeg.GetStdMatrix(matkey);
961 StdRegions::StdMatrixKey matkey(StdRegions::eBwdTrans,
962 StdSeg.DetShapeType(), StdSeg);
964 loc_mat = StdSeg.GetStdMatrix(matkey);
969 for (
int i = 0; i < num_trans_per_proc; ++i)
971 BlkMatrix->SetBlock(i, i, loc_mat);
977std::vector<LibUtilities::FieldDefinitionsSharedPtr> ExpListHomogeneous1D::
978 v_GetFieldDefinitions()
980 std::vector<LibUtilities::FieldDefinitionsSharedPtr> returnval;
983 Array<OneD, LibUtilities::BasisSharedPtr> HomoBasis(1, m_homogeneousBasis);
985 std::vector<NekDouble> HomoLen;
986 HomoLen.push_back(m_lhom);
988 std::vector<unsigned int> StripsIDs;
991 m_session->MatchSolverInfo(
"HomoStrip",
"True", strips,
false);
994 StripsIDs.push_back(m_transposition->GetStripID());
997 std::vector<unsigned int> PlanesIDs;
1002 if (m_homogeneousBasis->GetBasisType() == LibUtilities::eFourierSingleMode)
1007 for (
int i = 0; i < m_planes.size(); i++)
1009 PlanesIDs.push_back(m_transposition->GetPlaneID(i) + IDoffset);
1012 m_planes[0]->GeneralGetFieldDefinitions(returnval, 1, HomoBasis, HomoLen,
1013 strips, StripsIDs, PlanesIDs);
1017void ExpListHomogeneous1D::v_GetFieldDefinitions(
1018 std::vector<LibUtilities::FieldDefinitionsSharedPtr> &fielddef)
1021 Array<OneD, LibUtilities::BasisSharedPtr> HomoBasis(1, m_homogeneousBasis);
1023 std::vector<NekDouble> HomoLen;
1024 HomoLen.push_back(m_lhom);
1026 std::vector<unsigned int> StripsIDs;
1029 m_session->MatchSolverInfo(
"HomoStrip",
"True", strips,
false);
1032 StripsIDs.push_back(m_transposition->GetStripID());
1035 std::vector<unsigned int> PlanesIDs;
1038 if (m_homogeneousBasis->GetBasisType() == LibUtilities::eFourierSingleMode)
1043 for (
int i = 0; i < m_planes.size(); i++)
1045 PlanesIDs.push_back(m_transposition->GetPlaneID(i) + IDoffset);
1049 m_planes[0]->GeneralGetFieldDefinitions(fielddef, 1, HomoBasis, HomoLen,
1050 strips, StripsIDs, PlanesIDs);
1059void ExpListHomogeneous1D::v_AppendFieldData(
1060 LibUtilities::FieldDefinitionsSharedPtr &fielddef,
1061 std::vector<NekDouble> &fielddata, Array<OneD, NekDouble> &coeffs)
1064 int ncoeffs_per_plane = m_planes[0]->GetNcoeffs();
1068 if (m_elmtToExpId.size() == 0)
1070 for (i = 0; i < m_planes[0]->GetExpSize(); ++i)
1072 m_elmtToExpId[(*m_exp)[i]->GetGeom()->GetGlobalID()] = i;
1076 for (i = 0; i < fielddef->m_elementIDs.size(); ++i)
1078 int eid = m_elmtToExpId[fielddef->m_elementIDs[i]];
1079 int datalen = (*m_exp)[eid]->GetNcoeffs();
1081 for (n = 0; n < m_planes.size(); ++n)
1085 &coeffs[m_coeff_offset[eid] + n * ncoeffs_per_plane],
1086 &coeffs[m_coeff_offset[eid] + n * ncoeffs_per_plane] + datalen);
1091void ExpListHomogeneous1D::v_AppendFieldData(
1092 LibUtilities::FieldDefinitionsSharedPtr &fielddef,
1093 std::vector<NekDouble> &fielddata)
1095 v_AppendFieldData(fielddef, fielddata, m_coeffs);
1099void ExpListHomogeneous1D::v_ExtractDataToCoeffs(
1100 LibUtilities::FieldDefinitionsSharedPtr &fielddef,
1101 std::vector<NekDouble> &fielddata, std::string &field,
1102 Array<OneD, NekDouble> &coeffs, std::unordered_map<int, int> zIdToPlane)
1107 int datalen = fielddata.size() / fielddef->m_fields.size();
1108 std::vector<unsigned int> fieldDefHomoZids;
1111 for (i = 0; i < fielddef->m_fields.size(); ++i)
1113 if (fielddef->m_fields[i] == field)
1120 if (i == fielddef->m_fields.size())
1122 cout <<
"Field " <<
field <<
"not found in data file. " << endl;
1127 int modes_offset = 0;
1128 int planes_offset = 0;
1129 Array<OneD, NekDouble> coeff_tmp;
1133 if (zIdToPlane.size() == 0)
1135 int IDoffset = m_homogeneousBasis->GetBasisType() ==
1136 LibUtilities::eFourierSingleMode
1139 for (i = 0; i < m_planes.size(); ++i)
1141 zIdToPlane[m_transposition->GetPlaneID(i) + IDoffset] = i;
1145 if (m_elmtToExpId.size() == 0)
1147 for (i = 0; i < m_planes[0]->GetExpSize(); ++i)
1149 m_elmtToExpId[(*m_exp)[i]->GetGeom()->GetGlobalID()] = i;
1153 if (fielddef->m_numHomogeneousDir)
1155 nzmodes = fielddef->m_homogeneousZIDs.size();
1156 fieldDefHomoZids = fielddef->m_homogeneousZIDs;
1161 fieldDefHomoZids.push_back(0);
1165 int ncoeffs_per_plane = m_planes[0]->GetNcoeffs();
1167 for (i = 0; i < fielddef->m_elementIDs.size(); ++i)
1169 if (fielddef->m_uniOrder ==
true)
1174 int datalen = LibUtilities::GetNumberOfCoefficients(
1175 fielddef->m_shapeType, fielddef->m_numModes, modes_offset);
1177 auto it = m_elmtToExpId.find(fielddef->m_elementIDs[i]);
1180 if (it == m_elmtToExpId.end())
1183 offset += datalen * nzmodes;
1185 (*m_exp)[0]->GetNumBases() + fielddef->m_numHomogeneousDir;
1189 int eid = it->second;
1190 bool sameBasis =
true;
1191 for (
int j = 0; j < fielddef->m_basis.size() - 1; ++j)
1193 if (fielddef->m_basis[j] != (*m_exp)[eid]->GetBasisType(j))
1200 for (n = 0; n < nzmodes; ++n, offset += datalen)
1203 it = zIdToPlane.find(fieldDefHomoZids[n]);
1206 if (it == zIdToPlane.end())
1211 planes_offset = it->second;
1212 if (datalen == (*m_exp)[eid]->GetNcoeffs() && sameBasis)
1215 &coeffs[m_coeff_offset[eid] +
1216 planes_offset * ncoeffs_per_plane],
1221 (*m_exp)[eid]->ExtractDataToCoeffs(
1222 &fielddata[offset], fielddef->m_numModes, modes_offset,
1223 &coeffs[m_coeff_offset[eid] +
1224 planes_offset * ncoeffs_per_plane],
1229 (*m_exp)[0]->GetNumBases() + fielddef->m_numHomogeneousDir;
1235void ExpListHomogeneous1D::v_ExtractCoeffsToCoeffs(
1236 const std::shared_ptr<ExpList> &fromExpList,
1237 const Array<OneD, const NekDouble> &fromCoeffs,
1238 Array<OneD, NekDouble> &toCoeffs)
1241 int fromNcoeffs_per_plane = fromExpList->GetPlane(0)->GetNcoeffs();
1242 int toNcoeffs_per_plane = m_planes[0]->GetNcoeffs();
1243 Array<OneD, NekDouble> tocoeffs_tmp, fromcoeffs_tmp;
1245 for (i = 0; i < m_planes.size(); ++i)
1247 m_planes[i]->ExtractCoeffsToCoeffs(
1248 fromExpList->GetPlane(i),
1249 fromcoeffs_tmp = fromCoeffs + fromNcoeffs_per_plane * i,
1250 tocoeffs_tmp = toCoeffs + toNcoeffs_per_plane * i);
1254void ExpListHomogeneous1D::v_WriteVtkPieceData(std::ostream &outfile,
1255 int expansion, std::string var)
1258 if (m_planes.size() == 1)
1260 m_planes[0]->WriteVtkPieceData(outfile, expansion, var);
1265 int nq = (*m_exp)[expansion]->GetTotPoints();
1266 int npoints_per_plane = m_planes[0]->GetTotPoints();
1269 int outputExtraPlane = 0;
1270 Array<OneD, NekDouble> extraPlane;
1271 if (m_homogeneousBasis->GetBasisType() == LibUtilities::eFourier &&
1272 m_homogeneousBasis->GetPointsType() ==
1273 LibUtilities::eFourierEvenlySpaced)
1275 outputExtraPlane = 1;
1277 if (m_StripZcomm->GetSize() == 1)
1279 extraPlane = m_phys + m_phys_offset[expansion];
1284 int size = m_StripZcomm->GetSize();
1285 int rank = m_StripZcomm->GetRank();
1286 int fromRank = (rank + 1) % size;
1287 int toRank = (rank == 0) ? size - 1 : rank - 1;
1289 extraPlane = Array<OneD, NekDouble>(nq);
1290 Array<OneD, NekDouble> send(nq, m_phys + m_phys_offset[expansion]);
1292 m_StripZcomm->SendRecv(toRank, send, fromRank, extraPlane);
1297 outfile << R
"( <DataArray type="Float64" Name=")" << var << "\">"
1300 for (
int n = 0; n < m_planes.size(); ++n)
1302 const Array<OneD, NekDouble> phys =
1303 m_phys + m_phys_offset[expansion] + n * npoints_per_plane;
1305 for (i = 0; i < nq; ++i)
1307 outfile << (fabs(phys[i]) < NekConstants::kNekZeroTol ? 0 : phys[i])
1311 if (outputExtraPlane)
1313 for (i = 0; i < nq; ++i)
1315 outfile << (fabs(extraPlane[i]) < NekConstants::kNekZeroTol
1322 outfile <<
" </DataArray>" << endl;
1325void ExpListHomogeneous1D::v_PhysInterp1DScaled(
1326 const NekDouble scale,
const Array<OneD, NekDouble> &inarray,
1327 Array<OneD, NekDouble> &outarray)
1330 Array<OneD, NekDouble> tmparray;
1331 cnt = m_planes[0]->GetTotPoints();
1332 cnt1 = m_planes[0]->Get1DScaledTotPoints(scale);
1334 ASSERTL1(m_planes.size() * cnt1 <= outarray.size(),
1335 "size of outarray does not match internal estimage");
1337 for (
int i = 0; i < m_planes.size(); i++)
1340 m_planes[i]->PhysInterp1DScaled(scale, inarray + i * cnt,
1341 tmparray = outarray + i * cnt1);
1345void ExpListHomogeneous1D::v_PhysGalerkinProjection1DScaled(
1346 const NekDouble scale,
const Array<OneD, NekDouble> &inarray,
1347 Array<OneD, NekDouble> &outarray)
1350 Array<OneD, NekDouble> tmparray;
1351 cnt = m_planes[0]->Get1DScaledTotPoints(scale);
1352 cnt1 = m_planes[0]->GetTotPoints();
1353 ASSERTL1(m_planes.size() * cnt <= inarray.size(),
1354 "size of outarray does not match internal estimage");
1356 for (
int i = 0; i < m_planes.size(); i++)
1358 m_planes[i]->PhysGalerkinProjection1DScaled(
1359 scale, inarray + i * cnt, tmparray = outarray + i * cnt1);
1362void ExpListHomogeneous1D::v_PhysDeriv(
1363 const Array<OneD, const NekDouble> &inarray, Array<OneD, NekDouble> &out_d0,
1364 Array<OneD, NekDouble> &out_d1, Array<OneD, NekDouble> &out_d2)
1366 int nT_pts = m_npoints;
1369 nT_pts / m_planes.size();
1372 Array<OneD, NekDouble> temparray(nT_pts);
1373 Array<OneD, NekDouble> outarray(nT_pts);
1374 Array<OneD, NekDouble> tmp1;
1375 Array<OneD, NekDouble> tmp2;
1376 Array<OneD, NekDouble> tmp3;
1378 for (
int i = 0; i < m_planes.size(); i++)
1380 m_planes[i]->PhysDeriv(inarray + i * nP_pts, tmp2 = out_d0 + i * nP_pts,
1381 tmp3 = out_d1 + i * nP_pts);
1384 if (out_d2 != NullNekDouble1DArray)
1386 if (m_homogeneousBasis->GetBasisType() == LibUtilities::eFourier ||
1387 m_homogeneousBasis->GetBasisType() ==
1388 LibUtilities::eFourierSingleMode ||
1389 m_homogeneousBasis->GetBasisType() ==
1390 LibUtilities::eFourierHalfModeRe ||
1391 m_homogeneousBasis->GetBasisType() ==
1392 LibUtilities::eFourierHalfModeIm)
1396 temparray = inarray;
1400 HomogeneousFwdTrans(nT_pts, inarray, temparray);
1407 if (m_homogeneousBasis->GetBasisType() ==
1408 LibUtilities::eFourierHalfModeRe)
1410 beta =
sign * 2 * M_PI * (m_transposition->GetK(0)) / m_lhom;
1412 Vmath::Smul(nP_pts, beta, temparray, 1, outarray, 1);
1414 else if (m_homogeneousBasis->GetBasisType() ==
1415 LibUtilities::eFourierHalfModeIm)
1417 beta = -
sign * 2 * M_PI * (m_transposition->GetK(0)) / m_lhom;
1419 Vmath::Smul(nP_pts, beta, temparray, 1, outarray, 1);
1425 for (
int i = 0; i < m_planes.size(); i++)
1428 -
sign * 2 * M_PI * (m_transposition->GetK(i)) / m_lhom;
1430 Vmath::Smul(nP_pts, beta, tmp1 = temparray + i * nP_pts, 1,
1431 tmp2 = outarray + (i -
int(
sign)) * nP_pts, 1);
1443 HomogeneousBwdTrans(nT_pts, outarray, out_d2);
1448 if (!m_session->DefinesSolverInfo(
"HomoStrip"))
1450 ASSERTL0(m_comm->GetColumnComm()->GetSize() == 1,
1451 "Parallelisation in the homogeneous direction "
1452 "implemented just for Fourier basis");
1456 ASSERTL0(m_StripZcomm->GetSize() == 1,
1457 "Parallelisation in the homogeneous direction "
1458 "implemented just for Fourier basis");
1463 ASSERTL0(
false,
"Semi-phyisical time-stepping not "
1464 "implemented yet for non-Fourier "
1469 StdRegions::StdSegExp StdSeg(m_homogeneousBasis->GetBasisKey());
1471 m_transposition->Transpose(nT_pts, inarray, temparray,
false,
1472 LibUtilities::eXYtoZ);
1474 for (
int i = 0; i < nP_pts; i++)
1476 StdSeg.PhysDeriv(temparray + i * m_planes.size(),
1477 tmp2 = outarray + i * m_planes.size());
1480 m_transposition->Transpose(nT_pts, outarray, out_d2,
false,
1481 LibUtilities::eZtoXY);
1483 Vmath::Smul(nT_pts, 2.0 / m_lhom, out_d2, 1, out_d2, 1);
1489void ExpListHomogeneous1D::v_PhysDeriv(
1490 Direction edir,
const Array<OneD, const NekDouble> &inarray,
1491 Array<OneD, NekDouble> &out_d)
1494 int nT_pts = m_npoints;
1497 nT_pts / m_planes.size();
1500 int dir = (int)edir;
1502 Array<OneD, NekDouble> temparray(nT_pts);
1503 Array<OneD, NekDouble> outarray(nT_pts);
1504 Array<OneD, NekDouble> tmp1;
1505 Array<OneD, NekDouble> tmp2;
1509 for (
int i = 0; i < m_planes.size(); i++)
1511 m_planes[i]->PhysDeriv(edir, inarray + i * nP_pts,
1512 tmp2 = out_d + i * nP_pts);
1517 if (m_homogeneousBasis->GetBasisType() == LibUtilities::eFourier ||
1518 m_homogeneousBasis->GetBasisType() ==
1519 LibUtilities::eFourierSingleMode ||
1520 m_homogeneousBasis->GetBasisType() ==
1521 LibUtilities::eFourierHalfModeRe ||
1522 m_homogeneousBasis->GetBasisType() ==
1523 LibUtilities::eFourierHalfModeIm)
1527 temparray = inarray;
1531 HomogeneousFwdTrans(nT_pts, inarray, temparray);
1538 if (m_homogeneousBasis->GetBasisType() ==
1539 LibUtilities::eFourierHalfModeRe)
1541 beta = 2 *
sign * M_PI * (m_transposition->GetK(0)) / m_lhom;
1543 Vmath::Smul(nP_pts, beta, temparray, 1, outarray, 1);
1545 else if (m_homogeneousBasis->GetBasisType() ==
1546 LibUtilities::eFourierHalfModeIm)
1548 beta = -2 *
sign * M_PI * (m_transposition->GetK(0)) / m_lhom;
1550 Vmath::Smul(nP_pts, beta, temparray, 1, outarray, 1);
1555 for (
int i = 0; i < m_planes.size(); i++)
1558 -
sign * 2 * M_PI * (m_transposition->GetK(i)) / m_lhom;
1560 Vmath::Smul(nP_pts, beta, tmp1 = temparray + i * nP_pts, 1,
1561 tmp2 = outarray + (i -
int(
sign)) * nP_pts, 1);
1572 HomogeneousBwdTrans(nT_pts, outarray, out_d);
1577 if (!m_session->DefinesSolverInfo(
"HomoStrip"))
1579 ASSERTL0(m_comm->GetColumnComm()->GetSize() == 1,
1580 "Parallelisation in the homogeneous direction "
1581 "implemented just for Fourier basis");
1585 ASSERTL0(m_StripZcomm->GetSize() == 1,
1586 "Parallelisation in the homogeneous direction "
1587 "implemented just for Fourier basis");
1592 ASSERTL0(
false,
"Semi-phyisical time-stepping not implemented "
1593 "yet for non-Fourier basis");
1597 StdRegions::StdSegExp StdSeg(m_homogeneousBasis->GetBasisKey());
1599 m_transposition->Transpose(nT_pts, inarray, temparray,
false,
1600 LibUtilities::eXYtoZ);
1602 for (
int i = 0; i < nP_pts; i++)
1604 StdSeg.PhysDeriv(temparray + i * m_planes.size(),
1605 tmp2 = outarray + i * m_planes.size());
1608 m_transposition->Transpose(nT_pts, outarray, out_d,
false,
1609 LibUtilities::eZtoXY);
1611 Vmath::Smul(nT_pts, 2.0 / m_lhom, out_d, 1, out_d, 1);
1617void ExpListHomogeneous1D::PhysDeriv(
1618 const Array<OneD, const NekDouble> &inarray, Array<OneD, NekDouble> &out_d0,
1619 Array<OneD, NekDouble> &out_d1, Array<OneD, NekDouble> &out_d2)
1622 v_PhysDeriv(inarray, out_d0, out_d1, out_d2);
1625void ExpListHomogeneous1D::PhysDeriv(
1626 Direction edir,
const Array<OneD, const NekDouble> &inarray,
1627 Array<OneD, NekDouble> &out_d)
1629 v_PhysDeriv(edir, inarray, out_d);
1632LibUtilities::TranspositionSharedPtr ExpListHomogeneous1D::v_GetTransposition(
1635 return m_transposition;
1638NekDouble ExpListHomogeneous1D::v_GetHomoLen(
void)
1643void ExpListHomogeneous1D::v_SetHomoLen(
const NekDouble lhom)
1648Array<OneD, const unsigned int> ExpListHomogeneous1D::v_GetZIDs(
void)
1650 return m_transposition->GetPlanesIDs();
1653NekDouble ExpListHomogeneous1D::v_Integral(
1654 const Array<OneD, const NekDouble> &inarray)
1659 for (i = 0; i < (*m_exp).size(); ++i)
1661 val += (*m_exp)[i]->Integral(inarray + m_phys_offset[i]);
1663 val *= m_lhom / m_homogeneousBasis->GetNumModes();
1665 m_comm->GetSpaceComm()->AllReduce(val, LibUtilities::ReduceSum);
#define ASSERTL0(condition, msg)
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
#define ASSERTL2(condition, msg)
Assert Level 2 – Debugging which is used FULLDEBUG compilation mode. This level assert is designed to...
#define sign(a, b)
return the sign(b)*a
ExpListHomogeneous1D(const ExpansionType type)
Default constructor.
static BasisSharedPtr NullBasisSharedPtr
@ beta
Gauss Radau pinned at x=-1,.
std::map< Homogeneous1DMatType, DNekBlkMatSharedPtr > Homo1DBlockMatrixMap
A map between homo matrix keys and their associated block matrices.
std::shared_ptr< DNekBlkMat > DNekBlkMatSharedPtr
std::shared_ptr< DNekMat > DNekMatSharedPtr
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.
void Vvtvp(int n, const T *w, const int incw, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
vvtvp (vector times vector plus vector): z = w*x + y
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.
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
void Zero(int n, T *x, const int incx)
Zero vector.
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)