Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
SmoothShockCapture.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: SmoothShockCapture.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 // License for the specific language governing rights and limitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 //
32 // Description: Smooth artificial diffusion for shock capture
33 //
34 ///////////////////////////////////////////////////////////////////////////////
35 
36 #include "SmoothShockCapture.h"
37 
38 using namespace std;
39 
40 namespace Nektar
41 {
42 
43 std::string SmoothShockCapture::className = GetArtificialDiffusionFactory().
44  RegisterCreatorFunction("Smooth",
45  SmoothShockCapture::create,
46  "Smooth artificial diffusion for shock capture.");
47 
48 SmoothShockCapture::SmoothShockCapture(const LibUtilities::SessionReaderSharedPtr& pSession,
50  const int spacedim)
51  : ArtificialDiffusion(pSession, pFields, spacedim)
52 {
53  ASSERTL0(m_fields.num_elements() == spacedim + 3,
54  "Not enough variables for smooth shock capturing; "
55  "make sure you have added eps to variable list.");
56 }
57 
59  const Array<OneD, const Array<OneD, NekDouble> > &inarray,
60  Array<OneD, Array<OneD, NekDouble> > &outarray)
61 {
62  int i;
63  int nvariables = inarray.num_elements();
64  int npoints = m_fields[0]->GetNpoints();
65 
66  Array<OneD, Array<OneD, NekDouble> > outarrayDiff(nvariables);
67 
68  for (i = 0; i < nvariables; ++i)
69  {
70  outarrayDiff[i] = Array<OneD, NekDouble>(npoints, 0.0);
71  }
72 
73  m_diffusion->Diffuse(nvariables, m_fields, inarray, outarrayDiff);
74 
75  const Array<OneD, int> ExpOrder = m_fields[0]->EvalBasisNumModesMaxPerExp();
76 
77  NekDouble pOrder = Vmath::Vmax(ExpOrder.num_elements(), ExpOrder, 1);
78 
79  Array <OneD, NekDouble > a_vel (npoints, 0.0);
80  Array <OneD, NekDouble > u_abs (npoints, 0.0);
81  Array <OneD, NekDouble > tmp (npoints, 0.0);
82 
83  m_varConv->GetPressure(inarray, tmp);
84  m_varConv->GetSoundSpeed(inarray, tmp, a_vel);
85  m_varConv->GetAbsoluteVelocity(inarray, u_abs);
86 
87  Vmath::Vadd(npoints, a_vel, 1, u_abs, 1, tmp, 1);
88 
89  NekDouble max_wave_sp = Vmath::Vmax(npoints, tmp, 1);
90 
91  NekDouble fac = m_C2*max_wave_sp*pOrder;
92 
93  Vmath::Smul(npoints,
94  fac,
95  outarrayDiff[nvariables-1], 1,
96  outarrayDiff[nvariables-1], 1);
97 
98  for (i = 0; i < nvariables; ++i)
99  {
100  Vmath::Vadd(npoints,
101  outarray[i], 1,
102  outarrayDiff[i], 1,
103  outarray[i], 1);
104  }
105 
106  Array<OneD, Array<OneD, NekDouble> > outarrayForcing(nvariables);
107 
108  for (i = 0; i < nvariables; ++i)
109  {
110  outarrayForcing[i] = Array<OneD, NekDouble>(npoints, 0.0);
111  }
112 
113  GetForcingTerm(inarray, outarrayForcing);
114 
115  for (i = 0; i < nvariables; ++i)
116  {
117  // Add Forcing Term
118  Vmath::Vadd(npoints,
119  outarray[i], 1,
120  outarrayForcing[i], 1,
121  outarray[i], 1);
122  }
123 }
124 
126  const Array<OneD, Array<OneD, NekDouble> > &physfield,
128 {
129  int nvariables = physfield.num_elements();
130  int nPts = m_fields[0]->GetTotPoints();
131 
132  Array<OneD, NekDouble > sensor (nPts, 0.0);
133  Array<OneD, NekDouble > SensorKappa(nPts, 0.0);
134 
135  // Calculate sensor
136  m_varConv->GetSensor(m_fields[0], physfield, sensor, SensorKappa);
137 
138  NekDouble ThetaH = m_FacH;
139  NekDouble ThetaL = m_FacL;
140 
141  NekDouble Phi0 = (ThetaH+ThetaL)/2;
142  NekDouble DeltaPhi = ThetaH-Phi0;
143 
144  for (int e = 0; e < mu.num_elements(); e++)
145  {
146  if (physfield[nvariables-1][e] <= (Phi0 - DeltaPhi))
147  {
148  mu[e] = 0;
149  }
150  else if(physfield[nvariables-1][e] >= (Phi0 + DeltaPhi))
151  {
152  mu[e] = m_mu0;
153  }
154  else if(abs(physfield[nvariables-1][e]-Phi0) < DeltaPhi)
155  {
156  mu[e] = m_mu0/2*(1+sin(M_PI*
157  (physfield[nvariables-1][e]-Phi0)/(2*DeltaPhi)));
158  }
159  }
160 }
161 
163  const Array<OneD, const Array<OneD, NekDouble> > &inarray,
164  Array<OneD, Array<OneD, NekDouble> > outarrayForcing)
165 {
166  const int nPts = m_fields[0]->GetTotPoints();
167  const int nvariables = m_fields.num_elements();
168  const int nElements = m_fields[0]->GetExpSize();
169 
170  Array<OneD, NekDouble> Sensor(nPts, 0.0);
171  Array<OneD, NekDouble> SensorKappa(nPts, 0.0);
172  Array <OneD, NekDouble > Lambda(nPts, 0.0);
173  Array <OneD, NekDouble > Tau(nPts, 1.0);
174  Array <OneD, NekDouble > soundspeed(nPts, 0.0);
175  Array <OneD, NekDouble > pressure(nPts, 0.0);
176  Array <OneD, NekDouble > absVelocity(nPts, 0.0);
177 
178  Array<OneD,int> pOrderElmt = m_fields[0]->EvalBasisNumModesMaxPerExp();
179  Array<OneD, NekDouble> pOrder (nPts, 0.0);
180 
181  // Thermodynamic related quantities
182  m_varConv->GetPressure(inarray, pressure);
183  m_varConv->GetSoundSpeed(inarray, pressure, soundspeed);
184  m_varConv->GetAbsoluteVelocity(inarray, absVelocity);
185  m_varConv->GetSensor(m_fields[0], inarray, Sensor, SensorKappa);
186 
187  // Determine the maximum wavespeed
188  Vmath::Vadd(nPts, absVelocity, 1, soundspeed, 1, Lambda, 1);
189 
190  NekDouble LambdaMax = Vmath::Vmax(nPts, Lambda, 1);
191 
192  int PointCount = 0;
193 
194  for (int e = 0; e < nElements; e++)
195  {
196  int nQuadPointsElement = m_fields[0]->GetExp(e)->GetTotPoints();
197 
198  for (int n = 0; n < nQuadPointsElement; n++)
199  {
200  pOrder[n + PointCount] = pOrderElmt[e];
201 
202  // order 1.0e-06
203  Tau[n + PointCount] =
204  1.0 / (m_C1*pOrder[n + PointCount]*LambdaMax);
205 
206  outarrayForcing[nvariables-1][n + PointCount] =
207  1 / Tau[n + PointCount] * (m_hFactor * LambdaMax /
208  pOrder[n + PointCount] *
209  SensorKappa[n + PointCount] -
210  inarray[nvariables-1][n + PointCount]);
211  }
212  PointCount += nQuadPointsElement;
213  }
214 }
215 
216 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:198
Definition: Tau.hpp:39
virtual void v_DoArtificialDiffusion(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray)
T Vmax(int n, const T *x, const int incx)
Return the maximum element in x – called vmax to avoid conflict with max.
Definition: Vmath.cpp:779
STL namespace.
boost::shared_ptr< SessionReader > SessionReaderSharedPtr
Definition: MeshPartition.h:51
Encapsulates the artificial diffusion used in shock capture.
SolverUtils::DiffusionSharedPtr m_diffusion
LDG Diffusion operator.
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*y.
Definition: Vmath.cpp:213
ArtificialDiffusionFactory & GetArtificialDiffusionFactory()
Declaration of the artificial diffusion factory singleton.
double NekDouble
virtual void v_GetArtificialViscosity(const Array< OneD, Array< OneD, NekDouble > > &physfield, Array< OneD, NekDouble > &mu)
void GetForcingTerm(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > outarrayForcing)
NekDouble m_FacL
Parameters.
VariableConverterSharedPtr m_varConv
Auxiliary object to convert variables.
Array< OneD, MultiRegions::ExpListSharedPtr > m_fields
Array of fields.
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.cpp:299