Nektar++
CoalescedGeomData.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: CoalescedGeomData.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: Coalesced geometry data definition
32//
33///////////////////////////////////////////////////////////////////////////////
34
37
39
40using namespace std;
41
42namespace Nektar
43{
44namespace Collections
45{
46
48{
49}
50
52{
53}
54
56 vector<StdRegions::StdExpansionSharedPtr> &pCollExp)
57{
58
59 if (m_oneDGeomData.count(eJac) == 0)
60 {
61
62 LibUtilities::PointsKeyVector ptsKeys = pCollExp[0]->GetPointsKeys();
63 int nElmts = pCollExp.size();
64
65 // set up Cached Jacobians to be continuous
66 int npts = 1;
67 for (int i = 0; i < ptsKeys.size(); ++i)
68 {
69 npts *= ptsKeys[i].GetNumPoints();
70 }
71
72 if (IsDeformed(pCollExp))
73 {
74 Array<OneD, NekDouble> newjac(npts * nElmts);
75
76 // copy Jacobians into a continuous list and set new chatched value
77 int cnt = 0;
78 for (int i = 0; i < nElmts; ++i)
79 {
80 const StdRegions::StdExpansion *sep = &(*pCollExp[i]);
81 const LocalRegions::Expansion *lep =
82 dynamic_cast<const LocalRegions::Expansion *>(sep);
83
85 lep->GetMetricInfo()->GetJac(ptsKeys);
86
87 Vmath::Vcopy(npts, &jac[0], 1, &newjac[cnt], 1);
88
89 cnt += npts;
90 }
91
92 m_oneDGeomData[eJac] = newjac;
93 }
94 else
95 {
96 Array<OneD, NekDouble> newjac(nElmts);
97 // copy Jacobians into a continuous list
98 for (int i = 0; i < nElmts; ++i)
99 {
100 const StdRegions::StdExpansion *sep = &(*pCollExp[i]);
101 const LocalRegions::Expansion *lep =
102 dynamic_cast<const LocalRegions::Expansion *>(sep);
103
105 lep->GetMetricInfo()->GetJac(ptsKeys);
106
107 newjac[i] = jac[0];
108 }
109 m_oneDGeomData[eJac] = newjac;
110 }
111 }
112
113 return m_oneDGeomData[eJac];
114}
115
116const std::shared_ptr<VecVec_t> CoalescedGeomData::GetJacInterLeave(
117 vector<StdRegions::StdExpansionSharedPtr> &pCollExp, 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
195 }
196
198}
199
201 vector<StdRegions::StdExpansionSharedPtr> &pCollExp)
202{
203 if (m_oneDGeomData.count(eJacWithStdWeights) == 0)
204 {
205 LibUtilities::PointsKeyVector ptsKeys = pCollExp[0]->GetPointsKeys();
206 int nElmts = pCollExp.size();
207
208 // set up Cached Jacobians to be continuous
209 int npts = 1;
210 for (int i = 0; i < ptsKeys.size(); ++i)
211 {
212 npts *= ptsKeys[i].GetNumPoints();
213 }
214
215 Array<OneD, NekDouble> newjac(npts * nElmts), tmp;
216
217 // copy Jacobians into a continuous list and set new chatched value
218 int cnt = 0;
219 for (int i = 0; i < nElmts; ++i)
220 {
221 const StdRegions::StdExpansion *sep = &(*pCollExp[i]);
222 const LocalRegions::Expansion *lep =
223 dynamic_cast<const LocalRegions::Expansion *>(sep);
224
226 lep->GetMetricInfo()->GetJac(ptsKeys);
227
228 if (lep->GetMetricInfo()->GetGtype() == SpatialDomains::eDeformed)
229 {
230 Vmath::Vcopy(npts, &jac[0], 1, &newjac[cnt], 1);
231 }
232 else
233 {
234 Vmath::Fill(npts, jac[0], &newjac[cnt], 1);
235 }
236
237 pCollExp[0]->MultiplyByStdQuadratureMetric(newjac + cnt,
238 tmp = newjac + cnt);
239 cnt += npts;
240 }
241
243 }
244
246}
247
249 vector<StdRegions::StdExpansionSharedPtr> &pCollExp)
250{
251 if (m_twoDGeomData.count(eDerivFactors) == 0)
252 {
253 LibUtilities::PointsKeyVector ptsKeys = pCollExp[0]->GetPointsKeys();
254
255 int nElmts = pCollExp.size();
256 const int coordim = pCollExp[0]->GetCoordim();
257 int dim = ptsKeys.size();
258
259 // set up Cached Jacobians to be continuous
260 int npts = 1;
261 for (int i = 0; i < dim; ++i)
262 {
263 npts *= ptsKeys[i].GetNumPoints();
264 }
265
267
268 if (IsDeformed(pCollExp))
269 {
270 newDFac = Array<TwoD, NekDouble>(dim * coordim, npts * nElmts);
271 }
272 else
273 {
274 newDFac = Array<TwoD, NekDouble>(dim * coordim, nElmts);
275 }
276
277 // copy Jacobians into a continuous list and set new chatched value
278 int cnt = 0;
279 for (int i = 0; i < nElmts; ++i)
280 {
281 const StdRegions::StdExpansion *sep = &(*pCollExp[i]);
282 const LocalRegions::Expansion *lep =
283 dynamic_cast<const LocalRegions::Expansion *>(sep);
284
286 lep->GetMetricInfo()->GetDerivFactors(ptsKeys);
287
288 if (IsDeformed(pCollExp))
289 {
290 for (int j = 0; j < dim * coordim; ++j)
291 {
292 Vmath::Vcopy(npts, &Dfac[j][0], 1, &newDFac[j][cnt], 1);
293 }
294 }
295 else
296 {
297 for (int j = 0; j < dim * coordim; ++j)
298 {
299 newDFac[j][i] = Dfac[j][0];
300 }
301 }
302 cnt += npts;
303 }
304
305 m_twoDGeomData[eDerivFactors] = newDFac;
306 }
307
309}
310
311const std::shared_ptr<VecVec_t> CoalescedGeomData::GetDerivFactorsInterLeave(
312 vector<StdRegions::StdExpansionSharedPtr> &pCollExp, int nElmt)
313{
315 {
316 ASSERTL1(nElmt % vec_t::width == 0,
317 "Number of elements not divisible by vector "
318 "width, padding not yet implemented.");
319
320 int nBlocks = nElmt / vec_t::width;
321
322 LibUtilities::PointsKeyVector ptsKeys = pCollExp[0]->GetPointsKeys();
323 const int coordim = pCollExp[0]->GetCoordim();
324 int dim = ptsKeys.size();
325
326 unsigned int n_df = coordim * dim;
327 alignas(vec_t::alignment) NekDouble vec[vec_t::width];
328
330 int dfsize = df.GetColumns();
331
332 VecVec_t newdf;
333
334 int nq = 1;
335 for (int i = 0; i < dim; ++i)
336 {
337 nq *= ptsKeys[i].GetNumPoints();
338 }
339
340 if (IsDeformed(pCollExp))
341 {
342 newdf.resize(nBlocks * n_df * nq);
343 auto *df_ptr = &newdf[0];
344 for (int e = 0; e < nBlocks; ++e)
345 {
346 for (int q = 0; q < nq; q++)
347 {
348 for (int dir = 0; dir < n_df; ++dir, ++df_ptr)
349 {
350 for (int j = 0; j < vec_t::width; ++j)
351 {
352 // manage padding
353 if ((vec_t::width * e + j) * nq + q < dfsize)
354 {
355 vec[j] =
356 df[dir][(vec_t::width * e + j) * nq + q];
357 }
358 else
359 {
360 vec[j] = 0.0;
361 }
362 }
363 (*df_ptr).load(&vec[0]);
364 }
365 }
366 }
367 }
368 else
369 {
370 newdf.resize(nBlocks * n_df);
371 for (int e = 0; e < nBlocks; ++e)
372 {
373 for (int dir = 0; dir < n_df; ++dir)
374 {
375 for (int j = 0; j < vec_t::width; ++j)
376 {
377 // padding
378 if (vec_t::width * e + j < dfsize)
379 {
380 vec[j] = df[dir][vec_t::width * e + j];
381 }
382 else
383 {
384 vec[j] = 0.0;
385 }
386 }
387 // Must have all vec_t::width elemnts aligned to do a load.
388 newdf[e * n_df + dir].load(&vec[0]);
389 }
390 }
391 }
392
395 }
396
398}
399
401 vector<StdRegions::StdExpansionSharedPtr> &pCollExp)
402{
403 if (!m_isDeformedSet)
404 {
405 LibUtilities::PointsKeyVector ptsKeys = pCollExp[0]->GetPointsKeys();
406 const StdRegions::StdExpansion *sep = &(*pCollExp[0]);
407 const LocalRegions::Expansion *lep =
408 dynamic_cast<const LocalRegions::Expansion *>(sep);
409
411 lep->GetMetricInfo()->GetJac(ptsKeys);
412
413 m_deformed =
414 lep->GetMetricInfo()->GetGtype() == SpatialDomains::eDeformed;
415 }
416
417 return m_deformed;
418}
419
420} // namespace Collections
421} // namespace Nektar
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:249
std::map< GeomData, std::shared_ptr< VecVec_t > > m_twoDGeomDataInterLeave
std::map< GeomData, std::shared_ptr< VecVec_t > > m_oneDGeomDataInterLeave
const Array< OneD, const NekDouble > & GetJacWithStdWeights(std::vector< StdRegions::StdExpansionSharedPtr > &pColLExp)
bool IsDeformed(std::vector< StdRegions::StdExpansionSharedPtr > &pCollExp)
const std::shared_ptr< VecVec_t > GetJacInterLeave(std::vector< StdRegions::StdExpansionSharedPtr > &pCollExp, int nElmts)
std::map< GeomData, Array< OneD, NekDouble > > m_oneDGeomData
const Array< OneD, const NekDouble > & GetJac(std::vector< StdRegions::StdExpansionSharedPtr > &pColLExp)
const std::shared_ptr< VecVec_t > GetDerivFactorsInterLeave(std::vector< StdRegions::StdExpansionSharedPtr > &pCollExp, int nElmts)
std::map< GeomData, Array< TwoD, NekDouble > > m_twoDGeomData
const Array< TwoD, const NekDouble > & GetDerivFactors(std::vector< StdRegions::StdExpansionSharedPtr > &pColLExp)
const SpatialDomains::GeomFactorsSharedPtr & GetMetricInfo() const
Definition: Expansion.cpp:250
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
The base class for all shapes.
Definition: StdExpansion.h:71
std::vector< vec_t, tinysimd::allocator< vec_t > > VecVec_t
std::vector< PointsKey > PointsKeyVector
Definition: Points.h:236
@ eDeformed
Geometry is curved or has non-constant factors.
std::vector< double > q(NPUPPER *NPUPPER)
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
double NekDouble
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
Definition: Vmath.cpp:43
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1191