Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 // License for the specific language governing rights and limitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 //
32 // Description: An ExpList which is homogeneous in 2-directions
33 //
34 ///////////////////////////////////////////////////////////////////////////////
35 
37 #include <LibUtilities/Foundations/ManagerAccess.h> // for PointsManager, etc
38 #include <StdRegions/StdSegExp.h>
39 #include <StdRegions/StdQuadExp.h>
40 #include <LocalRegions/Expansion.h>
41 
42 namespace Nektar
43 {
44  namespace MultiRegions
45  {
46  // Forward declaration for typedefs
48  ExpList(),
49  m_homogeneousBasis_y(LibUtilities::NullBasisSharedPtr),
50  m_homogeneousBasis_z(LibUtilities::NullBasisSharedPtr),
51  m_lhom_y(1),
52  m_lhom_z(1),
53  m_homogeneous2DBlockMat(MemoryManager<Homo2DBlockMatrixMap>::AllocateSharedPtr())
54  {
55  }
56 
58  const LibUtilities::BasisKey &HomoBasis_y,
59  const LibUtilities::BasisKey &HomoBasis_z,
60  const NekDouble lhom_y,
61  const NekDouble lhom_z,
62  const bool useFFT,
63  const bool dealiasing):
64  ExpList(pSession),
65  m_useFFT(useFFT),
66  m_lhom_y(lhom_y),
67  m_lhom_z(lhom_z),
68  m_homogeneous2DBlockMat(MemoryManager<Homo2DBlockMatrixMap>::AllocateSharedPtr()),
69  m_dealiasing(dealiasing)
70  {
71  ASSERTL2(HomoBasis_y != LibUtilities::NullBasisKey,
72  "Homogeneous Basis in y direction is a null basis");
73  ASSERTL2(HomoBasis_z != LibUtilities::NullBasisKey,
74  "Homogeneous Basis in z direction is a null basis");
75 
78 
80 
81  m_Ycomm = m_comm->GetColumnComm()->GetRowComm();
82  m_Zcomm = m_comm->GetColumnComm()->GetRowComm();
83 
84  m_ny = m_homogeneousBasis_y->GetNumPoints()/m_Ycomm->GetSize();
85  m_nz = m_homogeneousBasis_z->GetNumPoints()/m_Zcomm->GetSize();
86 
88 
89  if(m_useFFT)
90  {
93  }
94 
95  if(m_dealiasing)
96  {
97  ASSERTL0(m_comm->GetColumnComm()->GetSize() == 1,"Remove dealiasing if you want to run in parallel");
99  }
100  }
101 
102 
103  /**
104  * @param In ExpListHomogeneous2D object to copy.
105  */
107  ExpList(In,false),
108  m_useFFT(In.m_useFFT),
109  m_FFT_y(In.m_FFT_y),
110  m_FFT_z(In.m_FFT_z),
111  m_transposition(In.m_transposition),
112  m_Ycomm(In.m_Ycomm),
113  m_Zcomm(In.m_Ycomm),
114  m_homogeneousBasis_y(In.m_homogeneousBasis_y),
115  m_homogeneousBasis_z(In.m_homogeneousBasis_z),
116  m_lhom_y(In.m_lhom_y),
117  m_lhom_z(In.m_lhom_z),
118  m_homogeneous2DBlockMat(In.m_homogeneous2DBlockMat),
119  m_ny(In.m_ny),
120  m_nz(In.m_nz),
121  m_dealiasing(In.m_dealiasing),
122  m_padsize_y(In.m_padsize_y),
123  m_padsize_z(In.m_padsize_z),
124  MatFwdPAD(In.MatFwdPAD),
125  MatBwdPAD(In.MatBwdPAD)
126  {
127  m_lines = Array<OneD, ExpListSharedPtr>(In.m_lines.num_elements());
128  }
129 
130  /**
131  * Destructor
132  */
134  {
135  }
136 
138  Array<OneD, NekDouble> &outarray,
139  CoeffState coeffstate,
140  bool Shuff,
141  bool UnShuff)
142  {
143  // Forwards trans
144  Homogeneous2DTrans(inarray,outarray,true,coeffstate,Shuff,UnShuff);
145  }
146 
148  Array<OneD, NekDouble> &outarray,
149  CoeffState coeffstate,
150  bool Shuff,
151  bool UnShuff)
152  {
153  // Backwards trans
154  Homogeneous2DTrans(inarray,outarray,false,coeffstate,Shuff,UnShuff);
155  }
156 
158  const Array<OneD, NekDouble> &inarray2,
159  Array<OneD, NekDouble> &outarray,
160  CoeffState coeffstate)
161  {
162  int npoints = outarray.num_elements(); // number of total physical points
163  int nlines = m_lines.num_elements(); // number of lines == number of Fourier modes = number of Fourier coeff = number of points per slab
164  int nslabs = npoints/nlines; // number of slabs = numebr of physical points per line
165 
166  Array<OneD, NekDouble> V1(npoints);
167  Array<OneD, NekDouble> V2(npoints);
168  Array<OneD, NekDouble> V1V2(npoints);
169  Array<OneD, NekDouble> ShufV1(npoints);
170  Array<OneD, NekDouble> ShufV2(npoints);
171  Array<OneD, NekDouble> ShufV1V2(npoints);
172 
173  if(m_WaveSpace)
174  {
175  V1 = inarray1;
176  V2 = inarray2;
177  }
178  else
179  {
180  HomogeneousFwdTrans(inarray1,V1,coeffstate);
181  HomogeneousFwdTrans(inarray2,V2,coeffstate);
182  }
183 
184  m_transposition->Transpose(V1,ShufV1,false,LibUtilities::eXtoYZ);
185  m_transposition->Transpose(V2,ShufV2,false,LibUtilities::eXtoYZ);
186 
187  Array<OneD, NekDouble> PadV1_slab_coeff(m_padsize_y*m_padsize_z,0.0);
188  Array<OneD, NekDouble> PadV2_slab_coeff(m_padsize_y*m_padsize_z,0.0);
189  Array<OneD, NekDouble> PadRe_slab_coeff(m_padsize_y*m_padsize_z,0.0);
190 
191  Array<OneD, NekDouble> PadV1_slab_phys(m_padsize_y*m_padsize_z,0.0);
192  Array<OneD, NekDouble> PadV2_slab_phys(m_padsize_y*m_padsize_z,0.0);
193  Array<OneD, NekDouble> PadRe_slab_phys(m_padsize_y*m_padsize_z,0.0);
194 
195  NekVector<NekDouble> PadIN_V1(m_padsize_y*m_padsize_z,PadV1_slab_coeff,eWrapper);
196  NekVector<NekDouble> PadOUT_V1(m_padsize_y*m_padsize_z,PadV1_slab_phys,eWrapper);
197 
198  NekVector<NekDouble> PadIN_V2(m_padsize_y*m_padsize_z,PadV2_slab_coeff,eWrapper);
199  NekVector<NekDouble> PadOUT_V2(m_padsize_y*m_padsize_z,PadV2_slab_phys,eWrapper);
200 
201  NekVector<NekDouble> PadIN_Re(m_padsize_y*m_padsize_z,PadRe_slab_phys,eWrapper);
202  NekVector<NekDouble> PadOUT_Re(m_padsize_y*m_padsize_z,PadRe_slab_coeff,eWrapper);
203 
204  //Looping on the slabs
205  for(int j = 0 ; j< nslabs ; j++)
206  {
207  //Copying the j-th slab of size N*M into a bigger slab of lenght 2*N*M
208  //We are in Fourier space
209  for(int i = 0 ; i< m_nz ; i++)
210  {
211  Vmath::Vcopy(m_ny,&(ShufV1[i*m_ny + j*nlines]),1,&(PadV1_slab_coeff[i*2*m_ny]),1);
212  Vmath::Vcopy(m_ny,&(ShufV2[i*m_ny + j*nlines]),1,&(PadV2_slab_coeff[i*2*m_ny]),1);
213  }
214 
215  //Moving to physical space using the padded system
216  PadOUT_V1 = (*MatBwdPAD)*PadIN_V1;
217  PadOUT_V2 = (*MatBwdPAD)*PadIN_V2;
218 
219  //Perfroming the vectors multiplication in physical
220  //space on the padded system
221  Vmath::Vmul(m_padsize_y*m_padsize_z,PadV1_slab_phys,1,PadV2_slab_phys,1,PadRe_slab_phys,1);
222 
223  //Moving back the result (V1*V2)_phys in Fourier
224  //space, padded system
225  PadOUT_Re = (*MatFwdPAD)*PadIN_Re;
226 
227  //Copying the first half of the padded pencil in the
228  //full vector (Fourier space)
229  for (int i = 0; i < m_nz; i++)
230  {
231  Vmath::Vcopy(m_ny,&(PadRe_slab_coeff[i*2*m_ny]),1,&(ShufV1V2[i*m_ny + j*nlines]),1);
232  }
233  }
234 
235  if(m_WaveSpace)
236  {
237  m_transposition->Transpose(ShufV1V2,outarray,false,LibUtilities::eYZtoX);
238  }
239  else
240  {
241  m_transposition->Transpose(ShufV1V2,V1V2,false,LibUtilities::eYZtoX);
242 
243  //Moving the results in physical space for the output
244  HomogeneousBwdTrans(V1V2,outarray,coeffstate);
245  }
246  }
247 
249  {
250  int cnt = 0, cnt1 = 0;
251  Array<OneD, NekDouble> tmparray;
252  int nlines = m_lines.num_elements();
253 
254  for(int n = 0; n < nlines; ++n)
255  {
256  m_lines[n]->FwdTrans(inarray+cnt, tmparray = outarray + cnt1,
257  coeffstate);
258  cnt += m_lines[n]->GetTotPoints();
259  cnt1 += m_lines[n]->GetNcoeffs();
260  }
261  if(!m_WaveSpace)
262  {
263  HomogeneousFwdTrans(outarray,outarray,coeffstate);
264  }
265  }
266 
268  {
269  int cnt = 0, cnt1 = 0;
270  Array<OneD, NekDouble> tmparray;
271  int nlines = m_lines.num_elements();
272 
273  for(int n = 0; n < nlines; ++n)
274  {
275  m_lines[n]->FwdTrans_IterPerExp(inarray+cnt, tmparray = outarray + cnt1);
276 
277  cnt += m_lines[n]->GetTotPoints();
278  cnt1 += m_lines[n]->GetNcoeffs();
279  }
280  if(!m_WaveSpace)
281  {
282  HomogeneousFwdTrans(outarray,outarray);
283  }
284  }
285 
287  {
288  int cnt = 0, cnt1 = 0;
289  Array<OneD, NekDouble> tmparray;
290  int nlines = m_lines.num_elements();
291 
292  for(int n = 0; n < nlines; ++n)
293  {
294  m_lines[n]->BwdTrans(inarray+cnt, tmparray = outarray + cnt1,
295  coeffstate);
296  cnt += m_lines[n]->GetNcoeffs();
297  cnt1 += m_lines[n]->GetTotPoints();
298  }
299  if(!m_WaveSpace)
300  {
301  HomogeneousBwdTrans(outarray,outarray);
302  }
303  }
304 
306  {
307  int cnt = 0, cnt1 = 0;
308  Array<OneD, NekDouble> tmparray;
309  int nlines = m_lines.num_elements();
310 
311  for(int n = 0; n < nlines; ++n)
312  {
313  m_lines[n]->BwdTrans_IterPerExp(inarray+cnt, tmparray = outarray + cnt1);
314 
315  cnt += m_lines[n]->GetNcoeffs();
316  cnt1 += m_lines[n]->GetTotPoints();
317  }
318  if(!m_WaveSpace)
319  {
320  HomogeneousBwdTrans(outarray,outarray);
321  }
322  }
323 
324 
326  {
327  int cnt = 0, cnt1 = 0;
328  Array<OneD, NekDouble> tmparray;
329  int nlines = m_lines.num_elements();
330 
331  for(int n = 0; n < nlines; ++n)
332  {
333  m_lines[n]->IProductWRTBase(inarray+cnt, tmparray = outarray + cnt1,coeffstate);
334 
335  cnt += m_lines[n]->GetNcoeffs();
336  cnt1 += m_lines[n]->GetTotPoints();
337  }
338  }
339 
341  {
342  int cnt = 0, cnt1 = 0;
343  Array<OneD, NekDouble> tmparray;
344  int nlines = m_lines.num_elements();
345 
346  for(int n = 0; n < nlines; ++n)
347  {
348  m_lines[n]->IProductWRTBase_IterPerExp(inarray+cnt, tmparray = outarray + cnt1);
349 
350  cnt += m_lines[n]->GetNcoeffs();
351  cnt1 += m_lines[n]->GetTotPoints();
352  }
353  }
354 
356  Array<OneD, NekDouble> &outarray,
357  bool IsForwards,
358  CoeffState coeffstate,
359  bool Shuff,
360  bool UnShuff)
361  {
362  if(m_useFFT)
363  {
364 
365  int n = m_lines.num_elements(); //number of Fourier points in the Fourier directions (x-z grid)
366  int s = inarray.num_elements(); //number of total points = n. of Fourier points * n. of points per line
367  int p = s/n; //number of points per line = n of Fourier transform required
368 
369  Array<OneD, NekDouble> fft_in(s);
370  Array<OneD, NekDouble> fft_out(s);
371 
372  m_transposition->Transpose(inarray,fft_in,false,LibUtilities::eXtoYZ);
373 
374  if(IsForwards)
375  {
376  for(int i=0;i<(p*m_nz);i++)
377  {
378  m_FFT_y->FFTFwdTrans(m_tmpIN = fft_in + i*m_ny, m_tmpOUT = fft_out + i*m_ny);
379  }
380 
381  }
382  else
383  {
384  for(int i=0;i<(p*m_nz);i++)
385  {
386  m_FFT_y->FFTBwdTrans(m_tmpIN = fft_in + i*m_ny, m_tmpOUT = fft_out + i*m_ny);
387  }
388  }
389 
390  m_transposition->Transpose(fft_out,fft_in,false,LibUtilities::eYZtoZY);
391 
392  if(IsForwards)
393  {
394  for(int i=0;i<(p*m_ny);i++)
395  {
396  m_FFT_z->FFTFwdTrans(m_tmpIN = fft_in + i*m_nz, m_tmpOUT = fft_out + i*m_nz);
397  }
398 
399  }
400  else
401  {
402  for(int i=0;i<(p*m_ny);i++)
403  {
404  m_FFT_z->FFTBwdTrans(m_tmpIN = fft_in + i*m_nz, m_tmpOUT = fft_out + i*m_nz);
405  }
406  }
407 
408  //TODO: required ZYtoX routine
409  m_transposition->Transpose(fft_out,fft_in,false,LibUtilities::eZYtoYZ);
410 
411  m_transposition->Transpose(fft_in,outarray,false,LibUtilities::eYZtoX);
412 
413  }
414  else
415  {
416  DNekBlkMatSharedPtr blkmatY;
417  DNekBlkMatSharedPtr blkmatZ;
418 
419  if(inarray.num_elements() == m_npoints) //transform phys space
420  {
421  if(IsForwards)
422  {
425  }
426  else
427  {
430  }
431  }
432  else
433  {
434  if(IsForwards)
435  {
438  }
439  else
440  {
443  }
444  }
445 
446  int nrowsY = blkmatY->GetRows();
447  int ncolsY = blkmatY->GetColumns();
448 
449  Array<OneD, NekDouble> sortedinarrayY(ncolsY);
450  Array<OneD, NekDouble> sortedoutarrayY(nrowsY);
451 
452  int nrowsZ = blkmatZ->GetRows();
453  int ncolsZ = blkmatZ->GetColumns();
454 
455  Array<OneD, NekDouble> sortedinarrayZ(ncolsZ);
456  Array<OneD, NekDouble> sortedoutarrayZ(nrowsZ);
457 
458  NekVector<NekDouble> inY (ncolsY,sortedinarrayY,eWrapper);
459  NekVector<NekDouble> outY(nrowsY,sortedoutarrayY,eWrapper);
460 
461  NekVector<NekDouble> inZ (ncolsZ,sortedinarrayZ,eWrapper);
462  NekVector<NekDouble> outZ(nrowsZ,sortedoutarrayZ,eWrapper);
463 
464  m_transposition->Transpose(inarray,sortedinarrayY,!IsForwards,LibUtilities::eXtoYZ);
465 
466  outY = (*blkmatY)*inY;
467 
468  m_transposition->Transpose(sortedoutarrayY,sortedinarrayZ,false,LibUtilities::eYZtoZY);
469 
470  outZ = (*blkmatZ)*inZ;
471 
472  m_transposition->Transpose(sortedoutarrayZ,sortedoutarrayY,false,LibUtilities::eZYtoYZ);
473 
474  m_transposition->Transpose(sortedoutarrayY,outarray,false,LibUtilities::eYZtoX);
475  }
476  }
477 
479  {
480  Homo2DBlockMatrixMap::iterator matrixIter = m_homogeneous2DBlockMat->find(mattype);
481 
482  if(matrixIter == m_homogeneous2DBlockMat->end())
483  {
484  return ((*m_homogeneous2DBlockMat)[mattype] =
485  GenHomogeneous2DBlockMatrix(mattype,coeffstate));
486  }
487  else
488  {
489  return matrixIter->second;
490  }
491  }
492 
494  {
495  int i;
496  int n_exp = 0;
497 
498  DNekMatSharedPtr loc_mat;
499  DNekBlkMatSharedPtr BlkMatrix;
500 
502 
503  int NumPoints = 0;
504  int NumModes = 0;
505  int NumPencils = 0;
506 
507  if((mattype == eForwardsCoeffSpaceY1D) || (mattype == eBackwardsCoeffSpaceY1D)
508  ||(mattype == eForwardsPhysSpaceY1D) || (mattype == eBackwardsPhysSpaceY1D))
509  {
510  Basis = m_homogeneousBasis_y;
511  NumPoints = m_homogeneousBasis_y->GetNumModes();
512  NumModes = m_homogeneousBasis_y->GetNumPoints();
513  NumPencils = m_homogeneousBasis_z->GetNumPoints();
514  }
515  else
516  {
517  Basis = m_homogeneousBasis_z;
518  NumPoints = m_homogeneousBasis_z->GetNumModes();
519  NumModes = m_homogeneousBasis_z->GetNumPoints();
520  NumPencils = m_homogeneousBasis_y->GetNumPoints();
521  }
522 
523  if((mattype == eForwardsCoeffSpaceY1D) || (mattype == eForwardsCoeffSpaceZ1D)
524  ||(mattype == eBackwardsCoeffSpaceY1D)||(mattype == eBackwardsCoeffSpaceZ1D))
525  {
526  n_exp = m_lines[0]->GetNcoeffs();
527  }
528  else
529  {
530  n_exp = m_lines[0]->GetTotPoints(); // will operatore on m_phys
531  }
532 
533  Array<OneD,unsigned int> nrows(n_exp);
534  Array<OneD,unsigned int> ncols(n_exp);
535 
536  if((mattype == eForwardsCoeffSpaceY1D)||(mattype == eForwardsPhysSpaceY1D) ||
537  (mattype == eForwardsCoeffSpaceZ1D)||(mattype == eForwardsPhysSpaceZ1D))
538  {
539  nrows = Array<OneD, unsigned int>(n_exp*NumPencils,NumModes);
540  ncols = Array<OneD, unsigned int>(n_exp*NumPencils,NumPoints);
541  }
542  else
543  {
544  nrows = Array<OneD, unsigned int>(n_exp*NumPencils,NumPoints);
545  ncols = Array<OneD, unsigned int>(n_exp*NumPencils,NumModes);
546  }
547 
548  MatrixStorage blkmatStorage = eDIAGONAL;
549  BlkMatrix = MemoryManager<DNekBlkMat>::AllocateSharedPtr(nrows,ncols,blkmatStorage);
550 
551  StdRegions::StdSegExp StdSeg(Basis->GetBasisKey());
552 
553  if((mattype == eForwardsCoeffSpaceY1D)||(mattype == eForwardsPhysSpaceY1D) ||
554  (mattype == eForwardsCoeffSpaceZ1D)||(mattype == eForwardsPhysSpaceZ1D))
555  {
557  StdSeg.DetShapeType(),
558  StdSeg);
559 
560  loc_mat = StdSeg.GetStdMatrix(matkey);
561  }
562  else
563  {
565  StdSeg.DetShapeType(),
566  StdSeg);
567 
568  loc_mat = StdSeg.GetStdMatrix(matkey);
569  }
570 
571  // set up array of block matrices.
572  for(i = 0; i < (n_exp*NumPencils); ++i)
573  {
574  BlkMatrix->SetBlock(i,i,loc_mat);
575  }
576 
577  return BlkMatrix;
578  }
579 
580  std::vector<LibUtilities::FieldDefinitionsSharedPtr> ExpListHomogeneous2D::v_GetFieldDefinitions()
581  {
582  std::vector<LibUtilities::FieldDefinitionsSharedPtr> returnval;
583  // Set up Homogeneous length details.
585  HomoBasis[0] = m_homogeneousBasis_y;
586  HomoBasis[1] = m_homogeneousBasis_z;
587 
588  std::vector<NekDouble> HomoLen(2);
589  HomoLen[0] = m_lhom_y;
590  HomoLen[1] = m_lhom_z;
591 
592  int nhom_modes_y = m_homogeneousBasis_y->GetNumModes();
593  int nhom_modes_z = m_homogeneousBasis_z->GetNumModes();
594 
595  std::vector<unsigned int> sIDs
597 
598  std::vector<unsigned int> yIDs;
599  std::vector<unsigned int> zIDs;
600 
601  for(int n = 0; n < nhom_modes_z; ++n)
602  {
603  for(int m = 0; m < nhom_modes_y; ++m)
604  {
605  zIDs.push_back(n);
606  yIDs.push_back(m);
607  }
608  }
609 
610  m_lines[0]->GeneralGetFieldDefinitions(returnval, 2, HomoBasis,
611  HomoLen, false,
612  sIDs, zIDs, yIDs);
613  return returnval;
614  }
615 
616  void ExpListHomogeneous2D::v_GetFieldDefinitions(std::vector<LibUtilities::FieldDefinitionsSharedPtr> &fielddef)
617  {
618  // Set up Homogeneous length details.
620  HomoBasis[0] = m_homogeneousBasis_y;
621  HomoBasis[1] = m_homogeneousBasis_z;
622  std::vector<NekDouble> HomoLen(2);
623  HomoLen[0] = m_lhom_y;
624  HomoLen[1] = m_lhom_z;
625 
626  int nhom_modes_y = m_homogeneousBasis_y->GetNumModes();
627  int nhom_modes_z = m_homogeneousBasis_z->GetNumModes();
628 
629  std::vector<unsigned int> sIDs
631 
632  std::vector<unsigned int> yIDs;
633  std::vector<unsigned int> zIDs;
634 
635  for(int n = 0; n < nhom_modes_z; ++n)
636  {
637  for(int m = 0; m < nhom_modes_y; ++m)
638  {
639  zIDs.push_back(n);
640  yIDs.push_back(m);
641  }
642  }
643 
644  // enforce NumHomoDir == 1 by direct call
645  m_lines[0]->GeneralGetFieldDefinitions(fielddef, 2, HomoBasis,
646  HomoLen, false,
647  sIDs, zIDs, yIDs);
648  }
649 
651  {
652  int i,k;
653 
654  int NumMod_y = m_homogeneousBasis_y->GetNumModes();
655  int NumMod_z = m_homogeneousBasis_z->GetNumModes();
656 
657  int ncoeffs_per_line = m_lines[0]->GetNcoeffs();
658 
659  // Determine mapping from element ids to location in
660  // expansion list
661  map<int, int> ElmtID_to_ExpID;
662  for(i = 0; i < m_lines[0]->GetExpSize(); ++i)
663  {
664  ElmtID_to_ExpID[(*m_exp)[i]->GetGeom()->GetGlobalID()] = i;
665  }
666 
667  for(i = 0; i < fielddef->m_elementIDs.size(); ++i)
668  {
669  int eid = ElmtID_to_ExpID[fielddef->m_elementIDs[i]];
670  int datalen = (*m_exp)[eid]->GetNcoeffs();
671 
672  for(k = 0; k < (NumMod_y*NumMod_z); ++k)
673  {
674  fielddata.insert(fielddata.end(),&coeffs[m_coeff_offset[eid]+k*ncoeffs_per_line],&coeffs[m_coeff_offset[eid]+k*ncoeffs_per_line]+datalen);
675  }
676  }
677  }
678 
679  void ExpListHomogeneous2D::v_AppendFieldData(LibUtilities::FieldDefinitionsSharedPtr &fielddef, std::vector<NekDouble> &fielddata)
680  {
681  v_AppendFieldData(fielddef,fielddata,m_coeffs);
682  }
683 
684  //Extract the data in fielddata into the m_coeff list
685  void ExpListHomogeneous2D::v_ExtractDataToCoeffs(LibUtilities::FieldDefinitionsSharedPtr &fielddef, std::vector<NekDouble> &fielddata, std::string &field, Array<OneD, NekDouble> &coeffs)
686  {
687  int i,k;
688  int offset = 0;
689  int datalen = fielddata.size()/fielddef->m_fields.size();
690  int ncoeffs_per_line = m_lines[0]->GetNcoeffs();
691  int NumMod_y = m_homogeneousBasis_y->GetNumModes();
692  int NumMod_z = m_homogeneousBasis_z->GetNumModes();
693 
694  // Find data location according to field definition
695  for(i = 0; i < fielddef->m_fields.size(); ++i)
696  {
697  if(fielddef->m_fields[i] == field)
698  {
699  break;
700  }
701  offset += datalen;
702  }
703 
704  ASSERTL0(i!= fielddef->m_fields.size(),"Field not found in data file");
705 
706  // Determine mapping from element ids to location in
707  // expansion list
708  map<int, int> ElmtID_to_ExpID;
709  for(i = 0; i < m_lines[0]->GetExpSize(); ++i)
710  {
711  ElmtID_to_ExpID[(*m_exp)[i]->GetGeom()->GetGlobalID()] = i;
712  }
713 
714  for(i = 0; i < fielddef->m_elementIDs.size(); ++i)
715  {
716  int eid = ElmtID_to_ExpID[fielddef->m_elementIDs[i]];
717  int datalen = (*m_exp)[eid]->GetNcoeffs();
718 
719  for(k = 0; k < (NumMod_y*NumMod_z); ++k)
720  {
721  Vmath::Vcopy(datalen,&fielddata[offset],1,&coeffs[m_coeff_offset[eid] + k*ncoeffs_per_line],1);
722  offset += datalen;
723  }
724  }
725  }
726 
727  void ExpListHomogeneous2D::v_WriteVtkPieceData(std::ostream &outfile, int expansion,
728  std::string var)
729  {
730  int i;
731  int nq = (*m_exp)[expansion]->GetTotPoints();
732  int npoints_per_line = m_lines[0]->GetTotPoints();
733 
734  // printing the fields of that zone
735  outfile << " <DataArray type=\"Float32\" Name=\""
736  << var << "\">" << endl;
737  outfile << " ";
738  for (int n = 0; n < m_lines.num_elements(); ++n)
739  {
740  const Array<OneD, NekDouble> phys = m_phys + m_phys_offset[expansion] + n*npoints_per_line;
741  for(i = 0; i < nq; ++i)
742  {
743  outfile << (fabs(phys[i]) < NekConstants::kNekZeroTol ? 0 : phys[i]) << " ";
744  }
745  }
746  outfile << endl;
747  outfile << " </DataArray>" << endl;
748  }
749 
751  Array<OneD, NekDouble> &out_d0,
752  Array<OneD, NekDouble> &out_d1,
753  Array<OneD, NekDouble> &out_d2)
754 
755  {
756  int nyzlines = m_lines.num_elements(); //number of Fourier points in the Fourier directions (nF_pts)
757  int npoints = inarray.num_elements(); //number of total points = n. of Fourier points * n. of points per line (nT_pts)
758  int n_points_line = npoints/nyzlines; //number of points per line
759 
760  Array<OneD, NekDouble> temparray(npoints);
761  Array<OneD, NekDouble> temparray1(npoints);
762  Array<OneD, NekDouble> temparray2(npoints);
766 
767  for( int i=0 ; i<nyzlines ; i++ )
768  {
769  m_lines[i]->PhysDeriv( tmp1 = inarray + i*n_points_line ,tmp2 = out_d0 + i*n_points_line);
770  }
771 
773  {
774  if(m_WaveSpace)
775  {
776  temparray = inarray;
777  }
778  else
779  {
780  HomogeneousFwdTrans(inarray,temparray);
781  }
782  NekDouble sign = -1.0;
783  NekDouble beta;
784 
785  //along y
786  for(int i = 0; i < m_ny; i++)
787  {
788  beta = -sign*2*M_PI*(i/2)/m_lhom_y;
789 
790  for(int j = 0; j < m_nz; j++)
791  {
792  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);
793  }
794 
795  sign = -1.0*sign;
796  }
797 
798  //along z
799  sign = -1.0;
800  for(int i = 0; i < m_nz; i++)
801  {
802  beta = -sign*2*M_PI*(i/2)/m_lhom_z;
803  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);
804  sign = -1.0*sign;
805  }
806  if(m_WaveSpace)
807  {
808  out_d1 = temparray1;
809  out_d2 = temparray2;
810  }
811  else
812  {
813  HomogeneousBwdTrans(temparray1,out_d1);
814  HomogeneousBwdTrans(temparray2,out_d2);
815  }
816  }
817  else
818  {
819  if(m_WaveSpace)
820  {
821  ASSERTL0(false,"Semi-phyisical time-stepping not implemented yet for non-Fourier basis")
822  }
823  else
824  {
825  StdRegions::StdQuadExp StdQuad(m_homogeneousBasis_y->GetBasisKey(),m_homogeneousBasis_z->GetBasisKey());
826 
827  m_transposition->Transpose(inarray,temparray,false,LibUtilities::eXtoYZ);
828 
829  for(int i = 0; i < n_points_line; i++)
830  {
831  StdQuad.PhysDeriv(tmp1 = temparray + i*nyzlines, tmp2 = temparray1 + i*nyzlines, tmp3 = temparray2 + i*nyzlines);
832  }
833 
834  m_transposition->Transpose(temparray1,out_d1,false,LibUtilities::eYZtoX);
835  m_transposition->Transpose(temparray2,out_d2,false,LibUtilities::eYZtoX);
836  Vmath::Smul(npoints,2.0/m_lhom_y,out_d1,1,out_d1,1);
837  Vmath::Smul(npoints,2.0/m_lhom_z,out_d2,1,out_d2,1);
838  }
839  }
840  }
841 
843  const Array<OneD, const NekDouble> &inarray,
844  Array<OneD, NekDouble> &out_d)
845 
846  {
847  int nyzlines = m_lines.num_elements(); //number of Fourier points in the Fourier directions (nF_pts)
848  int npoints = inarray.num_elements(); //number of total points = n. of Fourier points * n. of points per line (nT_pts)
849  int n_points_line = npoints/nyzlines; //number of points per line
850  //convert enum into int
851  int dir = (int)edir;
852 
853  Array<OneD, NekDouble> temparray(npoints);
854  Array<OneD, NekDouble> temparray1(npoints);
855  Array<OneD, NekDouble> temparray2(npoints);
859 
860  if (dir < 1)
861  {
862  for( int i=0 ; i<nyzlines ; i++)
863  {
864  m_lines[i]->PhysDeriv( tmp1 = inarray + i*n_points_line ,tmp2 = out_d + i*n_points_line);
865  }
866  }
867  else
868  {
870  {
871  if(m_WaveSpace)
872  {
873  temparray = inarray;
874  }
875  else
876  {
877  HomogeneousFwdTrans(inarray,temparray);
878  }
879  NekDouble sign = -1.0;
880  NekDouble beta;
881 
882  if (dir == 1)
883  {
884  //along y
885  for(int i = 0; i < m_ny; i++)
886  {
887  beta = -sign*2*M_PI*(i/2)/m_lhom_y;
888 
889  for(int j = 0; j < m_nz; j++)
890  {
891  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);
892  }
893  sign = -1.0*sign;
894  }
895  if(m_WaveSpace)
896  {
897  out_d = temparray1;
898  }
899  else
900  {
901  HomogeneousBwdTrans(temparray1,out_d);
902  }
903  }
904  else
905  {
906  //along z
907  for(int i = 0; i < m_nz; i++)
908  {
909  beta = -sign*2*M_PI*(i/2)/m_lhom_z;
910  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);
911  sign = -1.0*sign;
912  }
913  if(m_WaveSpace)
914  {
915  out_d = temparray2;
916  }
917  else
918  {
919  HomogeneousBwdTrans(temparray2,out_d);
920  }
921  }
922  }
923  else
924  {
925  if(m_WaveSpace)
926  {
927  ASSERTL0(false,"Semi-phyisical time-stepping not implemented yet for non-Fourier basis")
928  }
929  else
930  {
931  StdRegions::StdQuadExp StdQuad(m_homogeneousBasis_y->GetBasisKey(),m_homogeneousBasis_z->GetBasisKey());
932 
933  m_transposition->Transpose(inarray,temparray,false,LibUtilities::eXtoYZ);
934 
935  for(int i = 0; i < n_points_line; i++)
936  {
937  StdQuad.PhysDeriv(tmp1 = temparray + i*nyzlines, tmp2 = temparray1 + i*nyzlines, tmp3 = temparray2 + i*nyzlines);
938  }
939 
940  if (dir == 1)
941  {
942  m_transposition->Transpose(temparray1,out_d,false,LibUtilities::eYZtoX);
943  Vmath::Smul(npoints,2.0/m_lhom_y,out_d,1,out_d,1);
944  }
945  else
946  {
947  m_transposition->Transpose(temparray2,out_d,false,LibUtilities::eYZtoX);
948  Vmath::Smul(npoints,2.0/m_lhom_z,out_d,1,out_d,1);
949  }
950  }
951  }
952  }
953  }
954 
956  Array<OneD, NekDouble> &out_d0,
957  Array<OneD, NekDouble> &out_d1,
958  Array<OneD, NekDouble> &out_d2)
959 
960  {
961  v_PhysDeriv(inarray,out_d0,out_d1,out_d2);
962  }
963 
965  const Array<OneD, const NekDouble> &inarray,
966  Array<OneD, NekDouble> &out_d)
967  {
968  //convert int into enum
969  v_PhysDeriv(edir,inarray,out_d);
970  }
971 
973  {
974  NekDouble size_y = 1.5*m_ny;
975  NekDouble size_z = 1.5*m_nz;
976  m_padsize_y = int(size_y);
977  m_padsize_z = int(size_z);
978 
981 
984 
987 
988  StdRegions::StdQuadExp StdQuad(m_paddingBasis_y->GetBasisKey(),m_paddingBasis_z->GetBasisKey());
989 
990  StdRegions::StdMatrixKey matkey1(StdRegions::eFwdTrans,StdQuad.DetShapeType(),StdQuad);
991  StdRegions::StdMatrixKey matkey2(StdRegions::eBwdTrans,StdQuad.DetShapeType(),StdQuad);
992 
993  MatFwdPAD = StdQuad.GetStdMatrix(matkey1);
994  MatBwdPAD = StdQuad.GetStdMatrix(matkey2);
995  }
996  } //end of namespace
997 } //end of namespace
998 
999 
1000 /**
1001 * $Log: v $
1002 *
1003 **/
1004 
Abstraction of a two-dimensional multi-elemental expansion which is merely a collection of local expa...
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:161
LibUtilities::TranspositionSharedPtr m_transposition
void HomogeneousFwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, CoeffState coeffstate=eLocal, bool Shuff=true, bool UnShuff=true)
tBaseSharedPtr CreateInstance(tKey idKey BOOST_PP_COMMA_IF(MAX_PARAM) BOOST_PP_ENUM_BINARY_PARAMS(MAX_PARAM, tParam, x))
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:162
DNekBlkMatSharedPtr GenHomogeneous2DBlockMatrix(Homogeneous2DMatType mattype, CoeffState coeffstate=eLocal) const
static boost::shared_ptr< DataType > AllocateSharedPtr()
Allocate a shared pointer from the memory pool.
#define sign(a, b)
return the sign(b)*a
Definition: Polylib.cpp:22
virtual std::vector< LibUtilities::FieldDefinitionsSharedPtr > v_GetFieldDefinitions(void)
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
LibUtilities::BasisSharedPtr m_paddingBasis_z
Base expansion in z direction.
boost::shared_ptr< FieldDefinitions > FieldDefinitionsSharedPtr
Definition: FieldIO.h:118
static BasisSharedPtr NullBasisSharedPtr
Definition: Basis.h:358
Array< OneD, NekDouble > m_phys
The global expansion evaluated at the quadrature points.
Definition: ExpList.h:956
Fourier Expansion .
Definition: BasisType.h:52
LibUtilities::NektarFFTSharedPtr m_FFT_z
NekDouble m_lhom_z
Width of homogeneous direction z.
virtual void v_DealiasedProd(const Array< OneD, NekDouble > &inarray1, const Array< OneD, NekDouble > &inarray2, Array< OneD, NekDouble > &outarray, CoeffState coeffstate=eLocal)
Array< OneD, NekDouble > m_coeffs
Concatenation of all local expansion coefficients.
Definition: ExpList.h:939
void PhysDeriv(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_d0, Array< OneD, NekDouble > &out_d1, Array< OneD, NekDouble > &out_d2)
boost::shared_ptr< DNekMat > DNekMatSharedPtr
Definition: NekTypeDefs.hpp:70
NektarFFTFactory & GetNektarFFTFactory()
Definition: NektarFFT.cpp:69
boost::shared_ptr< SessionReader > SessionReaderSharedPtr
Definition: MeshPartition.h:51
virtual void v_BwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, CoeffState coeffstate)
Array< OneD, ExpListSharedPtr > m_lines
Vector of ExpList, will be filled with ExpList1D.
BasisManagerT & BasisManager(void)
virtual void v_IProductWRTBase_IterPerExp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Class representing a segment element in reference space.
Definition: StdSegExp.h:54
Array< OneD, int > m_coeff_offset
Offset of elemental data into the array m_coeffs.
Definition: ExpList.h:988
Base class for all multi-elemental spectral/hp expansions.
Definition: ExpList.h:101
1D Evenly-spaced points using Fourier Fit
Definition: PointsType.h:64
static const NekDouble kNekZeroTol
LibUtilities::BasisSharedPtr m_homogeneousBasis_z
Base expansion in z direction.
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*y.
Definition: Vmath.cpp:199
Array< OneD, int > m_phys_offset
Offset of elemental data into the array m_phys.
Definition: ExpList.h:991
virtual void v_HomogeneousFwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, CoeffState coeffstate=eLocal, bool Shuff=true, bool UnShuff=true)
NekDouble m_lhom_y
Width of homogeneous direction y.
static std::vector< unsigned int > NullUnsignedIntVector
Definition: FieldIO.h:51
Defines a specification for a set of points.
Definition: Points.h:58
double NekDouble
virtual void v_IProductWRTBase(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, CoeffState coeffstate)
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)
int m_ny
Number of modes = number of poitns in y direction.
LibUtilities::BasisSharedPtr m_homogeneousBasis_y
Definition of the total number of degrees of freedom and quadrature points. Sets up the storage for m...
void Homogeneous2DTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool IsForwards, CoeffState coeffstate=eLocal, bool Shuff=true, bool UnShuff=true)
int m_nz
Number of modes = number of poitns in z direction.
LibUtilities::BasisSharedPtr m_paddingBasis_y
Base expansion in y direction.
boost::shared_ptr< DNekBlkMat > DNekBlkMatSharedPtr
Definition: NekTypeDefs.hpp:72
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
virtual void v_BwdTrans_IterPerExp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
LibUtilities::CommSharedPtr m_comm
Communicator.
Definition: ExpList.h:907
map< Homogeneous2DMatType, DNekBlkMatSharedPtr > Homo2DBlockMatrixMap
A map between homo matrix keys and their associated block matrices.
#define ASSERTL2(condition, msg)
Assert Level 2 – Debugging which is used FULLDEBUG compilation mode. This level assert is designed t...
Definition: ErrorUtil.hpp:213
static const BasisKey NullBasisKey(eNoBasisType, 0, NullPointsKey)
Defines a null basis with no type or points.
LibUtilities::NektarFFTSharedPtr m_FFT_y
virtual void v_FwdTrans_IterPerExp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
virtual void v_WriteVtkPieceData(std::ostream &outfile, int expansion, std::string var)
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.
boost::shared_ptr< Basis > BasisSharedPtr
virtual void v_HomogeneousBwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, CoeffState coeffstate=eLocal, bool Shuff=true, bool UnShuff=true)
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1047
Describes the specification for a Basis.
Definition: Basis.h:50
virtual void v_FwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, CoeffState coeffstate)
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:169
virtual void v_AppendFieldData(LibUtilities::FieldDefinitionsSharedPtr &fielddef, std::vector< NekDouble > &fielddata)
void HomogeneousBwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, CoeffState coeffstate=eLocal, bool Shuff=true, bool UnShuff=true)
DNekBlkMatSharedPtr GetHomogeneous2DBlockMatrix(Homogeneous2DMatType mattype, CoeffState coeffstate=eLocal) const