Nektar++
EigenValuesAdvection.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: EigenValuesAdvection.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:
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
35 #include <iostream>
36 
38 
39 using namespace std;
40 
41 namespace Nektar
42 {
43 string EigenValuesAdvection::className =
45  "EigenValuesAdvection", EigenValuesAdvection::create,
46  "Eigenvalues of the weak advection operator.");
47 
48 EigenValuesAdvection::EigenValuesAdvection(
51  : EquationSystem(pSession, pGraph)
52 {
53 }
54 
55 void EigenValuesAdvection::v_InitObject(bool DeclareFields)
56 {
57  EquationSystem::v_InitObject(DeclareFields);
58 
59  // Define Velocity fields
61  std::vector<std::string> vel;
62  vel.push_back("Vx");
63  vel.push_back("Vy");
64  vel.push_back("Vz");
65  vel.resize(m_spacedim);
66 
67  GetFunction("AdvectionVelocity")->Evaluate(vel, m_velocity);
68 
69  // Type of advection class to be used
70  switch (m_projectionType)
71  {
72  // Discontinuous field
74  {
75  // Define the normal velocity fields
76  if (m_fields[0]->GetTrace())
77  {
79  }
80 
81  string advName;
82  string riemName;
83  m_session->LoadSolverInfo("AdvectionType", advName, "WeakDG");
85  advName, advName);
87  this);
88  m_session->LoadSolverInfo("UpwindType", riemName, "Upwind");
91  riemName, m_session);
92  m_riemannSolver->SetScalar(
94 
95  m_advObject->SetRiemannSolver(m_riemannSolver);
96  m_advObject->InitObject(m_session, m_fields);
97  break;
98  }
99  // Continuous field
102  {
103  string advName;
104  m_session->LoadSolverInfo("AdvectionType", advName,
105  "NonConservative");
107  advName, advName);
109  this);
110  break;
111  }
112  default:
113  {
114  ASSERTL0(false, "Unsupported projection type.");
115  break;
116  }
117  }
118 }
119 
120 /**
121  * @brief Get the normal velocity
122  */
124 {
125  // Number of trace (interface) points
126  int nTracePts = GetTraceNpoints();
127 
128  // Auxiliary variable to compute the normal velocity
129  Array<OneD, NekDouble> tmp(nTracePts);
130 
131  // Reset the normal velocity
132  Vmath::Zero(nTracePts, m_traceVn, 1);
133 
134  for (int i = 0; i < m_velocity.size(); ++i)
135  {
136  m_fields[0]->ExtractTracePhys(m_velocity[i], tmp);
137 
138  Vmath::Vvtvp(nTracePts, m_traceNormals[i], 1, tmp, 1, m_traceVn, 1,
139  m_traceVn, 1);
140  }
141 
142  return m_traceVn;
143 }
144 
146 {
147 }
148 
150 {
151 }
152 
154 {
155  int nvariables = 1;
156  int dofs = GetNcoeffs();
157  // bool UseContCoeffs = false;
158 
159  Array<OneD, Array<OneD, NekDouble>> inarray(nvariables);
160  Array<OneD, Array<OneD, NekDouble>> tmp(nvariables);
161  Array<OneD, Array<OneD, NekDouble>> outarray(nvariables);
162  Array<OneD, Array<OneD, NekDouble>> WeakAdv(nvariables);
163 
164  int npoints = GetNpoints();
165  int ncoeffs = GetNcoeffs();
166 
167  switch (m_projectionType)
168  {
170  {
171  dofs = ncoeffs;
172  break;
173  }
176  {
177  // dofs = GetContNcoeffs();
178  // UseContCoeffs = true;
179  break;
180  }
181  }
182 
183  cout << endl;
184  cout << "Num Phys Points = " << npoints << endl; // phisical points
185  cout << "Num Coeffs = " << ncoeffs << endl; //
186  cout << "Num Cont Coeffs = " << dofs << endl;
187 
188  inarray[0] = Array<OneD, NekDouble>(npoints, 0.0);
189  outarray[0] = Array<OneD, NekDouble>(npoints, 0.0);
190  tmp[0] = Array<OneD, NekDouble>(npoints, 0.0);
191 
192  WeakAdv[0] = Array<OneD, NekDouble>(ncoeffs, 0.0);
193  Array<OneD, NekDouble> MATRIX(npoints * npoints, 0.0);
194 
195  for (int j = 0; j < npoints; j++)
196  {
197 
198  inarray[0][j] = 1.0;
199 
200  /// Feeding the weak Advection oprator with a vector (inarray)
201  /// Looping on inarray and changing the position of the only non-zero
202  /// entry we simulate the multiplication by the identity matrix. The
203  /// results stored in outarray is one of the columns of the weak
204  /// advection oprators which are then stored in MATRIX for the futher
205  /// eigenvalues calculation.
206  m_advObject->Advect(nvariables, m_fields, m_velocity, inarray, outarray,
207  0.0);
208  Vmath::Neg(npoints, outarray[0], 1);
209  switch (m_projectionType)
210  {
212  {
213  break;
214  }
217  {
218  for (int i = 0; i < nvariables; ++i)
219  {
220  // m_fields[i]->MultiplyByInvMassMatrix(WeakAdv[i],WeakAdv[i]);
221  // Projection
222  m_fields[i]->FwdTrans(outarray[i], WeakAdv[i]);
223 
224  m_fields[i]->BwdTrans(WeakAdv[i], outarray[i]);
225  }
226  break;
227  }
228  }
229 
230  /// The result is stored in outarray (is the j-th columns of the weak
231  /// advection operator). We now store it in MATRIX(j)
232  Vmath::Vcopy(npoints, &(outarray[0][0]), 1, &(MATRIX[j]), npoints);
233 
234  /// Set the j-th entry of inarray back to zero
235  inarray[0][j] = 0.0;
236  }
237 
238  ////////////////////////////////////////////////////////////////////////////////
239  /// Calulating the eigenvalues of the weak advection operator stored in
240  /// (MATRIX) using Lapack routines
241 
242  char jobvl = 'N';
243  char jobvr = 'N';
244  int info = 0, lwork = 3 * npoints;
245  NekDouble dum;
246 
247  Array<OneD, NekDouble> EIG_R(npoints);
248  Array<OneD, NekDouble> EIG_I(npoints);
249 
250  Array<OneD, NekDouble> work(lwork);
251 
252  Lapack::Dgeev(jobvl, jobvr, npoints, MATRIX.get(), npoints, EIG_R.get(),
253  EIG_I.get(), &dum, 1, &dum, 1, &work[0], lwork, info);
254 
255  ////////////////////////////////////////////////////////
256  // Print Matrix
257  FILE *mFile;
258 
259  mFile = fopen("WeakAdvMatrix.txt", "w");
260  for (int j = 0; j < npoints; j++)
261  {
262  for (int k = 0; k < npoints; k++)
263  {
264  fprintf(mFile, "%e ", MATRIX[j * npoints + k]);
265  }
266  fprintf(mFile, "\n");
267  }
268  fclose(mFile);
269 
270  ////////////////////////////////////////////////////////
271  // Output of the EigenValues
272  FILE *pFile;
273 
274  pFile = fopen("Eigenvalues.txt", "w");
275  for (int j = 0; j < npoints; j++)
276  {
277  fprintf(pFile, "%e %e\n", EIG_R[j], EIG_I[j]);
278  }
279  fclose(pFile);
280 
281  cout << "\nEigenvalues : " << endl;
282  for (int j = 0; j < npoints; j++)
283  {
284  cout << EIG_R[j] << "\t" << EIG_I[j] << endl;
285  }
286  cout << endl;
287 }
288 
290  const Array<OneD, Array<OneD, NekDouble>> &physfield,
292 {
293  ASSERTL1(flux[0].size() == m_velocity.size(),
294  "Dimension of flux array and velocity array do not match");
295 
296  int nq = physfield[0].size();
297 
298  for (int i = 0; i < flux.size(); ++i)
299  {
300  for (int j = 0; j < flux[0].size(); ++j)
301  {
302  Vmath::Vmul(nq, physfield[i], 1, m_velocity[j], 1, flux[i][j], 1);
303  }
304  }
305 }
306 } // namespace Nektar
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:249
virtual void v_InitObject(bool DeclareFields=true) override
Initialisation object for EquationSystem.
virtual void v_DoInitialise() override
Virtual function for initialisation implementation.
void GetFluxVector(const Array< OneD, Array< OneD, NekDouble >> &physfield, Array< OneD, Array< OneD, Array< OneD, NekDouble >>> &flux)
SolverUtils::RiemannSolverSharedPtr m_riemannSolver
Array< OneD, NekDouble > & GetNormalVelocity()
Get the normal velocity.
Array< OneD, Array< OneD, NekDouble > > m_velocity
SolverUtils::AdvectionSharedPtr m_advObject
Array< OneD, NekDouble > m_traceVn
virtual void v_DoSolve() override
Virtual function for solve implementation.
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:198
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:144
A base class for describing how to solve specific equations.
int m_spacedim
Spatial dimension (>= expansion dim).
SOLVER_UTILS_EXPORT int GetTraceNpoints()
Array< OneD, MultiRegions::ExpListSharedPtr > m_fields
Array holding all dependent variables.
virtual SOLVER_UTILS_EXPORT void v_InitObject(bool DeclareFeld=true)
Initialisation object for EquationSystem.
LibUtilities::SessionReaderSharedPtr m_session
The session reader.
Array< OneD, Array< OneD, NekDouble > > m_traceNormals
Array holding trace normals for DG simulations in the forwards direction.
SOLVER_UTILS_EXPORT int GetNpoints()
SOLVER_UTILS_EXPORT int GetNcoeffs()
enum MultiRegions::ProjectionType m_projectionType
Type of projection; e.g continuous or discontinuous.
SOLVER_UTILS_EXPORT SessionFunctionSharedPtr GetFunction(std::string name, const MultiRegions::ExpListSharedPtr &field=MultiRegions::NullExpListSharedPtr, bool cache=false)
Get a SessionFunction by name.
static void Dgeev(const char &uplo, const char &lrev, const int &n, const double *a, const int &lda, double *wr, double *wi, double *rev, const int &ldr, double *lev, const int &ldv, double *work, const int &lwork, int &info)
Solve general real matrix eigenproblem.
Definition: Lapack.hpp:348
std::shared_ptr< SessionReader > SessionReaderSharedPtr
AdvectionFactory & GetAdvectionFactory()
Gets the factory for initialising advection objects.
Definition: Advection.cpp:47
EquationSystemFactory & GetEquationSystemFactory()
RiemannSolverFactory & GetRiemannSolverFactory()
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:172
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
double NekDouble
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.cpp:209
void Neg(int n, T *x, const int incx)
Negate x = -x.
Definition: Vmath.cpp:518
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.cpp:574
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:492
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1255