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