Nektar++
Loading...
Searching...
No Matches
SegExp.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: SegExp.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: SegExp routines
32//
33///////////////////////////////////////////////////////////////////////////////
34
37#include <LocalRegions/SegExp.h>
38
39using namespace std;
40
42{
43
44/**
45 * @class SegExp
46 * Defines a Segment local expansion.
47 */
48
49/// Constructor using BasisKey class for quadrature points and
50/// order definition.
51/**
52 * @param Ba Basis key of segment expansion.
53 * @param geom Description of geometry.
54 */
57 : StdExpansion(Ba.GetNumModes(), 1, Ba),
58 StdExpansion1D(Ba.GetNumModes(), Ba), StdRegions::StdSegExp(Ba),
59 Expansion(geom), Expansion1D(geom),
60 m_matrixManager(
61 std::bind(&SegExp::CreateMatrix, this, std::placeholders::_1)),
62 m_staticCondMatrixManager(std::bind(&Expansion::CreateStaticCondMatrix,
63 this, std::placeholders::_1))
64{
65}
66
67/// Copy Constructor
68/**
69 * @param S Existing segment to duplicate.
70 */
72 : StdExpansion(S), StdExpansion1D(S), StdRegions::StdSegExp(S),
73 Expansion(S), Expansion1D(S), m_matrixManager(S.m_matrixManager),
74 m_staticCondMatrixManager(S.m_staticCondMatrixManager)
75{
76}
77
78//-----------------------------
79// Transforms
80//-----------------------------
82 const Array<OneD, const NekDouble> &inarray,
83 Array<OneD, NekDouble> &outarray)
84{
85 if (m_base[0]->Collocation())
86 {
87 Vmath::Vcopy(m_ncoeffs, inarray, 1, outarray, 1);
88 }
89 else
90 {
91 int nInteriorDofs = m_ncoeffs - 2;
92 int offset = 0;
93 bool hasEndPoints = true;
94 bool hasEndModes = true;
95
96 switch (m_base[0]->GetBasisType())
97 {
99 {
100 nInteriorDofs = m_ncoeffs - 2;
101 offset = 1;
102 hasEndModes = true;
103 }
104 break;
107 {
108 nInteriorDofs = m_ncoeffs;
109 offset = 0;
110 hasEndModes = false;
111 }
112 break;
115 {
116 nInteriorDofs = m_ncoeffs - 2;
117 offset = 2;
118 hasEndModes = true;
119 }
120 break;
121 default:
122 ASSERTL0(false, "This type of FwdTrans is not defined"
123 "for this expansion type");
124 }
125
126 switch (m_base[0]->GetPointsType())
127 {
130 case LibUtilities::eGaussKronrodLegendre:
131 {
132 hasEndPoints = false;
133 }
134 break;
141 {
142 hasEndPoints = true;
143 }
144 break;
145 default:
146 ASSERTL0(false, "FwdTransBndConstrained cannot be used "
147 "with this point type");
148 }
149
150 fill(outarray.data(), outarray.data() + m_ncoeffs, 0.0);
151
152 if (hasEndPoints && hasEndModes)
153 {
154
155 outarray[GetVertexMap(0)] = inarray[0];
156 outarray[GetVertexMap(1)] = inarray[m_base[0]->GetNumPoints() - 1];
157
158 if (m_ncoeffs > 2)
159 {
160 // ideally, we would like to have tmp0 to be replaced
161 // by outarray (currently MassMatrixOp does not allow
162 // aliasing)
165
167 DetShapeType(), *this);
168 MassMatrixOp(outarray, tmp0, stdmasskey);
169 v_IProductWRTBase(inarray, tmp1);
170
171 Vmath::Vsub(m_ncoeffs, tmp1, 1, tmp0, 1, tmp1, 1);
172
173 // get Mass matrix inverse (only of interior DOF)
174 MatrixKey masskey(StdRegions::eMass, DetShapeType(), *this);
175 DNekScalMatSharedPtr matsys =
176 (m_staticCondMatrixManager[masskey])->GetBlock(1, 1);
177
178 Blas::Dgemv('N', nInteriorDofs, nInteriorDofs, matsys->Scale(),
179 &((matsys->GetOwnedMatrix())->GetPtr())[0],
180 nInteriorDofs, tmp1.data() + offset, 1, 0.0,
181 outarray.data() + offset, 1);
182 }
183 }
184 else
185 {
186 v_FwdTrans(inarray, outarray);
187 }
188 }
189}
190
191//-----------------------------
192// Inner product functions
193//-----------------------------
195 const Array<OneD, const NekDouble> &inarray,
196 Array<OneD, NekDouble> &outarray)
197{
198 ASSERTL1(dir < 3, "input dir is out of range");
199 ASSERTL1((dir == 2) ? m_geom->GetCoordim() == 3 : true,
200 "input dir is out of range");
201
202 int nquad = m_base[0]->GetNumPoints();
203 const Array<TwoD, const NekDouble> &gmat = m_geomFactors->GetDerivFactors();
204
205 Array<OneD, NekDouble> tmp1(nquad);
206 const bool Deformed =
208
209 if (Deformed)
210 {
211 Vmath::Vmul(nquad, gmat[dir], 1, inarray, 1, tmp1, 1);
212 }
213 else
214 {
215 Vmath::Smul(nquad, gmat[dir][0], inarray, 1, tmp1, 1);
216 }
217
218 const Array<OneD, const NekDouble> &jac = m_geomFactors->GetJac();
219 v_IProductWRTBaseKernel(m_base[0]->GetDbdata(), tmp1, outarray, jac,
220 Deformed);
221}
222
225 Array<OneD, NekDouble> &outarray)
226{
227 int nq = m_base[0]->GetNumPoints();
229
230 // @TODO: This routine no longer makes sense as a normal is not unique to an
231 // edge
233 GetLeftAdjacentElementExp()->GetTraceNormal(
235 Vmath::Vmul(nq, &Fx[0], 1, &normals[0][0], 1, &Fn[0], 1);
236 Vmath::Vvtvp(nq, &Fy[0], 1, &normals[1][0], 1, &Fn[0], 1, &Fn[0], 1);
237
238 v_IProductWRTBase(Fn, outarray);
239}
240
242 const Array<OneD, const Array<OneD, NekDouble>> &Fvec,
243 Array<OneD, NekDouble> &outarray)
244{
245 NormVectorIProductWRTBase(Fvec[0], Fvec[1], outarray);
246}
247
248//-----------------------------
249// Evaluation functions
250//-----------------------------
252 const Array<OneD, NekDouble> &coord,
253 const Array<OneD, const NekDouble> &inarray,
254 std::array<NekDouble, 3> &firstOrderDerivs)
255{
256 Array<OneD, NekDouble> Lcoord(1);
257 ASSERTL0(m_geom, "m_geom not defined");
258 m_geom->GetLocCoords(coord, Lcoord);
259 return StdSegExp::v_PhysEvalFirstDeriv(Lcoord, inarray, firstOrderDerivs);
260}
261
263 const Array<OneD, NekDouble> &coord,
264 const Array<OneD, const NekDouble> &inarray,
265 std::array<NekDouble, 3> &firstOrderDerivs,
266 std::array<NekDouble, 6> &secondOrderDerivs)
267{
268 Array<OneD, NekDouble> Lcoord(1);
269 ASSERTL0(m_geom, "m_geom not defined");
270 m_geom->GetLocCoords(coord, Lcoord);
271 return StdSegExp::v_PhysEvalFirstSecondDeriv(
272 Lcoord, inarray, firstOrderDerivs, secondOrderDerivs);
273}
274
277{
278 int i;
279
280 ASSERTL1(Lcoords[0] >= -1.0 && Lcoords[0] <= 1.0,
281 "Local coordinates are not in region [-1,1]");
282
283 m_geom->FillGeom();
284 for (i = 0; i < m_geom->GetCoordim(); ++i)
285 {
286 coords[i] = m_geom->GetCoord(i, Lcoords);
287 }
288}
289
291 Array<OneD, NekDouble> &coords_1,
292 Array<OneD, NekDouble> &coords_2)
293{
294 Expansion::v_GetCoords(coords_0, coords_1, coords_2);
295}
296
297// Get vertex value from the 1D Phys space.
298void SegExp::v_GetVertexPhysVals(const int vertex,
299 const Array<OneD, const NekDouble> &inarray,
300 NekDouble &outarray)
301{
302 int nquad = m_base[0]->GetNumPoints();
303
305 {
306 switch (vertex)
307 {
308 case 0:
309 outarray = inarray[0];
310 break;
311 case 1:
312 outarray = inarray[nquad - 1];
313 break;
314 }
315 }
316 else
317 {
319 factors[StdRegions::eFactorGaussVertex] = vertex;
320
322 *this, factors);
323
324 DNekScalMatSharedPtr mat_gauss = m_matrixManager[key];
325
326 outarray =
327 Vmath::Dot(nquad, mat_gauss->GetOwnedMatrix()->GetPtr().data(), 1,
328 &inarray[0], 1);
329 }
330}
331
332// Get vertex value from the 1D Phys space.
334 const int edge,
335 [[maybe_unused]] const StdRegions::StdExpansionSharedPtr &EdgeExp,
336 const Array<OneD, const NekDouble> &inarray,
337 Array<OneD, NekDouble> &outarray,
338 [[maybe_unused]] StdRegions::Orientation orient)
339{
340 NekDouble result;
341 v_GetVertexPhysVals(edge, inarray, result);
342 outarray[0] = result;
343}
344
345// Get vertex map from the 1D Phys space.
346void SegExp::v_GetTracePhysMap(const int vertex, Array<OneD, int> &map)
347{
348 int nquad = m_base[0]->GetNumPoints();
349
350 ASSERTL1(vertex == 0 || vertex == 1, "Vertex value should be 0 or 1");
351
352 map = Array<OneD, int>(1);
353
354 map[0] = vertex == 0 ? 0 : nquad - 1;
355}
356
357//-----------------------------
358// Helper functions
359//-----------------------------
360
363 Array<OneD, NekDouble> &outarray)
364{
365
366 if (dir == StdRegions::eBackwards)
367 {
368 if (&inarray[0] != &outarray[0])
369 {
370 Array<OneD, NekDouble> intmp(inarray);
371 ReverseCoeffsAndSign(intmp, outarray);
372 }
373 else
374 {
375 ReverseCoeffsAndSign(inarray, outarray);
376 }
377 }
378}
379
385
393
399
401{
402 return 2;
403}
404
406{
407 return 2;
408}
409
410/// Unpack data from input file assuming it comes from
411// the same expansion type
413 const NekDouble *data, const std::vector<unsigned int> &nummodes,
414 const int mode_offset, NekDouble *coeffs,
415 [[maybe_unused]] std::vector<LibUtilities::BasisType> &fromType)
416{
417 switch (m_base[0]->GetBasisType())
418 {
420 {
421 int fillorder = min((int)nummodes[mode_offset], m_ncoeffs);
422
423 Vmath::Zero(m_ncoeffs, coeffs, 1);
424 Vmath::Vcopy(fillorder, &data[0], 1, &coeffs[0], 1);
425 }
426 break;
428 {
429 // Assume that input is also Gll_Lagrange
430 // but no way to check;
431 LibUtilities::PointsKey f0(nummodes[mode_offset],
433 LibUtilities::PointsKey t0(m_base[0]->GetNumModes(),
435 LibUtilities::Interp1D(f0, data, t0, coeffs);
436 }
437 break;
439 {
440 // Assume that input is also Gauss_Lagrange
441 // but no way to check;
442 LibUtilities::PointsKey f0(nummodes[mode_offset],
444 LibUtilities::PointsKey t0(m_base[0]->GetNumModes(),
446 LibUtilities::Interp1D(f0, data, t0, coeffs);
447 }
448 break;
449 default:
450 ASSERTL0(false, "basis is either not set up or not hierarchicial");
451 }
452}
453
454void SegExp::v_ComputeTraceNormal(const int vertex)
455{
456 int i;
457 SpatialDomains::GeomType type = m_geomFactors->GetGtype();
458 const Array<TwoD, const NekDouble> &gmat = m_geomFactors->GetDerivFactors();
459 int nqe = 1;
460 int vCoordDim = GetCoordim();
461
464 for (i = 0; i < vCoordDim; ++i)
465 {
466 normal[i] = Array<OneD, NekDouble>(nqe);
467 }
468
469 size_t nqb = nqe;
470 size_t nbnd = vertex;
473
474 // Regular geometry case
475 if ((type == SpatialDomains::eRegular) ||
477 {
478 NekDouble vert;
479 // Set up normals
480 switch (vertex)
481 {
482 case 0:
483 for (i = 0; i < vCoordDim; ++i)
484 {
485 Vmath::Fill(nqe, -gmat[i][0], normal[i], 1);
486 }
487 break;
488 case 1:
489 for (i = 0; i < vCoordDim; ++i)
490 {
491 Vmath::Fill(nqe, gmat[i][0], normal[i], 1);
492 }
493 break;
494 default:
495 ASSERTL0(false, "point is out of range (point < 2)");
496 }
497
498 // normalise
499 vert = 0.0;
500 for (i = 0; i < vCoordDim; ++i)
501 {
502 vert += normal[i][0] * normal[i][0];
503 }
504 vert = 1.0 / sqrt(vert);
505
506 Vmath::Fill(nqb, vert, length, 1);
507
508 for (i = 0; i < vCoordDim; ++i)
509 {
510 Vmath::Smul(nqe, vert, normal[i], 1, normal[i], 1);
511 }
512 }
513}
514
515//-----------------------------
516// Operator creation functions
517//-----------------------------
518
520 const Array<OneD, const NekDouble> &inarray,
521 Array<OneD, NekDouble> &outarray,
522 [[maybe_unused]] const StdRegions::StdMatrixKey &mkey)
523{
524 int nquad = m_base[0]->GetNumPoints();
525 const Array<TwoD, const NekDouble> &gmat = m_geomFactors->GetDerivFactors();
526
527 Array<OneD, NekDouble> physValues(nquad);
528 Array<OneD, NekDouble> dPhysValuesdx(nquad);
529
530 BwdTrans(inarray, physValues);
531
532 // Laplacian matrix operation
533 switch (m_geom->GetCoordim())
534 {
535 case 1:
536 {
537 v_PhysDeriv(physValues, dPhysValuesdx, NullNekDouble1DArray,
539
540 // multiply with the proper geometric factors
541 if (m_geomFactors->GetGtype() == SpatialDomains::eDeformed)
542 {
543 Vmath::Vmul(nquad, &gmat[0][0], 1, dPhysValuesdx.data(), 1,
544 dPhysValuesdx.data(), 1);
545 }
546 else
547 {
548 Blas::Dscal(nquad, gmat[0][0], dPhysValuesdx.data(), 1);
549 }
550 }
551 break;
552 case 2:
553 {
554 Array<OneD, NekDouble> dPhysValuesdy(nquad);
555
556 PhysDeriv(physValues, dPhysValuesdx, dPhysValuesdy);
557
558 // multiply with the proper geometric factors
559 if (m_geomFactors->GetGtype() == SpatialDomains::eDeformed)
560 {
561 Vmath::Vmul(nquad, &gmat[0][0], 1, dPhysValuesdx.data(), 1,
562 dPhysValuesdx.data(), 1);
563 Vmath::Vvtvp(nquad, &gmat[1][0], 1, dPhysValuesdy.data(), 1,
564 dPhysValuesdx.data(), 1, dPhysValuesdx.data(), 1);
565 }
566 else
567 {
568 Blas::Dscal(nquad, gmat[0][0], dPhysValuesdx.data(), 1);
569 Blas::Daxpy(nquad, gmat[1][0], dPhysValuesdy.data(), 1,
570 dPhysValuesdx.data(), 1);
571 }
572 }
573 break;
574 case 3:
575 {
576 Array<OneD, NekDouble> dPhysValuesdy(nquad);
577 Array<OneD, NekDouble> dPhysValuesdz(nquad);
578
579 PhysDeriv(physValues, dPhysValuesdx, dPhysValuesdy, dPhysValuesdz);
580
581 // multiply with the proper geometric factors
582 if (m_geomFactors->GetGtype() == SpatialDomains::eDeformed)
583 {
584 Vmath::Vmul(nquad, &gmat[0][0], 1, dPhysValuesdx.data(), 1,
585 dPhysValuesdx.data(), 1);
586 Vmath::Vvtvp(nquad, &gmat[1][0], 1, dPhysValuesdy.data(), 1,
587 dPhysValuesdx.data(), 1, dPhysValuesdx.data(), 1);
588 Vmath::Vvtvp(nquad, &gmat[2][0], 1, dPhysValuesdz.data(), 1,
589 dPhysValuesdx.data(), 1, dPhysValuesdx.data(), 1);
590 }
591 else
592 {
593 Blas::Dscal(nquad, gmat[0][0], dPhysValuesdx.data(), 1);
594 Blas::Daxpy(nquad, gmat[1][0], dPhysValuesdy.data(), 1,
595 dPhysValuesdx.data(), 1);
596 Blas::Daxpy(nquad, gmat[2][0], dPhysValuesdz.data(), 1,
597 dPhysValuesdx.data(), 1);
598 }
599 }
600 break;
601 default:
602 ASSERTL0(false, "Wrong number of dimensions");
603 break;
604 }
605
606 const Array<OneD, const NekDouble> &jac = m_geomFactors->GetJac();
607 const bool Deformed =
609 v_IProductWRTBaseKernel(m_base[0]->GetDbdata(), dPhysValuesdx, outarray,
610 jac, Deformed);
611}
612
613void SegExp::v_LaplacianMatrixOp(const int k1, const int k2,
614 const Array<OneD, const NekDouble> &inarray,
615 Array<OneD, NekDouble> &outarray,
616 const StdRegions::StdMatrixKey &mkey)
617{
618 StdExpansion::LaplacianMatrixOp_MatFree(k1, k2, inarray, outarray, mkey);
619}
620
622 Array<OneD, NekDouble> &outarray,
623 const StdRegions::StdMatrixKey &mkey)
624{
625 int nquad = m_base[0]->GetNumPoints();
626 const Array<TwoD, const NekDouble> &gmat = m_geomFactors->GetDerivFactors();
628
629 Array<OneD, NekDouble> physValues(nquad);
630 Array<OneD, NekDouble> dPhysValuesdx(nquad);
632
633 BwdTrans(inarray, physValues);
634
635 // mass matrix operation
636 v_IProductWRTBase(physValues, wsp);
637
638 // Laplacian matrix operation
639 switch (m_geom->GetCoordim())
640 {
641 case 1:
642 {
643 PhysDeriv(physValues, dPhysValuesdx);
644
645 // multiply with the proper geometric factors
646 if (m_geomFactors->GetGtype() == SpatialDomains::eDeformed)
647 {
648 Vmath::Vmul(nquad, &gmat[0][0], 1, dPhysValuesdx.data(), 1,
649 dPhysValuesdx.data(), 1);
650 }
651 else
652 {
653 Blas::Dscal(nquad, gmat[0][0], dPhysValuesdx.data(), 1);
654 }
655 }
656 break;
657 case 2:
658 {
659 Array<OneD, NekDouble> dPhysValuesdy(nquad);
660
661 PhysDeriv(physValues, dPhysValuesdx, dPhysValuesdy);
662
663 // multiply with the proper geometric factors
664 if (m_geomFactors->GetGtype() == SpatialDomains::eDeformed)
665 {
666 Vmath::Vmul(nquad, &gmat[0][0], 1, dPhysValuesdx.data(), 1,
667 dPhysValuesdx.data(), 1);
668 Vmath::Vvtvp(nquad, &gmat[1][0], 1, dPhysValuesdy.data(), 1,
669 dPhysValuesdx.data(), 1, dPhysValuesdx.data(), 1);
670 }
671 else
672 {
673 Blas::Dscal(nquad, gmat[0][0], dPhysValuesdx.data(), 1);
674 Blas::Daxpy(nquad, gmat[1][0], dPhysValuesdy.data(), 1,
675 dPhysValuesdx.data(), 1);
676 }
677 }
678 break;
679 case 3:
680 {
681 Array<OneD, NekDouble> dPhysValuesdy(nquad);
682 Array<OneD, NekDouble> dPhysValuesdz(nquad);
683
684 PhysDeriv(physValues, dPhysValuesdx, dPhysValuesdy, dPhysValuesdz);
685
686 // multiply with the proper geometric factors
687 if (m_geomFactors->GetGtype() == SpatialDomains::eDeformed)
688 {
689 Vmath::Vmul(nquad, &gmat[0][0], 1, dPhysValuesdx.data(), 1,
690 dPhysValuesdx.data(), 1);
691 Vmath::Vvtvp(nquad, &gmat[1][0], 1, dPhysValuesdy.data(), 1,
692 dPhysValuesdx.data(), 1, dPhysValuesdx.data(), 1);
693 Vmath::Vvtvp(nquad, &gmat[2][0], 1, dPhysValuesdz.data(), 1,
694 dPhysValuesdx.data(), 1, dPhysValuesdx.data(), 1);
695 }
696 else
697 {
698 Blas::Dscal(nquad, gmat[0][0], dPhysValuesdx.data(), 1);
699 Blas::Daxpy(nquad, gmat[1][0], dPhysValuesdy.data(), 1,
700 dPhysValuesdx.data(), 1);
701 Blas::Daxpy(nquad, gmat[2][0], dPhysValuesdz.data(), 1,
702 dPhysValuesdx.data(), 1);
703 }
704 }
705 break;
706 default:
707 ASSERTL0(false, "Wrong number of dimensions");
708 break;
709 }
710
711 const Array<OneD, const NekDouble> &jac = m_geomFactors->GetJac();
712 const bool Deformed =
714 v_IProductWRTBaseKernel(m_base[0]->GetDbdata(), dPhysValuesdx, outarray,
715 jac, Deformed);
716 Blas::Daxpy(m_ncoeffs, lambda, wsp.data(), 1, outarray.data(), 1);
717}
718
719//-----------------------------
720// Matrix creation functions
721//-----------------------------
722
727
729{
730 m_staticCondMatrixManager.DeleteObject(mkey);
731}
732
737
739{
740 m_matrixManager.DeleteObject(mkey);
741}
742
744{
745 LibUtilities::BasisKey bkey = m_base[0]->GetBasisKey();
748
749 return tmp->GetStdMatrix(mkey);
750}
751
753{
754 DNekScalMatSharedPtr returnval;
755 NekDouble fac;
757
759 "Geometric information is not set up");
760
761 switch (mkey.GetMatrixType())
762 {
764 {
765 if ((m_geomFactors->GetGtype() == SpatialDomains::eDeformed) ||
766 (mkey.GetNVarCoeff()))
767 {
768 fac = 1.0;
769 goto UseLocRegionsMatrix;
770 }
771 else
772 {
773 fac = (m_geomFactors->GetJac())[0];
774 goto UseStdRegionsMatrix;
775 }
776 }
777 break;
779 {
780 if ((m_geomFactors->GetGtype() == SpatialDomains::eDeformed) ||
781 (mkey.GetNVarCoeff()))
782 {
783 NekDouble one = 1.0;
785 DetShapeType(), *this);
786 DNekMatSharedPtr mat = GenMatrix(masskey);
787 mat->Invert();
788
789 returnval =
791 }
792 else
793 {
794 fac = 1.0 / (m_geomFactors->GetJac())[0];
795 goto UseStdRegionsMatrix;
796 }
797 }
798 break;
802 {
803 if (m_geomFactors->GetGtype() == SpatialDomains::eDeformed ||
804 mkey.GetNVarCoeff())
805 {
806 fac = 1.0;
807 goto UseLocRegionsMatrix;
808 }
809 else
810 {
811 int dir = 0;
812 switch (mkey.GetMatrixType())
813 {
815 dir = 0;
816 break;
818 ASSERTL1(m_geom->GetCoordim() >= 2,
819 "Cannot call eWeakDeriv2 in a "
820 "coordinate system which is not at "
821 "least two-dimensional");
822 dir = 1;
823 break;
825 ASSERTL1(m_geom->GetCoordim() == 3,
826 "Cannot call eWeakDeriv2 in a "
827 "coordinate system which is not "
828 "three-dimensional");
829 dir = 2;
830 break;
831 default:
832 break;
833 }
834
836 mkey.GetShapeType(), *this);
837
838 DNekMatSharedPtr WeakDerivStd = GetStdMatrix(deriv0key);
839 fac = m_geomFactors->GetDerivFactors()[dir][0] *
840 m_geomFactors->GetJac()[0];
841
843 fac, WeakDerivStd);
844 }
845 }
846 break;
848 {
849 if (m_geomFactors->GetGtype() == SpatialDomains::eDeformed)
850 {
851 fac = 1.0;
852 goto UseLocRegionsMatrix;
853 }
854 else
855 {
856 int coordim = m_geom->GetCoordim();
857 fac = 0.0;
858 for (int i = 0; i < coordim; ++i)
859 {
860 fac += m_geomFactors->GetDerivFactors()[i][0] *
861 m_geomFactors->GetDerivFactors()[i][0];
862 }
863 fac *= m_geomFactors->GetJac()[0];
864 goto UseStdRegionsMatrix;
865 }
866 }
867 break;
869 {
870 if ((m_geomFactors->GetGtype() == SpatialDomains::eDeformed) ||
871 (mkey.GetNVarCoeff()))
872 {
873 fac = 1.0;
874 goto UseLocRegionsMatrix;
875 }
876 else
877 {
878 fac = (m_geomFactors->GetJac())[0];
879 goto UseStdRegionsMatrix;
880 }
881 }
882 break;
884 {
886 MatrixKey masskey(StdRegions::eMass, mkey.GetShapeType(), *this);
887 DNekScalMat &MassMat = *(this->m_matrixManager[masskey]);
888 MatrixKey lapkey(StdRegions::eLaplacian, mkey.GetShapeType(), *this,
889 mkey.GetConstFactors(), mkey.GetVarCoeffs());
890 DNekScalMat &LapMat = *(this->m_matrixManager[lapkey]);
891
892 int rows = LapMat.GetRows();
893 int cols = LapMat.GetColumns();
894
895 DNekMatSharedPtr helm =
897
898 NekDouble one = 1.0;
899 (*helm) = LapMat + factor * MassMat;
900
901 returnval =
903 }
904 break;
906 {
908
909 // Construct mass matrix
910 // Check for mass-specific varcoeffs to avoid unncessary
911 // re-computation of the elemental matrix every time step
914 {
915 massVarcoeffs[StdRegions::eVarCoeffMass] =
917 }
918 MatrixKey masskey(StdRegions::eMass, mkey.GetShapeType(), *this,
919 mkey.GetConstFactors(), massVarcoeffs);
920 DNekScalMat &MassMat = *GetLocMatrix(masskey);
921
922 // Construct advection matrix
923 // Check for varcoeffs not required;
924 // assume advection velocity is always time-dependent
926 DNekScalMat &AdvMat = *GetLocMatrix(advkey);
927
928 int rows = MassMat.GetRows();
929 int cols = MassMat.GetColumns();
930
931 DNekMatSharedPtr adr =
933
934 NekDouble one = 1.0;
935 (*adr) = -lambda * MassMat + AdvMat;
936
938
939 // Clear memory for time-dependent matrices
940 DropLocMatrix(advkey);
941 if (!massVarcoeffs.empty())
942 {
943 DropLocMatrix(masskey);
944 }
945 }
946 break;
948 {
950
951 // Construct mass matrix
952 // Check for mass-specific varcoeffs to avoid unncessary
953 // re-computation of the elemental matrix every time step
956 {
957 massVarcoeffs[StdRegions::eVarCoeffMass] =
959 }
960 MatrixKey masskey(StdRegions::eMass, mkey.GetShapeType(), *this,
961 mkey.GetConstFactors(), massVarcoeffs);
962 DNekScalMat &MassMat = *GetLocMatrix(masskey);
963
964 // Construct laplacian matrix (Check for varcoeffs)
965 // Take all varcoeffs if one or more are detected
966 // TODO We might want to have a map
967 // from MatrixType to Vector of Varcoeffs and vice-versa
979 {
980 lapVarcoeffs = mkey.GetVarCoeffs();
981 }
982 MatrixKey lapkey(StdRegions::eLaplacian, mkey.GetShapeType(), *this,
983 mkey.GetConstFactors(), lapVarcoeffs);
984 DNekScalMat &LapMat = *GetLocMatrix(lapkey);
985
986 // Construct advection matrix
987 // Check for varcoeffs not required;
988 // assume advection velocity is always time-dependent
990 DNekScalMat &AdvMat = *GetLocMatrix(advkey);
991
992 int rows = LapMat.GetRows();
993 int cols = LapMat.GetColumns();
994
995 DNekMatSharedPtr adr =
997
998 NekDouble one = 1.0;
999 (*adr) = LapMat - lambda * MassMat + AdvMat;
1000
1002
1003 // Clear memory for time-dependent matrices
1004 DropLocMatrix(advkey);
1005 if (!massVarcoeffs.empty())
1006 {
1007 DropLocMatrix(masskey);
1008 }
1009 if (!lapVarcoeffs.empty())
1010 {
1011 DropLocMatrix(lapkey);
1012 }
1013 }
1014 break;
1019 {
1020 NekDouble one = 1.0;
1021
1022 DNekMatSharedPtr mat = GenMatrix(mkey);
1024 }
1025 break;
1027 {
1028 NekDouble one = 1.0;
1029
1030 // StdRegions::StdMatrixKey
1031 // hkey(StdRegions::eHybridDGHelmholtz,
1032 // DetShapeType(),*this,
1033 // mkey.GetConstant(0),
1034 // mkey.GetConstant(1));
1036 *this, mkey.GetConstFactors(), mkey.GetVarCoeffs());
1037 DNekMatSharedPtr mat = GenMatrix(hkey);
1038
1039 mat->Invert();
1041 }
1042 break;
1044 {
1045 DNekMatSharedPtr m_Ix;
1046 Array<OneD, NekDouble> coords(1, 0.0);
1048 int vertex = (int)factors[StdRegions::eFactorGaussVertex];
1049
1050 coords[0] = (vertex == 0) ? -1.0 : 1.0;
1051
1052 m_Ix = m_base[0]->GetI(coords);
1053 returnval =
1055 }
1056 break;
1057
1058 UseLocRegionsMatrix:
1059 {
1060 DNekMatSharedPtr mat = GenMatrix(mkey);
1062 }
1063 break;
1064 UseStdRegionsMatrix:
1065 {
1066 DNekMatSharedPtr mat = GetStdMatrix(mkey);
1068 }
1069 break;
1070 default:
1071 {
1072 NekDouble one = 1.0;
1073 DNekMatSharedPtr mat = GenMatrix(mkey);
1074
1076 }
1077 break;
1078 }
1079
1080 return returnval;
1081}
1082
1084{
1085 DNekMatSharedPtr returnval;
1086
1087 switch (mkey.GetMatrixType())
1088 {
1095 returnval = Expansion1D::v_GenMatrix(mkey);
1096 break;
1097 default:
1098 returnval = StdSegExp::v_GenMatrix(mkey);
1099 break;
1100 }
1101
1102 return returnval;
1103}
1104
1105//-----------------------------
1106// Private methods
1107//-----------------------------
1108
1109/// Reverse the coefficients in a boundary interior expansion
1110/// this routine is of use when we need the segment
1111/// coefficients corresponding to a expansion in the reverse
1112/// coordinate direction
1114 Array<OneD, NekDouble> &outarray)
1115{
1116
1117 int m;
1118 NekDouble sgn = 1;
1119
1120 ASSERTL1(&inarray[0] != &outarray[0],
1121 "inarray and outarray can not be the same");
1122 switch (GetBasisType(0))
1123 {
1125 // Swap vertices
1126 outarray[0] = inarray[1];
1127 outarray[1] = inarray[0];
1128 // negate odd modes
1129 for (m = 2; m < m_ncoeffs; ++m)
1130 {
1131 outarray[m] = sgn * inarray[m];
1132 sgn = -sgn;
1133 }
1134 break;
1137 for (m = 0; m < m_ncoeffs; ++m)
1138 {
1139 outarray[m_ncoeffs - 1 - m] = inarray[m];
1140 }
1141 break;
1142 default:
1143 ASSERTL0(false, "This basis is not allowed in this method");
1144 break;
1145 }
1146}
1147
1148/* \brief Mass inversion product from \a inarray to \a outarray
1149 *
1150 * Multiply by the inverse of the mass matrix
1151 * \f$ {\bf \hat{u}} = {\bf M}^{-1} {\bf I} \f$
1152 *
1153 **/
1155 Array<OneD, NekDouble> &outarray)
1156{
1157 // get Mass matrix inverse
1158 MatrixKey masskey(StdRegions::eInvMass, DetShapeType(), *this);
1159 DNekScalMatSharedPtr matsys = m_matrixManager[masskey];
1160
1161 NekVector<NekDouble> in(m_ncoeffs, inarray, eCopy);
1162 NekVector<NekDouble> out(m_ncoeffs, outarray, eWrapper);
1163
1164 out = (*matsys) * in;
1165}
1166
1167} // namespace Nektar::LocalRegions
#define ASSERTL0(condition, msg)
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
#define ASSERTL2(condition, msg)
Assert Level 2 – Debugging which is used FULLDEBUG compilation mode. This level assert is designed to...
Describes the specification for a Basis.
Definition Basis.h:45
Defines a specification for a set of points.
Definition Points.h:50
void v_IProductWRTBase(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Inner product of inarray over region with respect to expansion basis base and return in outarray.
DNekMatSharedPtr v_GenMatrix(const StdRegions::StdMatrixKey &mkey) override
void v_PhysDeriv(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Calculate the derivative of the physical points in a given direction.
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
void DropLocMatrix(const LocalRegions::MatrixKey &mkey)
Definition Expansion.cpp:94
ExpansionSharedPtr GetLeftAdjacentElementExp() const
Definition Expansion.h:531
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
void v_FwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Forward transform from physical quadrature space stored in inarray and evaluate the expansion coeffic...
int GetLeftAdjacentElementTrace() const
Definition Expansion.h:544
DNekScalMatSharedPtr GetLocMatrix(const LocalRegions::MatrixKey &mkey)
Definition Expansion.cpp:88
SpatialDomains::GeomFactorsUniquePtr m_geomFactors
Definition Expansion.h:307
void v_LaplacianMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::StdMatrixKey &mkey) override
Definition SegExp.cpp:519
void v_DropLocMatrix(const MatrixKey &mkey) override
Definition SegExp.cpp:738
StdRegions::StdExpansionSharedPtr v_GetLinStdExp(void) const override
Definition SegExp.cpp:386
void v_GetTracePhysVals(const int edge, const StdRegions::StdExpansionSharedPtr &EdgeExp, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, StdRegions::Orientation orient) override
Definition SegExp.cpp:333
void v_GetVertexPhysVals(const int vertex, const Array< OneD, const NekDouble > &inarray, NekDouble &outarray) override
Definition SegExp.cpp:298
NekDouble v_PhysEvalFirstSecondDeriv(const Array< OneD, NekDouble > &coord, const Array< OneD, const NekDouble > &inarray, std::array< NekDouble, 3 > &firstOrderDerivs, std::array< NekDouble, 6 > &secondOrderDerivs) override
Definition SegExp.cpp:262
void ReverseCoeffsAndSign(const Array< OneD, NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Reverse the coefficients in a boundary interior expansion this routine is of use when we need the seg...
Definition SegExp.cpp:1113
void v_NormVectorIProductWRTBase(const Array< OneD, const NekDouble > &Fx, const Array< OneD, const NekDouble > &Fy, Array< OneD, NekDouble > &outarray) override
Definition SegExp.cpp:223
DNekScalMatSharedPtr CreateMatrix(const MatrixKey &mkey)
Definition SegExp.cpp:752
StdRegions::StdExpansionSharedPtr v_GetStdExp(void) const override
Definition SegExp.cpp:380
void v_FwdTransBndConstrained(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Definition SegExp.cpp:81
DNekMatSharedPtr v_GenMatrix(const StdRegions::StdMatrixKey &mkey) override
Definition SegExp.cpp:1083
SegExp(const LibUtilities::BasisKey &Ba, SpatialDomains::Geometry1D *geom)
Constructor using BasisKey class for quadrature points and order definition.
Definition SegExp.cpp:55
LibUtilities::NekManager< MatrixKey, DNekScalBlkMat, MatrixKey::opLess > m_staticCondMatrixManager
Definition SegExp.h:195
void v_HelmholtzMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::StdMatrixKey &mkey) override
Definition SegExp.cpp:621
void v_ExtractDataToCoeffs(const NekDouble *data, const std::vector< unsigned int > &nummodes, const int mode_offset, NekDouble *coeffs, std::vector< LibUtilities::BasisType > &fromType) override
Unpack data from input file assuming it comes from.
Definition SegExp.cpp:412
void v_GetCoords(Array< OneD, NekDouble > &coords_1, Array< OneD, NekDouble > &coords_2, Array< OneD, NekDouble > &coords_3) override
Definition SegExp.cpp:290
DNekScalBlkMatSharedPtr v_GetLocStaticCondMatrix(const MatrixKey &mkey) override
Definition SegExp.cpp:723
void MultiplyByElmtInvMass(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Definition SegExp.cpp:1154
int v_NumBndryCoeffs() const override
Definition SegExp.cpp:400
LibUtilities::NekManager< MatrixKey, DNekScalMat, MatrixKey::opLess > m_matrixManager
Definition SegExp.h:193
void v_GetTracePhysMap(const int vertex, Array< OneD, int > &map) override
Definition SegExp.cpp:346
int v_NumDGBndryCoeffs() const override
Definition SegExp.cpp:405
DNekMatSharedPtr v_CreateStdMatrix(const StdRegions::StdMatrixKey &mkey) override
Definition SegExp.cpp:743
void v_SetCoeffsToOrientation(StdRegions::Orientation dir, Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Definition SegExp.cpp:361
void v_DropLocStaticCondMatrix(const MatrixKey &mkey) override
Definition SegExp.cpp:728
const Array< OneD, const NekDouble > & v_GetPhysNormals() override
Definition SegExp.cpp:394
DNekScalMatSharedPtr v_GetLocMatrix(const MatrixKey &mkey) override
Definition SegExp.cpp:733
void v_GetCoord(const Array< OneD, const NekDouble > &Lcoords, Array< OneD, NekDouble > &coords) override
Definition SegExp.cpp:275
NekDouble v_PhysEvalFirstDeriv(const Array< OneD, NekDouble > &coord, const Array< OneD, const NekDouble > &inarray, std::array< NekDouble, 3 > &firstOrderDerivs) override
Definition SegExp.cpp:251
void v_ComputeTraceNormal(const int vertex) override
Definition SegExp.cpp:454
void v_IProductWRTDerivBase(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Definition SegExp.cpp:194
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
1D geometry information
Definition Geometry1D.h:49
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
void FillGeom()
Populate the coordinate mapping Geometry::m_coeffs information from any children geometry elements.
Definition Geometry.h:461
LibUtilities::BasisType GetBasisType(const int dir) const
This function returns the type of basis used in the dir direction.
DNekMatSharedPtr GetStdMatrix(const StdMatrixKey &mkey)
const LibUtilities::PointsKeyVector GetPointsKeys() const
void MassMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdMatrixKey &mkey)
int GetVertexMap(const int localVertexId, bool useCoeffPacking=false)
void NormVectorIProductWRTBase(const Array< OneD, const NekDouble > &Fx, Array< OneD, NekDouble > &outarray)
LibUtilities::ShapeType DetShapeType() const
This function returns the shape of the expansion domain.
void BwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
This function performs the Backward transformation from coefficient space to physical space.
DNekMatSharedPtr GenMatrix(const StdMatrixKey &mkey)
LibUtilities::PointsType GetPointsType(const int dir) const
This function returns the type of quadrature points used in the dir direction.
void PhysDeriv(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_d0, Array< OneD, NekDouble > &out_d1=NullNekDouble1DArray, Array< OneD, NekDouble > &out_d2=NullNekDouble1DArray)
Array< OneD, LibUtilities::BasisSharedPtr > m_base
LibUtilities::ShapeType GetShapeType() const
const VarCoeffMap & GetVarCoeffs() const
MatrixType GetMatrixType() const
bool HasVarCoeff(const StdRegions::VarCoeffType &coeff) const
const ConstFactorMap & GetConstFactors() const
const Array< OneD, const NekDouble > & GetVarCoeff(const StdRegions::VarCoeffType &coeff) const
NekDouble GetConstFactor(const ConstFactorType &factor) const
void v_IProductWRTBaseKernel(const Array< OneD, const NekDouble > &base0, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const Array< OneD, const NekDouble > &jac, const bool Deformed) override
Inner product of inarray over region with respect to the expansion basis (this)->m_base[0] and return...
static void Dgemv(const char &trans, const int &m, const int &n, const double &alpha, const double *a, const int &lda, const double *x, const int &incx, const double &beta, double *y, const int &incy)
BLAS level 2: Matrix vector multiply y = alpha A x plus beta y where A[m x n].
Definition Blas.hpp:152
static void Dscal(const int &n, const double &alpha, double *x, const int &incx)
BLAS level 1: x = alpha x.
Definition Blas.hpp:124
static void Daxpy(const int &n, const double &alpha, const double *x, const int &incx, const double *y, const int &incy)
BLAS level 1: y = alpha x plus y.
Definition Blas.hpp:117
void Interp1D(const BasisKey &fbasis0, const Array< OneD, const NekDouble > &from, const BasisKey &tbasis0, Array< OneD, NekDouble > &to)
this function interpolates a 1D function evaluated at the quadrature points of the basis fbasis0 to ...
Definition Interp.cpp:47
std::vector< PointsKey > PointsKeyVector
Definition Points.h:313
@ eGaussLegendreWithMP
1D Gauss-Legendre quadrature points with additional x=-1 and x=1 end points
Definition PointsType.h:95
@ eGaussLobattoChebyshev
1D Gauss-Lobatto-Legendre quadrature points
Definition PointsType.h:57
@ eFourierEvenlySpaced
1D Evenly-spaced points using Fourier Fit
Definition PointsType.h:74
@ eGaussLobattoLegendre
1D Gauss-Lobatto-Legendre quadrature points
Definition PointsType.h:51
@ eGaussGaussChebyshev
1D Gauss-Gauss-Chebyshev quadrature points
Definition PointsType.h:52
@ ePolyEvenlySpaced
1D Evenly-spaced points using Lagrange polynomial
Definition PointsType.h:73
@ eGaussLobattoKronrodLegendre
1D Lobatto Kronrod quadrature points
Definition PointsType.h:72
@ eGaussGaussLegendre
1D Gauss-Gauss-Legendre quadrature points
Definition PointsType.h:46
@ eModified_B
Principle Modified Functions .
Definition BasisType.h:49
@ eGauss_Lagrange
Lagrange Polynomials using the Gauss points.
Definition BasisType.h:57
@ eOrtho_A
Principle Orthogonal Functions .
Definition BasisType.h:42
@ eGLL_Lagrange
Lagrange for SEM basis .
Definition BasisType.h:56
@ eModified_A
Principle Modified Functions .
Definition BasisType.h:48
GeomType
Indicates the type of element geometry.
@ eRegular
Geometry is straight-sided with constant geometric factors.
@ eNoGeomType
No type defined.
@ eMovingRegular
Currently unused.
@ eDeformed
Geometry is curved or has non-constant factors.
std::shared_ptr< StdExpansion > StdExpansionSharedPtr
std::map< ConstFactorType, NekDouble > ConstFactorMap
static VarCoeffMap NullVarCoeffMap
std::shared_ptr< StdSegExp > StdSegExpSharedPtr
Definition StdSegExp.h:182
std::map< StdRegions::VarCoeffType, VarCoeffEntry > VarCoeffMap
std::shared_ptr< DNekScalMat > DNekScalMatSharedPtr
std::shared_ptr< DNekScalBlkMat > DNekScalBlkMatSharedPtr
static Array< OneD, NekDouble > NullNekDouble1DArray
std::shared_ptr< DNekMat > DNekMatSharedPtr
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 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
T Dot(int n, const T *w, const T *x)
dot product
Definition Vmath.hpp:761
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 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 Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition Vmath.hpp:825
void Vsub(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Subtract vector z = x-y.
Definition Vmath.hpp:220
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