Nektar++
LinearisedAdvection.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File LinearisedAdvection.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: Evaluation of the linearised advective term
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
36 #include <StdRegions/StdSegExp.h>
37 
38 using namespace std;
39 
40 namespace Nektar
41 {
42 string LinearisedAdvection::className
44  "Linearised",
45  LinearisedAdvection::create);
46 
47 /**
48  * Constructor. Creates ...
49  *
50  * \param
51  * \param
52  */
53 
54 LinearisedAdvection::LinearisedAdvection():
55  Advection()
56 {
57 }
58 
59 
63 {
64  Advection::v_InitObject(pSession, pFields);
65 
66  m_session = pSession;
68  ::AllocateSharedPtr(m_session, pFields[0]->GetGraph());
69  m_spacedim = pFields[0]->GetGraph()->GetSpaceDimension();
70  m_expdim = pFields[0]->GetGraph()->GetMeshDimension();
71 
72  //Setting parameters for homogeneous problems
73  m_HomoDirec = 0;
74  m_useFFT = false;
76  m_singleMode = false;
77  m_halfMode = false;
78  m_multipleModes = false;
79 
80  if(m_session->DefinesSolverInfo("HOMOGENEOUS"))
81  {
82  std::string HomoStr = m_session->GetSolverInfo("HOMOGENEOUS");
83  m_spacedim = 3;
84 
85  if((HomoStr == "HOMOGENEOUS1D")||(HomoStr == "Homogeneous1D")||
86  (HomoStr == "1D")||(HomoStr == "Homo1D"))
87  {
89  m_LhomZ = m_session->GetParameter("LZ");
90  m_HomoDirec = 1;
91 
92  ASSERTL0(m_session->DefinesSolverInfo("ModeType"),
93  "Need to specify ModeType as HalfMode,SingleMode or "
94  "MultipleModes");
95 
96  m_session->MatchSolverInfo("ModeType", "SingleMode",
97  m_singleMode, false);
98  m_session->MatchSolverInfo("ModeType", "HalfMode",
99  m_halfMode, false);
100  m_session->MatchSolverInfo("ModeType", "MultipleModes",
101  m_multipleModes, false);
102 
103  if(m_singleMode)
104  {
105  m_npointsZ = 2;
106  }
107  else if(m_halfMode)
108  {
109  m_npointsZ = 1;
110  }
111  else if(m_multipleModes)
112  {
113  m_npointsZ = m_session->GetParameter("HomModesZ");
114  }
115  }
116 
117  if((HomoStr == "HOMOGENEOUS2D")||(HomoStr == "Homogeneous2D")||
118  (HomoStr == "2D")||(HomoStr == "Homo2D"))
119  {
121  m_session->LoadParameter("HomModesY", m_npointsY);
122  m_session->LoadParameter("LY", m_LhomY);
123  m_session->LoadParameter("HomModesZ", m_npointsZ);
124  m_session->LoadParameter("LZ", m_LhomZ);
125  m_HomoDirec = 2;
126  }
127 
128  if((HomoStr == "HOMOGENEOUS3D")||(HomoStr == "Homogeneous3D")||
129  (HomoStr == "3D")||(HomoStr == "Homo3D"))
130  {
132  m_session->LoadParameter("HomModesX",m_npointsX);
133  m_session->LoadParameter("LX", m_LhomX );
134  m_session->LoadParameter("HomModesY",m_npointsY);
135  m_session->LoadParameter("LY", m_LhomY );
136  m_session->LoadParameter("HomModesZ",m_npointsZ);
137  m_session->LoadParameter("LZ", m_LhomZ );
138  m_HomoDirec = 3;
139  }
140 
141  if(m_session->DefinesSolverInfo("USEFFT"))
142  {
143  m_useFFT = true;
144  }
145  }
146  else
147  {
148  m_npointsZ = 1; // set to default value so can use to identify 2d or 3D (homogeneous) expansions
149  }
150 
151  int nvar = m_session->GetVariables().size();
153  for (int i = 0; i < nvar; ++i)
154  {
155  m_baseflow[i] = Array<OneD, NekDouble>(pFields[i]->GetTotPoints(), 0.0);
156  }
157 
158  int nBaseDerivs = (m_halfMode || m_singleMode) ? 2 : m_spacedim;
159  m_gradBase = Array<OneD, Array<OneD, NekDouble> >(nvar*nBaseDerivs);
160  for (int i = 0; i < nvar; ++i)
161  {
162  for (int j = 0; j < nBaseDerivs; ++j)
163  {
164  m_gradBase[i*nBaseDerivs + j ] = Array<OneD, NekDouble>
165  (pFields[i]->GetTotPoints(), 0.0);
166  }
167  }
168 
169  ASSERTL0(m_session->DefinesFunction("BaseFlow"),
170  "Base flow must be defined for linearised forms.");
171  string file = m_session->GetFunctionFilename("BaseFlow", 0);
172 
173 
174  //Periodic base flows
175  if (m_session->DefinesParameter("N_slices"))
176  {
177  m_session->LoadParameter("N_slices",m_slices);
178  if (m_slices > 1)
179  {
180  ASSERTL0(m_session->GetFunctionType("BaseFlow", 0)
182  "Base flow should be a sequence of files.");
183  m_session->LoadParameter("BaseFlow_interporder", m_interporder, 0);
185  "BaseFlow_interporder should be smaller than or equal to N_slices.");
187  m_session->LoadParameter("N_start", m_start, 0);
188  m_session->LoadParameter("N_skip", m_skip, 1);
189  DFT(file,pFields,m_slices);
190  }
191  else
192  {
193  ASSERTL0(false, "Number of slices must be a positive number "
194  "greater than 1");
195  }
196  }
197  //Steady base-flow
198  else
199  {
200  m_slices=1;
201 
202  //BaseFlow from file
203  if (m_session->GetFunctionType("BaseFlow", m_session->GetVariable(0))
205  {
206  ImportFldBase(file,pFields,1);
207 
208  }
209  //analytic base flow
210  else
211  {
212  int nq = pFields[0]->GetNpoints();
213  Array<OneD,NekDouble> x0(nq);
214  Array<OneD,NekDouble> x1(nq);
215  Array<OneD,NekDouble> x2(nq);
216 
217  // get the coordinates (assuming all fields have the same
218  // discretisation)
219  pFields[0]->GetCoords(x0,x1,x2);
220 
221  for(unsigned int i = 0 ; i < pFields.size(); i++)
222  {
224  = m_session->GetFunction("BaseFlow", i);
225 
226  ifunc->Evaluate(x0,x1,x2,m_baseflow[i]);
227  }
228  }
229  }
230 
231  for (int i = 0; i < nvar; ++i)
232  {
233  UpdateGradBase(i, pFields[i]);
234  }
235 
236  if (m_session->DefinesParameter("period"))
237  {
238  m_period=m_session->GetParameter("period");
239  }
240  else
241  {
242  m_period=(m_session->GetParameter("TimeStep")*m_slices)/(m_slices-1.);
243  }
244  if (m_session->GetComm()->GetRank() == 0)
245  {
246  cout << "baseflow info : interpolation order " << m_interporder
247  << ", period " << m_period << ", periodicity ";
248  if (m_isperiodic)
249  {
250  cout << "yes\n";
251  }
252  else
253  {
254  cout << "no\n";
255  }
256  cout << "baseflow info : files from " << m_start << " to "
257  << (m_start + (m_slices-1)*m_skip)
258  << " (skip " << m_skip << ") with " << (m_slices - (m_interporder > 1))
259  << " time intervals" << endl;
260  }
261 }
262 
264 {
265 }
266 
267 
268 //Advection function
269 
271  const int nConvectiveFields,
273  const Array<OneD, Array<OneD, NekDouble> > &advVel,
274  const Array<OneD, Array<OneD, NekDouble> > &inarray,
275  Array<OneD, Array<OneD, NekDouble> > &outarray,
276  const NekDouble &time,
277  const Array<OneD, Array<OneD, NekDouble> > &pFwd,
278  const Array<OneD, Array<OneD, NekDouble> > &pBwd)
279 {
280  ASSERTL1(nConvectiveFields == inarray.size(),
281  "Number of convective fields and Inarray are not compatible");
282 
283  int nPointsTot = fields[0]->GetNpoints();
284  int ndim = advVel.size();
285  int nBaseDerivs = (m_halfMode || m_singleMode) ? 2 : m_spacedim;
286  int nDerivs = (m_halfMode) ? 2 : m_spacedim;
287 
288  Array<OneD, Array<OneD, NekDouble> > velocity(ndim);
289  for(int i = 0; i < ndim; ++i)
290  {
291  if(fields[i]->GetWaveSpace() && !m_singleMode && !m_halfMode)
292  {
293  velocity[i] = Array<OneD, NekDouble>(nPointsTot,0.0);
294  fields[i]->HomogeneousBwdTrans(advVel[i],velocity[i]);
295  }
296  else
297  {
298  velocity[i] = advVel[i];
299  }
300  }
301 
302  Array<OneD, Array<OneD, NekDouble> > grad (nDerivs);
303  for( int i = 0; i < nDerivs; ++i)
304  {
305  grad[i] = Array<OneD, NekDouble> (nPointsTot);
306  }
307 
308  // Evaluation of the base flow for periodic cases
309  if (m_slices > 1)
310  {
311  for (int i = 0; i < ndim; ++i)
312  {
314  time, m_period);
315  UpdateGradBase(i, fields[i]);
316  }
317  }
318 
319  //Evaluate the linearised advection term
320  for( int i = 0; i < nConvectiveFields; ++i)
321  {
322  // Calculate gradient
323  switch(nDerivs)
324  {
325  case 1:
326  {
327  fields[i]->PhysDeriv(inarray[i], grad[0]);
328  }
329  break;
330  case 2:
331  {
332  fields[i]->PhysDeriv(inarray[i], grad[0], grad[1]);
333  }
334  break;
335  case 3:
336  {
337  fields[i]->PhysDeriv(inarray[i], grad[0], grad[1], grad[2]);
338  if(m_multipleModes)
339  {
340  // transform gradients into physical Fourier space
341  fields[i]->HomogeneousBwdTrans(grad[0], grad[0]);
342  fields[i]->HomogeneousBwdTrans(grad[1], grad[1]);
343  fields[i]->HomogeneousBwdTrans(grad[2], grad[2]);
344  }
345  }
346  break;
347  }
348 
349  // Calculate U_j du'_i/dx_j
350  Vmath::Vmul(nPointsTot,grad[0], 1, m_baseflow[0], 1, outarray[i], 1);
351  for( int j = 1; j < nDerivs; ++j)
352  {
353  Vmath::Vvtvp(nPointsTot,grad[j], 1,
354  m_baseflow[j], 1,
355  outarray[i], 1,
356  outarray[i], 1);
357  }
358 
359  // Add u'_j dU_i/dx_j
360  int lim = (m_halfMode || m_singleMode) ? 2 : ndim;
361  if (m_halfMode && i==2)
362  {
363  lim = 0;
364  }
365  for( int j = 0; j < lim; ++j)
366  {
367  Vmath::Vvtvp(nPointsTot,m_gradBase[i*nBaseDerivs + j], 1,
368  velocity[j], 1,
369  outarray[i], 1,
370  outarray[i], 1);
371  }
372 
373  if(m_multipleModes)
374  {
375  fields[i]->HomogeneousFwdTrans(outarray[i],outarray[i]);
376  }
377  Vmath::Neg(nPointsTot,outarray[i],1);
378  }
379 }
380 
382  const Array<OneD, Array<OneD, NekDouble> > &inarray,
384 {
385  if (m_session->GetSolverInfo("EqType") == "UnsteadyNavierStokes")
386  {
387  // The SFD method is only applied to the velocity variables in
388  // incompressible
389  ASSERTL1(inarray.size() == (m_baseflow.size() - 1),
390  "Number of base flow variables does not match what is "
391  "expected.");
392  }
393  else
394  {
395  ASSERTL1(inarray.size() == (m_baseflow.size()),
396  "Number of base flow variables does not match what is expected.");
397  }
398 
399  int npts = inarray[0].size();
400 
401  for (int i = 0; i < inarray.size(); ++i)
402  {
403  ASSERTL1(npts == m_baseflow[i].size(),
404  "Size of base flow array does not match expected.");
405  Vmath::Vcopy(npts, inarray[i], 1, m_baseflow[i], 1);
406  UpdateGradBase(i, fields[i]);
407  }
408 }
409 
410 
411 /**
412  * Import field from infile and load into \a m_fields. This routine will
413  * also perform a \a BwdTrans to ensure data is in both the physical and
414  * coefficient storage.
415  * @param pInFile Filename to read.
416  * @param pFields Array of expansion lists
417  */
419  std::string pInfile,
421  int pSlice)
422 {
423  std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef;
424  std::vector<std::vector<NekDouble> > FieldData;
425 
426  int nqtot = m_baseflow[0].size();
427  Array<OneD, NekDouble> tmp_coeff(pFields[0]->GetNcoeffs(), 0.0);
428 
429  int numexp = pFields[0]->GetExpSize();
430  Array<OneD,int> ElementGIDs(numexp);
431 
432  // Define list of global element ids
433  for(int i = 0; i < numexp; ++i)
434  {
435  ElementGIDs[i] = pFields[0]->GetExp(i)->GetGeom()->GetGlobalID();
436  }
437 
438  //Get Homogeneous
440  m_session, pInfile);
441  fld->Import(pInfile, FieldDef, FieldData,
443  ElementGIDs);
444 
445  int nSessionVar = m_session->GetVariables().size();
446  int nSessionConvVar = nSessionVar - 1;
447  int nFileVar = FieldDef[0]->m_fields.size();
448  int nFileConvVar = nFileVar - 1; // Ignore pressure
449  if (m_halfMode)
450  {
451  ASSERTL0(nFileVar == 3, "For half mode, expect 2D2C base flow.");
452  nFileConvVar = 2;
453  }
454 
455  for(int j = 0; j < nFileConvVar; ++j)
456  {
457  for(int i = 0; i < FieldDef.size(); ++i)
458  {
459  bool flag = FieldDef[i]->m_fields[j] ==
460  m_session->GetVariable(j);
461 
462  ASSERTL0(flag, (std::string("Order of ") + pInfile
463  + std::string(" data and that defined in "
464  "the session file differs")).c_str());
465 
466  pFields[j]->ExtractDataToCoeffs(
467  FieldDef[i],
468  FieldData[i],
469  FieldDef[i]->m_fields[j],
470  tmp_coeff);
471  }
472 
473  if(m_singleMode || m_halfMode)
474  {
475  pFields[j]->GetPlane(0)->BwdTrans(tmp_coeff, m_baseflow[j]);
476 
477  if(m_singleMode)
478  {
479  //copy the bwd trans into the second plane for single
480  //Mode Analysis
481  int ncplane=(pFields[0]->GetNpoints())/m_npointsZ;
482  Vmath::Vcopy(ncplane,&m_baseflow[j][0],1,&m_baseflow[j][ncplane],1);
483  }
484  }
485  else // fully 3D base flow - put in physical space.
486  {
487  bool oldwavespace = pFields[j]->GetWaveSpace();
488  pFields[j]->SetWaveSpace(false);
489  pFields[j]->BwdTrans(tmp_coeff, m_baseflow[j]);
490  pFields[j]->SetWaveSpace(oldwavespace);
491  }
492  }
493 
494  // Zero unused fields (e.g. w in a 2D2C base flow).
495  for (int j = nFileConvVar; j < nSessionConvVar; ++j)
496  {
497  Vmath::Fill(nqtot, 0.0, m_baseflow[j], 1);
498  }
499 
500  // If time-periodic, put loaded data into the slice storage.
501  if (m_slices > 1)
502  {
503  for(int i = 0; i < nSessionConvVar; ++i)
504  {
505  Vmath::Vcopy(nqtot, &m_baseflow[i][0], 1, &m_interp[i][pSlice*nqtot], 1);
506  }
507  }
508 }
509 
510 
512  const NekDouble m_slices,
513  const Array<OneD, const NekDouble> &inarray,
514  Array<OneD, NekDouble> &outarray,
515  const NekDouble m_time,
516  const NekDouble m_period)
517 {
518  int npoints = m_baseflow[0].size();
519  if (m_isperiodic)
520  {
521  NekDouble BetaT = 2*M_PI*fmod (m_time, m_period) / m_period;
522  NekDouble phase;
523  Array<OneD, NekDouble> auxiliary(npoints);
524 
525  Vmath::Vcopy(npoints,&inarray[0],1,&outarray[0],1);
526  Vmath::Svtvp(npoints, cos(0.5*m_slices*BetaT),&inarray[npoints],1,&outarray[0],1,&outarray[0],1);
527 
528  for (int i = 2; i < m_slices; i += 2)
529  {
530  phase = (i>>1) * BetaT;
531 
532  Vmath::Svtvp(npoints, cos(phase),&inarray[i*npoints],1,&outarray[0],1,&outarray[0],1);
533  Vmath::Svtvp(npoints, -sin(phase), &inarray[(i+1)*npoints], 1, &outarray[0], 1,&outarray[0],1);
534  }
535  }
536  else
537  {
538  NekDouble x = m_time;
539  x = x/m_period*(m_slices-1);
540  int ix = x;
541  if (ix < 0)
542  {
543  ix = 0;
544  }
545  if (ix > m_slices-2)
546  {
547  ix = m_slices-2;
548  }
549  int padleft = m_interporder/2 - 1;
550  if (padleft > ix)
551  {
552  padleft = ix;
553  }
554  int padright = m_interporder - 1 - padleft;
555  if (padright > m_slices-1-ix)
556  {
557  padright = m_slices-1-ix;
558  }
559  padleft = m_interporder - 1 - padright;
561  for (int i=0; i<m_interporder; ++i)
562  {
563  for (int j=0; j<m_interporder; ++j)
564  {
565  if (i!=j)
566  {
567  coeff[i] *= (x - ix + padleft - (NekDouble)j) /
568  ((NekDouble)i - (NekDouble)j);
569  }
570  }
571  }
572  Vmath::Zero(npoints, &outarray[0], 1);
573  for (int i = ix-padleft; i < ix+padright+1; ++i)
574  {
575  Vmath::Svtvp(npoints, coeff[i-ix+padleft], &inarray[i*npoints], 1,
576  &outarray[0], 1, &outarray[0], 1);
577  }
578  }
579 }
580 
582  const int var,
583  const MultiRegions::ExpListSharedPtr &field)
584 {
585  int nBaseDerivs = (m_halfMode || m_singleMode) ? 2 : m_spacedim;
586  switch(m_spacedim)
587  {
588  case 1: // 1D
589  {
590  field->PhysDeriv(m_baseflow[var], m_gradBase[var*nBaseDerivs + 0]);
591  }
592  break;
593  case 2: //2D
594  {
595  field->PhysDeriv(m_baseflow[var], m_gradBase[var*nBaseDerivs + 0],
596  m_gradBase[var*nBaseDerivs + 1]);
597  }
598  break;
599  case 3:
600  {
601  if(m_halfMode) // can assume W = 0 and d/dz == 0
602  {
603  if( var < 2)
604  {
605  field->PhysDeriv(m_baseflow[var],
606  m_gradBase[var*nBaseDerivs + 0],
607  m_gradBase[var*nBaseDerivs + 1]);
608  }
609  }
610  else if(m_singleMode) // single mode where d/dz = 0
611  {
612  field->PhysDeriv(m_baseflow[var], m_gradBase[var*nBaseDerivs + 0],
613  m_gradBase[var*nBaseDerivs + 1]);
614  }
615  else
616  {
617  // Differentiate base flow in physical space
618  bool oldwavespace = field->GetWaveSpace();
619  field->SetWaveSpace(false);
620  field->PhysDeriv(m_baseflow[var], m_gradBase[var*nBaseDerivs + 0],
621  m_gradBase[var*nBaseDerivs + 1],
622  m_gradBase[var*nBaseDerivs + 2]);
623  field->SetWaveSpace(oldwavespace);
624  }
625  }
626  break;
627  }
628 }
629 
631 {
632  DNekMatSharedPtr loc_mat;
633  DNekBlkMatSharedPtr BlkMatrix;
634  int n_exp = 0;
635 
636  n_exp = m_baseflow[0].size(); // will operatore on m_phys
637 
638  Array<OneD,unsigned int> nrows(n_exp);
639  Array<OneD,unsigned int> ncols(n_exp);
640 
641  nrows = Array<OneD, unsigned int>(n_exp,m_slices);
642  ncols = Array<OneD, unsigned int>(n_exp,m_slices);
643 
644  MatrixStorage blkmatStorage = eDIAGONAL;
645  BlkMatrix = MemoryManager<DNekBlkMat>
646  ::AllocateSharedPtr(nrows,ncols,blkmatStorage);
647 
648 
651  StdRegions::StdSegExp StdSeg(BK);
652 
654  StdSeg.DetShapeType(),
655  StdSeg);
656 
657  loc_mat = StdSeg.GetStdMatrix(matkey);
658 
659  // set up array of block matrices.
660  for(int i = 0; i < n_exp; ++i)
661  {
662  BlkMatrix->SetBlock(i,i,loc_mat);
663  }
664 
665  return BlkMatrix;
666 }
667 
668 //Discrete Fourier Transform for Floquet analysis
669 void LinearisedAdvection::DFT(const string file,
671  const NekDouble m_slices)
672 {
673  int ConvectedFields = m_baseflow.size()-1;
674  int npoints = m_baseflow[0].size();
675  m_interp = Array<OneD, Array<OneD, NekDouble> > (ConvectedFields);
676 
677  for (int i = 0; i < ConvectedFields; ++i)
678  {
679  m_interp[i] = Array<OneD,NekDouble>(npoints*m_slices, 0.0);
680  }
681 
682  // Import the slides into auxiliary vector
683  // The base flow should be stored in the form "filename_%d.ext"
684  // A subdirectory can also be included, such as "dir/filename_%d.ext"
685  size_t found = file.find("%d");
686  ASSERTL0(found != string::npos && file.find("%d", found+1) == string::npos,
687  "Since N_slices is specified, the filename provided for function "
688  "'BaseFlow' must include exactly one instance of the format "
689  "specifier '%d', to index the time-slices.");
690  char* buffer = new char[file.length() + 8];
691  int nstart = m_start;
692  for (int i = nstart; i < nstart+m_slices*m_skip; i+=m_skip)
693  {
694  sprintf(buffer, file.c_str(), i);
695  ImportFldBase(buffer,pFields,(i-nstart)/m_skip);
696  if(m_session->GetComm()->GetRank() == 0)
697  {
698  cout << "read base flow file " << buffer << endl;
699  }
700  }
701  delete[] buffer;
702  if(!m_isperiodic)
703  {
704  return;
705  }
706 
707  // Discrete Fourier Transform of the fields
708  for(int k=0; k< ConvectedFields;++k)
709  {
710 #ifdef NEKTAR_USING_FFTW
711 
712  //Discrete Fourier Transform using FFTW
713  Array<OneD, NekDouble> fft_in(npoints*m_slices);
714  Array<OneD, NekDouble> fft_out(npoints*m_slices);
715 
718 
719  //Shuffle the data
720  for(int j= 0; j < m_slices; ++j)
721  {
722  Vmath::Vcopy(npoints,&m_interp[k][j*npoints],1,&(fft_in[j]),m_slices);
723  }
724 
726 
727  //FFT Transform
728  for(int i=0; i<npoints; i++)
729  {
730  m_FFT->FFTFwdTrans(m_tmpIN =fft_in + i*m_slices, m_tmpOUT =fft_out + i*m_slices);
731 
732  }
733 
734  //Reshuffle data
735  for(int s = 0; s < m_slices; ++s)
736  {
737  Vmath::Vcopy(npoints,&fft_out[s],m_slices,&m_interp[k][s*npoints],1);
738 
739  }
740 
741  Vmath::Zero(fft_in.size(),&fft_in[0],1);
742  Vmath::Zero(fft_out.size(),&fft_out[0],1);
743 #else
744  //Discrete Fourier Transform using MVM
745  DNekBlkMatSharedPtr blkmat;
747 
748  int nrows = blkmat->GetRows();
749  int ncols = blkmat->GetColumns();
750 
751  Array<OneD, NekDouble> sortedinarray(ncols);
752  Array<OneD, NekDouble> sortedoutarray(nrows);
753 
754  //Shuffle the data
755  for(int j= 0; j < m_slices; ++j)
756  {
757  Vmath::Vcopy(npoints,&m_interp[k][j*npoints],1,&(sortedinarray[j]),m_slices);
758  }
759 
760  // Create NekVectors from the given data arrays
761  NekVector<NekDouble> in (ncols,sortedinarray,eWrapper);
762  NekVector<NekDouble> out(nrows,sortedoutarray,eWrapper);
763 
764  // Perform matrix-vector multiply.
765  out = (*blkmat)*in;
766 
767  //Reshuffle data
768  for(int s = 0; s < m_slices; ++s)
769  {
770  Vmath::Vcopy(npoints,&sortedoutarray[s],m_slices,&m_interp[k][s*npoints],1);
771  }
772 
773  for(int r=0; r<sortedinarray.size();++r)
774  {
775  sortedinarray[0]=0;
776  sortedoutarray[0]=0;
777  }
778 
779 #endif
780  }
781 
782 }
783 
784 } //end of namespace
785 
#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
Describes the specification for a Basis.
Definition: Basis.h:50
static std::shared_ptr< FieldIO > CreateForFile(const LibUtilities::SessionReaderSharedPtr session, const std::string &filename)
Construct a FieldIO object for a given input filename.
Definition: FieldIO.cpp:226
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:200
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
SpatialDomains::BoundaryConditionsSharedPtr m_boundaryConditions
int m_npointsZ
number of points in Z direction (if homogeneous)
NekDouble m_LhomZ
physical length in Z direction (if homogeneous)
enum HomogeneousType m_HomogeneousType
NekDouble m_period
period length
int m_npointsX
number of points in X direction (if homogeneous)
int m_npointsY
number of points in Y direction (if homogeneous)
int m_HomoDirec
number of homogenous directions
virtual void v_SetBaseFlow(const Array< OneD, Array< OneD, NekDouble > > &inarray, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields)
Overrides the base flow used during linearised advection.
virtual void v_Advect(const int nConvectiveFields, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble > > &advVel, const Array< OneD, Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble &time, const Array< OneD, Array< OneD, NekDouble > > &pFwd=NullNekDoubleArrayOfArray, const Array< OneD, Array< OneD, NekDouble > > &pBwd=NullNekDoubleArrayOfArray)
Advects a vector field.
bool m_useFFT
flag to determine if use or not the FFT for transformations
Array< OneD, NekDouble > m_tmpIN
LibUtilities::SessionReaderSharedPtr m_session
virtual void v_InitObject(LibUtilities::SessionReaderSharedPtr pSession, Array< OneD, MultiRegions::ExpListSharedPtr > pFields)
Initialises the advection object.
void UpdateGradBase(const int var, const MultiRegions::ExpListSharedPtr &field)
DNekBlkMatSharedPtr GetFloquetBlockMatrix(FloquetMatType mattype, bool UseContCoeffs=false) const
void DFT(const std::string file, Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const NekDouble m_slices)
bool m_singleMode
flag to determine if use single mode or not
Array< OneD, Array< OneD, NekDouble > > m_baseflow
Storage for base flow.
Array< OneD, Array< OneD, NekDouble > > m_gradBase
void UpdateBase(const NekDouble m_slices, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const NekDouble m_time, const NekDouble m_period)
bool m_multipleModes
flag to determine if use multiple mode or not
LibUtilities::NektarFFTSharedPtr m_FFT
auxiliary variables
bool m_halfMode
flag to determine if use half mode or not
NekDouble m_LhomY
physical length in Y direction (if homogeneous)
void ImportFldBase(std::string pInfile, Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, int slice)
Import Base flow.
NekDouble m_LhomX
physical length in X direction (if homogeneous)
Array< OneD, Array< OneD, NekDouble > > m_interp
interpolation vector
Array< OneD, NekDouble > m_tmpOUT
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
An abstract base class encapsulating the concept of advection of a vector field.
Definition: Advection.h:73
virtual SOLVER_UTILS_EXPORT void v_InitObject(LibUtilities::SessionReaderSharedPtr pSession, Array< OneD, MultiRegions::ExpListSharedPtr > pFields)
Initialises the advection object.
Definition: Advection.cpp:366
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
Class representing a segment element in reference space.
Definition: StdSegExp.h:54
array buffer
Definition: GsLib.hpp:61
NektarFFTFactory & GetNektarFFTFactory()
Definition: NektarFFT.cpp:69
std::shared_ptr< FieldIO > FieldIOSharedPtr
Definition: FieldIO.h:306
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< Equation > EquationSharedPtr
Definition: Equation.h:131
static FieldMetaDataMap NullFieldMetaDataMap
Definition: FieldIO.h:53
@ eFourierEvenlySpaced
1D Evenly-spaced points using Fourier Fit
Definition: PointsType.h:65
@ eFourier
Fourier Expansion .
Definition: BasisType.h:53
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
AdvectionFactory & GetAdvectionFactory()
Gets the factory for initialising advection objects.
Definition: Advection.cpp:47
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 Svtvp(int n, const T alpha, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
svtvp (scalar times vector plus vector): z = alpha*x + y
Definition: Vmath.cpp:565
void Neg(int n, T *x, const int incx)
Negate x = -x.
Definition: Vmath.cpp:461
void Vvtvp(int n, const T *w, const int incw, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
vvtvp (vector times vector plus vector): z = w*x + y
Definition: Vmath.cpp:513
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:436
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
Definition: Vmath.cpp:45
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1199