Nektar++
Loading...
Searching...
No Matches
PyrExp.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: PyrExp.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: PyrExp routines
32//
33///////////////////////////////////////////////////////////////////////////////
34
36#include <LocalRegions/PyrExp.h>
37
38using namespace std;
39
41{
42
44 const LibUtilities::BasisKey &Bb,
45 const LibUtilities::BasisKey &Bc,
47 : StdExpansion(LibUtilities::StdPyrData::getNumberOfCoefficients(
48 Ba.GetNumModes(), Bb.GetNumModes(), Bc.GetNumModes()),
49 3, Ba, Bb, Bc),
50 StdExpansion3D(LibUtilities::StdPyrData::getNumberOfCoefficients(
51 Ba.GetNumModes(), Bb.GetNumModes(), Bc.GetNumModes()),
52 Ba, Bb, Bc),
53 StdPyrExp(Ba, Bb, Bc), Expansion(geom), Expansion3D(geom),
54 m_matrixManager(
55 std::bind(&Expansion3D::CreateMatrix, this, std::placeholders::_1)),
56 m_staticCondMatrixManager(std::bind(&Expansion::CreateStaticCondMatrix,
57 this, std::placeholders::_1))
58{
59}
60
62 : StdExpansion(T), StdExpansion3D(T), StdPyrExp(T), Expansion(T),
63 Expansion3D(T), m_matrixManager(T.m_matrixManager),
64 m_staticCondMatrixManager(T.m_staticCondMatrixManager)
65{
66}
67
68//---------------------------------------
69// Inner product functions
70//---------------------------------------
71/**
72 * @brief Calculates the inner product \f$ I_{pqr} = (u,
73 * \partial_{x_i} \phi_{pqr}) \f$.
74 *
75 * The derivative of the basis functions is performed using the chain
76 * rule in order to incorporate the geometric factors. Assuming that
77 * the basis functions are a tensor product
78 * \f$\phi_{pqr}(\eta_1,\eta_2,\eta_3) =
79 * \phi_1(\eta_1)\phi_2(\eta_2)\phi_3(\eta_3)\f$, this yields the
80 * result
81 *
82 * \f[
83 * I_{pqr} = \sum_{j=1}^3 \left(u, \frac{\partial u}{\partial \eta_j}
84 * \frac{\partial \eta_j}{\partial x_i}\right)
85 * \f]
86 *
87 * In the pyramid element, we must also incorporate a second set
88 * of geometric factors which incorporate the collapsed co-ordinate
89 * system, so that
90 *
91 * \f[ \frac{\partial\eta_j}{\partial x_i} = \sum_{k=1}^3
92 * \frac{\partial\eta_j}{\partial\xi_k}\frac{\partial\xi_k}{\partial
93 * x_i} \f]
94 *
95 * These derivatives can be found on p152 of Sherwin & Karniadakis.
96 *
97 * @param dir Direction in which to take the derivative.
98 * @param inarray The function \f$ u \f$.
99 * @param outarray Value of the inner product.
100 */
102 const Array<OneD, const NekDouble> &inarray,
103 Array<OneD, NekDouble> &outarray)
104{
105 const int nquad0 = m_base[0]->GetNumPoints();
106 const int nquad1 = m_base[1]->GetNumPoints();
107 const int nquad2 = m_base[2]->GetNumPoints();
108 const int nqtot = nquad0 * nquad1 * nquad2;
109
110 Array<OneD, NekDouble> tmp2(nqtot);
111 Array<OneD, NekDouble> tmp3(nqtot);
112 Array<OneD, NekDouble> tmp4(nqtot);
114
116 tmp2D[0] = tmp2;
117 tmp2D[1] = tmp3;
118 tmp2D[2] = tmp4;
119
120 const Array<OneD, const NekDouble> &jac = m_geomFactors->GetJac();
121 bool Deformed = (m_geomFactors->GetGtype() == SpatialDomains::eDeformed);
122
123 v_AlignVectorToCollapsedDir(dir, inarray, tmp2D);
124
125 v_IProductWRTBaseKernel(m_base[0]->GetDbdata(), m_base[1]->GetBdata(),
126 m_base[2]->GetBdata(), tmp2, outarray, jac,
127 Deformed);
128
129 v_IProductWRTBaseKernel(m_base[0]->GetBdata(), m_base[1]->GetDbdata(),
130 m_base[2]->GetBdata(), tmp3, tmp6, jac, Deformed);
131 Vmath::Vadd(m_ncoeffs, tmp6, 1, outarray, 1, outarray, 1);
132
133 v_IProductWRTBaseKernel(m_base[0]->GetBdata(), m_base[1]->GetBdata(),
134 m_base[2]->GetDbdata(), tmp4, tmp6, jac, Deformed);
135 Vmath::Vadd(m_ncoeffs, tmp6, 1, outarray, 1, outarray, 1);
136}
137
139 const int dir, const Array<OneD, const NekDouble> &inarray,
141{
142 const int nquad0 = m_base[0]->GetNumPoints();
143 const int nquad1 = m_base[1]->GetNumPoints();
144 const int nquad2 = m_base[2]->GetNumPoints();
145 const int nqtot = nquad0 * nquad1 * nquad2;
146
147 const Array<OneD, const NekDouble> &z0 = m_base[0]->GetZ();
148 const Array<OneD, const NekDouble> &z1 = m_base[1]->GetZ();
149 const Array<OneD, const NekDouble> &z2 = m_base[2]->GetZ();
150
151 Array<OneD, NekDouble> tmp2 = outarray[0];
152 Array<OneD, NekDouble> tmp3 = outarray[1];
153 Array<OneD, NekDouble> tmp4 = outarray[2];
154
155 const Array<TwoD, const NekDouble> &df = m_geomFactors->GetDerivFactors();
156
157 if (m_geomFactors->GetGtype() == SpatialDomains::eDeformed)
158 {
159 Vmath::Vmul(nqtot, &df[3 * dir][0], 1, inarray.data(), 1, tmp2.data(),
160 1);
161 Vmath::Vmul(nqtot, &df[3 * dir + 1][0], 1, inarray.data(), 1,
162 tmp3.data(), 1);
163 Vmath::Vmul(nqtot, &df[3 * dir + 2][0], 1, inarray.data(), 1,
164 tmp4.data(), 1);
165 }
166 else
167 {
168 Vmath::Smul(nqtot, df[3 * dir][0], inarray.data(), 1, tmp2.data(), 1);
169 Vmath::Smul(nqtot, df[3 * dir + 1][0], inarray.data(), 1, tmp3.data(),
170 1);
171 Vmath::Smul(nqtot, df[3 * dir + 2][0], inarray.data(), 1, tmp4.data(),
172 1);
173 }
174
175 int i, j;
176 NekDouble g0, g1, g2, g02;
177
178 for (int k = 0, cnt = 0; k < nquad2; ++k)
179 {
180 g2 = 2.0 / (1.0 - z2[k]);
181
182 for (j = 0; j < nquad1; ++j)
183 {
184 g1 = 0.5 * (1.0 + z1[j]) * g2;
185
186 for (i = 0; i < nquad0; ++i, ++cnt)
187 {
188 g0 = 0.5 * (1.0 + z0[i]);
189 g02 = g0 * g2;
190
191 outarray[0][cnt] = g2 * tmp2[cnt] + g02 * tmp4[cnt];
192 outarray[1][cnt] = g2 * tmp3[cnt] + g1 * tmp4[cnt];
193 }
194 }
195 }
196}
197
198//---------------------------------------
199// Evaluation functions
200//---------------------------------------
201
203{
205 m_base[0]->GetBasisKey(), m_base[1]->GetBasisKey(),
206 m_base[2]->GetBasisKey());
207}
208
210{
212 m_base[0]->GetPointsKey());
214 m_base[1]->GetPointsKey());
216 m_base[2]->GetPointsKey());
217
219 bkey2);
220}
221
222/*
223 * @brief Get the coordinates #coords at the local coordinates
224 * #Lcoords
225 */
228{
229 int i;
230
231 ASSERTL1(Lcoords[0] <= -1.0 && Lcoords[0] >= 1.0 && Lcoords[1] <= -1.0 &&
232 Lcoords[1] >= 1.0 && Lcoords[2] <= -1.0 && Lcoords[2] >= 1.0,
233 "Local coordinates are not in region [-1,1]");
234
235 // m_geom->FillGeom(); // TODO: implement FillGeom()
236
237 for (i = 0; i < m_geom->GetCoordim(); ++i)
238 {
239 coords[i] = m_geom->GetCoord(i, Lcoords);
240 }
241}
242
244 Array<OneD, NekDouble> &coords_2,
245 Array<OneD, NekDouble> &coords_3)
246{
247 Expansion::v_GetCoords(coords_1, coords_2, coords_3);
248}
249
251 const NekDouble *data, const std::vector<unsigned int> &nummodes,
252 const int mode_offset, NekDouble *coeffs,
253 std::vector<LibUtilities::BasisType> &fromType)
254{
255 int data_order0 = nummodes[mode_offset];
256 int fillorder0 = min(m_base[0]->GetNumModes(), data_order0);
257 int data_order1 = nummodes[mode_offset + 1];
258 int order1 = m_base[1]->GetNumModes();
259 int fillorder1 = min(order1, data_order1);
260 int data_order2 = nummodes[mode_offset + 2];
261 int order2 = m_base[2]->GetNumModes();
262 int fillorder2 = min(order2, data_order2);
263
264 // Check if not same order or basis and if not make temp
265 // element to read in data
266 if (fromType[0] != m_base[0]->GetBasisType() ||
267 fromType[1] != m_base[1]->GetBasisType() ||
268 fromType[2] != m_base[2]->GetBasisType() || data_order0 != fillorder0 ||
269 data_order1 != fillorder1 || data_order2 != fillorder2)
270 {
271 // Construct a pyr with the appropriate basis type at our
272 // quadrature points, and one more to do a forwards
273 // transform. We can then copy the output to coeffs.
275 LibUtilities::BasisKey(fromType[0], data_order0,
276 m_base[0]->GetPointsKey()),
277 LibUtilities::BasisKey(fromType[1], data_order1,
278 m_base[1]->GetPointsKey()),
279 LibUtilities::BasisKey(fromType[2], data_order2,
280 m_base[2]->GetPointsKey()));
281
282 StdRegions::StdPyrExp tmpPyr2(m_base[0]->GetBasisKey(),
283 m_base[1]->GetBasisKey(),
284 m_base[2]->GetBasisKey());
285
286 Array<OneD, const NekDouble> tmpData(tmpPyr.GetNcoeffs(), data);
287 Array<OneD, NekDouble> tmpBwd(tmpPyr2.GetTotPoints());
288 Array<OneD, NekDouble> tmpOut(tmpPyr2.GetNcoeffs());
289
290 tmpPyr.BwdTrans(tmpData, tmpBwd);
291 tmpPyr2.FwdTrans(tmpBwd, tmpOut);
292 Vmath::Vcopy(tmpOut.size(), &tmpOut[0], 1, coeffs, 1);
293 }
294 else
295 {
296 Vmath::Vcopy(m_ncoeffs, &data[0], 1, coeffs, 1);
297 }
298}
299
301 const Array<OneD, NekDouble> &coord,
302 const Array<OneD, const NekDouble> &inarray,
303 std::array<NekDouble, 3> &firstOrderDerivs)
304{
305 Array<OneD, NekDouble> Lcoord(3);
306 ASSERTL0(m_geom, "m_geom not defined");
307 m_geom->GetLocCoords(coord, Lcoord);
308 return StdPyrExp::v_PhysEvalFirstDeriv(Lcoord, inarray, firstOrderDerivs);
309}
310
311//---------------------------------------
312// Helper functions
313//---------------------------------------
314
315void PyrExp::v_GetTracePhysMap(const int face, Array<OneD, int> &outarray)
316{
317 int nquad0 = m_base[0]->GetNumPoints();
318 int nquad1 = m_base[1]->GetNumPoints();
319 int nquad2 = m_base[2]->GetNumPoints();
320
321 int nq0 = 0;
322 int nq1 = 0;
323
324 switch (face)
325 {
326 case 0:
327 nq0 = nquad0;
328 nq1 = nquad1;
329 if (outarray.size() != nq0 * nq1)
330 {
331 outarray = Array<OneD, int>(nq0 * nq1);
332 }
333
334 // Directions A and B positive
335 for (int i = 0; i < nquad0 * nquad1; ++i)
336 {
337 outarray[i] = i;
338 }
339
340 break;
341 case 1:
342 nq0 = nquad0;
343 nq1 = nquad2;
344 if (outarray.size() != nq0 * nq1)
345 {
346 outarray = Array<OneD, int>(nq0 * nq1);
347 }
348
349 // Direction A and B positive
350 for (int k = 0; k < nquad2; k++)
351 {
352 for (int i = 0; i < nquad0; ++i)
353 {
354 outarray[k * nquad0 + i] = (nquad0 * nquad1 * k) + i;
355 }
356 }
357
358 break;
359 case 2:
360 nq0 = nquad1;
361 nq1 = nquad2;
362 if (outarray.size() != nq0 * nq1)
363 {
364 outarray = Array<OneD, int>(nq0 * nq1);
365 }
366
367 // Directions A and B positive
368 for (int j = 0; j < nquad1 * nquad2; ++j)
369 {
370 outarray[j] = nquad0 - 1 + j * nquad0;
371 }
372 break;
373 case 3:
374
375 nq0 = nquad0;
376 nq1 = nquad2;
377 if (outarray.size() != nq0 * nq1)
378 {
379 outarray = Array<OneD, int>(nq0 * nq1);
380 }
381
382 // Direction A and B positive
383 for (int k = 0; k < nquad2; k++)
384 {
385 for (int i = 0; i < nquad0; ++i)
386 {
387 outarray[k * nquad0 + i] =
388 nquad0 * (nquad1 - 1) + (nquad0 * nquad1 * k) + i;
389 }
390 }
391 break;
392 case 4:
393 nq0 = nquad1;
394 nq1 = nquad2;
395
396 if (outarray.size() != nq0 * nq1)
397 {
398 outarray = Array<OneD, int>(nq0 * nq1);
399 }
400
401 // Directions A and B positive
402 for (int j = 0; j < nquad1 * nquad2; ++j)
403 {
404 outarray[j] = j * nquad0;
405 }
406 break;
407 default:
408 ASSERTL0(false, "face value (> 4) is out of range");
409 break;
410 }
411}
412
414{
416 for (int i = 0; i < ptsKeys.size(); ++i)
417 {
418 // Need at least 2 points for computing normals
419 if (ptsKeys[i].GetNumPoints() == 1)
420 {
421 LibUtilities::PointsKey pKey(2, ptsKeys[i].GetPointsType());
422 ptsKeys[i] = pKey;
423 }
424 }
425
426 SpatialDomains::GeomType type = m_geomFactors->GetGtype();
428 m_geomFactors->ComputeDerivFactors(ptsKeys);
430 m_geomFactors->ComputeJac(ptsKeys);
431
432 LibUtilities::BasisKey tobasis0 = GetTraceBasisKey(face, 0);
433 LibUtilities::BasisKey tobasis1 = GetTraceBasisKey(face, 1);
434
435 // Number of quadrature points in face expansion.
436 int nq_face = tobasis0.GetNumPoints() * tobasis1.GetNumPoints();
437
438 int vCoordDim = GetCoordim();
439 int i;
440
443 for (i = 0; i < vCoordDim; ++i)
444 {
445 normal[i] = Array<OneD, NekDouble>(nq_face);
446 }
447
448 size_t nqb = nq_face;
449 size_t nbnd = face;
452
453 // Regular geometry case
454 if (type == SpatialDomains::eRegular ||
456 {
457 NekDouble fac;
458 // Set up normals
459 switch (face)
460 {
461 case 0:
462 {
463 for (i = 0; i < vCoordDim; ++i)
464 {
465 normal[i][0] = -df[3 * i + 2][0];
466 }
467 break;
468 }
469 case 1:
470 {
471 for (i = 0; i < vCoordDim; ++i)
472 {
473 normal[i][0] = -df[3 * i + 1][0];
474 }
475 break;
476 }
477 case 2:
478 {
479 for (i = 0; i < vCoordDim; ++i)
480 {
481 normal[i][0] = df[3 * i][0] + df[3 * i + 2][0];
482 }
483 break;
484 }
485 case 3:
486 {
487 for (i = 0; i < vCoordDim; ++i)
488 {
489 normal[i][0] = df[3 * i + 1][0] + df[3 * i + 2][0];
490 }
491 break;
492 }
493 case 4:
494 {
495 for (i = 0; i < vCoordDim; ++i)
496 {
497 normal[i][0] = -df[3 * i][0];
498 }
499 break;
500 }
501 default:
502 ASSERTL0(false, "face is out of range (face < 4)");
503 }
504
505 // Normalise resulting vector.
506 fac = 0.0;
507 for (i = 0; i < vCoordDim; ++i)
508 {
509 fac += normal[i][0] * normal[i][0];
510 }
511 fac = 1.0 / sqrt(fac);
512
513 Vmath::Fill(nqb, fac, length, 1);
514
515 for (i = 0; i < vCoordDim; ++i)
516 {
517 Vmath::Fill(nq_face, fac * normal[i][0], normal[i], 1);
518 }
519 }
520 else
521 {
522 // Set up deformed normals.
523 int j, k;
524
525 int nq0 = ptsKeys[0].GetNumPoints();
526 int nq1 = ptsKeys[1].GetNumPoints();
527 int nq2 = ptsKeys[2].GetNumPoints();
528 int nq01 = nq0 * nq1;
529 int nqtot;
530
531 // Determine number of quadrature points on the face.
532 if (face == 0)
533 {
534 nqtot = nq0 * nq1;
535 }
536 else if (face == 1 || face == 3)
537 {
538 nqtot = nq0 * nq2;
539 }
540 else
541 {
542 nqtot = nq1 * nq2;
543 }
544
547
548 Array<OneD, NekDouble> faceJac(nqtot);
549 Array<OneD, NekDouble> normals(vCoordDim * nqtot, 0.0);
550
551 // Extract Jacobian along face and recover local derivatives
552 // (dx/dr) for polynomial interpolation by multiplying m_gmat by
553 // jacobian
554 switch (face)
555 {
556 case 0:
557 {
558 for (j = 0; j < nq01; ++j)
559 {
560 normals[j] = -df[2][j] * jac[j];
561 normals[nqtot + j] = -df[5][j] * jac[j];
562 normals[2 * nqtot + j] = -df[8][j] * jac[j];
563 faceJac[j] = jac[j];
564 }
565
566 points0 = ptsKeys[0];
567 points1 = ptsKeys[1];
568 break;
569 }
570
571 case 1:
572 {
573 for (j = 0; j < nq0; ++j)
574 {
575 for (k = 0; k < nq2; ++k)
576 {
577 int tmp = j + nq01 * k;
578 normals[j + k * nq0] = -df[1][tmp] * jac[tmp];
579 normals[nqtot + j + k * nq0] = -df[4][tmp] * jac[tmp];
580 normals[2 * nqtot + j + k * nq0] =
581 -df[7][tmp] * jac[tmp];
582 faceJac[j + k * nq0] = jac[tmp];
583 }
584 }
585
586 points0 = ptsKeys[0];
587 points1 = ptsKeys[2];
588 break;
589 }
590
591 case 2:
592 {
593 for (j = 0; j < nq1; ++j)
594 {
595 for (k = 0; k < nq2; ++k)
596 {
597 int tmp = nq0 - 1 + nq0 * j + nq01 * k;
598 normals[j + k * nq1] =
599 (df[0][tmp] + df[2][tmp]) * jac[tmp];
600 normals[nqtot + j + k * nq1] =
601 (df[3][tmp] + df[5][tmp]) * jac[tmp];
602 normals[2 * nqtot + j + k * nq1] =
603 (df[6][tmp] + df[8][tmp]) * jac[tmp];
604 faceJac[j + k * nq1] = jac[tmp];
605 }
606 }
607
608 points0 = ptsKeys[1];
609 points1 = ptsKeys[2];
610 break;
611 }
612
613 case 3:
614 {
615 for (j = 0; j < nq0; ++j)
616 {
617 for (k = 0; k < nq2; ++k)
618 {
619 int tmp = nq0 * (nq1 - 1) + j + nq01 * k;
620 normals[j + k * nq0] =
621 (df[1][tmp] + df[2][tmp]) * jac[tmp];
622 normals[nqtot + j + k * nq0] =
623 (df[4][tmp] + df[5][tmp]) * jac[tmp];
624 normals[2 * nqtot + j + k * nq0] =
625 (df[7][tmp] + df[8][tmp]) * jac[tmp];
626 faceJac[j + k * nq0] = jac[tmp];
627 }
628 }
629
630 points0 = ptsKeys[0];
631 points1 = ptsKeys[2];
632 break;
633 }
634
635 case 4:
636 {
637 for (j = 0; j < nq1; ++j)
638 {
639 for (k = 0; k < nq2; ++k)
640 {
641 int tmp = j * nq0 + nq01 * k;
642 normals[j + k * nq1] = -df[0][tmp] * jac[tmp];
643 normals[nqtot + j + k * nq1] = -df[3][tmp] * jac[tmp];
644 normals[2 * nqtot + j + k * nq1] =
645 -df[6][tmp] * jac[tmp];
646 faceJac[j + k * nq1] = jac[tmp];
647 }
648 }
649
650 points0 = ptsKeys[1];
651 points1 = ptsKeys[2];
652 break;
653 }
654
655 default:
656 ASSERTL0(false, "face is out of range (face < 4)");
657 }
658
659 Array<OneD, NekDouble> work(nq_face, 0.0);
660 // Interpolate Jacobian and invert
661 LibUtilities::Interp2D(points0, points1, faceJac,
662 tobasis0.GetPointsKey(), tobasis1.GetPointsKey(),
663 work);
664 Vmath::Sdiv(nq_face, 1.0, &work[0], 1, &work[0], 1);
665
666 // Interpolate normal and multiply by inverse Jacobian.
667 for (i = 0; i < vCoordDim; ++i)
668 {
669 LibUtilities::Interp2D(points0, points1, &normals[i * nqtot],
670 tobasis0.GetPointsKey(),
671 tobasis1.GetPointsKey(), &normal[i][0]);
672 Vmath::Vmul(nq_face, work, 1, normal[i], 1, normal[i], 1);
673 }
674
675 // Normalise to obtain unit normals.
676 Vmath::Zero(nq_face, work, 1);
677 for (i = 0; i < GetCoordim(); ++i)
678 {
679 Vmath::Vvtvp(nq_face, normal[i], 1, normal[i], 1, work, 1, work, 1);
680 }
681
682 Vmath::Vsqrt(nq_face, work, 1, work, 1);
683 Vmath::Sdiv(nq_face, 1.0, work, 1, work, 1);
684
685 Vmath::Vcopy(nqb, work, 1, length, 1);
686
687 for (i = 0; i < GetCoordim(); ++i)
688 {
689 Vmath::Vmul(nq_face, normal[i], 1, work, 1, normal[i], 1);
690 }
691 }
692}
693
695 const StdRegions::StdMatrixKey &mkey)
696{
697 int nq = GetTotPoints();
698
699 // Calculate sqrt of the Jacobian
701 Array<OneD, NekDouble> sqrt_jac(nq);
702 if (m_geomFactors->GetGtype() == SpatialDomains::eDeformed)
703 {
704 Vmath::Vsqrt(nq, jac, 1, sqrt_jac, 1);
705 }
706 else
707 {
708 Vmath::Fill(nq, sqrt(jac[0]), sqrt_jac, 1);
709 }
710
711 // Multiply array by sqrt(Jac)
712 Vmath::Vmul(nq, sqrt_jac, 1, array, 1, array, 1);
713
714 // Apply std region filter
715 StdPyrExp::v_SVVLaplacianFilter(array, mkey);
716
717 // Divide by sqrt(Jac)
718 Vmath::Vdiv(nq, array, 1, sqrt_jac, 1, array, 1);
719}
720
721//---------------------------------------
722// Matrix creation functions
723//---------------------------------------
724
726{
727 DNekMatSharedPtr returnval;
728
729 switch (mkey.GetMatrixType())
730 {
737 returnval = Expansion3D::v_GenMatrix(mkey);
738 break;
739 default:
740 returnval = StdPyrExp::v_GenMatrix(mkey);
741 }
742
743 return returnval;
744}
745
747{
748 LibUtilities::BasisKey bkey0 = m_base[0]->GetBasisKey();
749 LibUtilities::BasisKey bkey1 = m_base[1]->GetBasisKey();
750 LibUtilities::BasisKey bkey2 = m_base[2]->GetBasisKey();
753
754 return tmp->GetStdMatrix(mkey);
755}
756
761
763{
764 m_matrixManager.DeleteObject(mkey);
765}
766
771
773{
774 m_staticCondMatrixManager.DeleteObject(mkey);
775}
776
778{
779 int i, j;
780 const unsigned int nqtot = GetTotPoints();
781 const unsigned int dim = 3;
782 const MetricType m[3][3] = {
786
787 for (unsigned int i = 0; i < dim; ++i)
788 {
789 for (unsigned int j = i; j < dim; ++j)
790 {
791 m_metrics[m[i][j]] = Array<OneD, NekDouble>(nqtot);
792 }
793 }
794
795 // Define shorthand synonyms for m_metrics storage
802
803 // Allocate temporary storage
804 Array<OneD, NekDouble> alloc(9 * nqtot, 0.0);
805 Array<OneD, NekDouble> h0(nqtot, alloc);
806 Array<OneD, NekDouble> h1(nqtot, alloc + 1 * nqtot);
807 Array<OneD, NekDouble> h2(nqtot, alloc + 2 * nqtot);
808 Array<OneD, NekDouble> wsp1(nqtot, alloc + 3 * nqtot);
809 Array<OneD, NekDouble> wsp2(nqtot, alloc + 4 * nqtot);
810 Array<OneD, NekDouble> wsp3(nqtot, alloc + 5 * nqtot);
811 Array<OneD, NekDouble> wsp4(nqtot, alloc + 6 * nqtot);
812 Array<OneD, NekDouble> wsp5(nqtot, alloc + 7 * nqtot);
813 Array<OneD, NekDouble> wsp6(nqtot, alloc + 8 * nqtot);
814
815 const Array<TwoD, const NekDouble> &df = m_geomFactors->GetDerivFactors();
816 const Array<OneD, const NekDouble> &z0 = m_base[0]->GetZ();
817 const Array<OneD, const NekDouble> &z1 = m_base[1]->GetZ();
818 const Array<OneD, const NekDouble> &z2 = m_base[2]->GetZ();
819 const unsigned int nquad0 = m_base[0]->GetNumPoints();
820 const unsigned int nquad1 = m_base[1]->GetNumPoints();
821 const unsigned int nquad2 = m_base[2]->GetNumPoints();
822
823 // Populate collapsed coordinate arrays h0, h1 and h2.
824 for (j = 0; j < nquad2; ++j)
825 {
826 for (i = 0; i < nquad1; ++i)
827 {
828 Vmath::Fill(nquad0, 2.0 / (1.0 - z2[j]),
829 &h0[0] + i * nquad0 + j * nquad0 * nquad1, 1);
830 Vmath::Fill(nquad0, 1.0 / (1.0 - z2[j]),
831 &h1[0] + i * nquad0 + j * nquad0 * nquad1, 1);
832 Vmath::Fill(nquad0, (1.0 + z1[i]) / (1.0 - z2[j]),
833 &h2[0] + i * nquad0 + j * nquad0 * nquad1, 1);
834 }
835 }
836 for (i = 0; i < nquad0; i++)
837 {
838 Blas::Dscal(nquad1 * nquad2, 1 + z0[i], &h1[0] + i, nquad0);
839 }
840
841 // Step 3. Construct combined metric terms for physical space to
842 // collapsed coordinate system.
843 // Order of construction optimised to minimise temporary storage
844 if (m_geomFactors->GetGtype() == SpatialDomains::eDeformed)
845 {
846 // f_{1k}
847 Vmath::Vvtvvtp(nqtot, &df[0][0], 1, &h0[0], 1, &df[2][0], 1, &h1[0], 1,
848 &wsp1[0], 1);
849 Vmath::Vvtvvtp(nqtot, &df[3][0], 1, &h0[0], 1, &df[5][0], 1, &h1[0], 1,
850 &wsp2[0], 1);
851 Vmath::Vvtvvtp(nqtot, &df[6][0], 1, &h0[0], 1, &df[8][0], 1, &h1[0], 1,
852 &wsp3[0], 1);
853
854 // g0
855 Vmath::Vvtvvtp(nqtot, &wsp1[0], 1, &wsp1[0], 1, &wsp2[0], 1, &wsp2[0],
856 1, &g0[0], 1);
857 Vmath::Vvtvp(nqtot, &wsp3[0], 1, &wsp3[0], 1, &g0[0], 1, &g0[0], 1);
858
859 // g4
860 Vmath::Vvtvvtp(nqtot, &df[2][0], 1, &wsp1[0], 1, &df[5][0], 1, &wsp2[0],
861 1, &g4[0], 1);
862 Vmath::Vvtvp(nqtot, &df[8][0], 1, &wsp3[0], 1, &g4[0], 1, &g4[0], 1);
863
864 // f_{2k}
865 Vmath::Vvtvvtp(nqtot, &df[1][0], 1, &h0[0], 1, &df[2][0], 1, &h2[0], 1,
866 &wsp4[0], 1);
867 Vmath::Vvtvvtp(nqtot, &df[4][0], 1, &h0[0], 1, &df[5][0], 1, &h2[0], 1,
868 &wsp5[0], 1);
869 Vmath::Vvtvvtp(nqtot, &df[7][0], 1, &h0[0], 1, &df[8][0], 1, &h2[0], 1,
870 &wsp6[0], 1);
871
872 // g1
873 Vmath::Vvtvvtp(nqtot, &wsp4[0], 1, &wsp4[0], 1, &wsp5[0], 1, &wsp5[0],
874 1, &g1[0], 1);
875 Vmath::Vvtvp(nqtot, &wsp6[0], 1, &wsp6[0], 1, &g1[0], 1, &g1[0], 1);
876
877 // g3
878 Vmath::Vvtvvtp(nqtot, &wsp1[0], 1, &wsp4[0], 1, &wsp2[0], 1, &wsp5[0],
879 1, &g3[0], 1);
880 Vmath::Vvtvp(nqtot, &wsp3[0], 1, &wsp6[0], 1, &g3[0], 1, &g3[0], 1);
881
882 // g5
883 Vmath::Vvtvvtp(nqtot, &df[2][0], 1, &wsp4[0], 1, &df[5][0], 1, &wsp5[0],
884 1, &g5[0], 1);
885 Vmath::Vvtvp(nqtot, &df[8][0], 1, &wsp6[0], 1, &g5[0], 1, &g5[0], 1);
886
887 // g2
888 Vmath::Vvtvvtp(nqtot, &df[2][0], 1, &df[2][0], 1, &df[5][0], 1,
889 &df[5][0], 1, &g2[0], 1);
890 Vmath::Vvtvp(nqtot, &df[8][0], 1, &df[8][0], 1, &g2[0], 1, &g2[0], 1);
891 }
892 else
893 {
894 // f_{1k}
895 Vmath::Svtsvtp(nqtot, df[0][0], &h0[0], 1, df[2][0], &h1[0], 1,
896 &wsp1[0], 1);
897 Vmath::Svtsvtp(nqtot, df[3][0], &h0[0], 1, df[5][0], &h1[0], 1,
898 &wsp2[0], 1);
899 Vmath::Svtsvtp(nqtot, df[6][0], &h0[0], 1, df[8][0], &h1[0], 1,
900 &wsp3[0], 1);
901
902 // g0
903 Vmath::Vvtvvtp(nqtot, &wsp1[0], 1, &wsp1[0], 1, &wsp2[0], 1, &wsp2[0],
904 1, &g0[0], 1);
905 Vmath::Vvtvp(nqtot, &wsp3[0], 1, &wsp3[0], 1, &g0[0], 1, &g0[0], 1);
906
907 // g4
908 Vmath::Svtsvtp(nqtot, df[2][0], &wsp1[0], 1, df[5][0], &wsp2[0], 1,
909 &g4[0], 1);
910 Vmath::Svtvp(nqtot, df[8][0], &wsp3[0], 1, &g4[0], 1, &g4[0], 1);
911
912 // f_{2k}
913 Vmath::Svtsvtp(nqtot, df[1][0], &h0[0], 1, df[2][0], &h2[0], 1,
914 &wsp4[0], 1);
915 Vmath::Svtsvtp(nqtot, df[4][0], &h0[0], 1, df[5][0], &h2[0], 1,
916 &wsp5[0], 1);
917 Vmath::Svtsvtp(nqtot, df[7][0], &h0[0], 1, df[8][0], &h2[0], 1,
918 &wsp6[0], 1);
919
920 // g1
921 Vmath::Vvtvvtp(nqtot, &wsp4[0], 1, &wsp4[0], 1, &wsp5[0], 1, &wsp5[0],
922 1, &g1[0], 1);
923 Vmath::Vvtvp(nqtot, &wsp6[0], 1, &wsp6[0], 1, &g1[0], 1, &g1[0], 1);
924
925 // g3
926 Vmath::Vvtvvtp(nqtot, &wsp1[0], 1, &wsp4[0], 1, &wsp2[0], 1, &wsp5[0],
927 1, &g3[0], 1);
928 Vmath::Vvtvp(nqtot, &wsp3[0], 1, &wsp6[0], 1, &g3[0], 1, &g3[0], 1);
929
930 // g5
931 Vmath::Svtsvtp(nqtot, df[2][0], &wsp4[0], 1, df[5][0], &wsp5[0], 1,
932 &g5[0], 1);
933 Vmath::Svtvp(nqtot, df[8][0], &wsp6[0], 1, &g5[0], 1, &g5[0], 1);
934
935 // g2
936 Vmath::Fill(nqtot,
937 df[2][0] * df[2][0] + df[5][0] * df[5][0] +
938 df[8][0] * df[8][0],
939 &g2[0], 1);
940 }
941}
942
944 const Array<OneD, const NekDouble> &inarray,
946{
947 // This implementation is only valid when there are no coefficients
948 // associated to the Laplacian operator
949 if (m_metrics.count(eMetricLaplacian00) == 0)
950 {
952 }
953
954 int nquad0 = m_base[0]->GetNumPoints();
955 int nquad1 = m_base[1]->GetNumPoints();
956 int nq2 = m_base[2]->GetNumPoints();
957 int nqtot = nquad0 * nquad1 * nq2;
958
959 ASSERTL1(wsp.size() >= 6 * nqtot, "Insufficient workspace size.");
960 ASSERTL1(m_ncoeffs <= nqtot, "Workspace not set up for ncoeffs > nqtot");
961
962 const Array<OneD, const NekDouble> &base0 = m_base[0]->GetBdata();
963 const Array<OneD, const NekDouble> &base1 = m_base[1]->GetBdata();
964 const Array<OneD, const NekDouble> &base2 = m_base[2]->GetBdata();
965 const Array<OneD, const NekDouble> &dbase0 = m_base[0]->GetDbdata();
966 const Array<OneD, const NekDouble> &dbase1 = m_base[1]->GetDbdata();
967 const Array<OneD, const NekDouble> &dbase2 = m_base[2]->GetDbdata();
968 const Array<OneD, const NekDouble> &metric00 =
969 m_metrics[eMetricLaplacian00];
970 const Array<OneD, const NekDouble> &metric01 =
971 m_metrics[eMetricLaplacian01];
972 const Array<OneD, const NekDouble> &metric02 =
973 m_metrics[eMetricLaplacian02];
974 const Array<OneD, const NekDouble> &metric11 =
975 m_metrics[eMetricLaplacian11];
976 const Array<OneD, const NekDouble> &metric12 =
977 m_metrics[eMetricLaplacian12];
978 const Array<OneD, const NekDouble> &metric22 =
979 m_metrics[eMetricLaplacian22];
980
981 // Allocate temporary storage
982 Array<OneD, NekDouble> wsp0(2 * nqtot, wsp);
983 Array<OneD, NekDouble> wsp1(nqtot, wsp + 1 * nqtot);
984 Array<OneD, NekDouble> wsp2(nqtot, wsp + 2 * nqtot);
985 Array<OneD, NekDouble> wsp3(nqtot, wsp + 3 * nqtot);
986 Array<OneD, NekDouble> wsp4(nqtot, wsp + 4 * nqtot);
987 Array<OneD, NekDouble> wsp5(nqtot, wsp + 5 * nqtot);
988
989 // LAPLACIAN MATRIX OPERATION
990 // wsp1 = du_dxi1 = D_xi1 * inarray = D_xi1 * u
991 // wsp2 = du_dxi2 = D_xi2 * inarray = D_xi2 * u
992 // wsp2 = du_dxi3 = D_xi3 * inarray = D_xi3 * u
993 PhysTensorDeriv(inarray, wsp0, wsp1, wsp2);
994
995 // wsp0 = k = g0 * wsp1 + g1 * wsp2 = g0 * du_dxi1 + g1 * du_dxi2
996 // wsp2 = l = g1 * wsp1 + g2 * wsp2 = g0 * du_dxi1 + g1 * du_dxi2
997 // where g0, g1 and g2 are the metric terms set up in the GeomFactors class
998 // especially for this purpose
999 Vmath::Vvtvvtp(nqtot, &metric00[0], 1, &wsp0[0], 1, &metric01[0], 1,
1000 &wsp1[0], 1, &wsp3[0], 1);
1001 Vmath::Vvtvp(nqtot, &metric02[0], 1, &wsp2[0], 1, &wsp3[0], 1, &wsp3[0], 1);
1002 Vmath::Vvtvvtp(nqtot, &metric01[0], 1, &wsp0[0], 1, &metric11[0], 1,
1003 &wsp1[0], 1, &wsp4[0], 1);
1004 Vmath::Vvtvp(nqtot, &metric12[0], 1, &wsp2[0], 1, &wsp4[0], 1, &wsp4[0], 1);
1005 Vmath::Vvtvvtp(nqtot, &metric02[0], 1, &wsp0[0], 1, &metric12[0], 1,
1006 &wsp1[0], 1, &wsp5[0], 1);
1007 Vmath::Vvtvp(nqtot, &metric22[0], 1, &wsp2[0], 1, &wsp5[0], 1, &wsp5[0], 1);
1008
1009 const Array<OneD, const NekDouble> &jac = m_geomFactors->GetJac();
1010 bool Deformed = (m_geomFactors->GetGtype() == SpatialDomains::eDeformed);
1011
1012 v_IProductWRTBaseKernel(dbase0, base1, base2, wsp3, outarray, jac,
1013 Deformed);
1014 v_IProductWRTBaseKernel(base0, dbase1, base2, wsp4, wsp2, jac, Deformed);
1015 Vmath::Vadd(m_ncoeffs, wsp2.data(), 1, outarray.data(), 1, outarray.data(),
1016 1);
1017 v_IProductWRTBaseKernel(base0, base1, dbase2, wsp5, wsp2, jac, Deformed);
1018 Vmath::Vadd(m_ncoeffs, wsp2.data(), 1, outarray.data(), 1, outarray.data(),
1019 1);
1020}
1021
1022} // namespace Nektar::LocalRegions
#define ASSERTL0(condition, msg)
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Describes the specification for a Basis.
Definition Basis.h:45
int GetNumPoints() const
Return points order at which basis is defined.
Definition Basis.h:120
PointsKey GetPointsKey() const
Return distribution of points.
Definition Basis.h:137
Defines a specification for a set of points.
Definition Points.h:50
DNekMatSharedPtr v_GenMatrix(const StdRegions::StdMatrixKey &mkey) override
std::map< int, NormalVector > m_traceNormals
Definition Expansion.h:309
std::map< int, Array< OneD, NekDouble > > m_elmtBndNormDirElmtLen
the element length in each element boundary(Vertex, edge or face) normal direction calculated based o...
Definition Expansion.h:319
SpatialDomains::Geometry * m_geom
Definition Expansion.h:306
void v_GetCoords(Array< OneD, NekDouble > &coords_1, Array< OneD, NekDouble > &coords_2, Array< OneD, NekDouble > &coords_3) override
SpatialDomains::GeomFactorsUniquePtr m_geomFactors
Definition Expansion.h:307
void v_ExtractDataToCoeffs(const NekDouble *data, const std::vector< unsigned int > &nummodes, const int mode_offset, NekDouble *coeffs, std::vector< LibUtilities::BasisType > &fromType) override
Definition PyrExp.cpp:250
void v_ComputeLaplacianMetric() override
Definition PyrExp.cpp:777
LibUtilities::NekManager< MatrixKey, DNekScalMat, MatrixKey::opLess > m_matrixManager
Definition PyrExp.h:130
void v_GetCoords(Array< OneD, NekDouble > &coords_1, Array< OneD, NekDouble > &coords_2, Array< OneD, NekDouble > &coords_3) override
Definition PyrExp.cpp:243
DNekMatSharedPtr v_CreateStdMatrix(const StdRegions::StdMatrixKey &mkey) override
Definition PyrExp.cpp:746
PyrExp(const LibUtilities::BasisKey &Ba, const LibUtilities::BasisKey &Bb, const LibUtilities::BasisKey &Bc, SpatialDomains::Geometry3D *geom)
Constructor using BasisKey class for quadrature points and order definition.
Definition PyrExp.cpp:43
void v_SVVLaplacianFilter(Array< OneD, NekDouble > &array, const StdRegions::StdMatrixKey &mkey) override
Definition PyrExp.cpp:694
NekDouble v_PhysEvalFirstDeriv(const Array< OneD, NekDouble > &coord, const Array< OneD, const NekDouble > &inarray, std::array< NekDouble, 3 > &firstOrderDerivs) override
Definition PyrExp.cpp:300
void v_ComputeTraceNormal(const int face) override
Definition PyrExp.cpp:413
void v_GetCoord(const Array< OneD, const NekDouble > &Lcoords, Array< OneD, NekDouble > &coords) override
Definition PyrExp.cpp:226
LibUtilities::NekManager< MatrixKey, DNekScalBlkMat, MatrixKey::opLess > m_staticCondMatrixManager
Definition PyrExp.h:132
void v_IProductWRTDerivBase(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Calculates the inner product .
Definition PyrExp.cpp:101
StdRegions::StdExpansionSharedPtr v_GetStdExp(void) const override
Definition PyrExp.cpp:202
void v_DropLocMatrix(const MatrixKey &mkey) override
Definition PyrExp.cpp:762
void v_LaplacianMatrixOp_MatFree_Kernel(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, Array< OneD, NekDouble > &wsp) override
Definition PyrExp.cpp:943
DNekMatSharedPtr v_GenMatrix(const StdRegions::StdMatrixKey &mkey) override
Definition PyrExp.cpp:725
StdRegions::StdExpansionSharedPtr v_GetLinStdExp(void) const override
Definition PyrExp.cpp:209
DNekScalBlkMatSharedPtr v_GetLocStaticCondMatrix(const MatrixKey &mkey) override
Definition PyrExp.cpp:767
void v_AlignVectorToCollapsedDir(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray) override
Definition PyrExp.cpp:138
void v_GetTracePhysMap(const int face, Array< OneD, int > &outarray) override
Definition PyrExp.cpp:315
void v_DropLocStaticCondMatrix(const MatrixKey &mkey) override
Definition PyrExp.cpp:772
DNekScalMatSharedPtr v_GetLocMatrix(const MatrixKey &mkey) override
Definition PyrExp.cpp:757
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
3D geometry information
Definition Geometry3D.h:50
NekDouble GetCoord(const int i, const Array< OneD, const NekDouble > &Lcoord)
Given local collapsed coordinate Lcoord, return the value of physical coordinate in direction i.
Definition Geometry.h:559
NekDouble GetLocCoords(const Array< OneD, const NekDouble > &coords, Array< OneD, NekDouble > &Lcoords)
Determine the local collapsed coordinates that correspond to a given Cartesian coordinate for this ge...
Definition Geometry.h:549
int GetCoordim() const
Return the coordinate dimension of this object (i.e. the dimension of the space in which this object ...
Definition Geometry.h:277
int GetNcoeffs(void) const
This function returns the total number of coefficients used in the expansion.
int GetTotPoints() const
This function returns the total number of quadrature points used in the element.
LibUtilities::BasisType GetBasisType(const int dir) const
This function returns the type of basis used in the dir direction.
const LibUtilities::PointsKeyVector GetPointsKeys() const
void BwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
This function performs the Backward transformation from coefficient space to physical space.
LibUtilities::PointsType GetPointsType(const int dir) const
This function returns the type of quadrature points used in the dir direction.
void FwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
int GetNumPoints(const int dir) const
This function returns the number of quadrature points in the dir direction.
const LibUtilities::BasisKey GetTraceBasisKey(const int i, int k=-1, bool UseGLL=false) const
This function returns the basis key belonging to the i-th trace.
Array< OneD, LibUtilities::BasisSharedPtr > m_base
MatrixType GetMatrixType() const
void v_IProductWRTBaseKernel(const Array< OneD, const NekDouble > &base0, const Array< OneD, const NekDouble > &base1, const Array< OneD, const NekDouble > &base2, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const Array< OneD, NekDouble > &jac, const bool Deformed, bool CollDir0=false, bool CollDir1=false, bool CollDir2=false) override
Inner product of inarray over region with respect to the expansion basis (this)->m_base[0] and return...
static void Dscal(const int &n, const double &alpha, double *x, const int &incx)
BLAS level 1: x = alpha x.
Definition Blas.hpp:124
void Interp2D(const BasisKey &fbasis0, const BasisKey &fbasis1, const Array< OneD, const NekDouble > &from, const BasisKey &tbasis0, const BasisKey &tbasis1, Array< OneD, NekDouble > &to)
this function interpolates a 2D function evaluated at the quadrature points of the 2D basis,...
Definition Interp.cpp:101
std::vector< PointsKey > PointsKeyVector
Definition Points.h:313
GeomType
Indicates the type of element geometry.
@ eRegular
Geometry is straight-sided with constant geometric factors.
@ eMovingRegular
Currently unused.
@ eDeformed
Geometry is curved or has non-constant factors.
std::shared_ptr< StdExpansion > StdExpansionSharedPtr
std::shared_ptr< StdPyrExp > StdPyrExpSharedPtr
Definition StdPyrExp.h:178
std::shared_ptr< DNekScalMat > DNekScalMatSharedPtr
std::shared_ptr< DNekScalBlkMat > DNekScalBlkMatSharedPtr
std::shared_ptr< DNekMat > DNekMatSharedPtr
void Vsqrt(int n, const T *x, const int incx, T *y, const int incy)
sqrt y = sqrt(x)
Definition Vmath.hpp:340
void Svtsvtp(int n, const T alpha, const T *x, int incx, const T beta, const T *y, int incy, T *z, int incz)
Svtsvtp (scalar times vector plus scalar times vector):
Definition Vmath.hpp:473
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.hpp:72
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.hpp:396
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.hpp:366
void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Add vector z = x+y.
Definition Vmath.hpp:180
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
Definition Vmath.hpp:100
void Sdiv(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha/x.
Definition Vmath.hpp:154
void Vdiv(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.hpp:126
void Zero(int n, T *x, const int incx)
Zero vector.
Definition Vmath.hpp:273
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
Definition Vmath.hpp:54
void Vvtvvtp(int n, const T *v, int incv, const T *w, int incw, const T *x, int incx, const T *y, int incy, T *z, int incz)
vvtvvtp (vector times vector plus vector times vector):
Definition Vmath.hpp:439
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition Vmath.hpp:825
STL namespace.
scalarT< T > min(scalarT< T > lhs, scalarT< T > rhs)
Definition scalar.hpp:300
scalarT< T > sqrt(scalarT< T > in)
Definition scalar.hpp:290