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  DFT(file,pFields,m_slices);
184  }
185  else
186  {
187  ASSERTL0(false, "Number of slices must be a positive number "
188  "greater than 1");
189  }
190  }
191  //Steady base-flow
192  else
193  {
194  m_slices=1;
195 
196  //BaseFlow from file
197  if (m_session->GetFunctionType("BaseFlow", m_session->GetVariable(0))
199  {
200  ImportFldBase(file,pFields,1);
201 
202  }
203  //analytic base flow
204  else
205  {
206  int nq = pFields[0]->GetNpoints();
207  Array<OneD,NekDouble> x0(nq);
208  Array<OneD,NekDouble> x1(nq);
209  Array<OneD,NekDouble> x2(nq);
210 
211  // get the coordinates (assuming all fields have the same
212  // discretisation)
213  pFields[0]->GetCoords(x0,x1,x2);
214 
215  for(unsigned int i = 0 ; i < pFields.num_elements(); i++)
216  {
218  = m_session->GetFunction("BaseFlow", i);
219 
220  ifunc->Evaluate(x0,x1,x2,m_baseflow[i]);
221  }
222  }
223  }
224 
225  for (int i = 0; i < nvar; ++i)
226  {
227  UpdateGradBase(i, pFields[i]);
228  }
229 
230  if(m_session->DefinesParameter("period"))
231  {
232  m_period=m_session->GetParameter("period");
233  }
234  else
235  {
236  m_period=(m_session->GetParameter("TimeStep")*m_slices)/(m_slices-1.);
237  }
238 
239 }
240 
242 {
243 }
244 
245 
246 //Advection function
247 
249  const int nConvectiveFields,
251  const Array<OneD, Array<OneD, NekDouble> > &advVel,
252  const Array<OneD, Array<OneD, NekDouble> > &inarray,
253  Array<OneD, Array<OneD, NekDouble> > &outarray,
254  const NekDouble &time,
255  const Array<OneD, Array<OneD, NekDouble> > &pFwd,
256  const Array<OneD, Array<OneD, NekDouble> > &pBwd)
257 {
258  ASSERTL1(nConvectiveFields == inarray.num_elements(),
259  "Number of convective fields and Inarray are not compatible");
260 
261  int nPointsTot = fields[0]->GetNpoints();
262  int ndim = advVel.num_elements();
263  int nBaseDerivs = (m_halfMode || m_singleMode) ? 2 : m_spacedim;
264  int nDerivs = (m_halfMode) ? 2 : m_spacedim;
265 
266  Array<OneD, Array<OneD, NekDouble> > velocity(ndim);
267  for(int i = 0; i < ndim; ++i)
268  {
269  if(fields[i]->GetWaveSpace() && !m_singleMode && !m_halfMode)
270  {
271  velocity[i] = Array<OneD, NekDouble>(nPointsTot,0.0);
272  fields[i]->HomogeneousBwdTrans(advVel[i],velocity[i]);
273  }
274  else
275  {
276  velocity[i] = advVel[i];
277  }
278  }
279 
280  Array<OneD, Array<OneD, NekDouble> > grad (nDerivs);
281  for( int i = 0; i < nDerivs; ++i)
282  {
283  grad[i] = Array<OneD, NekDouble> (nPointsTot);
284  }
285 
286  // Evaluation of the base flow for periodic cases
287  if (m_slices > 1)
288  {
289  for (int i = 0; i < ndim; ++i)
290  {
292  time, m_period);
293  UpdateGradBase(i, fields[i]);
294  }
295  }
296 
297  //Evaluate the linearised advection term
298  for( int i = 0; i < nConvectiveFields; ++i)
299  {
300  // Calculate gradient
301  switch(nDerivs)
302  {
303  case 1:
304  {
305  fields[i]->PhysDeriv(inarray[i], grad[0]);
306  }
307  break;
308  case 2:
309  {
310  fields[i]->PhysDeriv(inarray[i], grad[0], grad[1]);
311  }
312  break;
313  case 3:
314  {
315  fields[i]->PhysDeriv(inarray[i], grad[0], grad[1], grad[2]);
316  if(m_multipleModes)
317  {
318  // transform gradients into physical Fourier space
319  fields[i]->HomogeneousBwdTrans(grad[0], grad[0]);
320  fields[i]->HomogeneousBwdTrans(grad[1], grad[1]);
321  fields[i]->HomogeneousBwdTrans(grad[2], grad[2]);
322  }
323  }
324  break;
325  }
326 
327  // Calculate U_j du'_i/dx_j
328  Vmath::Vmul(nPointsTot,grad[0], 1, m_baseflow[0], 1, outarray[i], 1);
329  for( int j = 1; j < nDerivs; ++j)
330  {
331  Vmath::Vvtvp(nPointsTot,grad[j], 1,
332  m_baseflow[j], 1,
333  outarray[i], 1,
334  outarray[i], 1);
335  }
336 
337  // Add u'_j dU_i/dx_j
338  int lim = (m_halfMode || m_singleMode) ? 2 : ndim;
339  if (m_halfMode && i==2)
340  {
341  lim = 0;
342  }
343  for( int j = 0; j < lim; ++j)
344  {
345  Vmath::Vvtvp(nPointsTot,m_gradBase[i*nBaseDerivs + j], 1,
346  velocity[j], 1,
347  outarray[i], 1,
348  outarray[i], 1);
349  }
350 
351  if(m_multipleModes)
352  {
353  fields[i]->HomogeneousFwdTrans(outarray[i],outarray[i]);
354  }
355  Vmath::Neg(nPointsTot,outarray[i],1);
356  }
357 }
358 
360  const Array<OneD, Array<OneD, NekDouble> > &inarray,
362 {
363  if (m_session->GetSolverInfo("EqType") == "UnsteadyNavierStokes")
364  {
365  // The SFD method is only applied to the velocity variables in
366  // incompressible
367  ASSERTL1(inarray.num_elements() == (m_baseflow.num_elements() - 1),
368  "Number of base flow variables does not match what is "
369  "expected.");
370  }
371  else
372  {
373  ASSERTL1(inarray.num_elements() == (m_baseflow.num_elements()),
374  "Number of base flow variables does not match what is expected.");
375  }
376 
377  int npts = inarray[0].num_elements();
378 
379  for (int i = 0; i < inarray.num_elements(); ++i)
380  {
381  ASSERTL1(npts == m_baseflow[i].num_elements(),
382  "Size of base flow array does not match expected.");
383  Vmath::Vcopy(npts, inarray[i], 1, m_baseflow[i], 1);
384  UpdateGradBase(i, fields[i]);
385  }
386 }
387 
388 
389 /**
390  * Import field from infile and load into \a m_fields. This routine will
391  * also perform a \a BwdTrans to ensure data is in both the physical and
392  * coefficient storage.
393  * @param pInFile Filename to read.
394  * @param pFields Array of expansion lists
395  */
397  std::string pInfile,
399  int pSlice)
400 {
401  std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef;
402  std::vector<std::vector<NekDouble> > FieldData;
403 
404  int nqtot = m_baseflow[0].num_elements();
405  Array<OneD, NekDouble> tmp_coeff(pFields[0]->GetNcoeffs(), 0.0);
406 
407  int numexp = pFields[0]->GetExpSize();
408  Array<OneD,int> ElementGIDs(numexp);
409 
410  // Define list of global element ids
411  for(int i = 0; i < numexp; ++i)
412  {
413  ElementGIDs[i] = pFields[0]->GetExp(i)->GetGeom()->GetGlobalID();
414  }
415 
416  //Get Homogeneous
418  m_session, pInfile);
419  fld->Import(pInfile, FieldDef, FieldData,
421  ElementGIDs);
422 
423  int nSessionVar = m_session->GetVariables().size();
424  int nSessionConvVar = nSessionVar - 1;
425  int nFileVar = FieldDef[0]->m_fields.size();
426  int nFileConvVar = nFileVar - 1; // Ignore pressure
427  if (m_halfMode)
428  {
429  ASSERTL0(nFileVar == 3, "For half mode, expect 2D2C base flow.");
430  nFileConvVar = 2;
431  }
432 
433  for(int j = 0; j < nFileConvVar; ++j)
434  {
435  for(int i = 0; i < FieldDef.size(); ++i)
436  {
437  bool flag = FieldDef[i]->m_fields[j] ==
438  m_session->GetVariable(j);
439 
440  ASSERTL0(flag, (std::string("Order of ") + pInfile
441  + std::string(" data and that defined in "
442  "the session file differs")).c_str());
443 
444  pFields[j]->ExtractDataToCoeffs(
445  FieldDef[i],
446  FieldData[i],
447  FieldDef[i]->m_fields[j],
448  tmp_coeff);
449  }
450 
451  if(m_singleMode || m_halfMode)
452  {
453  pFields[j]->GetPlane(0)->BwdTrans(tmp_coeff, m_baseflow[j]);
454 
455  if(m_singleMode)
456  {
457  //copy the bwd trans into the second plane for single
458  //Mode Analysis
459  int ncplane=(pFields[0]->GetNpoints())/m_npointsZ;
460  Vmath::Vcopy(ncplane,&m_baseflow[j][0],1,&m_baseflow[j][ncplane],1);
461  }
462  }
463  else // fully 3D base flow - put in physical space.
464  {
465  bool oldwavespace = pFields[j]->GetWaveSpace();
466  pFields[j]->SetWaveSpace(false);
467  pFields[j]->BwdTrans(tmp_coeff, m_baseflow[j]);
468  pFields[j]->SetWaveSpace(oldwavespace);
469  }
470  }
471 
472  // Zero unused fields (e.g. w in a 2D2C base flow).
473  for (int j = nFileConvVar; j < nSessionConvVar; ++j)
474  {
475  Vmath::Fill(nqtot, 0.0, m_baseflow[j], 1);
476  }
477 
478  // If time-periodic, put loaded data into the slice storage.
479  if(m_session->DefinesParameter("N_slices"))
480  {
481  for(int i = 0; i < nSessionConvVar; ++i)
482  {
483  Vmath::Vcopy(nqtot, &m_baseflow[i][0], 1, &m_interp[i][pSlice*nqtot], 1);
484  }
485  }
486 }
487 
488 
490  const NekDouble m_slices,
491  const Array<OneD, const NekDouble> &inarray,
492  Array<OneD, NekDouble> &outarray,
493  const NekDouble m_time,
494  const NekDouble m_period)
495 {
496  int npoints = m_baseflow[0].num_elements();
497  NekDouble BetaT = 2*M_PI*fmod (m_time, m_period) / m_period;
498  NekDouble phase;
499  Array<OneD, NekDouble> auxiliary(npoints);
500 
501  Vmath::Vcopy(npoints,&inarray[0],1,&outarray[0],1);
502  Vmath::Svtvp(npoints, cos(0.5*m_slices*BetaT),&inarray[npoints],1,&outarray[0],1,&outarray[0],1);
503 
504  for (int i = 2; i < m_slices; i += 2)
505  {
506  phase = (i>>1) * BetaT;
507 
508  Vmath::Svtvp(npoints, cos(phase),&inarray[i*npoints],1,&outarray[0],1,&outarray[0],1);
509  Vmath::Svtvp(npoints, -sin(phase), &inarray[(i+1)*npoints], 1, &outarray[0], 1,&outarray[0],1);
510  }
511 
512 }
513 
515  const int var,
516  const MultiRegions::ExpListSharedPtr &field)
517 {
518  int nBaseDerivs = (m_halfMode || m_singleMode) ? 2 : m_spacedim;
519  switch(m_spacedim)
520  {
521  case 1: // 1D
522  {
523  field->PhysDeriv(m_baseflow[var], m_gradBase[var*nBaseDerivs + 0]);
524  }
525  break;
526  case 2: //2D
527  {
528  field->PhysDeriv(m_baseflow[var], m_gradBase[var*nBaseDerivs + 0],
529  m_gradBase[var*nBaseDerivs + 1]);
530  }
531  break;
532  case 3:
533  {
534  if(m_halfMode) // can assume W = 0 and d/dz == 0
535  {
536  if( var < 2)
537  {
538  field->PhysDeriv(m_baseflow[var],
539  m_gradBase[var*nBaseDerivs + 0],
540  m_gradBase[var*nBaseDerivs + 1]);
541  }
542  }
543  else if(m_singleMode) // single mode where d/dz = 0
544  {
545  field->PhysDeriv(m_baseflow[var], m_gradBase[var*nBaseDerivs + 0],
546  m_gradBase[var*nBaseDerivs + 1]);
547  }
548  else
549  {
550  // Differentiate base flow in physical space
551  bool oldwavespace = field->GetWaveSpace();
552  field->SetWaveSpace(false);
553  field->PhysDeriv(m_baseflow[var], m_gradBase[var*nBaseDerivs + 0],
554  m_gradBase[var*nBaseDerivs + 1],
555  m_gradBase[var*nBaseDerivs + 2]);
556  field->SetWaveSpace(oldwavespace);
557  }
558  }
559  break;
560  }
561 }
562 
564 {
565  DNekMatSharedPtr loc_mat;
566  DNekBlkMatSharedPtr BlkMatrix;
567  int n_exp = 0;
568 
569  n_exp = m_baseflow[0].num_elements(); // will operatore on m_phys
570 
571  Array<OneD,unsigned int> nrows(n_exp);
572  Array<OneD,unsigned int> ncols(n_exp);
573 
574  nrows = Array<OneD, unsigned int>(n_exp,m_slices);
575  ncols = Array<OneD, unsigned int>(n_exp,m_slices);
576 
577  MatrixStorage blkmatStorage = eDIAGONAL;
578  BlkMatrix = MemoryManager<DNekBlkMat>
579  ::AllocateSharedPtr(nrows,ncols,blkmatStorage);
580 
581 
584  StdRegions::StdSegExp StdSeg(BK);
585 
587  StdSeg.DetShapeType(),
588  StdSeg);
589 
590  loc_mat = StdSeg.GetStdMatrix(matkey);
591 
592  // set up array of block matrices.
593  for(int i = 0; i < n_exp; ++i)
594  {
595  BlkMatrix->SetBlock(i,i,loc_mat);
596  }
597 
598  return BlkMatrix;
599 }
600 
601 //Discrete Fourier Transform for Floquet analysis
602 void LinearisedAdvection::DFT(const string file,
604  const NekDouble m_slices)
605 {
606  int ConvectedFields = m_baseflow.num_elements()-1;
607  int npoints = m_baseflow[0].num_elements();
608  m_interp = Array<OneD, Array<OneD, NekDouble> > (ConvectedFields);
609 
610  for (int i = 0; i < ConvectedFields; ++i)
611  {
612  m_interp[i] = Array<OneD,NekDouble>(npoints*m_slices, 0.0);
613  }
614 
615  // Import the slides into auxiliary vector
616  // The base flow should be stored in the form "filename_%d.ext"
617  // A subdirectory can also be included, such as "dir/filename_%d.ext"
618  size_t found = file.find("%d");
619  ASSERTL0(found != string::npos && file.find("%d", found+1) == string::npos,
620  "Since N_slices is specified, the filename provided for function "
621  "'BaseFlow' must include exactly one instance of the format "
622  "specifier '%d', to index the time-slices.");
623  char* buffer = new char[file.length() + 8];
624  for (int i = 0; i < m_slices; ++i)
625  {
626  sprintf(buffer, file.c_str(), i);
627  ImportFldBase(buffer,pFields,i);
628  }
629  delete[] buffer;
630 
631 
632  // Discrete Fourier Transform of the fields
633  for(int k=0; k< ConvectedFields;++k)
634  {
635 #ifdef NEKTAR_USING_FFTW
636 
637  //Discrete Fourier Transform using FFTW
638  Array<OneD, NekDouble> fft_in(npoints*m_slices);
639  Array<OneD, NekDouble> fft_out(npoints*m_slices);
640 
643 
644  //Shuffle the data
645  for(int j= 0; j < m_slices; ++j)
646  {
647  Vmath::Vcopy(npoints,&m_interp[k][j*npoints],1,&(fft_in[j]),m_slices);
648  }
649 
650  m_FFT = LibUtilities::GetNektarFFTFactory().CreateInstance("NekFFTW", m_slices);
651 
652  //FFT Transform
653  for(int i=0; i<npoints; i++)
654  {
655  m_FFT->FFTFwdTrans(m_tmpIN =fft_in + i*m_slices, m_tmpOUT =fft_out + i*m_slices);
656 
657  }
658 
659  //Reshuffle data
660  for(int s = 0; s < m_slices; ++s)
661  {
662  Vmath::Vcopy(npoints,&fft_out[s],m_slices,&m_interp[k][s*npoints],1);
663 
664  }
665 
666  Vmath::Zero(fft_in.num_elements(),&fft_in[0],1);
667  Vmath::Zero(fft_out.num_elements(),&fft_out[0],1);
668 #else
669  //Discrete Fourier Transform using MVM
670  DNekBlkMatSharedPtr blkmat;
672 
673  int nrows = blkmat->GetRows();
674  int ncols = blkmat->GetColumns();
675 
676  Array<OneD, NekDouble> sortedinarray(ncols);
677  Array<OneD, NekDouble> sortedoutarray(nrows);
678 
679  //Shuffle the data
680  for(int j= 0; j < m_slices; ++j)
681  {
682  Vmath::Vcopy(npoints,&m_interp[k][j*npoints],1,&(sortedinarray[j]),m_slices);
683  }
684 
685  // Create NekVectors from the given data arrays
686  NekVector<NekDouble> in (ncols,sortedinarray,eWrapper);
687  NekVector<NekDouble> out(nrows,sortedoutarray,eWrapper);
688 
689  // Perform matrix-vector multiply.
690  out = (*blkmat)*in;
691 
692  //Reshuffle data
693  for(int s = 0; s < m_slices; ++s)
694  {
695  Vmath::Vcopy(npoints,&sortedoutarray[s],m_slices,&m_interp[k][s*npoints],1);
696  }
697 
698  for(int r=0; r<sortedinarray.num_elements();++r)
699  {
700  sortedinarray[0]=0;
701  sortedoutarray[0]=0;
702  }
703 
704 #endif
705 
706  //scaling of the Fourier coefficients
707  NekDouble j=-1;
708  for (int i = 2; i < m_slices; i += 2)
709  {
710  Vmath::Smul(2*npoints,j,&m_interp[k][i*npoints],1,&m_interp[k][i*npoints],1);
711  j=-j;
712 
713  }
714 
715  }
716 
717 }
718 
719 } //end of namespace
720 
enum HomogeneousType m_HomogeneousType
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
Array< OneD, NekDouble > m_tmpIN
int m_HomoDirec
number of homogenous directions
LibUtilities::ShapeType DetShapeType() const
This function returns the shape of the expansion domain.
Definition: StdExpansion.h:469
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
bool m_singleMode
flag to determine if use single mode or not
Array< OneD, Array< OneD, NekDouble > > m_baseflow
Storage for base flow.
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.
LibUtilities::NektarFFTSharedPtr m_FFT
auxiliary variables
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
Definition: Vmath.cpp:45
DNekBlkMatSharedPtr GetFloquetBlockMatrix(FloquetMatType mattype, bool UseContCoeffs=false) const
void ImportFldBase(std::string pInfile, Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, int slice)
Import Base flow.
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:488
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:445
array buffer
Definition: GsLib.hpp:61
STL namespace.
int m_slices
number of slices
Array< OneD, NekDouble > m_tmpOUT
Fourier Expansion .
Definition: BasisType.h:53
std::shared_ptr< DNekMat > DNekMatSharedPtr
Definition: NekTypeDefs.hpp:69
NektarFFTFactory & GetNektarFFTFactory()
Definition: NektarFFT.cpp:69
std::shared_ptr< DNekBlkMat > DNekBlkMatSharedPtr
Definition: NekTypeDefs.hpp:71
DNekMatSharedPtr GetStdMatrix(const StdMatrixKey &mkey)
Definition: StdExpansion.h:714
Array< OneD, Array< OneD, NekDouble > > m_interp
interpolation vector
Class representing a segment element in reference space.
Definition: StdSegExp.h:53
void UpdateBase(const NekDouble m_slices, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const NekDouble m_time, const NekDouble m_period)
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:144
1D Evenly-spaced points using Fourier Fit
Definition: PointsType.h:65
void DFT(const std::string file, Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const NekDouble m_slices)
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:216
int m_npointsZ
number of points in Z direction (if homogeneous)
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
AdvectionFactory & GetAdvectionFactory()
Gets the factory for initialising advection objects.
Definition: Advection.cpp:47
Defines a specification for a set of points.
Definition: Points.h:59
void Neg(int n, T *x, const int incx)
Negate x = -x.
Definition: Vmath.cpp:399
double NekDouble
NekDouble m_period
period length
int m_npointsY
number of points in Y direction (if homogeneous)
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_multipleModes
flag to determine if use multiple mode or not
SpatialDomains::BoundaryConditionsSharedPtr m_boundaryConditions
std::shared_ptr< Equation > EquationSharedPtr
Definition: Equation.h:131
NekDouble m_LhomY
physical length in Y direction (if homogeneous)
LibUtilities::SessionReaderSharedPtr m_session
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
int m_npointsX
number of points in X direction (if homogeneous)
NekDouble m_LhomX
physical length in X direction (if homogeneous)
bool m_halfMode
flag to determine if use half mode or not
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:199
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)
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:376
NekDouble m_LhomZ
physical length in Z direction (if homogeneous)
std::shared_ptr< FieldIO > FieldIOSharedPtr
Definition: FieldIO.h:306
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Definition: ErrorUtil.hpp:250
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1064
static FieldMetaDataMap NullFieldMetaDataMap
Definition: FieldIO.h:53
bool m_useFFT
flag to determine if use or not the FFT for transformations
Describes the specification for a Basis.
Definition: Basis.h:49
std::shared_ptr< SessionReader > SessionReaderSharedPtr
Array< OneD, Array< OneD, NekDouble > > m_gradBase
virtual SOLVER_UTILS_EXPORT void v_InitObject(LibUtilities::SessionReaderSharedPtr pSession, Array< OneD, MultiRegions::ExpListSharedPtr > pFields)
Initialises the advection object.
Definition: Advection.cpp:98
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:186
An abstract base class encapsulating the concept of advection of a vector field.
Definition: Advection.h:69