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
38 #include <LocalRegions/Expansion.h>
40 #include <StdRegions/StdQuadExp.h>
41 #include <StdRegions/StdSegExp.h>
42 
43 using namespace std;
44 
45 namespace Nektar
46 {
47 namespace MultiRegions
48 {
49 // Forward declaration for typedefs
50 ExpListHomogeneous2D::ExpListHomogeneous2D(const ExpansionType type)
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 
72  ASSERTL2(HomoBasis_y != LibUtilities::NullBasisKey,
73  "Homogeneous Basis in y direction is a null basis");
74  ASSERTL2(HomoBasis_z != LibUtilities::NullBasisKey,
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");
104  SetPaddingBase();
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,
276  Array<OneD, Array<OneD, NekDouble>> &outarray)
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] =
541  GenHomogeneous2DBlockMatrix(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 
644 std::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 }
795 void ExpListHomogeneous2D::v_WriteVtkPieceData(std::ostream &outfile,
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 
831  Array<OneD, NekDouble> temparray1(m_npoints);
832  Array<OneD, NekDouble> temparray2(m_npoints);
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 &&
844  m_homogeneousBasis_z->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;
855  NekDouble beta;
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;
880  Vmath::Smul(
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,
931  Array<OneD, NekDouble> &out_d)
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 
941  Array<OneD, NekDouble> temparray1(m_npoints);
942  Array<OneD, NekDouble> temparray2(m_npoints);
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 &&
958  m_homogeneousBasis_z->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;
969  NekDouble beta;
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  {
980  Vmath::Smul(
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 
1063  const Array<OneD, const NekDouble> &inarray, Array<OneD, NekDouble> &out_d0,
1065 
1066 {
1067  v_PhysDeriv(inarray, out_d0, out_d1, out_d2);
1068 }
1069 
1071  Direction edir, const Array<OneD, const NekDouble> &inarray,
1072  Array<OneD, NekDouble> &out_d)
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 
1085  const LibUtilities::PointsKey Ppad_y(m_padsize_y,
1088  Ppad_y);
1089 
1090  const LibUtilities::PointsKey Ppad_z(m_padsize_z,
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:213
const BasisKey GetBasisKey() const
Returns the specification for the Basis.
Definition: Basis.h:328
Describes the specification for a Basis.
Definition: Basis.h:50
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:59
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_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
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
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:103
Array< OneD, NekDouble > m_coeffs
Concatenation of all local expansion coefficients.
Definition: ExpList.h:1076
Array< OneD, int > m_coeff_offset
Offset of elemental data into the array m_coeffs.
Definition: ExpList.h:1120
void DealiasedProd(const int num_dofs, const Array< OneD, NekDouble > &inarray1, const Array< OneD, NekDouble > &inarray2, Array< OneD, NekDouble > &outarray)
Definition: ExpList.h:1816
LibUtilities::CommSharedPtr m_comm
Communicator.
Definition: ExpList.h:1049
void HomogeneousBwdTrans(const int npts, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool Shuff=true, bool UnShuff=true)
Definition: ExpList.h:1807
LibUtilities::SessionReaderSharedPtr m_session
Session.
Definition: ExpList.h:1051
Array< OneD, int > m_phys_offset
Offset of elemental data into the array m_phys.
Definition: ExpList.h:1122
Array< OneD, NekDouble > m_phys
The global expansion evaluated at the quadrature points.
Definition: ExpList.h:1092
void HomogeneousFwdTrans(const int npts, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool Shuff=true, bool UnShuff=true)
Definition: ExpList.h:1798
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:848
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:369
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:209
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:359
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:248
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:492
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1255