Nektar++
IncNavierStokes.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File IncNavierStokes.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: Incompressible Navier Stokes class definition built on
33 // ADRBase class
34 //
35 ///////////////////////////////////////////////////////////////////////////////
36 
37 #include <iomanip>
38 #include <boost/algorithm/string.hpp>
39 
46 
47 namespace Nektar
48 {
49 
50  /**
51  * Constructor. Creates ...
52  *
53  * \param
54  * \param
55  */
57  UnsteadySystem(pSession),
58  AdvectionSystem(pSession),
59  m_subSteppingScheme(false),
60  m_SmoothAdvection(false),
61  m_steadyStateSteps(0)
62  {
63  }
64 
66  {
67  AdvectionSystem::v_InitObject();
68 
69  int i,j;
70  int numfields = m_fields.num_elements();
71  std::string velids[] = {"u","v","w"};
72 
73  // Set up Velocity field to point to the first m_expdim of m_fields;
75 
76  for(i = 0; i < m_spacedim; ++i)
77  {
78  for(j = 0; j < numfields; ++j)
79  {
80  std::string var = m_boundaryConditions->GetVariable(j);
81  if(boost::iequals(velids[i], var))
82  {
83  m_velocity[i] = j;
84  break;
85  }
86 
87  ASSERTL0(j != numfields, "Failed to find field: " + var);
88  }
89  }
90 
91  // Set up equation type enum using kEquationTypeStr
92  for(i = 0; i < (int) eEquationTypeSize; ++i)
93  {
94  bool match;
95  m_session->MatchSolverInfo("EQTYPE",kEquationTypeStr[i],match,false);
96  if(match)
97  {
99  break;
100  }
101  }
102  ASSERTL0(i != eEquationTypeSize,"EQTYPE not found in SOLVERINFO section");
103 
104  // This probably should to into specific implementations
105  // Equation specific Setups
106  switch(m_equationType)
107  {
108  case eSteadyStokes:
109  case eSteadyOseen:
110  case eSteadyNavierStokes:
111  case eSteadyLinearisedNS:
112  break;
114  case eUnsteadyStokes:
115  {
116  m_session->LoadParameter("IO_InfoSteps", m_infosteps, 0);
117  m_session->LoadParameter("IO_CFLSteps", m_cflsteps, 0);
118  m_session->LoadParameter("SteadyStateSteps", m_steadyStateSteps, 0);
119  m_session->LoadParameter("SteadyStateTol", m_steadyStateTol, 1e-6);
120 
121  // check to see if any user defined boundary condition is
122  // indeed implemented
123 
124  for(int n = 0; n < m_fields[0]->GetBndConditions().num_elements(); ++n)
125  {
126  std::string type =m_fields[0]->GetBndConditions()[n]->GetUserDefined();
127  if(!type.empty())
128  // Time Dependent Boundary Condition (if no user
129  // defined then this is empty)
130  ASSERTL0 (boost::iequals(type,"Wall_Forces") ||
131  boost::iequals(type,"TimeDependent") ||
132  boost::iequals(type,"MovingBody") ||
133  boost::iequals(type,"Radiation") ||
134  boost::iequals(type,"I") ||
135  boost::iequals(type,"HOutflow"),
136  "Unknown USERDEFINEDTYPE boundary condition");
137  }
138  }
139  break;
140  case eNoEquationType:
141  default:
142  ASSERTL0(false,"Unknown or undefined equation type");
143  }
144 
145  m_session->LoadParameter("Kinvis", m_kinvis);
146 
147  // Default advection type per solver
148  std::string vConvectiveType;
149  switch(m_equationType)
150  {
151  case eUnsteadyStokes:
152  vConvectiveType = "NoAdvection";
153  break;
155  case eSteadyNavierStokes:
156  vConvectiveType = "Convective";
157  break;
159  vConvectiveType = "Linearised";
160  break;
161  default:
162  break;
163  }
164 
165  // Check if advection type overridden
166  if (m_session->DefinesTag("AdvectiveType") && m_equationType != eUnsteadyStokes)
167  {
168  vConvectiveType = m_session->GetTag("AdvectiveType");
169  }
170 
171  // Initialise advection
172  m_advObject = SolverUtils::GetAdvectionFactory().CreateInstance(vConvectiveType, vConvectiveType);
173  m_advObject->InitObject( m_session, m_fields);
174 
175  // Forcing terms
178 
179  // check to see if any Robin boundary conditions and if so set
180  // up m_field to boundary condition maps;
184 
185  for (i = 0; i < m_fields.num_elements(); ++i)
186  {
187  bool Set = false;
188 
191  int radpts = 0;
192 
193  BndConds = m_fields[i]->GetBndConditions();
194  BndExp = m_fields[i]->GetBndCondExpansions();
195  for(int n = 0; n < BndConds.num_elements(); ++n)
196  {
197  if(boost::iequals(BndConds[n]->GetUserDefined(),"Radiation"))
198  {
199  ASSERTL0(BndConds[n]->GetBoundaryConditionType() == SpatialDomains::eRobin,
200  "Radiation boundary condition must be of type Robin <R>");
201 
202  if(Set == false)
203  {
204  m_fields[i]->GetBoundaryToElmtMap(m_fieldsBCToElmtID[i],m_fieldsBCToTraceID[i]);
205  Set = true;
206  }
207  radpts += BndExp[n]->GetTotPoints();
208  }
209  }
210 
211  m_fieldsRadiationFactor[i] = Array<OneD, NekDouble>(radpts);
212 
213  radpts = 0; // reset to use as a counter
214 
215  for(int n = 0; n < BndConds.num_elements(); ++n)
216  {
217  if(boost::iequals(BndConds[n]->GetUserDefined(),"Radiation"))
218  {
219 
220  int npoints = BndExp[n]->GetNpoints();
221  Array<OneD, NekDouble> x0(npoints,0.0);
222  Array<OneD, NekDouble> x1(npoints,0.0);
223  Array<OneD, NekDouble> x2(npoints,0.0);
224  Array<OneD, NekDouble> tmpArray;
225 
226  BndExp[n]->GetCoords(x0,x1,x2);
227 
228  LibUtilities::Equation coeff =
229  boost::static_pointer_cast<
231  >(BndConds[n])->m_robinPrimitiveCoeff;
232 
233  coeff.Evaluate(x0,x1,x2,m_time,
234  tmpArray = m_fieldsRadiationFactor[i]+ radpts);
235  //Vmath::Neg(npoints,tmpArray = m_fieldsRadiationFactor[i]+ radpts,1);
236  radpts += npoints;
237  }
238  }
239  }
240 
241  // Set up Field Meta Data for output files
242  m_fieldMetaDataMap["Kinvis"] = boost::lexical_cast<std::string>(m_kinvis);
243  m_fieldMetaDataMap["TimeStep"] = boost::lexical_cast<std::string>(m_timestep);
244  }
245 
246  /**
247  * Destructor
248  */
250  {
251  }
252 
253 
254  /**
255  *
256  */
258  Array<OneD, Array<OneD, NekDouble> > &physfield,
260  {
261  ASSERTL1(flux.num_elements() == m_velocity.num_elements(),"Dimension of flux array and velocity array do not match");
262 
263  for(int j = 0; j < flux.num_elements(); ++j)
264  {
265  Vmath::Vmul(GetNpoints(), physfield[i], 1, m_fields[m_velocity[j]]->GetPhys(), 1, flux[j], 1);
266  }
267  }
268 
269  /**
270  * Calcualate numerical fluxes
271  */
273  Array<OneD, Array<OneD, NekDouble> > &numflux)
274  {
275  /// Counter variable
276  int i;
277 
278  /// Number of trace points
279  int nTracePts = GetTraceNpoints();
280 
281  /// Number of spatial dimensions
282  int nDimensions = m_spacedim;
283 
284  /// Forward state array
285  Array<OneD, NekDouble> Fwd(2*nTracePts);
286 
287  /// Backward state array
288  Array<OneD, NekDouble> Bwd = Fwd + nTracePts;
289 
290  /// Normal velocity array
291  Array<OneD, NekDouble> Vn (nTracePts, 0.0);
292 
293  // Extract velocity field along the trace space and multiply by trace normals
294  for(i = 0; i < nDimensions; ++i)
295  {
296  m_fields[0]->ExtractTracePhys(m_fields[m_velocity[i]]->GetPhys(), Fwd);
297  Vmath::Vvtvp(nTracePts, m_traceNormals[i], 1, Fwd, 1, Vn, 1, Vn, 1);
298  }
299 
300  /// Compute the numerical fluxes at the trace points
301  for(i = 0; i < numflux.num_elements(); ++i)
302  {
303  /// Extract forwards/backwards trace spaces
304  m_fields[i]->GetFwdBwdTracePhys(physfield[i], Fwd, Bwd);
305 
306  /// Upwind between elements
307  m_fields[i]->GetTrace()->Upwind(Vn, Fwd, Bwd, numflux[i]);
308 
309  /// Calculate the numerical fluxes multipling Fwd or Bwd
310  /// by the normal advection velocity
311  Vmath::Vmul(nTracePts, numflux[i], 1, Vn, 1, numflux[i], 1);
312  }
313  }
314 
315  /**
316  * Evaluation -N(V) for all fields except pressure using m_velocity
317  */
319  Array<OneD, Array<OneD, NekDouble> > &outarray,
321  {
322  int i;
323  int nqtot = m_fields[0]->GetTotPoints();
324  int VelDim = m_velocity.num_elements();
325  Array<OneD, Array<OneD, NekDouble> > velocity(VelDim);
327 
328  for(i = 0; i < VelDim; ++i)
329  {
330  if(m_fields[i]->GetWaveSpace() && !m_SingleMode && !m_HalfMode)
331  {
332  velocity[i] = Array<OneD, NekDouble>(nqtot,0.0);
333  m_fields[i]->HomogeneousBwdTrans(inarray[m_velocity[i]],velocity[i]);
334  }
335  else
336  {
337  velocity[i] = inarray[m_velocity[i]];
338  }
339  }
340 
341  // Set up Derivative work space;
342  if(wk.num_elements())
343  {
344  ASSERTL0(wk.num_elements() >= nqtot*VelDim,
345  "Workspace is not sufficient");
346  Deriv = wk;
347  }
348  else
349  {
350  Deriv = Array<OneD, NekDouble> (nqtot*VelDim);
351  }
352 
354  velocity, inarray, outarray, m_time);
355  }
356 
357  /**
358  * Time dependent boundary conditions updating
359  */
361  {
362  int i, n;
363  std::string varName;
364  int nvariables = m_fields.num_elements();
365 
366  for (i = 0; i < nvariables; ++i)
367  {
368  for(n = 0; n < m_fields[i]->GetBndConditions().num_elements(); ++n)
369  {
370  if(m_fields[i]->GetBndConditions()[n]->IsTimeDependent() ||
371  m_fields[i]->GetBndConditions()[n]->GetUserDefined() ==
372  "MovingBody")
373  {
374  varName = m_session->GetVariable(i);
375  m_fields[i]->EvaluateBoundaryConditions(time, varName);
376  }
377 
378  }
379 
380  // Set Radiation conditions if required
382  }
383  }
384 
385  /**
386  * Probably should be pushed back into ContField?
387  */
389  {
390  int i,n;
391 
394 
395  BndConds = m_fields[fieldid]->GetBndConditions();
396  BndExp = m_fields[fieldid]->GetBndCondExpansions();
397 
400 
401  int cnt;
402  int elmtid,nq,offset, boundary;
403  Array<OneD, NekDouble> Bvals, U;
404  int cnt1 = 0;
405 
406  for(cnt = n = 0; n < BndConds.num_elements(); ++n)
407  {
408  std::string type = BndConds[n]->GetUserDefined();
409 
410  if((BndConds[n]->GetBoundaryConditionType() == SpatialDomains::eRobin)&&(boost::iequals(type,"Radiation")))
411  {
412  for(i = 0; i < BndExp[n]->GetExpSize(); ++i,cnt++)
413  {
414  elmtid = m_fieldsBCToElmtID[fieldid][cnt];
415  elmt = m_fields[fieldid]->GetExp(elmtid);
416  offset = m_fields[fieldid]->GetPhys_Offset(elmtid);
417 
418  U = m_fields[fieldid]->UpdatePhys() + offset;
419  Bc = BndExp[n]->GetExp(i);
420 
421  boundary = m_fieldsBCToTraceID[fieldid][cnt];
422 
423  // Get edge values and put into ubc
424  nq = Bc->GetTotPoints();
425  Array<OneD, NekDouble> ubc(nq);
426  elmt->GetTracePhysVals(boundary,Bc,U,ubc);
427 
428  Vmath::Vmul(nq,&m_fieldsRadiationFactor[fieldid][cnt1 +
429  BndExp[n]->GetPhys_Offset(i)],1,&ubc[0],1,&ubc[0],1);
430 
431  Bvals = BndExp[n]->UpdateCoeffs()+BndExp[n]->GetCoeff_Offset(i);
432 
433  Bc->IProductWRTBase(ubc,Bvals);
434  }
435  cnt1 += BndExp[n]->GetTotPoints();
436  }
437  else
438  {
439  cnt += BndExp[n]->GetExpSize();
440  }
441  }
442  }
443 
444 
445  /**
446  * Add an additional forcing term programmatically.
447  */
449  {
450  m_forcing.push_back(pForce);
451  }
452 
453 
454  /**
455  * Decide if at a steady state if the discrerte L2 sum of the
456  * coefficients is the same as the previous step to within the
457  * tolerance m_steadyStateTol;
458  */
460  {
461  static NekDouble previousL2 = 0.0;
462  bool returnval = false;
463 
464  NekDouble L2 = 0.0;
465 
466  // calculate L2 discrete summation
467  int ncoeffs = m_fields[0]->GetNcoeffs();
468 
469  for(int i = 0; i < m_fields.num_elements(); ++i)
470  {
471  L2 += Vmath::Dot(ncoeffs,m_fields[i]->GetCoeffs(),1,m_fields[i]->GetCoeffs(),1);
472  }
473 
474  if(fabs(L2-previousL2) < ncoeffs*m_steadyStateTol)
475  {
476  returnval = true;
477  }
478 
479  previousL2 = L2;
480 
481  return returnval;
482  }
483 
484  /**
485  *
486  */
488  {
489  int n_vel = m_velocity.num_elements();
490  int n_element = m_fields[0]->GetExpSize();
491 
492  const Array<OneD, int> ExpOrder = GetNumExpModesPerExp();
493  Array<OneD, int> ExpOrderList (n_element, ExpOrder);
494 
495  const NekDouble cLambda = 0.2; // Spencer book pag. 317
496 
497  Array<OneD, NekDouble> cfl (n_element, 0.0);
498  Array<OneD, NekDouble> stdVelocity(n_element, 0.0);
500 
501  if(m_HomogeneousType == eHomogeneous1D) // just do check on 2D info
502  {
503  velfields = Array<OneD, Array<OneD, NekDouble> >(2);
504 
505  for(int i = 0; i < 2; ++i)
506  {
507  velfields[i] = m_fields[m_velocity[i]]->UpdatePhys();
508  }
509  }
510  else
511  {
512  velfields = Array<OneD, Array<OneD, NekDouble> >(n_vel);
513 
514  for(int i = 0; i < n_vel; ++i)
515  {
516  velfields[i] = m_fields[m_velocity[i]]->UpdatePhys();
517  }
518  }
519 
520  stdVelocity = m_extrapolation->GetMaxStdVelocity(velfields);
521 
522  for(int el = 0; el < n_element; ++el)
523  {
524  cfl[el] = m_timestep*(stdVelocity[el] * cLambda *
525  (ExpOrder[el]-1) * (ExpOrder[el]-1));
526  }
527 
528  return cfl;
529  }
530 
531  /**
532  *
533  */
535  {
536  int n_element = m_fields[0]->GetExpSize();
537 
539 
540  elmtid = Vmath::Imax(n_element,cfl,1);
541  NekDouble CFL,CFL_loc;
542 
543  CFL = CFL_loc = cfl[elmtid];
544  m_comm->AllReduce(CFL,LibUtilities::ReduceMax);
545 
546  // unshuffle elmt id if data is not stored in consecutive order.
547  elmtid = m_fields[0]->GetExp(elmtid)->GetGeom()->GetGlobalID();
548  if(CFL != CFL_loc)
549  {
550  elmtid = -1;
551  }
552 
553  m_comm->AllReduce(elmtid,LibUtilities::ReduceMax);
554 
555  // express element id with respect to plane
557  {
558  elmtid = elmtid%m_fields[0]->GetPlane(0)->GetExpSize();
559  }
560  return CFL;
561  }
562 
563 
564  /**
565  * Perform the extrapolation.
566  */
568  {
569  m_extrapolation->SubStepSaveFields(step);
570  m_extrapolation->SubStepAdvance(m_intSoln,step,m_time);
571  return false;
572  }
573 
574 
575  /**
576  * Estimate CFL and perform steady-state check
577  */
579  {
580  if(m_cflsteps && !((step+1)%m_cflsteps))
581  {
582  int elmtid;
583  NekDouble cfl = GetCFLEstimate(elmtid);
584 
585  if(m_comm->GetRank() == 0)
586  {
587  cout << "CFL (zero plane): "<< cfl << " (in elmt "
588  << elmtid << ")" << endl;
589  }
590  }
591 
592  if(m_steadyStateSteps && step && (!((step+1)%m_steadyStateSteps)))
593  {
594  if(CalcSteadyState() == true)
595  {
596  cout << "Reached Steady State to tolerance "
597  << m_steadyStateTol << endl;
598  return true;
599  }
600  }
601 
602  return false;
603  }
604 } //end of namespace
605 
EquationType m_equationType
equation type;
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:135
bool m_SingleMode
Flag to determine if single homogeneous mode is used.
void SetBoundaryConditions(NekDouble time)
time dependent boundary conditions updating
Array< OneD, Array< OneD, int > > m_fieldsBCToTraceID
Mapping from BCs to Elmt Edge IDs.
tBaseSharedPtr CreateInstance(tKey idKey BOOST_PP_COMMA_IF(MAX_PARAM) BOOST_PP_ENUM_BINARY_PARAMS(MAX_PARAM, tParam, x))
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:162
SolverUtils::AdvectionSharedPtr m_advObject
Advection term.
virtual bool v_PreIntegrate(int step)
NekDouble m_time
Current time of simulation.
void SetRadiationBoundaryForcing(int fieldid)
Set Radiation forcing term.
NekDouble m_kinvis
Kinematic viscosity.
bool CalcSteadyState(void)
evaluate steady state
NekDouble m_timestep
Time step size.
SOLVER_UTILS_EXPORT const Array< OneD, int > GetNumExpModesPerExp()
Array< OneD, int > m_velocity
int which identifies which components of m_fields contains the velocity (u,v,w);
ExtrapolateSharedPtr m_extrapolation
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:428
SOLVER_UTILS_EXPORT typedef boost::shared_ptr< Forcing > ForcingSharedPtr
A shared pointer to an EquationSystem object.
Definition: Forcing.h:51
static SOLVER_UTILS_EXPORT std::vector< ForcingSharedPtr > Load(const LibUtilities::SessionReaderSharedPtr &pSession, const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const unsigned int &pNumForcingFields=0)
Definition: Forcing.cpp:84
virtual bool v_PostIntegrate(int step)
int m_nConvectiveFields
Number of fields to be convected;.
boost::shared_ptr< SessionReader > SessionReaderSharedPtr
Definition: MeshPartition.h:50
int Imax(int n, const T *x, const int incx)
Return the index of the maximum element in x.
Definition: Vmath.cpp:732
LibUtilities::CommSharedPtr m_comm
Communicator.
Array< OneD, Array< OneD, NekDouble > > m_traceNormals
Array holding trace normals for DG simulations in the forwards direction.
Array< OneD, Array< OneD, NekDouble > > m_fieldsRadiationFactor
RHS Factor for Radiation Condition.
int m_cflsteps
dump cfl estimate
std::vector< SolverUtils::ForcingSharedPtr > m_forcing
Forcing terms.
NekDouble Evaluate() const
Definition: Equation.h:102
int m_steadyStateSteps
Check for steady state at step interval.
SpatialDomains::BoundaryConditionsSharedPtr m_boundaryConditions
Pointer to boundary conditions object.
bool m_HalfMode
Flag to determine if half homogeneous mode is used.
int m_spacedim
Spatial dimension (>= expansion dim).
LibUtilities::FieldMetaDataMap m_fieldMetaDataMap
Map to identify relevant solver info to dump in output fields.
AdvectionFactory & GetAdvectionFactory()
Gets the factory for initialising advection objects.
Definition: Advection.cpp:46
double NekDouble
virtual void v_NumericalFlux(Array< OneD, Array< OneD, NekDouble > > &physfield, Array< OneD, Array< OneD, NekDouble > > &numflux)
T Dot(int n, const T *w, const T *x)
vvtvp (vector times vector times vector): z = w*x*y
Definition: Vmath.cpp:869
SOLVER_UTILS_EXPORT int GetPhys_Offset(int n)
SOLVER_UTILS_EXPORT int GetNpoints()
void EvaluateAdvectionTerms(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, Array< OneD, NekDouble > &wk=NullNekDouble1DArray)
void AddForcing(const SolverUtils::ForcingSharedPtr &pForce)
Array< OneD, Array< OneD, int > > m_fieldsBCToElmtID
Mapping from BCs to Elmt IDs.
Array< OneD, MultiRegions::ExpListSharedPtr > m_fields
Array holding all dependent variables.
LibUtilities::SessionReaderSharedPtr m_session
The session reader.
SOLVER_UTILS_EXPORT int GetTraceNpoints()
const std::string kEquationTypeStr[]
int m_infosteps
Number of time steps between outputting status information.
NekDouble m_steadyStateTol
Tolerance to which steady state should be evaluated at.
boost::shared_ptr< StdExpansion > StdExpansionSharedPtr
virtual void v_GetFluxVector(const int i, Array< OneD, Array< OneD, NekDouble > > &physfield, Array< OneD, Array< OneD, NekDouble > > &flux)
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Definition: ErrorUtil.hpp:165
LibUtilities::TimeIntegrationSolutionSharedPtr m_intSoln
virtual void v_InitObject()
Init object for UnsteadySystem class.
virtual int v_GetForceDimension()=0
enum HomogeneousType m_HomogeneousType
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:169
NekDouble GetCFLEstimate(int &elmtid)
Array< OneD, NekDouble > GetElmtCFLVals(void)
IncNavierStokes(const LibUtilities::SessionReaderSharedPtr &pSession)
Constructor.