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 std::string("SegExpMatrix")),
63 m_staticCondMatrixManager(std::bind(&Expansion::CreateStaticCondMatrix,
64 this, std::placeholders::_1),
65 std::string("SegExpStaticCondMatrix"))
66{
67}
68
69/// Copy Constructor
70/**
71 * @param S Existing segment to duplicate.
72 */
74 : StdExpansion(S), StdExpansion1D(S), StdRegions::StdSegExp(S),
75 Expansion(S), Expansion1D(S), m_matrixManager(S.m_matrixManager),
76 m_staticCondMatrixManager(S.m_staticCondMatrixManager)
77{
78}
79
80//----------------------------
81// Integration Methods
82//----------------------------
83
84/** \brief Integrate the physical point list \a inarray over region
85 and return the value
86
87 Inputs:\n
88
89 - \a inarray: definition of function to be returned at
90 quadrature point of expansion.
91
92 Outputs:\n
93
94 - returns \f$\int^1_{-1} u(\xi_1)d \xi_1 \f$ where \f$inarray[i]
95 = u(\xi_{1i}) \f$
96*/
97
99{
100 int nquad0 = m_base[0]->GetNumPoints();
102 NekDouble ival;
103 Array<OneD, NekDouble> tmp(nquad0);
104
105 // multiply inarray with Jacobian
106 if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
107 {
108 Vmath::Vmul(nquad0, jac, 1, inarray, 1, tmp, 1);
109 }
110 else
111 {
112 Vmath::Smul(nquad0, jac[0], inarray, 1, tmp, 1);
113 }
114
115 // call StdSegExp version;
116 ival = StdSegExp::v_Integral(tmp);
117 // ival = StdSegExp::Integral(tmp);
118 return ival;
119}
120
121//-----------------------------
122// Differentiation Methods
123//-----------------------------
124
125/** \brief Evaluate the derivative \f$ d/d{\xi_1} \f$ at the
126 physical quadrature points given by \a inarray and return in \a
127 outarray.
128
129 This is a wrapper around StdExpansion1D::Tensor_Deriv
130
131 Input:\n
132
133 - \a n: number of derivatives to be evaluated where \f$ n \leq dim\f$
134
135 - \a inarray: array of function evaluated at the quadrature points
136
137 Output: \n
138
139 - \a outarray: array of the derivatives \f$
140 du/d_{\xi_1}|_{\xi_{1i}} d\xi_1/dx,
141 du/d_{\xi_1}|_{\xi_{1i}} d\xi_1/dy,
142 du/d_{\xi_1}|_{\xi_{1i}} d\xi_1/dz,
143 \f$ depending on value of \a dim
144*/
149{
150 int nquad0 = m_base[0]->GetNumPoints();
152 m_metricinfo->GetDerivFactors(GetPointsKeys());
153 Array<OneD, NekDouble> diff(nquad0);
154
155 // StdExpansion1D::PhysTensorDeriv(inarray,diff);
156 PhysTensorDeriv(inarray, diff);
157 if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
158 {
159 if (out_d0.size())
160 {
161 Vmath::Vmul(nquad0, &gmat[0][0], 1, &diff[0], 1, &out_d0[0], 1);
162 }
163
164 if (out_d1.size())
165 {
166 Vmath::Vmul(nquad0, &gmat[1][0], 1, &diff[0], 1, &out_d1[0], 1);
167 }
168
169 if (out_d2.size())
170 {
171 Vmath::Vmul(nquad0, &gmat[2][0], 1, &diff[0], 1, &out_d2[0], 1);
172 }
173 }
174 else
175 {
176 if (out_d0.size())
177 {
178 Vmath::Smul(nquad0, gmat[0][0], diff, 1, out_d0, 1);
179 }
180
181 if (out_d1.size())
182 {
183 Vmath::Smul(nquad0, gmat[1][0], diff, 1, out_d1, 1);
184 }
185
186 if (out_d2.size())
187 {
188 Vmath::Smul(nquad0, gmat[2][0], diff, 1, out_d2, 1);
189 }
190 }
191}
192
193/**
194 *\brief Evaluate the derivative along a line:
195 * \f$ d/ds=\frac{spacedim}{||tangent||}d/d{\xi} \f$.
196 * The derivative is calculated performing
197 *the product \f$ du/d{s}=\nabla u \cdot tangent \f$.
198 *\param inarray function to derive
199 *\param out_ds result of the derivative operation
200 **/
203{
204 int nquad0 = m_base[0]->GetNumPoints();
205 int coordim = m_geom->GetCoordim();
206 Array<OneD, NekDouble> diff(nquad0);
207 // this operation is needed if you put out_ds==inarray
208 Vmath::Zero(nquad0, out_ds, 1);
209 switch (coordim)
210 {
211 case 2:
212 // diff= dU/de
213 Array<OneD, NekDouble> diff(nquad0);
214
215 PhysTensorDeriv(inarray, diff);
216
217 // get dS/de= (Jac)^-1
219 if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
220 {
221 // calculate the derivative as (dU/de)*(Jac)^-1
222 Vmath::Vdiv(nquad0, diff, 1, Jac, 1, out_ds, 1);
223 }
224 else
225 {
226 NekDouble invJac = 1 / Jac[0];
227 Vmath::Smul(nquad0, invJac, diff, 1, out_ds, 1);
228 }
229 }
230}
231
232/**
233 *\brief Evaluate the derivative normal to a line:
234 * \f$ d/dn=\frac{spacedim}{||normal||}d/d{\xi} \f$.
235 * The derivative is calculated performing
236 *the product \f$ du/d{s}=\nabla u \cdot normal \f$.
237 *\param inarray function to derive
238 *\param out_dn result of the derivative operation
239 **/
242{
243 int nquad0 = m_base[0]->GetNumPoints();
245 m_metricinfo->GetDerivFactors(GetPointsKeys());
246 int coordim = m_geom->GetCoordim();
247 Array<OneD, NekDouble> out_dn_tmp(nquad0, 0.0);
248 switch (coordim)
249 {
250 case 2:
251
252 Array<OneD, NekDouble> inarray_d0(nquad0);
253 Array<OneD, NekDouble> inarray_d1(nquad0);
254
255 v_PhysDeriv(inarray, inarray_d0, inarray_d1);
257 normals = Array<OneD, Array<OneD, NekDouble>>(coordim);
258 cout << "der_n" << endl;
259 for (int k = 0; k < coordim; ++k)
260 {
261 normals[k] = Array<OneD, NekDouble>(nquad0);
262 }
263 // @TODO: this routine no longer makes sense, since normals are not
264 // unique on
265 // an edge
266 // normals = GetMetricInfo()->GetNormal();
267 for (int i = 0; i < nquad0; i++)
268 {
269 cout << "nx= " << normals[0][i] << " ny=" << normals[1][i]
270 << endl;
271 }
273 "normal vectors do not exist: check if a"
274 "boundary region is defined as I ");
275 // \nabla u \cdot normal
276 Vmath::Vmul(nquad0, normals[0], 1, inarray_d0, 1, out_dn_tmp, 1);
277 Vmath::Vadd(nquad0, out_dn_tmp, 1, out_dn, 1, out_dn, 1);
278 Vmath::Zero(nquad0, out_dn_tmp, 1);
279 Vmath::Vmul(nquad0, normals[1], 1, inarray_d1, 1, out_dn_tmp, 1);
280 Vmath::Vadd(nquad0, out_dn_tmp, 1, out_dn, 1, out_dn, 1);
281
282 for (int i = 0; i < nquad0; i++)
283 {
284 cout << "deps/dx =" << inarray_d0[i]
285 << " deps/dy=" << inarray_d1[i] << endl;
286 }
287 }
288}
289void SegExp::v_PhysDeriv(const int dir,
290 const Array<OneD, const NekDouble> &inarray,
291 Array<OneD, NekDouble> &outarray)
292{
293 switch (dir)
294 {
295 case 0:
296 {
297 PhysDeriv(inarray, outarray, NullNekDouble1DArray,
299 }
300 break;
301 case 1:
302 {
303 PhysDeriv(inarray, NullNekDouble1DArray, outarray,
305 }
306 break;
307 case 2:
308 {
310 outarray);
311 }
312 break;
313 default:
314 {
315 ASSERTL1(false, "input dir is out of range");
316 }
317 break;
318 }
319}
320
321//-----------------------------
322// Transforms
323//-----------------------------
324
325/** \brief Forward transform from physical quadrature space
326 stored in \a inarray and evaluate the expansion coefficients and
327 store in \a outarray
328
329 Perform a forward transform using a Galerkin projection by
330 taking the inner product of the physical points and multiplying
331 by the inverse of the mass matrix using the Solve method of the
332 standard matrix container holding the local mass matrix, i.e.
333 \f$ {\bf \hat{u}} = {\bf M}^{-1} {\bf I} \f$ where \f$ {\bf I}[p] =
334 \int^1_{-1} \phi_p(\xi_1) u(\xi_1) d\xi_1 \f$
335
336 Inputs:\n
337
338 - \a inarray: array of physical quadrature points to be transformed
339
340 Outputs:\n
341
342 - \a outarray: updated array of expansion coefficients.
343
344*/
345// need to sort out family of matrices
347 Array<OneD, NekDouble> &outarray)
348{
349 if (m_base[0]->Collocation())
350 {
351 Vmath::Vcopy(m_ncoeffs, inarray, 1, outarray, 1);
352 }
353 else
354 {
355 v_IProductWRTBase(inarray, outarray);
356
357 // get Mass matrix inverse
359 DNekScalMatSharedPtr matsys = m_matrixManager[masskey];
360
361 // copy inarray in case inarray == outarray
362 NekVector<NekDouble> in(m_ncoeffs, outarray, eCopy);
364
365 out = (*matsys) * in;
366 }
367}
368
370 const Array<OneD, const NekDouble> &inarray,
371 Array<OneD, NekDouble> &outarray)
372{
373 if (m_base[0]->Collocation())
374 {
375 Vmath::Vcopy(m_ncoeffs, inarray, 1, outarray, 1);
376 }
377 else
378 {
379 int nInteriorDofs = m_ncoeffs - 2;
380 int offset = 0;
381 bool hasEndPoints = true;
382 bool hasEndModes = true;
383
384 switch (m_base[0]->GetBasisType())
385 {
387 {
388 nInteriorDofs = m_ncoeffs - 2;
389 offset = 1;
390 hasEndModes = true;
391 }
392 break;
395 {
396 nInteriorDofs = m_ncoeffs;
397 offset = 0;
398 hasEndModes = false;
399 }
400 break;
403 {
404 nInteriorDofs = m_ncoeffs - 2;
405 offset = 2;
406 hasEndModes = true;
407 }
408 break;
409 default:
410 ASSERTL0(false, "This type of FwdTrans is not defined"
411 "for this expansion type");
412 }
413
414 switch (m_base[0]->GetPointsType())
415 {
418 case LibUtilities::eGaussKronrodLegendre:
419 {
420 hasEndPoints = false;
421 }
422 break;
429 {
430 hasEndPoints = true;
431 }
432 break;
433 default:
434 ASSERTL0(false, "FwdTransBndConstrained cannot be used "
435 "with this point type");
436 }
437
438 fill(outarray.data(), outarray.data() + m_ncoeffs, 0.0);
439
440 if (hasEndPoints && hasEndModes)
441 {
442
443 outarray[GetVertexMap(0)] = inarray[0];
444 outarray[GetVertexMap(1)] = inarray[m_base[0]->GetNumPoints() - 1];
445
446 if (m_ncoeffs > 2)
447 {
448 // ideally, we would like to have tmp0 to be replaced
449 // by outarray (currently MassMatrixOp does not allow
450 // aliasing)
453
455 DetShapeType(), *this);
456 MassMatrixOp(outarray, tmp0, stdmasskey);
457 v_IProductWRTBase(inarray, tmp1);
458
459 Vmath::Vsub(m_ncoeffs, tmp1, 1, tmp0, 1, tmp1, 1);
460
461 // get Mass matrix inverse (only of interior DOF)
462 MatrixKey masskey(StdRegions::eMass, DetShapeType(), *this);
463 DNekScalMatSharedPtr matsys =
464 (m_staticCondMatrixManager[masskey])->GetBlock(1, 1);
465
466 Blas::Dgemv('N', nInteriorDofs, nInteriorDofs, matsys->Scale(),
467 &((matsys->GetOwnedMatrix())->GetPtr())[0],
468 nInteriorDofs, tmp1.data() + offset, 1, 0.0,
469 outarray.data() + offset, 1);
470 }
471 }
472 else
473 {
474 SegExp::v_FwdTrans(inarray, outarray);
475 }
476 }
477}
478
479//-----------------------------
480// Inner product functions
481//-----------------------------
482
483/** \brief Inner product of \a inarray over region with respect to
484 the expansion basis (this)->_Base[0] and return in \a outarray
485
486 Wrapper call to SegExp::IProduct_WRT_B
487
488 Input:\n
489
490 - \a inarray: array of function evaluated at the physical
491 collocation points
492
493 Output:\n
494
495 - \a outarray: array of inner product with respect to each
496 basis over region
497*/
499 Array<OneD, NekDouble> &outarray)
500{
501 v_IProductWRTBase(m_base[0]->GetBdata(), inarray, outarray, 1);
502}
503
504/**
505 \brief Inner product of \a inarray over region with respect to
506 expansion basis \a base and return in \a outarray
507
508 Calculate \f$ I[p] = \int^{1}_{-1} \phi_p(\xi_1) u(\xi_1) d\xi_1
509 = \sum_{i=0}^{nq-1} \phi_p(\xi_{1i}) u(\xi_{1i}) w_i \f$ where
510 \f$ outarray[p] = I[p], inarray[i] = u(\xi_{1i}), base[p*nq+i] =
511 \phi_p(\xi_{1i}) \f$.
512
513 Inputs: \n
514
515 - \a base: an array definiing the local basis for the inner
516 product usually passed from Basis->get_bdata() or
517 Basis->get_Dbdata()
518 - \a inarray: physical point array of function to be integrated
519 \f$ u(\xi_1) \f$
520 - \a coll_check: Flag to identify when a Basis->collocation()
521 call should be performed to see if this is a GLL_Lagrange basis
522 with a collocation property. (should be set to 0 if taking the
523 inner product with respect to the derivative of basis)
524
525 Output: \n
526
527 - \a outarray: array of coefficients representing the inner
528 product of function with ever mode in the exapnsion
529
530**/
532 const Array<OneD, const NekDouble> &inarray,
533 Array<OneD, NekDouble> &outarray, int coll_check)
534{
535 int nquad0 = m_base[0]->GetNumPoints();
537 Array<OneD, NekDouble> tmp(nquad0);
538
539 // multiply inarray with Jacobian
540 if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
541 {
542 Vmath::Vmul(nquad0, jac, 1, inarray, 1, tmp, 1);
543 }
544 else
545 {
546 Vmath::Smul(nquad0, jac[0], inarray, 1, tmp, 1);
547 }
548 StdSegExp::v_IProductWRTBase(base, tmp, outarray, coll_check);
549}
550
552 const Array<OneD, const NekDouble> &inarray,
553 Array<OneD, NekDouble> &outarray)
554{
555 ASSERTL1(dir < 3, "input dir is out of range");
556 ASSERTL1((dir == 2) ? m_geom->GetCoordim() == 3 : true,
557 "input dir is out of range");
558
559 int nquad = m_base[0]->GetNumPoints();
560 const Array<TwoD, const NekDouble> &gmat =
561 m_metricinfo->GetDerivFactors(GetPointsKeys());
562
563 Array<OneD, NekDouble> tmp1(nquad);
564
565 if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
566 {
567 Vmath::Vmul(nquad, gmat[dir], 1, inarray, 1, tmp1, 1);
568 }
569 else
570 {
571 Vmath::Smul(nquad, gmat[dir][0], inarray, 1, tmp1, 1);
572 }
573
574 v_IProductWRTBase(m_base[0]->GetDbdata(), tmp1, outarray, 1);
575}
576
579 Array<OneD, NekDouble> &outarray)
580{
581 int nq = m_base[0]->GetNumPoints();
583
584 // @TODO: This routine no longer makes sense as a normal is not unique to an
585 // edge
587 GetLeftAdjacentElementExp()->GetTraceNormal(
589 Vmath::Vmul(nq, &Fx[0], 1, &normals[0][0], 1, &Fn[0], 1);
590 Vmath::Vvtvp(nq, &Fy[0], 1, &normals[1][0], 1, &Fn[0], 1, &Fn[0], 1);
591
592 v_IProductWRTBase(Fn, outarray);
593}
594
596 const Array<OneD, const Array<OneD, NekDouble>> &Fvec,
597 Array<OneD, NekDouble> &outarray)
598{
599 NormVectorIProductWRTBase(Fvec[0], Fvec[1], outarray);
600}
601
602//-----------------------------
603// Evaluation functions
604//-----------------------------
605
606/**
607 * Given the local cartesian coordinate \a Lcoord evaluate the
608 * value of physvals at this point by calling through to the
609 * StdExpansion method
610 */
612 const Array<OneD, const NekDouble> &Lcoord,
613 const Array<OneD, const NekDouble> &physvals)
614{
615 // Evaluate point in local (eta) coordinates.
616 return StdExpansion1D::v_PhysEvaluate(Lcoord, physvals);
617}
618
620 const Array<OneD, const NekDouble> &physvals)
621{
623
624 ASSERTL0(m_geom, "m_geom not defined");
625 m_geom->GetLocCoords(coord, Lcoord);
626
627 return StdExpansion1D::v_PhysEvaluate(Lcoord, physvals);
628}
629
631 const Array<OneD, NekDouble> &coord,
632 const Array<OneD, const NekDouble> &inarray,
633 std::array<NekDouble, 3> &firstOrderDerivs)
634{
635 Array<OneD, NekDouble> Lcoord(1);
636 ASSERTL0(m_geom, "m_geom not defined");
637 m_geom->GetLocCoords(coord, Lcoord);
638 return StdSegExp::v_PhysEvalFirstDeriv(Lcoord, inarray, firstOrderDerivs);
639}
640
642 const Array<OneD, NekDouble> &coord,
643 const Array<OneD, const NekDouble> &inarray,
644 std::array<NekDouble, 3> &firstOrderDerivs,
645 std::array<NekDouble, 6> &secondOrderDerivs)
646{
647 Array<OneD, NekDouble> Lcoord(1);
648 ASSERTL0(m_geom, "m_geom not defined");
649 m_geom->GetLocCoords(coord, Lcoord);
650 return StdSegExp::v_PhysEvalFirstSecondDeriv(
651 Lcoord, inarray, firstOrderDerivs, secondOrderDerivs);
652}
653
656{
657 int i;
658
659 ASSERTL1(Lcoords[0] >= -1.0 && Lcoords[0] <= 1.0,
660 "Local coordinates are not in region [-1,1]");
661
662 m_geom->FillGeom();
663 for (i = 0; i < m_geom->GetCoordim(); ++i)
664 {
665 coords[i] = m_geom->GetCoord(i, Lcoords);
666 }
667}
668
670 Array<OneD, NekDouble> &coords_1,
671 Array<OneD, NekDouble> &coords_2)
672{
673 Expansion::v_GetCoords(coords_0, coords_1, coords_2);
674}
675
676// Get vertex value from the 1D Phys space.
677void SegExp::v_GetVertexPhysVals(const int vertex,
678 const Array<OneD, const NekDouble> &inarray,
679 NekDouble &outarray)
680{
681 int nquad = m_base[0]->GetNumPoints();
682
684 {
685 switch (vertex)
686 {
687 case 0:
688 outarray = inarray[0];
689 break;
690 case 1:
691 outarray = inarray[nquad - 1];
692 break;
693 }
694 }
695 else
696 {
698 factors[StdRegions::eFactorGaussVertex] = vertex;
699
701 *this, factors);
702
703 DNekScalMatSharedPtr mat_gauss = m_matrixManager[key];
704
705 outarray =
706 Blas::Ddot(nquad, mat_gauss->GetOwnedMatrix()->GetPtr().data(), 1,
707 &inarray[0], 1);
708 }
709}
710
711// Get vertex value from the 1D Phys space.
713 const int edge,
714 [[maybe_unused]] const StdRegions::StdExpansionSharedPtr &EdgeExp,
715 const Array<OneD, const NekDouble> &inarray,
716 Array<OneD, NekDouble> &outarray,
717 [[maybe_unused]] StdRegions::Orientation orient)
718{
719 NekDouble result;
720 v_GetVertexPhysVals(edge, inarray, result);
721 outarray[0] = result;
722}
723
724// Get vertex map from the 1D Phys space.
725void SegExp::v_GetTracePhysMap(const int vertex, Array<OneD, int> &map)
726{
727 int nquad = m_base[0]->GetNumPoints();
728
729 ASSERTL1(vertex == 0 || vertex == 1, "Vertex value should be 0 or 1");
730
731 map = Array<OneD, int>(1);
732
733 map[0] = vertex == 0 ? 0 : nquad - 1;
734}
735
736//-----------------------------
737// Helper functions
738//-----------------------------
739
742 Array<OneD, NekDouble> &outarray)
743{
744
745 if (dir == StdRegions::eBackwards)
746 {
747 if (&inarray[0] != &outarray[0])
748 {
749 Array<OneD, NekDouble> intmp(inarray);
750 ReverseCoeffsAndSign(intmp, outarray);
751 }
752 else
753 {
754 ReverseCoeffsAndSign(inarray, outarray);
755 }
756 }
757}
758
764
772
778
780{
781 return 2;
782}
783
785{
786 return 2;
787}
788
789/// Unpack data from input file assuming it comes from
790// the same expansion type
792 const NekDouble *data, const std::vector<unsigned int> &nummodes,
793 const int mode_offset, NekDouble *coeffs,
794 [[maybe_unused]] std::vector<LibUtilities::BasisType> &fromType)
795{
796 switch (m_base[0]->GetBasisType())
797 {
799 {
800 int fillorder = min((int)nummodes[mode_offset], m_ncoeffs);
801
802 Vmath::Zero(m_ncoeffs, coeffs, 1);
803 Vmath::Vcopy(fillorder, &data[0], 1, &coeffs[0], 1);
804 }
805 break;
807 {
808 // Assume that input is also Gll_Lagrange
809 // but no way to check;
810 LibUtilities::PointsKey f0(nummodes[mode_offset],
812 LibUtilities::PointsKey t0(m_base[0]->GetNumModes(),
814 LibUtilities::Interp1D(f0, data, t0, coeffs);
815 }
816 break;
818 {
819 // Assume that input is also Gauss_Lagrange
820 // but no way to check;
821 LibUtilities::PointsKey f0(nummodes[mode_offset],
823 LibUtilities::PointsKey t0(m_base[0]->GetNumModes(),
825 LibUtilities::Interp1D(f0, data, t0, coeffs);
826 }
827 break;
828 default:
829 ASSERTL0(false, "basis is either not set up or not hierarchicial");
830 }
831}
832
833void SegExp::v_ComputeTraceNormal(const int vertex)
834{
835 int i;
836 const SpatialDomains::GeomFactorsSharedPtr &geomFactors =
838 SpatialDomains::GeomType type = geomFactors->GetGtype();
839 const Array<TwoD, const NekDouble> &gmat =
840 geomFactors->GetDerivFactors(GetPointsKeys());
841 int nqe = 1;
842 int vCoordDim = GetCoordim();
843
846 for (i = 0; i < vCoordDim; ++i)
847 {
848 normal[i] = Array<OneD, NekDouble>(nqe);
849 }
850
851 size_t nqb = nqe;
852 size_t nbnd = vertex;
855
856 // Regular geometry case
857 if ((type == SpatialDomains::eRegular) ||
859 {
860 NekDouble vert;
861 // Set up normals
862 switch (vertex)
863 {
864 case 0:
865 for (i = 0; i < vCoordDim; ++i)
866 {
867 Vmath::Fill(nqe, -gmat[i][0], normal[i], 1);
868 }
869 break;
870 case 1:
871 for (i = 0; i < vCoordDim; ++i)
872 {
873 Vmath::Fill(nqe, gmat[i][0], normal[i], 1);
874 }
875 break;
876 default:
877 ASSERTL0(false, "point is out of range (point < 2)");
878 }
879
880 // normalise
881 vert = 0.0;
882 for (i = 0; i < vCoordDim; ++i)
883 {
884 vert += normal[i][0] * normal[i][0];
885 }
886 vert = 1.0 / sqrt(vert);
887
888 Vmath::Fill(nqb, vert, length, 1);
889
890 for (i = 0; i < vCoordDim; ++i)
891 {
892 Vmath::Smul(nqe, vert, normal[i], 1, normal[i], 1);
893 }
894 }
895}
896
897//-----------------------------
898// Operator creation functions
899//-----------------------------
900
902 const Array<OneD, const NekDouble> &inarray,
903 Array<OneD, NekDouble> &outarray,
904 [[maybe_unused]] const StdRegions::StdMatrixKey &mkey)
905{
906 int nquad = m_base[0]->GetNumPoints();
907 const Array<TwoD, const NekDouble> &gmat =
908 m_metricinfo->GetDerivFactors(GetPointsKeys());
909
910 Array<OneD, NekDouble> physValues(nquad);
911 Array<OneD, NekDouble> dPhysValuesdx(nquad);
912
913 BwdTrans(inarray, physValues);
914
915 // Laplacian matrix operation
916 switch (m_geom->GetCoordim())
917 {
918 case 1:
919 {
920 PhysDeriv(physValues, dPhysValuesdx);
921
922 // multiply with the proper geometric factors
923 if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
924 {
925 Vmath::Vmul(nquad, &gmat[0][0], 1, dPhysValuesdx.data(), 1,
926 dPhysValuesdx.data(), 1);
927 }
928 else
929 {
930 Blas::Dscal(nquad, gmat[0][0], dPhysValuesdx.data(), 1);
931 }
932 }
933 break;
934 case 2:
935 {
936 Array<OneD, NekDouble> dPhysValuesdy(nquad);
937
938 PhysDeriv(physValues, dPhysValuesdx, dPhysValuesdy);
939
940 // multiply with the proper geometric factors
941 if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
942 {
943 Vmath::Vmul(nquad, &gmat[0][0], 1, dPhysValuesdx.data(), 1,
944 dPhysValuesdx.data(), 1);
945 Vmath::Vvtvp(nquad, &gmat[1][0], 1, dPhysValuesdy.data(), 1,
946 dPhysValuesdx.data(), 1, dPhysValuesdx.data(), 1);
947 }
948 else
949 {
950 Blas::Dscal(nquad, gmat[0][0], dPhysValuesdx.data(), 1);
951 Blas::Daxpy(nquad, gmat[1][0], dPhysValuesdy.data(), 1,
952 dPhysValuesdx.data(), 1);
953 }
954 }
955 break;
956 case 3:
957 {
958 Array<OneD, NekDouble> dPhysValuesdy(nquad);
959 Array<OneD, NekDouble> dPhysValuesdz(nquad);
960
961 PhysDeriv(physValues, dPhysValuesdx, dPhysValuesdy, dPhysValuesdz);
962
963 // multiply with the proper geometric factors
964 if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
965 {
966 Vmath::Vmul(nquad, &gmat[0][0], 1, dPhysValuesdx.data(), 1,
967 dPhysValuesdx.data(), 1);
968 Vmath::Vvtvp(nquad, &gmat[1][0], 1, dPhysValuesdy.data(), 1,
969 dPhysValuesdx.data(), 1, dPhysValuesdx.data(), 1);
970 Vmath::Vvtvp(nquad, &gmat[2][0], 1, dPhysValuesdz.data(), 1,
971 dPhysValuesdx.data(), 1, dPhysValuesdx.data(), 1);
972 }
973 else
974 {
975 Blas::Dscal(nquad, gmat[0][0], dPhysValuesdx.data(), 1);
976 Blas::Daxpy(nquad, gmat[1][0], dPhysValuesdy.data(), 1,
977 dPhysValuesdx.data(), 1);
978 Blas::Daxpy(nquad, gmat[2][0], dPhysValuesdz.data(), 1,
979 dPhysValuesdx.data(), 1);
980 }
981 }
982 break;
983 default:
984 ASSERTL0(false, "Wrong number of dimensions");
985 break;
986 }
987
988 v_IProductWRTBase(m_base[0]->GetDbdata(), dPhysValuesdx, outarray, 1);
989}
990
991void SegExp::v_LaplacianMatrixOp(const int k1, const int k2,
992 const Array<OneD, const NekDouble> &inarray,
993 Array<OneD, NekDouble> &outarray,
994 const StdRegions::StdMatrixKey &mkey)
995{
996 StdExpansion::LaplacianMatrixOp_MatFree(k1, k2, inarray, outarray, mkey);
997}
998
1000 Array<OneD, NekDouble> &outarray,
1001 const StdRegions::StdMatrixKey &mkey)
1002{
1003 int nquad = m_base[0]->GetNumPoints();
1004 const Array<TwoD, const NekDouble> &gmat =
1005 m_metricinfo->GetDerivFactors(GetPointsKeys());
1007
1008 Array<OneD, NekDouble> physValues(nquad);
1009 Array<OneD, NekDouble> dPhysValuesdx(nquad);
1011
1012 BwdTrans(inarray, physValues);
1013
1014 // mass matrix operation
1015 v_IProductWRTBase((m_base[0]->GetBdata()), physValues, wsp, 1);
1016
1017 // Laplacian matrix operation
1018 switch (m_geom->GetCoordim())
1019 {
1020 case 1:
1021 {
1022 PhysDeriv(physValues, dPhysValuesdx);
1023
1024 // multiply with the proper geometric factors
1025 if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1026 {
1027 Vmath::Vmul(nquad, &gmat[0][0], 1, dPhysValuesdx.data(), 1,
1028 dPhysValuesdx.data(), 1);
1029 }
1030 else
1031 {
1032 Blas::Dscal(nquad, gmat[0][0], dPhysValuesdx.data(), 1);
1033 }
1034 }
1035 break;
1036 case 2:
1037 {
1038 Array<OneD, NekDouble> dPhysValuesdy(nquad);
1039
1040 PhysDeriv(physValues, dPhysValuesdx, dPhysValuesdy);
1041
1042 // multiply with the proper geometric factors
1043 if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1044 {
1045 Vmath::Vmul(nquad, &gmat[0][0], 1, dPhysValuesdx.data(), 1,
1046 dPhysValuesdx.data(), 1);
1047 Vmath::Vvtvp(nquad, &gmat[1][0], 1, dPhysValuesdy.data(), 1,
1048 dPhysValuesdx.data(), 1, dPhysValuesdx.data(), 1);
1049 }
1050 else
1051 {
1052 Blas::Dscal(nquad, gmat[0][0], dPhysValuesdx.data(), 1);
1053 Blas::Daxpy(nquad, gmat[1][0], dPhysValuesdy.data(), 1,
1054 dPhysValuesdx.data(), 1);
1055 }
1056 }
1057 break;
1058 case 3:
1059 {
1060 Array<OneD, NekDouble> dPhysValuesdy(nquad);
1061 Array<OneD, NekDouble> dPhysValuesdz(nquad);
1062
1063 PhysDeriv(physValues, dPhysValuesdx, dPhysValuesdy, dPhysValuesdz);
1064
1065 // multiply with the proper geometric factors
1066 if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1067 {
1068 Vmath::Vmul(nquad, &gmat[0][0], 1, dPhysValuesdx.data(), 1,
1069 dPhysValuesdx.data(), 1);
1070 Vmath::Vvtvp(nquad, &gmat[1][0], 1, dPhysValuesdy.data(), 1,
1071 dPhysValuesdx.data(), 1, dPhysValuesdx.data(), 1);
1072 Vmath::Vvtvp(nquad, &gmat[2][0], 1, dPhysValuesdz.data(), 1,
1073 dPhysValuesdx.data(), 1, dPhysValuesdx.data(), 1);
1074 }
1075 else
1076 {
1077 Blas::Dscal(nquad, gmat[0][0], dPhysValuesdx.data(), 1);
1078 Blas::Daxpy(nquad, gmat[1][0], dPhysValuesdy.data(), 1,
1079 dPhysValuesdx.data(), 1);
1080 Blas::Daxpy(nquad, gmat[2][0], dPhysValuesdz.data(), 1,
1081 dPhysValuesdx.data(), 1);
1082 }
1083 }
1084 break;
1085 default:
1086 ASSERTL0(false, "Wrong number of dimensions");
1087 break;
1088 }
1089
1090 v_IProductWRTBase(m_base[0]->GetDbdata(), dPhysValuesdx, outarray, 1);
1091 Blas::Daxpy(m_ncoeffs, lambda, wsp.data(), 1, outarray.data(), 1);
1092}
1093
1094//-----------------------------
1095// Matrix creation functions
1096//-----------------------------
1097
1102
1104{
1105 m_staticCondMatrixManager.DeleteObject(mkey);
1106}
1107
1109{
1110 return m_matrixManager[mkey];
1111}
1112
1114{
1115 m_matrixManager.DeleteObject(mkey);
1116}
1117
1119{
1120 LibUtilities::BasisKey bkey = m_base[0]->GetBasisKey();
1123
1124 return tmp->GetStdMatrix(mkey);
1125}
1126
1128{
1129 DNekScalMatSharedPtr returnval;
1130 NekDouble fac;
1132
1134 "Geometric information is not set up");
1135
1136 switch (mkey.GetMatrixType())
1137 {
1138 case StdRegions::eMass:
1139 {
1140 if ((m_metricinfo->GetGtype() == SpatialDomains::eDeformed) ||
1141 (mkey.GetNVarCoeff()))
1142 {
1143 fac = 1.0;
1144 goto UseLocRegionsMatrix;
1145 }
1146 else
1147 {
1148 fac = (m_metricinfo->GetJac(ptsKeys))[0];
1149 goto UseStdRegionsMatrix;
1150 }
1151 }
1152 break;
1154 {
1155 if ((m_metricinfo->GetGtype() == SpatialDomains::eDeformed) ||
1156 (mkey.GetNVarCoeff()))
1157 {
1158 NekDouble one = 1.0;
1160 DetShapeType(), *this);
1161 DNekMatSharedPtr mat = GenMatrix(masskey);
1162 mat->Invert();
1163
1164 returnval =
1166 }
1167 else
1168 {
1169 fac = 1.0 / (m_metricinfo->GetJac(ptsKeys))[0];
1170 goto UseStdRegionsMatrix;
1171 }
1172 }
1173 break;
1177 {
1178 if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed ||
1179 mkey.GetNVarCoeff())
1180 {
1181 fac = 1.0;
1182 goto UseLocRegionsMatrix;
1183 }
1184 else
1185 {
1186 int dir = 0;
1187 switch (mkey.GetMatrixType())
1188 {
1190 dir = 0;
1191 break;
1193 ASSERTL1(m_geom->GetCoordim() >= 2,
1194 "Cannot call eWeakDeriv2 in a "
1195 "coordinate system which is not at "
1196 "least two-dimensional");
1197 dir = 1;
1198 break;
1200 ASSERTL1(m_geom->GetCoordim() == 3,
1201 "Cannot call eWeakDeriv2 in a "
1202 "coordinate system which is not "
1203 "three-dimensional");
1204 dir = 2;
1205 break;
1206 default:
1207 break;
1208 }
1209
1211 mkey.GetShapeType(), *this);
1212
1213 DNekMatSharedPtr WeakDerivStd = GetStdMatrix(deriv0key);
1214 fac = m_metricinfo->GetDerivFactors(ptsKeys)[dir][0] *
1215 m_metricinfo->GetJac(ptsKeys)[0];
1216
1218 fac, WeakDerivStd);
1219 }
1220 }
1221 break;
1223 {
1224 if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
1225 {
1226 fac = 1.0;
1227 goto UseLocRegionsMatrix;
1228 }
1229 else
1230 {
1231 int coordim = m_geom->GetCoordim();
1232 fac = 0.0;
1233 for (int i = 0; i < coordim; ++i)
1234 {
1235 fac += m_metricinfo->GetDerivFactors(ptsKeys)[i][0] *
1236 m_metricinfo->GetDerivFactors(ptsKeys)[i][0];
1237 }
1238 fac *= m_metricinfo->GetJac(ptsKeys)[0];
1239 goto UseStdRegionsMatrix;
1240 }
1241 }
1242 break;
1244 {
1245 if ((m_metricinfo->GetGtype() == SpatialDomains::eDeformed) ||
1246 (mkey.GetNVarCoeff()))
1247 {
1248 fac = 1.0;
1249 goto UseLocRegionsMatrix;
1250 }
1251 else
1252 {
1253 fac = (m_metricinfo->GetJac(ptsKeys))[0];
1254 goto UseStdRegionsMatrix;
1255 }
1256 }
1257 break;
1259 {
1261 MatrixKey masskey(StdRegions::eMass, mkey.GetShapeType(), *this);
1262 DNekScalMat &MassMat = *(this->m_matrixManager[masskey]);
1263 MatrixKey lapkey(StdRegions::eLaplacian, mkey.GetShapeType(), *this,
1264 mkey.GetConstFactors(), mkey.GetVarCoeffs());
1265 DNekScalMat &LapMat = *(this->m_matrixManager[lapkey]);
1266
1267 int rows = LapMat.GetRows();
1268 int cols = LapMat.GetColumns();
1269
1270 DNekMatSharedPtr helm =
1272
1273 NekDouble one = 1.0;
1274 (*helm) = LapMat + factor * MassMat;
1275
1276 returnval =
1278 }
1279 break;
1281 {
1283
1284 // Construct mass matrix
1285 // Check for mass-specific varcoeffs to avoid unncessary
1286 // re-computation of the elemental matrix every time step
1289 {
1290 massVarcoeffs[StdRegions::eVarCoeffMass] =
1292 }
1293 MatrixKey masskey(StdRegions::eMass, mkey.GetShapeType(), *this,
1294 mkey.GetConstFactors(), massVarcoeffs);
1295 DNekScalMat &MassMat = *GetLocMatrix(masskey);
1296
1297 // Construct advection matrix
1298 // Check for varcoeffs not required;
1299 // assume advection velocity is always time-dependent
1301 DNekScalMat &AdvMat = *GetLocMatrix(advkey);
1302
1303 int rows = MassMat.GetRows();
1304 int cols = MassMat.GetColumns();
1305
1306 DNekMatSharedPtr adr =
1308
1309 NekDouble one = 1.0;
1310 (*adr) = -lambda * MassMat + AdvMat;
1311
1313
1314 // Clear memory for time-dependent matrices
1315 DropLocMatrix(advkey);
1316 if (!massVarcoeffs.empty())
1317 {
1318 DropLocMatrix(masskey);
1319 }
1320 }
1321 break;
1323 {
1325
1326 // Construct mass matrix
1327 // Check for mass-specific varcoeffs to avoid unncessary
1328 // re-computation of the elemental matrix every time step
1331 {
1332 massVarcoeffs[StdRegions::eVarCoeffMass] =
1334 }
1335 MatrixKey masskey(StdRegions::eMass, mkey.GetShapeType(), *this,
1336 mkey.GetConstFactors(), massVarcoeffs);
1337 DNekScalMat &MassMat = *GetLocMatrix(masskey);
1338
1339 // Construct laplacian matrix (Check for varcoeffs)
1340 // Take all varcoeffs if one or more are detected
1341 // TODO We might want to have a map
1342 // from MatrixType to Vector of Varcoeffs and vice-versa
1354 {
1355 lapVarcoeffs = mkey.GetVarCoeffs();
1356 }
1357 MatrixKey lapkey(StdRegions::eLaplacian, mkey.GetShapeType(), *this,
1358 mkey.GetConstFactors(), lapVarcoeffs);
1359 DNekScalMat &LapMat = *GetLocMatrix(lapkey);
1360
1361 // Construct advection matrix
1362 // Check for varcoeffs not required;
1363 // assume advection velocity is always time-dependent
1365 DNekScalMat &AdvMat = *GetLocMatrix(advkey);
1366
1367 int rows = LapMat.GetRows();
1368 int cols = LapMat.GetColumns();
1369
1370 DNekMatSharedPtr adr =
1372
1373 NekDouble one = 1.0;
1374 (*adr) = LapMat - lambda * MassMat + AdvMat;
1375
1377
1378 // Clear memory for time-dependent matrices
1379 DropLocMatrix(advkey);
1380 if (!massVarcoeffs.empty())
1381 {
1382 DropLocMatrix(masskey);
1383 }
1384 if (!lapVarcoeffs.empty())
1385 {
1386 DropLocMatrix(lapkey);
1387 }
1388 }
1389 break;
1394 {
1395 NekDouble one = 1.0;
1396
1397 DNekMatSharedPtr mat = GenMatrix(mkey);
1399 }
1400 break;
1402 {
1403 NekDouble one = 1.0;
1404
1405 // StdRegions::StdMatrixKey
1406 // hkey(StdRegions::eHybridDGHelmholtz,
1407 // DetShapeType(),*this,
1408 // mkey.GetConstant(0),
1409 // mkey.GetConstant(1));
1411 *this, mkey.GetConstFactors(), mkey.GetVarCoeffs());
1412 DNekMatSharedPtr mat = GenMatrix(hkey);
1413
1414 mat->Invert();
1416 }
1417 break;
1419 {
1420 DNekMatSharedPtr m_Ix;
1421 Array<OneD, NekDouble> coords(1, 0.0);
1423 int vertex = (int)factors[StdRegions::eFactorGaussVertex];
1424
1425 coords[0] = (vertex == 0) ? -1.0 : 1.0;
1426
1427 m_Ix = m_base[0]->GetI(coords);
1428 returnval =
1430 }
1431 break;
1432
1433 UseLocRegionsMatrix:
1434 {
1435 DNekMatSharedPtr mat = GenMatrix(mkey);
1437 }
1438 break;
1439 UseStdRegionsMatrix:
1440 {
1441 DNekMatSharedPtr mat = GetStdMatrix(mkey);
1443 }
1444 break;
1445 default:
1446 {
1447 NekDouble one = 1.0;
1448 DNekMatSharedPtr mat = GenMatrix(mkey);
1449
1451 }
1452 break;
1453 }
1454
1455 return returnval;
1456}
1457
1459{
1460 DNekMatSharedPtr returnval;
1461
1462 switch (mkey.GetMatrixType())
1463 {
1470 returnval = Expansion1D::v_GenMatrix(mkey);
1471 break;
1472 default:
1473 returnval = StdSegExp::v_GenMatrix(mkey);
1474 break;
1475 }
1476
1477 return returnval;
1478}
1479
1480//-----------------------------
1481// Private methods
1482//-----------------------------
1483
1484/// Reverse the coefficients in a boundary interior expansion
1485/// this routine is of use when we need the segment
1486/// coefficients corresponding to a expansion in the reverse
1487/// coordinate direction
1489 Array<OneD, NekDouble> &outarray)
1490{
1491
1492 int m;
1493 NekDouble sgn = 1;
1494
1495 ASSERTL1(&inarray[0] != &outarray[0],
1496 "inarray and outarray can not be the same");
1497 switch (GetBasisType(0))
1498 {
1500 // Swap vertices
1501 outarray[0] = inarray[1];
1502 outarray[1] = inarray[0];
1503 // negate odd modes
1504 for (m = 2; m < m_ncoeffs; ++m)
1505 {
1506 outarray[m] = sgn * inarray[m];
1507 sgn = -sgn;
1508 }
1509 break;
1512 for (m = 0; m < m_ncoeffs; ++m)
1513 {
1514 outarray[m_ncoeffs - 1 - m] = inarray[m];
1515 }
1516 break;
1517 default:
1518 ASSERTL0(false, "This basis is not allowed in this method");
1519 break;
1520 }
1521}
1522
1523/* \brief Mass inversion product from \a inarray to \a outarray
1524 *
1525 * Multiply by the inverse of the mass matrix
1526 * \f$ {\bf \hat{u}} = {\bf M}^{-1} {\bf I} \f$
1527 *
1528 **/
1530 Array<OneD, NekDouble> &outarray)
1531{
1532 // get Mass matrix inverse
1533 MatrixKey masskey(StdRegions::eInvMass, DetShapeType(), *this);
1534 DNekScalMatSharedPtr matsys = m_matrixManager[masskey];
1535
1536 NekVector<NekDouble> in(m_ncoeffs, inarray, eCopy);
1537 NekVector<NekDouble> out(m_ncoeffs, outarray, eWrapper);
1538
1539 out = (*matsys) * in;
1540}
1541
1542} // 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
DNekMatSharedPtr v_GenMatrix(const StdRegions::StdMatrixKey &mkey) override
std::map< int, NormalVector > m_traceNormals
Definition Expansion.h:282
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:292
void DropLocMatrix(const LocalRegions::MatrixKey &mkey)
Definition Expansion.cpp:90
SpatialDomains::Geometry * GetGeom() const
ExpansionSharedPtr GetLeftAdjacentElementExp() const
Definition Expansion.h:447
SpatialDomains::Geometry * m_geom
Definition Expansion.h:279
void v_GetCoords(Array< OneD, NekDouble > &coords_1, Array< OneD, NekDouble > &coords_2, Array< OneD, NekDouble > &coords_3) override
int GetLeftAdjacentElementTrace() const
Definition Expansion.h:460
SpatialDomains::GeomFactorsSharedPtr m_metricinfo
Definition Expansion.h:280
DNekScalMatSharedPtr GetLocMatrix(const LocalRegions::MatrixKey &mkey)
Definition Expansion.cpp:84
void v_LaplacianMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::StdMatrixKey &mkey) override
Definition SegExp.cpp:901
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...
Definition SegExp.cpp:346
void v_DropLocMatrix(const MatrixKey &mkey) override
Definition SegExp.cpp:1113
StdRegions::StdExpansionSharedPtr v_GetLinStdExp(void) const override
Definition SegExp.cpp:765
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:712
void v_PhysDeriv_s(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_ds) override
Evaluate the derivative along a line: . The derivative is calculated performing the product .
Definition SegExp.cpp:201
void v_GetVertexPhysVals(const int vertex, const Array< OneD, const NekDouble > &inarray, NekDouble &outarray) override
Definition SegExp.cpp:677
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:641
NekDouble v_StdPhysEvaluate(const Array< OneD, const NekDouble > &Lcoord, const Array< OneD, const NekDouble > &physvals) override
Definition SegExp.cpp:611
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:1488
void v_NormVectorIProductWRTBase(const Array< OneD, const NekDouble > &Fx, const Array< OneD, const NekDouble > &Fy, Array< OneD, NekDouble > &outarray) override
Definition SegExp.cpp:577
DNekScalMatSharedPtr CreateMatrix(const MatrixKey &mkey)
Definition SegExp.cpp:1127
StdRegions::StdExpansionSharedPtr v_GetStdExp(void) const override
Definition SegExp.cpp:759
void v_FwdTransBndConstrained(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Definition SegExp.cpp:369
void v_IProductWRTBase(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Inner product of inarray over region with respect to the expansion basis (this)->_Base[0] and return ...
Definition SegExp.cpp:498
DNekMatSharedPtr v_GenMatrix(const StdRegions::StdMatrixKey &mkey) override
Definition SegExp.cpp:1458
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:239
NekDouble v_Integral(const Array< OneD, const NekDouble > &inarray) override
Integrate the physical point list inarray over region and return the value.
Definition SegExp.cpp:98
void v_HelmholtzMatrixOp(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::StdMatrixKey &mkey) override
Definition SegExp.cpp:999
void v_PhysDeriv_n(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_dn) override
Evaluate the derivative normal to a line: . The derivative is calculated performing the product .
Definition SegExp.cpp:240
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:791
void v_PhysDeriv(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out_d0, Array< OneD, NekDouble > &out_d1=NullNekDouble1DArray, Array< OneD, NekDouble > &out_d2=NullNekDouble1DArray) override
Evaluate the derivative at the physical quadrature points given by inarray and return in outarray.
Definition SegExp.cpp:145
void v_GetCoords(Array< OneD, NekDouble > &coords_1, Array< OneD, NekDouble > &coords_2, Array< OneD, NekDouble > &coords_3) override
Definition SegExp.cpp:669
DNekScalBlkMatSharedPtr v_GetLocStaticCondMatrix(const MatrixKey &mkey) override
Definition SegExp.cpp:1098
void MultiplyByElmtInvMass(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Definition SegExp.cpp:1529
int v_NumBndryCoeffs() const override
Definition SegExp.cpp:779
LibUtilities::NekManager< MatrixKey, DNekScalMat, MatrixKey::opLess > m_matrixManager
Definition SegExp.h:237
NekDouble v_PhysEvaluate(const Array< OneD, const NekDouble > &coord, const Array< OneD, const NekDouble > &physvals) override
Definition SegExp.cpp:619
void v_GetTracePhysMap(const int vertex, Array< OneD, int > &map) override
Definition SegExp.cpp:725
int v_NumDGBndryCoeffs() const override
Definition SegExp.cpp:784
DNekMatSharedPtr v_CreateStdMatrix(const StdRegions::StdMatrixKey &mkey) override
Definition SegExp.cpp:1118
void v_SetCoeffsToOrientation(StdRegions::Orientation dir, Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Definition SegExp.cpp:740
void v_DropLocStaticCondMatrix(const MatrixKey &mkey) override
Definition SegExp.cpp:1103
const Array< OneD, const NekDouble > & v_GetPhysNormals() override
Definition SegExp.cpp:773
DNekScalMatSharedPtr v_GetLocMatrix(const MatrixKey &mkey) override
Definition SegExp.cpp:1108
void v_GetCoord(const Array< OneD, const NekDouble > &Lcoords, Array< OneD, NekDouble > &coords) override
Definition SegExp.cpp:654
NekDouble v_PhysEvalFirstDeriv(const Array< OneD, NekDouble > &coord, const Array< OneD, const NekDouble > &inarray, std::array< NekDouble, 3 > &firstOrderDerivs) override
Definition SegExp.cpp:630
void v_ComputeTraceNormal(const int vertex) override
Definition SegExp.cpp:833
void v_IProductWRTDerivBase(const int dir, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Definition SegExp.cpp:551
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:558
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:548
int GetCoordim() const
Return the coordinate dimension of this object (i.e. the dimension of the space in which this object ...
Definition Geometry.h:279
void FillGeom()
Populate the coordinate mapping Geometry::m_coeffs information from any children geometry elements.
Definition Geometry.h:460
GeomFactorsSharedPtr GetMetricInfo()
Get the geometric factors for this object.
Definition Geometry.h:306
void PhysTensorDeriv(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Evaluate the derivative at the physical quadrature points given by inarray and return in outarray.
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.
int GetNumPoints(const int dir) const
This function returns the number of quadrature points 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
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:211
static void Dscal(const int &n, const double &alpha, double *x, const int &incx)
BLAS level 1: x = alpha x.
Definition Blas.hpp:149
static double Ddot(const int &n, const double *x, const int &incx, const double *y, const int &incy)
BLAS level 1: output = .
Definition Blas.hpp:163
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:135
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:231
@ 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
std::shared_ptr< GeomFactors > GeomFactorsSharedPtr
Pointer to a GeomFactors object.
Definition GeomFactors.h:58
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:214
std::map< StdRegions::VarCoeffType, VarCoeffEntry > VarCoeffMap
std::shared_ptr< DNekScalMat > DNekScalMatSharedPtr
static Array< OneD, Array< OneD, NekDouble > > NullNekDoubleArrayOfArray
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
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 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 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