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
38
39using namespace std;
40
41namespace Nektar::Collections
42{
43
45 vector<StdRegions::StdExpansionSharedPtr> &pCollExp)
46{
47
48 if (m_oneDGeomData.count(eJac) == 0)
49 {
50 LibUtilities::PointsKeyVector ptsKeys = pCollExp[0]->GetPointsKeys();
51 int nElmts = pCollExp.size();
52 int npts = pCollExp[0]->GetTotPoints();
53
54 if (IsDeformed(pCollExp))
55 {
56 Array<OneD, NekDouble> newjac(npts * nElmts);
57
58 // copy Jacobians into a continuous list and set new chatched value
59 int cnt = 0;
60 for (int i = 0; i < nElmts; ++i)
61 {
62 const StdRegions::StdExpansion *sep = &(*pCollExp[i]);
63 const LocalRegions::Expansion *lep =
64 dynamic_cast<const LocalRegions::Expansion *>(sep);
65
67 lep->GetMetricInfo()->GetJac(ptsKeys);
68
69 Vmath::Vcopy(npts, &jac[0], 1, &newjac[cnt], 1);
70
71 cnt += npts;
72 }
73
74 m_oneDGeomData[eJac] = newjac;
75 }
76 else
77 {
78 Array<OneD, NekDouble> newjac(nElmts);
79 // copy Jacobians into a continuous list
80 for (int i = 0; i < nElmts; ++i)
81 {
82 const StdRegions::StdExpansion *sep = &(*pCollExp[i]);
83 const LocalRegions::Expansion *lep =
84 dynamic_cast<const LocalRegions::Expansion *>(sep);
85
87 lep->GetMetricInfo()->GetJac(ptsKeys);
88
89 newjac[i] = jac[0];
90 }
91 m_oneDGeomData[eJac] = newjac;
92 }
93 }
94
95 return m_oneDGeomData[eJac];
96}
97
98const std::shared_ptr<VecVec_t> CoalescedGeomData::GetJacInterLeave(
99 vector<StdRegions::StdExpansionSharedPtr> &pCollExp, int nElmt)
100{
101
102 if (m_oneDGeomDataInterLeave.count(eJac) == 0)
103 {
104 const Array<OneD, const NekDouble> jac = GetJac(pCollExp);
105 int jacsize = jac.size();
106 int npts = pCollExp[0]->GetTotPoints();
107
108 ASSERTL1(nElmt % vec_t::width == 0,
109 "Number of elements not divisible by vector "
110 "width, padding not yet implemented.");
111 int nBlocks = nElmt / vec_t::width;
112
113 VecVec_t newjac;
114
115 LibUtilities::PointsKeyVector ptsKeys = pCollExp[0]->GetPointsKeys();
116
117 if (IsDeformed(pCollExp))
118 {
119 newjac.resize(nBlocks * npts);
120
121 alignas(vec_t::alignment) NekDouble tmp[vec_t::width];
122
123 for (size_t block = 0; block < nBlocks; ++block)
124 {
125 size_t nblock_width = block * npts * vec_t::width;
126 for (size_t q = 0; q < npts; q++)
127 {
128 for (int j = 0; j < vec_t::width; ++j)
129 {
130 if (nblock_width + npts * j + q < jacsize)
131 {
132 tmp[j] = jac[nblock_width + npts * j + q];
133 }
134 else
135 {
136 tmp[j] = 0.0;
137 }
138 }
139
140 // Order is [block][quadpt]
141 newjac[block * npts + q].load(&tmp[0]);
142 }
143 }
144 }
145 else
146 {
147 newjac.resize(nBlocks);
148
149 alignas(vec_t::alignment) NekDouble tmp[vec_t::width];
150 for (size_t i = 0; i < nBlocks; ++i)
151 {
152 for (int j = 0; j < vec_t::width; ++j)
153 {
154 if (vec_t::width * i + j < jacsize)
155 {
156 tmp[j] = jac[vec_t::width * i + j];
157 }
158 else
159 {
160 tmp[j] = 0.0;
161 }
162 }
163
164 newjac[i].load(&tmp[0]);
165 }
166 }
167
170 }
171
173}
174
176 vector<StdRegions::StdExpansionSharedPtr> &pCollExp)
177{
178 if (m_oneDGeomData.count(eJacWithStdWeights) == 0)
179 {
180 LibUtilities::PointsKeyVector ptsKeys = pCollExp[0]->GetPointsKeys();
181 int nElmts = pCollExp.size();
182 int npts = pCollExp[0]->GetTotPoints();
183
184 // copy Jacobians into a continuous list and set new chatched value
185 Array<OneD, NekDouble> newjac(npts * nElmts), tmp;
186 int cnt = 0;
187 for (int i = 0; i < nElmts; ++i)
188 {
189 const StdRegions::StdExpansion *sep = &(*pCollExp[i]);
190 const LocalRegions::Expansion *lep =
191 dynamic_cast<const LocalRegions::Expansion *>(sep);
192
194 lep->GetMetricInfo()->GetJac(ptsKeys);
195
196 if (lep->GetMetricInfo()->GetGtype() == SpatialDomains::eDeformed)
197 {
198 Vmath::Vcopy(npts, &jac[0], 1, &newjac[cnt], 1);
199 }
200 else
201 {
202 Vmath::Fill(npts, jac[0], &newjac[cnt], 1);
203 }
204
205 pCollExp[0]->MultiplyByStdQuadratureMetric(newjac + cnt,
206 tmp = newjac + cnt);
207 cnt += npts;
208 }
209
211 }
212
214}
215
217 vector<StdRegions::StdExpansionSharedPtr> &pCollExp)
218{
219 if (m_twoDGeomData.count(eDerivFactors) == 0)
220 {
221 LibUtilities::PointsKeyVector ptsKeys = pCollExp[0]->GetPointsKeys();
222
223 int nElmts = pCollExp.size();
224 int npts = pCollExp[0]->GetTotPoints();
225 const int coordim = pCollExp[0]->GetCoordim();
226 int dim = ptsKeys.size();
227
228 // set up Cached Jacobians to be continuous
230
231 if (IsDeformed(pCollExp))
232 {
233 newDFac = Array<TwoD, NekDouble>(dim * coordim, npts * nElmts);
234 }
235 else
236 {
237 newDFac = Array<TwoD, NekDouble>(dim * coordim, nElmts);
238 }
239
240 // copy Jacobians into a continuous list and set new chatched value
241 int cnt = 0;
242 for (int i = 0; i < nElmts; ++i)
243 {
244 const StdRegions::StdExpansion *sep = &(*pCollExp[i]);
245 const LocalRegions::Expansion *lep =
246 dynamic_cast<const LocalRegions::Expansion *>(sep);
247
249 lep->GetMetricInfo()->GetDerivFactors(ptsKeys);
250
251 if (IsDeformed(pCollExp))
252 {
253 for (int j = 0; j < dim * coordim; ++j)
254 {
255 Vmath::Vcopy(npts, &Dfac[j][0], 1, &newDFac[j][cnt], 1);
256 }
257 }
258 else
259 {
260 for (int j = 0; j < dim * coordim; ++j)
261 {
262 newDFac[j][i] = Dfac[j][0];
263 }
264 }
265 cnt += npts;
266 }
267
268 m_twoDGeomData[eDerivFactors] = newDFac;
269 }
270
272}
273
274const std::shared_ptr<VecVec_t> CoalescedGeomData::GetDerivFactorsInterLeave(
275 vector<StdRegions::StdExpansionSharedPtr> &pCollExp, int nElmt)
276{
278 {
279 ASSERTL1(nElmt % vec_t::width == 0,
280 "Number of elements not divisible by vector "
281 "width, padding not yet implemented.");
282
283 int nBlocks = nElmt / vec_t::width;
284
285 LibUtilities::PointsKeyVector ptsKeys = pCollExp[0]->GetPointsKeys();
286 const int coordim = pCollExp[0]->GetCoordim();
287 int dim = ptsKeys.size();
288
289 unsigned int n_df = coordim * dim;
290 alignas(vec_t::alignment) NekDouble vec[vec_t::width];
291
293 int dfsize = df.GetColumns();
294
295 VecVec_t newdf;
296
297 int npts = pCollExp[0]->GetTotPoints();
298
299 if (IsDeformed(pCollExp))
300 {
301 newdf.resize(nBlocks * n_df * npts);
302 auto *df_ptr = &newdf[0];
303 for (int e = 0; e < nBlocks; ++e)
304 {
305 for (int q = 0; q < npts; q++)
306 {
307 for (int dir = 0; dir < n_df; ++dir, ++df_ptr)
308 {
309 for (int j = 0; j < vec_t::width; ++j)
310 {
311 // manage padding
312 if ((vec_t::width * e + j) * npts + q < dfsize)
313 {
314 vec[j] =
315 df[dir][(vec_t::width * e + j) * npts + q];
316 }
317 else
318 {
319 vec[j] = 0.0;
320 }
321 }
322 (*df_ptr).load(&vec[0]);
323 }
324 }
325 }
326 }
327 else
328 {
329 newdf.resize(nBlocks * n_df);
330 for (int e = 0; e < nBlocks; ++e)
331 {
332 for (int dir = 0; dir < n_df; ++dir)
333 {
334 for (int j = 0; j < vec_t::width; ++j)
335 {
336 // padding
337 if (vec_t::width * e + j < dfsize)
338 {
339 vec[j] = df[dir][vec_t::width * e + j];
340 }
341 else
342 {
343 vec[j] = 0.0;
344 }
345 }
346 // Must have all vec_t::width elemnts aligned to do a load.
347 newdf[e * n_df + dir].load(&vec[0]);
348 }
349 }
350 }
351
354 }
355
357}
358
360 vector<StdRegions::StdExpansionSharedPtr> &pCollExp)
361{
362 const StdRegions::StdExpansion *sep = &(*pCollExp[0]);
363 const LocalRegions::Expansion *lep =
364 dynamic_cast<const LocalRegions::Expansion *>(sep);
365 return lep->GetMetricInfo()->GetGtype() == SpatialDomains::eDeformed;
366}
367
368} // namespace Nektar::Collections
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:242
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:246
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:65
std::vector< vec_t, tinysimd::allocator< vec_t > > VecVec_t
std::vector< PointsKey > PointsKeyVector
Definition: Points.h:231
@ eDeformed
Geometry is curved or has non-constant factors.
std::vector< double > q(NPUPPER *NPUPPER)
double NekDouble
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
Definition: Vmath.hpp:54
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.hpp:825