Nektar++
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CoalescedGeomData.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: Collection.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: Collection top class definition
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
37 
38 #include <LocalRegions/Expansion.h>
39 
40 using namespace std;
41 
42 namespace Nektar {
43 namespace Collections {
44 
45 CoalescedGeomData::CoalescedGeomData(void)
46 {
47 }
48 
49 CoalescedGeomData::~CoalescedGeomData(void)
50 {
51 }
52 
53 const Array<OneD, const NekDouble> &CoalescedGeomData::GetJac(
54  vector<StdRegions::StdExpansionSharedPtr> &pCollExp)
55 {
56 
57  if(m_oneDGeomData.count(eJac) == 0)
58  {
59 
60  LibUtilities::PointsKeyVector ptsKeys = pCollExp[0]->GetPointsKeys();
61  int nElmts = pCollExp.size();
62 
63  // set up Cached Jacobians to be continuous
64  int npts = 1;
65  for (int i = 0; i < ptsKeys.size(); ++i)
66  {
67  npts *= ptsKeys[i].GetNumPoints();
68  }
69 
70  if(IsDeformed(pCollExp))
71  {
72  Array<OneD, NekDouble> newjac(npts*nElmts);
73 
74  //copy Jacobians into a continuous list and set new chatched value
75  int cnt = 0;
76  for(int i = 0; i < nElmts; ++i)
77  {
78  const StdRegions::StdExpansion * sep = &(*pCollExp[i]);
80  *lep = dynamic_cast<const LocalRegions::Expansion*>( sep );
81 
83  jac = lep->GetMetricInfo()->GetJac( ptsKeys );
84 
85  Vmath::Vcopy(npts, &jac[0], 1, &newjac[cnt], 1);
86 
87  cnt += npts;
88  }
89 
90  m_oneDGeomData[eJac] = newjac;
91  }
92  else
93  {
94  Array<OneD, NekDouble> newjac(nElmts);
95  //copy Jacobians into a continuous list
96  for(int i = 0; i < nElmts; ++i)
97  {
98  const StdRegions::StdExpansion * sep = &(*pCollExp[i]);
99  const LocalRegions::Expansion * lep =
100  dynamic_cast<const LocalRegions::Expansion*>( sep );
101 
102  const Array<OneD, const NekDouble> jac =
103  lep->GetMetricInfo()->GetJac( ptsKeys );
104 
105  newjac[i] = jac[0];
106 
107  }
108  m_oneDGeomData[eJac] = newjac;
109  }
110  }
111 
112  return m_oneDGeomData[eJac];
113 }
114 
115 const std::shared_ptr<VecVec_t> CoalescedGeomData::GetJacInterLeave(
116  vector<StdRegions::StdExpansionSharedPtr> &pCollExp,
117  int nElmt)
118 {
119 
120  if(m_oneDGeomDataInterLeave.count(eJac) == 0)
121  {
122  const Array<OneD, const NekDouble> jac = GetJac(pCollExp);
123  int jacsize = jac.size();
124 
125  ASSERTL1(nElmt % vec_t::width == 0,
126  "Number of elements not divisible by vector "
127  "width, padding not yet implemented.");
128  int nBlocks = nElmt / vec_t::width;
129 
130  VecVec_t newjac;
131 
132  LibUtilities::PointsKeyVector ptsKeys = pCollExp[0]->GetPointsKeys();
133 
134  // set up Cached Jacobians to be continuous
135  int nq = 1;
136  for (int i = 0; i < ptsKeys.size(); ++i)
137  {
138  nq *= ptsKeys[i].GetNumPoints();
139  }
140 
141  if(IsDeformed(pCollExp))
142  {
143 
144  newjac.resize(nBlocks*nq);
145 
146  alignas(vec_t::alignment) NekDouble tmp[vec_t::width];
147 
148  for (size_t block = 0; block < nBlocks; ++block)
149  {
150  size_t nblock_width = block*nq*vec_t::width;
151  for(size_t q = 0; q < nq; q++)
152  {
153  for (int j = 0; j < vec_t::width; ++j)
154  {
155  if(nblock_width+ nq*j + q < jacsize)
156  {
157  tmp[j] = jac[nblock_width + nq*j + q];
158  }
159  else
160  {
161  tmp[j] = 0.0;
162  }
163  }
164 
165  //Order is [block][quadpt]
166  newjac[block*nq + q].load(&tmp[0]);
167  }
168  }
169  }
170  else
171  {
172  newjac.resize(nBlocks);
173 
174  alignas(vec_t::alignment) NekDouble tmp[vec_t::width];
175  for (size_t i = 0; i < nBlocks; ++i)
176  {
177  for (int j = 0; j < vec_t::width; ++j)
178  {
179  if(vec_t::width*i+j < jacsize)
180  {
181  tmp[j] = jac[vec_t::width*i+j];
182  }
183  else
184  {
185  tmp[j] = 0.0;
186  }
187  }
188 
189  newjac[i].load(&tmp[0]);
190  }
191  }
192 
193  m_oneDGeomDataInterLeave[eJac] =
195  }
196 
197  return m_oneDGeomDataInterLeave[eJac];
198 }
199 
200 
201 
202 
203 const Array<OneD, const NekDouble> &CoalescedGeomData::GetJacWithStdWeights(
204  vector<StdRegions::StdExpansionSharedPtr> &pCollExp)
205 {
206  if(m_oneDGeomData.count(eJacWithStdWeights) == 0)
207  {
208  LibUtilities::PointsKeyVector ptsKeys = pCollExp[0]->GetPointsKeys();
209  int nElmts = pCollExp.size();
210 
211  // set up Cached Jacobians to be continuous
212  int npts = 1;
213  for (int i = 0; i < ptsKeys.size(); ++i)
214  {
215  npts *= ptsKeys[i].GetNumPoints();
216  }
217 
218 
219  Array<OneD, NekDouble> newjac(npts*nElmts), tmp;
220 
221  //copy Jacobians into a continuous list and set new chatched value
222  int cnt = 0;
223  for(int i = 0; i < nElmts; ++i)
224  {
225  const StdRegions::StdExpansion * sep = &(*pCollExp[i]);
226  const LocalRegions::Expansion * lep = dynamic_cast<const LocalRegions::Expansion*>( sep );
227 
228  const Array<OneD, const NekDouble> jac = lep->GetMetricInfo()->GetJac(ptsKeys);
229 
230  if( lep->GetMetricInfo()->GetGtype() == SpatialDomains::eDeformed )
231  {
232  Vmath::Vcopy(npts, &jac[0], 1, &newjac[cnt], 1);
233  }
234  else
235  {
236  Vmath::Fill(npts, jac[0], &newjac[cnt], 1);
237  }
238 
239  pCollExp[0]->MultiplyByStdQuadratureMetric(newjac + cnt,
240  tmp = newjac + cnt);
241  cnt += npts;
242  }
243 
244  m_oneDGeomData[eJacWithStdWeights] = newjac;
245  }
246 
247  return m_oneDGeomData[eJacWithStdWeights];
248 }
249 
250 
251 const Array<TwoD, const NekDouble> &CoalescedGeomData::GetDerivFactors(
252  vector<StdRegions::StdExpansionSharedPtr> &pCollExp)
253 {
254  if(m_twoDGeomData.count(eDerivFactors) == 0)
255  {
256  LibUtilities::PointsKeyVector ptsKeys = pCollExp[0]->GetPointsKeys();
257 
258  int nElmts = pCollExp.size();
259  const int coordim = pCollExp[0]->GetCoordim();
260  int dim = ptsKeys.size();
261 
262  // set up Cached Jacobians to be continuous
263  int npts = 1;
264  for (int i = 0; i < dim; ++i)
265  {
266  npts *= ptsKeys[i].GetNumPoints();
267  }
268 
269 
270  Array<TwoD, NekDouble> newDFac;
271 
272  if(IsDeformed(pCollExp))
273  {
274  newDFac = Array<TwoD, NekDouble>(dim*coordim,npts*nElmts);
275  }
276  else
277  {
278  newDFac = Array<TwoD, NekDouble>(dim*coordim,nElmts);
279  }
280 
281  //copy Jacobians into a continuous list and set new chatched value
282  int cnt = 0;
283  for(int i = 0; i < nElmts; ++i)
284  {
285  const StdRegions::StdExpansion * sep = &(*pCollExp[i]);
287  *lep = dynamic_cast<const LocalRegions::Expansion*>( sep );
288 
290  Dfac = lep->GetMetricInfo()->GetDerivFactors( ptsKeys );
291 
292  if(IsDeformed(pCollExp))
293  {
294  for (int j = 0; j < dim*coordim; ++j)
295  {
296  Vmath::Vcopy(npts, &Dfac[j][0], 1, &newDFac[j][cnt], 1);
297  }
298  }
299  else
300  {
301  for (int j = 0; j < dim*coordim; ++j)
302  {
303  newDFac[j][i] = Dfac[j][0];
304  }
305  }
306  cnt += npts;
307  }
308 
309  m_twoDGeomData[eDerivFactors] = newDFac;
310  }
311 
312  return m_twoDGeomData[eDerivFactors];
313 }
314 
315 const std::shared_ptr<VecVec_t> CoalescedGeomData::GetDerivFactorsInterLeave(
316  vector<StdRegions::StdExpansionSharedPtr> &pCollExp,
317  int nElmt)
318 {
319  if(m_twoDGeomDataInterLeave.count(eDerivFactors) == 0)
320  {
321  ASSERTL1(nElmt % vec_t::width == 0,
322  "Number of elements not divisible by vector "
323  "width, padding not yet implemented.");
324 
325  int nBlocks = nElmt / vec_t::width;
326 
327  LibUtilities::PointsKeyVector ptsKeys = pCollExp[0]->GetPointsKeys();
328  const int coordim = pCollExp[0]->GetCoordim();
329  int dim = ptsKeys.size();
330 
331 
332  unsigned int n_df = coordim*dim;
333  alignas(vec_t::alignment) NekDouble vec[vec_t::width];
334 
335  const Array<TwoD, const NekDouble> df = GetDerivFactors(pCollExp);
336  int dfsize = df.GetColumns();
337 
338  VecVec_t newdf;
339 
340  int nq = 1;
341  for (int i = 0; i < dim; ++i)
342  {
343  nq *= ptsKeys[i].GetNumPoints();
344  }
345 
346  if(IsDeformed(pCollExp))
347  {
348  newdf.resize(nBlocks * n_df *nq);
349  auto *df_ptr = &newdf[0];
350  for (int e = 0; e < nBlocks; ++e)
351  {
352  for (int q = 0; q < nq; q++)
353  {
354  for (int dir = 0; dir < n_df; ++dir, ++df_ptr)
355  {
356  for (int j = 0; j < vec_t::width; ++j)
357  {
358  // manage padding
359  if((vec_t::width*e + j)*nq + q < dfsize)
360  {
361  vec[j] = df[dir][(vec_t::width*e + j)*nq + q];
362  }
363  else
364  {
365  vec[j] = 0.0;
366  }
367  }
368  (*df_ptr).load(&vec[0]);
369  }
370  }
371  }
372  }
373  else
374  {
375  newdf.resize(nBlocks * n_df);
376  for (int e = 0; e < nBlocks; ++e)
377  {
378  for (int dir = 0; dir < n_df; ++dir)
379  {
380  for (int j = 0; j < vec_t::width; ++j)
381  {
382  // padding
383  if(vec_t::width*e + j < dfsize)
384  {
385  vec[j] = df[dir][vec_t::width*e + j];
386  }
387  else
388  {
389  vec[j] = 0.0;
390  }
391  }
392  // Must have all vec_t::width elemnts aligned to do a load.
393  newdf[e*n_df + dir].load(&vec[0]);
394  }
395  }
396  }
397 
398  m_twoDGeomDataInterLeave[eDerivFactors] =
400  }
401 
402  return m_twoDGeomDataInterLeave[eDerivFactors];
403 }
404 
405 
406 bool CoalescedGeomData::IsDeformed(
407  vector<StdRegions::StdExpansionSharedPtr> &pCollExp)
408 {
409  if (!m_isDeformedSet)
410  {
411  LibUtilities::PointsKeyVector ptsKeys = pCollExp[0]->GetPointsKeys();
412  const StdRegions::StdExpansion * sep = &(*pCollExp[0]);
413  const LocalRegions::Expansion * lep =
414  dynamic_cast<const LocalRegions::Expansion*>( sep );
415 
416  const Array<OneD, const NekDouble> jac =
417  lep->GetMetricInfo()->GetJac(ptsKeys);
418 
419  m_deformed = lep->GetMetricInfo()->GetGtype() ==
421  }
422 
423  return m_deformed;
424 }
425 
426 }
427 }
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:250
const SpatialDomains::GeomFactorsSharedPtr & GetMetricInfo() const
Definition: Expansion.cpp:251
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
The base class for all shapes.
Definition: StdExpansion.h:63
std::vector< vec_t, tinysimd::allocator< vec_t > > VecVec_t
std::vector< PointsKey > PointsKeyVector
Definition: Points.h:246
@ eDeformed
Geometry is curved or has non-constant factors.
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:1
double NekDouble
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