Nektar++
ExpList2DHomogeneous1D.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File ExpList2DHomogeneous1D.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 ExpList2D which is homogeneous in 1 direction and so
32 // uses much of the functionality from a ExpList1D and its daughters
33 //
34 ///////////////////////////////////////////////////////////////////////////////
35 
37 #include <MultiRegions/ExpList1D.h>
38 
39 using namespace std;
40 
41 namespace Nektar
42 {
43  namespace MultiRegions
44  {
45  // Forward declaration for typedefs
46  ExpList2DHomogeneous1D::ExpList2DHomogeneous1D():
48  {
50  }
51 
52  // Constructor for ExpList2DHomogeneous1D to act as a Explist2D field
55  const LibUtilities::BasisKey &HomoBasis,
56  const NekDouble lhom,
57  const bool useFFT,
58  const bool dealiasing,
59  const Array<OneD, ExpListSharedPtr> &planes,
60  const LibUtilities::CommSharedPtr comm)
61  : ExpListHomogeneous1D(pSession,HomoBasis,lhom,useFFT,dealiasing)
62  {
64  int i, n, cnt, nel;
65 
66  if (comm)
67  {
68  m_comm = comm;
69  }
70 
71  ASSERTL1(m_planes.num_elements() == planes.num_elements(),
72  "Size of basis number of points and number"
73  "of planes are not the same");
74 
75  // Set up expansion list with elements from all planes.
78  planes.num_elements() * planes[0]->GetExpSize());
79 
80  for(cnt = n = 0; n < planes.num_elements(); ++n)
81  {
82  m_planes[n] = planes[n];
83  for (i = 0; i < planes[n]->GetExpSize(); ++i)
84  {
85  (*m_exp)[cnt++] = planes[n]->GetExp(i);
86  }
87  }
88 
89  // Setup Default optimisation information.
90  nel = GetExpSize();
93 
94  SetCoeffPhys();
95  }
96 
97  // Constructor for ExpList2DHomogeneous1D to act as a Explist2D field
100  const LibUtilities::BasisKey &HomoBasis,
101  const NekDouble lhom,
102  const bool useFFT,
103  const bool dealiasing,
104  const SpatialDomains::MeshGraphSharedPtr &graph1D,
105  const Collections::ImplementationType ImpType):
106  ExpListHomogeneous1D(pSession,HomoBasis,lhom,useFFT,dealiasing)
107  {
109  int n, j, nel;
110  ExpList1DSharedPtr plane_zero;
111 
112  // note that nzplanes can be larger than nzmodes
113  m_planes[0] = plane_zero = MemoryManager<ExpList1D>::
114  AllocateSharedPtr(m_session, graph1D, false, ImpType);
115 
117 
118  nel = m_planes[0]->GetExpSize();
119 
120  for (j = 0; j < nel; ++j)
121  {
122  (*m_exp).push_back(m_planes[0]->GetExp(j));
123  }
124 
125  for (n = 1; n < m_planes.num_elements(); ++n)
126  {
128  AllocateSharedPtr(*plane_zero, false);
129  for(j = 0; j < nel; ++j)
130  {
131  (*m_exp).push_back((*m_exp)[j]);
132  }
133  }
134 
135  // Setup Default optimisation information.
136  nel = GetExpSize();
139 
140  SetCoeffPhys();
141  }
142 
143 
144  /**
145  * @param In ExpList2DHomogeneous1D object to copy.
146  */
148  const ExpList2DHomogeneous1D &In):
150  {
152  ExpList1DSharedPtr zero_plane =
153  std::dynamic_pointer_cast<ExpList1D> (In.m_planes[0]);
154 
155  for (int n = 0; n < m_planes.num_elements(); ++n)
156  {
158  AllocateSharedPtr(*zero_plane, false);
159  }
160 
161  SetCoeffPhys();
162  }
163 
164  /**
165  * Destructor
166  */
168  {
169  }
170 
172  {
173  int i, n, cnt;
174  int ncoeffs_per_plane = m_planes[0]->GetNcoeffs();
175  int npoints_per_plane = m_planes[0]->GetTotPoints();
176 
177  int nzplanes = m_planes.num_elements();
178 
179  // Set total coefficients and points
180  m_ncoeffs = ncoeffs_per_plane*nzplanes;
181  m_npoints = npoints_per_plane*nzplanes;
182 
185 
186  int nel = m_planes[0]->GetExpSize();
187  m_coeff_offset = Array<OneD,int>(nel*nzplanes);
188  m_phys_offset = Array<OneD,int>(nel*nzplanes);
189  Array<OneD, NekDouble> tmparray;
190 
191  for (cnt = n = 0; n < nzplanes; ++n)
192  {
193  m_planes[n]->SetCoeffsArray(
194  tmparray= m_coeffs + ncoeffs_per_plane*n);
195  m_planes[n]->SetPhysArray(
196  tmparray = m_phys + npoints_per_plane*n);
197 
198  for(i = 0; i < nel; ++i)
199  {
200  m_coeff_offset[cnt] = m_planes[n]->GetCoeff_Offset(i)
201  + n*ncoeffs_per_plane;
202  m_phys_offset[cnt++] = m_planes[n]->GetPhys_Offset(i)
203  + n*npoints_per_plane;
204  }
205  }
206  }
207 
209  const int eid,
213  {
214  int n, coordim;
215  Array<OneD, NekDouble> tmp_xc,xhom;
216  int nyplanes = m_planes.num_elements();
217  int npoints = GetTotPoints(eid);
218 
219  switch(coordim = GetCoordim(0))
220  {
221  case 1:
222  {
223  (*m_exp)[eid]->GetCoords(xc0);
224  xhom = xc1;
225  }
226  break;
227  case 2:
228  ASSERTL0(xc1.num_elements() != 0,
229  "output coord_1 is not defined");
230  {
231  (*m_exp)[eid]->GetCoords(xc0,xc1);
232  xhom = xc2;
233  }
234  break;
235  default:
236  ASSERTL0(false, "Cannot have coordim being three dimensions"
237  "in a homogeneous field");
238  break;
239  }
240 
241  // Fill homogeneous-direction
243  Array<OneD, NekDouble> z(nyplanes);
244 
245  Array<OneD, NekDouble> local_pts(m_planes.num_elements());
246 
247  for(n = 0; n < m_planes.num_elements(); n++)
248  {
249  local_pts[n] = pts[m_transposition->GetPlaneID(n)];
250  }
251 
252  Vmath::Smul(nyplanes,m_lhom/2.0,local_pts,1,z,1);
253  Vmath::Sadd(nyplanes,m_lhom/2.0,z,1,z,1);
254 
255  for (n = 0; n < nyplanes; ++n)
256  {
257  Vmath::Fill(npoints,z[n],tmp_xc = xhom + npoints*n,1);
258  if(n)
259  {
260  Vmath::Vcopy(npoints,xc0,1,tmp_xc = xc0+npoints*n,1);
261  if(coordim == 2)
262  {
263  Vmath::Vcopy(npoints,xc1,1,tmp_xc = xc1+npoints*n,1);
264  }
265  }
266  }
267  }
268 
269  /**
270  * The operation calls the 2D plane coordinates through the
271  * function ExpList#GetCoords and then evaluated the third
272  * coordinate using the member \a m_lhom
273  *
274  * @param coord_0 After calculation, the \f$x_1\f$ coordinate
275  * will be stored in this array.
276  *
277  * @param coord_1 After calculation, the \f$x_2\f$ coordinate
278  * will be stored in this array. This
279  * coordinate might be evaluated using the
280  * predefined value \a m_lhom
281  *
282  * @param coord_2 After calculation, the \f$x_3\f$ coordinate
283  * will be stored in this array. This
284  * coordinate is evaluated using the
285  * predefined value \a m_lhom
286  */
291  {
292  int n,coordim;
293  Array<OneD, NekDouble> tmp_xc, xhom;
294  int nyplanes = m_planes.num_elements();
295  int npoints = m_planes[0]->GetTotPoints();
296 
297  m_planes[0]->GetCoords(xc0,xc1);
298 
299  if((coordim = GetCoordim(0)) == 1)
300  {
301  xhom = xc1;
302  }
303  else
304  {
305  xhom = xc2;
306  }
307 
308  // Fill z-direction
310  Array<OneD, NekDouble> z(nyplanes);
311  Array<OneD, NekDouble> local_pts(m_planes.num_elements());
312 
313  for(n = 0; n < m_planes.num_elements(); n++)
314  {
315  local_pts[n] = pts[m_transposition->GetPlaneID(n)];
316  }
317 
318  Vmath::Smul(nyplanes,m_lhom/2.0,local_pts,1,z,1);
319  Vmath::Sadd(nyplanes,m_lhom/2.0,z,1,z,1);
320 
321  for(n = 0; n < nyplanes; ++n)
322  {
323  Vmath::Fill(npoints,z[n],tmp_xc = xhom + npoints*n,1);
324  if(n)
325  {
326  Vmath::Vcopy(npoints,xc0,1,tmp_xc = xc0+npoints*n,1);
327  if(coordim == 2)
328  {
329  Vmath::Vcopy(npoints,xc1,1,tmp_xc = xc1+npoints*n,1);
330  }
331  }
332  }
333  }
334 
335 
336  /**
337  * Write Tecplot Files Zone
338  * @param outfile Output file name.
339  * @param expansion Expansion that is considered
340  */
342  std::ostream &outfile,
343  int expansion)
344  {
345  int i, j;
346 
347  int nquad0 = (*m_exp)[expansion]->GetNumPoints(0);
348  int nquad1 = m_planes.num_elements();
349 
350  Array<OneD,NekDouble> coords[3];
351 
352  coords[0] = Array<OneD,NekDouble>(3*nquad0*nquad1);
353  coords[1] = coords[0] + nquad0*nquad1;
354  coords[2] = coords[1] + nquad0*nquad1;
355 
356  GetCoords(expansion,coords[0],coords[1],coords[2]);
357 
358  outfile << "Zone, I=" << nquad0 << ", J=" << nquad1
359  << ", F=Block" << std::endl;
360 
361  for(j = 0; j < GetCoordim(0)+1; ++j)
362  {
363  for(i = 0; i < nquad0*nquad1; ++i)
364  {
365  outfile << coords[j][i] << " ";
366  }
367  outfile << std::endl;
368  }
369  }
370 
371 
373  std::ostream &outfile,
374  int expansion,
375  int istrip)
376  {
377  boost::ignore_unused(istrip);
378 
379  // If there is only one plane (e.g. HalfMode), we write a 2D plane.
380  if (m_planes.num_elements() == 1)
381  {
382  m_planes[0]->WriteVtkPieceHeader(outfile, expansion);
383  return;
384  }
385 
386  // If we are using Fourier points, output extra plane to fill domain
387  int outputExtraPlane = 0;
388  if ( m_homogeneousBasis->GetBasisType() == LibUtilities::eFourier
389  && m_homogeneousBasis->GetPointsType() ==
391  {
392  outputExtraPlane = 1;
393  }
394  int i, j;
395  int nquad0 = (*m_exp)[expansion]->GetNumPoints(0);
396  int nquad1 = m_planes.num_elements() + outputExtraPlane;
397  int ntot = nquad0*nquad1;
398  int ntotminus = (nquad0-1)*(nquad1-1);
399 
400  Array<OneD,NekDouble> coords[3];
401  coords[0] = Array<OneD,NekDouble>(ntot);
402  coords[1] = Array<OneD,NekDouble>(ntot);
403  coords[2] = Array<OneD,NekDouble>(ntot);
404  GetCoords(expansion,coords[0],coords[1],coords[2]);
405 
406  if (outputExtraPlane)
407  {
408  // Copy coords[0] and coords[1] to extra plane
410  Vmath::Vcopy (nquad0, coords[0], 1,
411  tmp = coords[0] + (nquad1-1)*nquad0, 1);
412  Vmath::Vcopy (nquad0, coords[1], 1,
413  tmp = coords[1] + (nquad1-1)*nquad0, 1);
414  // Fill coords[2] for extra plane
415  NekDouble z = coords[2][nquad0*m_planes.num_elements()-1] +
416  (coords[2][nquad0] - coords[2][0]);
417  Vmath::Fill(nquad0, z, tmp = coords[2] + (nquad1-1)*nquad0, 1);
418  }
419 
420  outfile << " <Piece NumberOfPoints=\""
421  << ntot << "\" NumberOfCells=\""
422  << ntotminus << "\">" << endl;
423  outfile << " <Points>" << endl;
424  outfile << " <DataArray type=\"Float64\" "
425  << "NumberOfComponents=\"3\" format=\"ascii\">" << endl;
426  outfile << " ";
427  for (i = 0; i < ntot; ++i)
428  {
429  for (j = 0; j < 3; ++j)
430  {
431  outfile << coords[j][i] << " ";
432  }
433  outfile << endl;
434  }
435  outfile << endl;
436  outfile << " </DataArray>" << endl;
437  outfile << " </Points>" << endl;
438  outfile << " <Cells>" << endl;
439  outfile << " <DataArray type=\"Int32\" "
440  << "Name=\"connectivity\" format=\"ascii\">" << endl;
441  for (i = 0; i < nquad0-1; ++i)
442  {
443  for (j = 0; j < nquad1-1; ++j)
444  {
445  outfile << j*nquad0 + i << " "
446  << j*nquad0 + i + 1 << " "
447  << (j+1)*nquad0 + i + 1 << " "
448  << (j+1)*nquad0 + i << endl;
449  }
450  }
451  outfile << endl;
452  outfile << " </DataArray>" << endl;
453  outfile << " <DataArray type=\"Int32\" "
454  << "Name=\"offsets\" format=\"ascii\">" << endl;
455  for (i = 0; i < ntotminus; ++i)
456  {
457  outfile << i*4+4 << " ";
458  }
459  outfile << endl;
460  outfile << " </DataArray>" << endl;
461  outfile << " <DataArray type=\"UInt8\" "
462  << "Name=\"types\" format=\"ascii\">" << endl;
463  for (i = 0; i < ntotminus; ++i)
464  {
465  outfile << "9 ";
466  }
467  outfile << endl;
468  outfile << " </DataArray>" << endl;
469  outfile << " </Cells>" << endl;
470  outfile << " <PointData>" << endl;
471  }
472 
474  Array<OneD, Array<OneD, NekDouble> > &normals)
475  {
476  int nPlanes = m_planes.num_elements();
477  int nPtsPlane = m_planes[0]->GetNpoints();
478  int nDim = GetCoordim(0) + 1;
479 
480  ASSERTL1(normals.num_elements() >= nDim,
481  "Output vector does not have sufficient dimensions to"
482  "match coordim");
483  ASSERTL1(normals[0].num_elements() >= nPtsPlane,
484  "Output vector does not have sufficient dimensions to"
485  "match coordim");
486 
487  // Calculate normals from plane 0.
488  m_planes[0]->GetNormals(normals);
489 
490  // Copy remaining planes.
491  for (int i = 0; i < nDim; ++i)
492  {
493  for (int n = 1; n < nPlanes; ++n)
494  {
495  Vmath::Vcopy(nPtsPlane, &normals[i][0], 1,
496  &normals[i][n*nPtsPlane], 1);
497  }
498  }
499  }
500 
502  const NekDouble> &inarray)
503  {
504  NekDouble val = 0.0;
505  int i = 0;
506 
507  for (i = 0; i < (*m_exp).size(); ++i)
508  {
509  val += (*m_exp)[i]->Integral(inarray + m_phys_offset[i]);
510  }
511  val *= m_lhom/m_homogeneousBasis->GetNumModes();
512 
513  m_comm->AllReduce(val, LibUtilities::ReduceSum);
514 
515  return val;
516  }
517  } //end of namespace
518 } //end of namespace
Abstraction of a two-dimensional multi-elemental expansion which is merely a collection of local expa...
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:163
virtual NekDouble v_Integral(const Array< OneD, const NekDouble > &inarray)
std::shared_ptr< LocalRegions::ExpansionVector > m_exp
The list of local expansions.
Definition: ExpList.h:1090
NekOptimize::GlobalOptParamSharedPtr m_globalOptParam
Definition: ExpList.h:1106
LibUtilities::TranspositionSharedPtr m_transposition
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
Definition: Vmath.cpp:45
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:53
STL namespace.
virtual void v_WriteTecplotZone(std::ostream &outfile, int expansion)
NekDouble m_lhom
Width of homogeneous direction.
Array< OneD, NekDouble > m_phys
The global expansion evaluated at the quadrature points.
Definition: ExpList.h:1069
Fourier Expansion .
Definition: BasisType.h:53
Array< OneD, NekDouble > m_coeffs
Concatenation of all local expansion coefficients.
Definition: ExpList.h:1052
int GetExpSize(void)
This function returns the number of elements in the expansion.
Definition: ExpList.h:2170
const std::shared_ptr< LocalRegions::ExpansionVector > GetExp() const
This function returns the vector of elements in the expansion.
Definition: ExpList.h:2191
Abstraction of a two-dimensional multi-elemental expansion which is merely a collection of local expa...
Array< OneD, int > m_coeff_offset
Offset of elemental data into the array m_coeffs.
Definition: ExpList.h:1101
LibUtilities::BasisSharedPtr m_homogeneousBasis
Definition of the total number of degrees of freedom and quadrature points. Sets up the storage for m...
1D Evenly-spaced points using Fourier Fit
Definition: PointsType.h:65
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
Array< OneD, int > m_phys_offset
Offset of elemental data into the array m_phys.
Definition: ExpList.h:1104
int m_ncoeffs
The total number of local degrees of freedom. m_ncoeffs .
Definition: ExpList.h:1030
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
LibUtilities::SessionReaderSharedPtr m_session
Session.
Definition: ExpList.h:1023
virtual void v_GetCoords(Array< OneD, NekDouble > &coord_0, Array< OneD, NekDouble > &coord_1, Array< OneD, NekDouble > &coord_2)
Array< OneD, ExpListSharedPtr > m_planes
double NekDouble
virtual void v_GetNormals(Array< OneD, Array< OneD, NekDouble > > &normals)
void Sadd(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Add vector y = alpha + x.
Definition: Vmath.cpp:318
void SetCoeffPhys(void)
Definition of the total number of degrees of freedom and quadrature points. Sets up the storage for m...
LibUtilities::CommSharedPtr m_comm
Communicator.
Definition: ExpList.h:1020
This class is the abstraction of a one-dimensional multi-elemental expansions which is merely a colle...
Definition: ExpList1D.h:58
int GetCoordim(int eid)
This function returns the dimension of the coordinates of the element eid.
Definition: ExpList.h:2013
void GetCoords(Array< OneD, NekDouble > &coord_0, Array< OneD, NekDouble > &coord_1=NullNekDouble1DArray, Array< OneD, NekDouble > &coord_2=NullNekDouble1DArray)
This function calculates the coordinates of all the elemental quadrature points . ...
void SetExpType(ExpansionType Type)
Returns the type of the expansion.
Definition: ExpList.cpp:279
int GetTotPoints(void) const
Returns the total number of quadrature points m_npoints .
Definition: ExpList.h:1608
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Definition: ErrorUtil.hpp:250
virtual void v_WriteVtkPieceHeader(std::ostream &outfile, int expansion, int istrip)
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1064
std::shared_ptr< ExpList1D > ExpList1DSharedPtr
Shared pointer to an ExpList1D object.
Definition: ExpList1D.h:49
Describes the specification for a Basis.
Definition: Basis.h:49
std::shared_ptr< SessionReader > SessionReaderSharedPtr