Nektar++
VelocityCorrectionScheme.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: VelocityCorrectionScheme.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: Velocity Correction Scheme for the Incompressible
32 // Navier Stokes equations
33 //
34 ///////////////////////////////////////////////////////////////////////////////
35 
40 #include <MultiRegions/ContField.h>
42 #include <SolverUtils/Core/Misc.h>
43 
44 #include <boost/algorithm/string.hpp>
45 
46 using namespace std;
47 
48 namespace Nektar
49 {
50 using namespace MultiRegions;
51 
52 string VelocityCorrectionScheme::className =
54  "VelocityCorrectionScheme", VelocityCorrectionScheme::create);
55 
56 /**
57  * Constructor. Creates ...
58  *
59  * \param
60  * \param
61  */
62 VelocityCorrectionScheme::VelocityCorrectionScheme(
65  : UnsteadySystem(pSession, pGraph), IncNavierStokes(pSession, pGraph),
66  m_varCoeffLap(StdRegions::NullVarCoeffMap)
67 {
68 }
69 
71 {
72  int n;
73 
74  IncNavierStokes::v_InitObject(DeclareField);
75  m_explicitDiffusion = false;
76 
77  // Set m_pressure to point to last field of m_fields;
78  if (boost::iequals(m_session->GetVariable(m_fields.size() - 1), "p"))
79  {
80  m_nConvectiveFields = m_fields.size() - 1;
82  }
83  else
84  {
85  ASSERTL0(false, "Need to set up pressure field definition");
86  }
87 
88  // Determine diffusion coefficients for each field
90  for (n = 0; n < m_nConvectiveFields; ++n)
91  {
92  std::string varName = m_session->GetVariable(n);
93  if (m_session->DefinesFunction("DiffusionCoefficient", varName))
94  {
96  m_session->GetFunction("DiffusionCoefficient", varName);
97  m_diffCoeff[n] = ffunc->Evaluate();
98  }
99  }
100 
101  // Integrate only the convective fields
102  for (n = 0; n < m_nConvectiveFields; ++n)
103  {
104  m_intVariables.push_back(n);
105  }
106 
108  SetUpSVV();
109 
110  // check to see if it is explicity turned off
111  m_session->MatchSolverInfo("GJPStabilisation", "False",
112  m_useGJPStabilisation, true);
113 
114  // if GJPStabilisation set to False bool will be true and
115  // if not false so negate/revese bool
117 
118  m_session->MatchSolverInfo("GJPNormalVelocity", "True", m_useGJPNormalVel,
119  false);
120 
121  if (m_useGJPNormalVel)
122  {
123  ASSERTL0(boost::iequals(m_session->GetSolverInfo("GJPStabilisation"),
124  "Explicit"),
125  "Can only specify GJPNormalVelocity with"
126  " GJPStabilisation set to Explicit currently");
127  }
128 
129  m_session->LoadParameter("GJPJumpScale", m_GJPJumpScale, 1.0);
130 
131  m_session->MatchSolverInfo("SmoothAdvection", "True", m_SmoothAdvection,
132  false);
133 
134  // set explicit time-intregration class operators
137 
138  // set implicit time-intregration class operators
141 
142  // Set up bits for flowrate.
143  m_session->LoadParameter("Flowrate", m_flowrate, 0.0);
144  m_session->LoadParameter("IO_FlowSteps", m_flowrateSteps, 0);
145 }
146 
148 {
149  // creation of the extrapolation object
152  {
153  std::string vExtrapolation = v_GetExtrapolateStr();
154  if (m_session->DefinesSolverInfo("Extrapolation"))
155  {
156  vExtrapolation = v_GetSubSteppingExtrapolateStr(
157  m_session->GetSolverInfo("Extrapolation"));
158  }
160  vExtrapolation, m_session, m_fields, m_pressure, m_velocity,
161  m_advObject);
162 
163  m_extrapolation->SetForcing(m_forcing);
164  m_extrapolation->SubSteppingTimeIntegration(m_intScheme);
165  m_extrapolation->GenerateHOPBCMap(m_session);
166  }
167 }
168 
169 /**
170  * @brief Set up the Stokes solution used to impose constant flowrate
171  * through a boundary.
172  *
173  * This routine solves a Stokes equation using a unit forcing direction,
174  * specified by the user to be in the desired flow direction. This field can
175  * then be used to correct the end of each timestep to impose a constant
176  * volumetric flow rate through a user-defined boundary.
177  *
178  * There are three modes of operation:
179  *
180  * - Standard two-dimensional or three-dimensional simulations (e.g. pipes
181  * or channels)
182  * - 3DH1D simulations where the forcing is not in the homogeneous
183  * direction (e.g. channel flow, where the y-direction of the 2D mesh
184  * is perpendicular to the wall);
185  * - 3DH1D simulations where the forcing is in the homogeneous direction
186  * (e.g. pipe flow in the z-direction).
187  *
188  * In the first two cases, the user should define:
189  * - the `Flowrate` parameter, which dictates the volumetric flux through
190  * the reference area
191  * - tag a boundary region with the `Flowrate` user-defined type to define
192  * the reference area
193  * - define a `FlowrateForce` function with components `ForceX`, `ForceY`
194  * and `ForceZ` that defines a unit forcing in the appropriate direction.
195  *
196  * In the latter case, the user should define only the `Flowrate`; the
197  * reference area is taken to be the homogeneous plane and the force is
198  * assumed to be the unit z-vector \f$ \hat{e}_z \f$.
199  *
200  * This routine solves a single timestep of the Stokes problem
201  * (premultiplied by the backwards difference coefficient):
202  *
203  * \f[ \frac{\partial\mathbf{u}}{\partial t} = -\nabla p +
204  * \nu\nabla^2\mathbf{u} + \mathbf{f} \f]
205  *
206  * with a zero initial condition to obtain a field \f$ \mathbf{u}_s \f$. The
207  * flowrate is then corrected at each timestep \f$ n \f$ by adding the
208  * correction \f$ \alpha\mathbf{u}_s \f$ where
209  *
210  * \f[ \alpha = \frac{\overline{Q} - Q(\mathbf{u^n})}{Q(\mathbf{u}_s)} \f]
211  *
212  * where \f$ Q(\cdot)\f$ is the volumetric flux through the appropriate
213  * surface or line, which is implemented in
214  * VelocityCorrectionScheme::MeasureFlowrate. For more details, see chapter
215  * 3.2 of the thesis of D. Moxey (University of Warwick, 2011).
216  */
218 {
219  m_flowrateBndID = -1;
220  m_flowrateArea = 0.0;
221 
223  m_fields[0]->GetBndConditions();
224 
225  std::string forces[] = {"X", "Y", "Z"};
226  Array<OneD, NekDouble> flowrateForce(m_spacedim, 0.0);
227 
228  // Set up flowrate forces.
229  bool defined = true;
230  for (int i = 0; i < m_spacedim; ++i)
231  {
232  std::string varName = std::string("Force") + forces[i];
233  defined = m_session->DefinesFunction("FlowrateForce", varName);
234 
235  if (!defined && m_HomogeneousType == eHomogeneous1D)
236  {
237  break;
238  }
239 
240  ASSERTL0(defined,
241  "A 'FlowrateForce' function must defined with components "
242  "[ForceX, ...] to define direction of flowrate forcing");
243 
245  m_session->GetFunction("FlowrateForce", varName);
246  flowrateForce[i] = ffunc->Evaluate();
247  }
248 
249  // Define flag for case with homogeneous expansion and forcing not in the
250  // z-direction
251  m_homd1DFlowinPlane = false;
252  if (defined && m_HomogeneousType == eHomogeneous1D)
253  {
254  m_homd1DFlowinPlane = true;
255  }
256 
257  // For 3DH1D simulations, if force isn't defined then assume in
258  // z-direction.
259  if (!defined)
260  {
261  flowrateForce[2] = 1.0;
262  }
263 
264  // Find the boundary condition that is tagged as the flowrate boundary.
265  for (size_t i = 0; i < bcs.size(); ++i)
266  {
267  if (boost::iequals(bcs[i]->GetUserDefined(), "Flowrate"))
268  {
269  m_flowrateBndID = i;
270  break;
271  }
272  }
273 
274  int tmpBr = m_flowrateBndID;
275  m_comm->AllReduce(tmpBr, LibUtilities::ReduceMax);
276  ASSERTL0(tmpBr >= 0 || m_HomogeneousType == eHomogeneous1D,
277  "One boundary region must be marked using the 'Flowrate' "
278  "user-defined type to monitor the volumetric flowrate.");
279 
280  // Extract an appropriate expansion list to represents the boundary.
281  if (m_flowrateBndID >= 0)
282  {
283  // For a boundary, extract the boundary itself.
284  m_flowrateBnd = m_fields[0]->GetBndCondExpansions()[m_flowrateBndID];
285  }
287  {
288  // For 3DH1D simulations with no force specified, find the mean
289  // (0th) plane.
290  Array<OneD, unsigned int> zIDs = m_fields[0]->GetZIDs();
291  int tmpId = -1;
292 
293  for (size_t i = 0; i < zIDs.size(); ++i)
294  {
295  if (zIDs[i] == 0)
296  {
297  tmpId = i;
298  break;
299  }
300  }
301 
302  ASSERTL1(tmpId <= 0, "Should be either at location 0 or -1 if not "
303  "found");
304 
305  if (tmpId != -1)
306  {
307  m_flowrateBnd = m_fields[0]->GetPlane(tmpId);
308  }
309  }
310 
311  // At this point, some processors may not have m_flowrateBnd
312  // set if they don't contain the appropriate boundary. To
313  // calculate the area, we integrate 1.0 over the boundary
314  // (which has been set up with the appropriate subcommunicator
315  // to avoid deadlock), and then communicate this to the other
316  // processors with an AllReduce.
317  if (m_flowrateBnd)
318  {
319  Array<OneD, NekDouble> inArea(m_flowrateBnd->GetNpoints(), 1.0);
320  m_flowrateArea = m_flowrateBnd->Integral(inArea);
321  }
323 
324  // In homogeneous case with forcing not aligned to the z-direction,
325  // redefine m_flowrateBnd so it is a 1D expansion
328  {
329  // For 3DH1D simulations with no force specified, find the mean
330  // (0th) plane.
331  Array<OneD, unsigned int> zIDs = m_fields[0]->GetZIDs();
332  m_planeID = -1;
333 
334  for (size_t i = 0; i < zIDs.size(); ++i)
335  {
336  if (zIDs[i] == 0)
337  {
338  m_planeID = i;
339  break;
340  }
341  }
342 
343  ASSERTL1(m_planeID <= 0, "Should be either at location 0 or -1 "
344  "if not found");
345 
346  if (m_planeID != -1)
347  {
348  m_flowrateBnd =
349  m_fields[0]->GetBndCondExpansions()[m_flowrateBndID]->GetPlane(
350  m_planeID);
351  }
352  }
353 
354  // Set up some storage for the Stokes solution (to be stored in
355  // m_flowrateStokes) and its initial condition (inTmp), which holds the
356  // unit forcing.
357  int nqTot = m_fields[0]->GetNpoints();
360 
361  for (int i = 0; i < m_spacedim; ++i)
362  {
363  inTmp[i] = Array<OneD, NekDouble>(nqTot, flowrateForce[i] * aii_dt);
364  m_flowrateStokes[i] = Array<OneD, NekDouble>(nqTot, 0.0);
365 
367  {
368  Array<OneD, NekDouble> inTmp2(nqTot);
369  m_fields[i]->HomogeneousFwdTrans(nqTot, inTmp[i], inTmp2);
370  m_fields[i]->SetWaveSpace(true);
371  inTmp[i] = inTmp2;
372  }
373 
374  Vmath::Zero(m_fields[i]->GetNcoeffs(), m_fields[i]->UpdateCoeffs(), 1);
375  }
376 
377  // Create temporary extrapolation object to avoid issues with
378  // m_extrapolation for HOPBCs using higher order timestepping schemes.
379  // Zero pressure BCs in Neumann boundaries that may have been
380  // set in the advection step.
382  m_pressure->GetBndConditions();
384  m_pressure->GetBndCondExpansions();
385  for (size_t n = 0; n < PBndConds.size(); ++n)
386  {
387  if (PBndConds[n]->GetBoundaryConditionType() ==
389  {
390  Vmath::Zero(PBndExp[n]->GetNcoeffs(), PBndExp[n]->UpdateCoeffs(),
391  1);
392  }
393  }
394 
395  // Finally, calculate the solution and the flux of the Stokes
396  // solution. We set m_greenFlux to maximum numeric limit, which signals
397  // to SolveUnsteadyStokesSystem that we don't need to apply a flowrate
398  // force.
399  m_greenFlux = numeric_limits<NekDouble>::max();
400  m_flowrateAiidt = aii_dt;
401 
402  // Save the number of convective field in case it is not set
403  // to spacedim. Only need velocity components for stokes forcing
404  int SaveNConvectiveFields = m_nConvectiveFields;
406  SolveUnsteadyStokesSystem(inTmp, m_flowrateStokes, 0.0, aii_dt);
407  m_nConvectiveFields = SaveNConvectiveFields;
409 
410  // If the user specified IO_FlowSteps, open a handle to store output.
411  if (m_comm->GetRank() == 0 && m_flowrateSteps &&
412  !m_flowrateStream.is_open())
413  {
414  std::string filename = m_session->GetSessionName();
415  filename += ".prs";
416  m_flowrateStream.open(filename.c_str());
417  m_flowrateStream.setf(ios::scientific, ios::floatfield);
418  m_flowrateStream << "# step time dP" << endl
419  << "# -------------------------------------------"
420  << endl;
421  }
422 
423  // Replace pressure BCs with those evaluated from advection step
424  m_extrapolation->CopyPressureHBCsToPbndExp();
425 }
426 
427 /**
428  * @brief Measure the volumetric flow rate through the volumetric flow rate
429  * reference surface.
430  *
431  * This routine computes the volumetric flow rate
432  *
433  * \f[
434  * Q(\mathbf{u}) = \frac{1}{\mu(R)} \int_R \mathbf{u} \cdot d\mathbf{s}
435  * \f]
436  *
437  * through the boundary region \f$ R \f$.
438  */
440  const Array<OneD, Array<OneD, NekDouble>> &inarray)
441 {
442  NekDouble flowrate = 0.0;
443 
444  if (m_flowrateBnd && m_flowrateBndID >= 0)
445  {
446  // If we're an actual boundary, calculate the vector flux through
447  // the boundary.
449 
450  if (!m_homd1DFlowinPlane)
451  {
452  // General case
453  for (int i = 0; i < m_spacedim; ++i)
454  {
455  m_fields[i]->ExtractPhysToBnd(m_flowrateBndID, inarray[i],
456  boundary[i]);
457  }
458  flowrate = m_flowrateBnd->VectorFlux(boundary);
459  }
460  else if (m_planeID == 0)
461  {
462  // Homogeneous with forcing in plane. Calculate flux only on
463  // the meanmode - calculateFlux necessary for hybrid
464  // parallelisation.
465  for (int i = 0; i < m_spacedim; ++i)
466  {
467  m_fields[i]->GetPlane(m_planeID)->ExtractPhysToBnd(
468  m_flowrateBndID, inarray[i], boundary[i]);
469  }
470 
471  // the flowrate is calculated on the mean mode so it needs to be
472  // multiplied by LZ to be consistent with the general case.
473  flowrate = m_flowrateBnd->VectorFlux(boundary) *
474  m_session->GetParameter("LZ");
475  }
476  }
477  else if (m_flowrateBnd && !m_homd1DFlowinPlane)
478  {
479  // 3DH1D case with no Flowrate boundary defined: compute flux
480  // through the zero-th (mean) plane.
481  flowrate = m_flowrateBnd->Integral(inarray[2]);
482  }
483 
484  // Communication to obtain the total flowrate
486  {
487  m_comm->GetColumnComm()->AllReduce(flowrate, LibUtilities::ReduceSum);
488  }
489  else
490  {
491  m_comm->GetSpaceComm()->AllReduce(flowrate, LibUtilities::ReduceSum);
492  }
493  return flowrate / m_flowrateArea;
494 }
495 
497 {
498  if (m_flowrateSteps > 0)
499  {
500  if (m_comm->GetRank() == 0 && (step + 1) % m_flowrateSteps == 0)
501  {
502  m_flowrateStream << setw(8) << step << setw(16) << m_time
503  << setw(16) << m_alpha << endl;
504  }
505  }
506 
508 }
509 
510 /**
511  * Destructor
512  */
514 {
515 }
516 
517 /**
518  *
519  */
521 {
523  SolverUtils::AddSummaryItem(s, "Splitting Scheme",
524  "Velocity correction (strong press. form)");
525 
526  if (m_extrapolation->GetSubStepName().size())
527  {
528  SolverUtils::AddSummaryItem(s, "Substepping",
529  m_extrapolation->GetSubStepName());
530  }
531 
532  string dealias = m_homogen_dealiasing ? "Homogeneous1D" : "";
534  {
535  dealias += (dealias == "" ? "" : " + ") + string("spectral/hp");
536  }
537  if (dealias != "")
538  {
539  SolverUtils::AddSummaryItem(s, "Dealiasing", dealias);
540  }
541 
542  string smoothing = m_useSpecVanVisc ? "spectral/hp" : "";
543  if (smoothing != "")
544  {
546  {
548  s, "Smoothing-SpecHP",
549  "SVV (" + smoothing + " Exp Kernel(cut-off = " +
550  boost::lexical_cast<string>(m_sVVCutoffRatio) +
551  ", diff coeff = " +
552  boost::lexical_cast<string>(m_sVVDiffCoeff) + "))");
553  }
554  else
555  {
556  if (m_IsSVVPowerKernel)
557  {
559  s, "Smoothing-SpecHP",
560  "SVV (" + smoothing + " Power Kernel (Power ratio =" +
561  boost::lexical_cast<string>(m_sVVCutoffRatio) +
562  ", diff coeff = " +
563  boost::lexical_cast<string>(m_sVVDiffCoeff) +
564  "*Uh/p))");
565  }
566  else
567  {
569  s, "Smoothing-SpecHP",
570  "SVV (" + smoothing + " DG Kernel (diff coeff = " +
571  boost::lexical_cast<string>(m_sVVDiffCoeff) +
572  "*Uh/p))");
573  }
574  }
575  }
576 
578  {
580  s, "Smoothing-Homo1D",
581  "SVV (Homogeneous1D - Exp Kernel(cut-off = " +
582  boost::lexical_cast<string>(m_sVVCutoffRatioHomo1D) +
583  ", diff coeff = " +
584  boost::lexical_cast<string>(m_sVVDiffCoeffHomo1D) + "))");
585  }
586 
588  {
590  s, "GJP Stab. Impl. ",
591  m_session->GetSolverInfo("GJPStabilisation"));
592  SolverUtils::AddSummaryItem(s, "GJP Stab. JumpScale", m_GJPJumpScale);
593 
594  if (boost::iequals(m_session->GetSolverInfo("GJPStabilisation"),
595  "Explicit"))
596  {
598  s, "GJP Normal Velocity",
599  m_session->GetSolverInfo("GJPNormalVelocity"));
600  }
601  }
602 }
603 
604 /**
605  *
606  */
608 {
610 
611  for (int i = 0; i < m_nConvectiveFields; ++i)
612  {
614  }
615 
616  m_flowrateAiidt = 0.0;
617 
619 
620  // Set up Field Meta Data for output files
621  m_fieldMetaDataMap["Kinvis"] = boost::lexical_cast<std::string>(m_kinvis);
622  m_fieldMetaDataMap["TimeStep"] =
623  boost::lexical_cast<std::string>(m_timestep);
624 
625  // set boundary conditions here so that any normal component
626  // correction are imposed before they are imposed on initial
627  // field below
629 
630  // Ensure the initial conditions have correct BCs
631  for (size_t i = 0; i < m_fields.size(); ++i)
632  {
633  m_fields[i]->ImposeDirichletConditions(m_fields[i]->UpdateCoeffs());
634  m_fields[i]->LocalToGlobal();
635  m_fields[i]->GlobalToLocal();
636  m_fields[i]->BwdTrans(m_fields[i]->GetCoeffs(),
637  m_fields[i]->UpdatePhys());
638  }
639 }
640 
641 /**
642  *
643  */
645 {
646  size_t nfields = m_fields.size() - 1;
647  for (size_t k = 0; k < nfields; ++k)
648  {
649  // Backward Transformation in physical space for time evolution
650  m_fields[k]->BwdTrans(m_fields[k]->GetCoeffs(),
651  m_fields[k]->UpdatePhys());
652  }
653 }
654 
655 /**
656  *
657  */
659 {
660 
661  size_t nfields = m_fields.size() - 1;
662  for (size_t k = 0; k < nfields; ++k)
663  {
664  // Forward Transformation in physical space for time evolution
665  m_fields[k]->FwdTransLocalElmt(m_fields[k]->GetPhys(),
666  m_fields[k]->UpdateCoeffs());
667  }
668 }
669 
670 /**
671  *
672  */
674 {
675  int vVar = m_session->GetVariables().size();
676  Array<OneD, bool> vChecks(vVar, false);
677  vChecks[vVar - 1] = true;
678  return vChecks;
679 }
680 
681 /**
682  *
683  */
685 {
686  return m_session->GetVariables().size() - 1;
687 }
688 
689 /**
690  * Explicit part of the method - Advection, Forcing + HOPBCs
691  */
693  const Array<OneD, const Array<OneD, NekDouble>> &inarray,
694  Array<OneD, Array<OneD, NekDouble>> &outarray, const NekDouble time)
695 {
696  LibUtilities::Timer timer;
697  timer.Start();
698  EvaluateAdvectionTerms(inarray, outarray, time);
699  timer.Stop();
700  timer.AccumulateRegion("Advection Terms");
701 
702  // Smooth advection
703  if (m_SmoothAdvection)
704  {
705  for (int i = 0; i < m_nConvectiveFields; ++i)
706  {
707  m_pressure->SmoothField(outarray[i]);
708  }
709  }
710 
711  // Add forcing terms
712  for (auto &x : m_forcing)
713  {
714  x->Apply(m_fields, inarray, outarray, time);
715  }
716 
717  // Calculate High-Order pressure boundary conditions
718  timer.Start();
719  m_extrapolation->EvaluatePressureBCs(inarray, outarray, m_kinvis);
720  timer.Stop();
721  timer.AccumulateRegion("Pressure BCs");
722 }
723 
724 /**
725  * Implicit part of the method - Poisson + nConv*Helmholtz
726  */
728  const Array<OneD, const Array<OneD, NekDouble>> &inarray,
729  Array<OneD, Array<OneD, NekDouble>> &outarray, const NekDouble time,
730  const NekDouble aii_Dt)
731 {
732  boost::ignore_unused(time);
733 
734  // Set up flowrate if we're starting for the first time or the value of
735  // aii_Dt has changed.
736  if (m_flowrate > 0.0 && (aii_Dt != m_flowrateAiidt))
737  {
738  SetupFlowrate(aii_Dt);
739  }
740 
741  size_t physTot = m_fields[0]->GetTotPoints();
742 
743  // Substep the pressure boundary condition if using substepping
744  m_extrapolation->SubStepSetPressureBCs(inarray, aii_Dt, m_kinvis);
745 
746  // Set up forcing term for pressure Poisson equation
747  LibUtilities::Timer timer;
748  timer.Start();
749  SetUpPressureForcing(inarray, m_F, aii_Dt);
750  timer.Stop();
751  timer.AccumulateRegion("Pressure Forcing");
752 
753  // Solve Pressure System
754  timer.Start();
755  SolvePressure(m_F[0]);
756  timer.Stop();
757  timer.AccumulateRegion("Pressure Solve");
758 
759  // Set up forcing term for Helmholtz problems
760  timer.Start();
761  SetUpViscousForcing(inarray, m_F, aii_Dt);
762  timer.Stop();
763  timer.AccumulateRegion("Viscous Forcing");
764 
765  // Solve velocity system
766  timer.Start();
767  SolveViscous(m_F, inarray, outarray, aii_Dt);
768  timer.Stop();
769  timer.AccumulateRegion("Viscous Solve");
770 
771  // Apply flowrate correction
772  if (m_flowrate > 0.0 && m_greenFlux != numeric_limits<NekDouble>::max())
773  {
774  NekDouble currentFlux = MeasureFlowrate(outarray);
775  m_alpha = (m_flowrate - currentFlux) / m_greenFlux;
776 
777  for (int i = 0; i < m_spacedim; ++i)
778  {
779  Vmath::Svtvp(physTot, m_alpha, m_flowrateStokes[i], 1, outarray[i],
780  1, outarray[i], 1);
781  // Enusre coeff space is updated for next time step
782  m_fields[i]->FwdTransLocalElmt(outarray[i],
783  m_fields[i]->UpdateCoeffs());
784  // Impsoe symmetry of flow on coeff space (good to enfore
785  // periodicity).
786  m_fields[i]->LocalToGlobal();
787  m_fields[i]->GlobalToLocal();
788  }
789  }
790 }
791 
792 /**
793  * Forcing term for Poisson solver solver
794  */
796  const Array<OneD, const Array<OneD, NekDouble>> &fields,
798 {
799  size_t i;
800  size_t physTot = m_fields[0]->GetTotPoints();
801  size_t nvel = m_velocity.size();
802 
803  m_fields[0]->PhysDeriv(eX, fields[0], Forcing[0]);
804 
805  for (i = 1; i < nvel; ++i)
806  {
807  // Use Forcing[1] as storage since it is not needed for the pressure
808  m_fields[i]->PhysDeriv(DirCartesianMap[i], fields[i], Forcing[1]);
809  Vmath::Vadd(physTot, Forcing[1], 1, Forcing[0], 1, Forcing[0], 1);
810  }
811 
812  Vmath::Smul(physTot, 1.0 / aii_Dt, Forcing[0], 1, Forcing[0], 1);
813 }
814 
815 /**
816  * Forcing term for Helmholtz solver
817  */
819  const Array<OneD, const Array<OneD, NekDouble>> &inarray,
821 {
822  NekDouble aii_dtinv = 1.0 / aii_Dt;
823  size_t phystot = m_fields[0]->GetTotPoints();
824 
825  // Grad p
826  m_pressure->BwdTrans(m_pressure->GetCoeffs(), m_pressure->UpdatePhys());
827 
828  int nvel = m_velocity.size();
829  if (nvel == 2)
830  {
831  m_pressure->PhysDeriv(m_pressure->GetPhys(), Forcing[m_velocity[0]],
832  Forcing[m_velocity[1]]);
833  }
834  else
835  {
836  m_pressure->PhysDeriv(m_pressure->GetPhys(), Forcing[m_velocity[0]],
838  }
839 
840  // zero convective fields.
841  for (int i = nvel; i < m_nConvectiveFields; ++i)
842  {
843  Vmath::Zero(phystot, Forcing[i], 1);
844  }
845 
846  // Subtract inarray/(aii_dt) and divide by kinvis. Kinvis will
847  // need to be updated for the convected fields.
848  for (int i = 0; i < m_nConvectiveFields; ++i)
849  {
850  Blas::Daxpy(phystot, -aii_dtinv, inarray[i], 1, Forcing[i], 1);
851  Blas::Dscal(phystot, 1.0 / m_diffCoeff[i], &(Forcing[i])[0], 1);
852  }
853 }
854 
855 /**
856  * Solve pressure system
857  */
860 {
862  // Setup coefficient for equation
863  factors[StdRegions::eFactorLambda] = 0.0;
864 
865  // Solver Pressure Poisson Equation
866  m_pressure->HelmSolve(Forcing, m_pressure->UpdateCoeffs(), factors);
867 
868  // Add presure to outflow bc if using convective like BCs
869  m_extrapolation->AddPressureToOutflowBCs(m_kinvis);
870 }
871 
872 /**
873  * Solve velocity system
874  */
876  const Array<OneD, const Array<OneD, NekDouble>> &Forcing,
877  const Array<OneD, const Array<OneD, NekDouble>> &inarray,
878  Array<OneD, Array<OneD, NekDouble>> &outarray, const NekDouble aii_Dt)
879 {
883 
884  AppendSVVFactors(factors, varFactorsMap);
885 
886  // Calculate Normal velocity at Trace for GJP explicit stabiliation
887  if (m_useGJPNormalVel)
888  {
890  std::dynamic_pointer_cast<MultiRegions::ContField>(m_fields[0]);
891 
893  cfield->GetGJPForcing();
894 
895  int nTracePts = GJPData->GetNumTracePts();
896  Array<OneD, NekDouble> unorm(nTracePts, 1.0);
897  Array<OneD, NekDouble> Fwd(nTracePts), Bwd(nTracePts);
898  Array<OneD, Array<OneD, NekDouble>> traceNormals =
899  GJPData->GetTraceNormals();
900 
901  m_fields[0]->GetFwdBwdTracePhys(inarray[0], Fwd, Bwd, true, true);
902  Vmath::Vmul(nTracePts, Fwd, 1, traceNormals[0], 1, unorm, 1);
903 
904  // Evaluate u.n on trace
905  for (int f = 1; f < m_fields[0]->GetCoordim(0); ++f)
906  {
907  m_fields[0]->GetFwdBwdTracePhys(inarray[f], Fwd, Bwd, true, true);
908  Vmath::Vvtvp(nTracePts, Fwd, 1, traceNormals[f], 1, unorm, 1, unorm,
909  1);
910  }
911  Vmath::Vabs(nTracePts, unorm, 1, unorm, 1);
912  varCoeffMap[StdRegions::eVarCoeffGJPNormVel] = unorm;
913  }
914 
915  // Solve Helmholtz system and put in Physical space
916  for (int i = 0; i < m_nConvectiveFields; ++i)
917  {
918  // test by adding GJP implicit
920  {
922  }
923 
924  // Setup coefficients for equation
925  factors[StdRegions::eFactorLambda] = 1.0 / aii_Dt / m_diffCoeff[i];
926  m_fields[i]->HelmSolve(Forcing[i], m_fields[i]->UpdateCoeffs(), factors,
927  varCoeffMap, varFactorsMap);
928  m_fields[i]->BwdTrans(m_fields[i]->GetCoeffs(), outarray[i]);
929  }
930 }
931 
933 {
934 
935  m_session->MatchSolverInfo("SpectralVanishingViscosity", "PowerKernel",
936  m_useSpecVanVisc, false);
937 
938  if (m_useSpecVanVisc)
939  {
940  m_useHomo1DSpecVanVisc = true;
941  }
942  else
943  {
944  m_session->MatchSolverInfo("SpectralVanishingViscositySpectralHP",
945  "PowerKernel", m_useSpecVanVisc, false);
946  }
947 
948  if (m_useSpecVanVisc)
949  {
950  m_IsSVVPowerKernel = true;
951  }
952  else
953  {
954  m_session->MatchSolverInfo("SpectralVanishingViscosity", "DGKernel",
955  m_useSpecVanVisc, false);
956  if (m_useSpecVanVisc)
957  {
958  m_useHomo1DSpecVanVisc = true;
959  }
960  else
961  {
962  m_session->MatchSolverInfo("SpectralVanishingViscositySpectralHP",
963  "DGKernel", m_useSpecVanVisc, false);
964  }
965 
966  if (m_useSpecVanVisc)
967  {
968  m_IsSVVPowerKernel = false;
969  }
970  }
971 
972  // set up varcoeff kernel if PowerKernel or DG is specified
973  if (m_useSpecVanVisc)
974  {
975  Array<OneD, Array<OneD, NekDouble>> SVVVelFields =
977  if (m_session->DefinesFunction("SVVVelocityMagnitude"))
978  {
979  if (m_comm->GetRank() == 0)
980  {
981  cout << "Seting up SVV velocity from "
982  "SVVVelocityMagnitude section in session file"
983  << endl;
984  }
985  size_t nvel = m_velocity.size();
986  size_t phystot = m_fields[0]->GetTotPoints();
987  SVVVelFields = Array<OneD, Array<OneD, NekDouble>>(nvel);
988  vector<string> vars;
989  for (size_t i = 0; i < nvel; ++i)
990  {
991  SVVVelFields[i] = Array<OneD, NekDouble>(phystot);
992  vars.push_back(m_session->GetVariable(m_velocity[i]));
993  }
994 
995  // Load up files into m_fields;
996  GetFunction("SVVVelocityMagnitude")->Evaluate(vars, SVVVelFields);
997  }
998 
1000  SVVVarDiffCoeff(1.0, m_svvVarDiffCoeff, SVVVelFields);
1001  m_session->LoadParameter("SVVDiffCoeff", m_sVVDiffCoeff, 1.0);
1002  }
1003  else
1004  {
1006  m_session->LoadParameter("SVVDiffCoeff", m_sVVDiffCoeff, 0.1);
1007  }
1008 
1009  // Load parameters for Spectral Vanishing Viscosity
1010  if (m_useSpecVanVisc == false)
1011  {
1012  m_session->MatchSolverInfo("SpectralVanishingViscosity", "True",
1013  m_useSpecVanVisc, false);
1014  if (m_useSpecVanVisc == false)
1015  {
1016  m_session->MatchSolverInfo("SpectralVanishingViscosity",
1017  "ExpKernel", m_useSpecVanVisc, false);
1018  }
1020 
1021  if (m_useSpecVanVisc == false)
1022  {
1023  m_session->MatchSolverInfo("SpectralVanishingViscositySpectralHP",
1024  "True", m_useSpecVanVisc, false);
1025  if (m_useSpecVanVisc == false)
1026  {
1027  m_session->MatchSolverInfo(
1028  "SpectralVanishingViscositySpectralHP", "ExpKernel",
1029  m_useSpecVanVisc, false);
1030  }
1031  }
1032  }
1033 
1034  // Case of only Homo1D kernel
1035  if (m_session->DefinesSolverInfo("SpectralVanishingViscosityHomo1D"))
1036  {
1037  m_session->MatchSolverInfo("SpectralVanishingViscosityHomo1D", "True",
1038  m_useHomo1DSpecVanVisc, false);
1039  if (m_useHomo1DSpecVanVisc == false)
1040  {
1041  m_session->MatchSolverInfo("SpectralVanishingViscosityHomo1D",
1042  "ExpKernel", m_useHomo1DSpecVanVisc,
1043  false);
1044  }
1045  }
1046 
1047  m_session->LoadParameter("SVVCutoffRatio", m_sVVCutoffRatio, 0.75);
1048  m_session->LoadParameter("SVVCutoffRatioHomo1D", m_sVVCutoffRatioHomo1D,
1050  m_session->LoadParameter("SVVDiffCoeffHomo1D", m_sVVDiffCoeffHomo1D,
1051  m_sVVDiffCoeff);
1052 
1054  {
1055  ASSERTL0(
1056  m_nConvectiveFields > 2,
1057  "Expect to have three velocity fields with homogenous expansion");
1058 
1060  {
1062  planes = m_fields[0]->GetZIDs();
1063 
1064  size_t num_planes = planes.size();
1065  Array<OneD, NekDouble> SVV(num_planes, 0.0);
1066  NekDouble fac;
1067  size_t kmodes = m_fields[0]->GetHomogeneousBasis()->GetNumModes();
1068  size_t pstart;
1069 
1070  pstart = m_sVVCutoffRatioHomo1D * kmodes;
1071 
1072  for (size_t n = 0; n < num_planes; ++n)
1073  {
1074  if (planes[n] > pstart)
1075  {
1076  fac = (NekDouble)((planes[n] - kmodes) *
1077  (planes[n] - kmodes)) /
1078  ((NekDouble)((planes[n] - pstart) *
1079  (planes[n] - pstart)));
1080  SVV[n] = m_sVVDiffCoeffHomo1D * exp(-fac) / m_kinvis;
1081  }
1082  }
1083 
1084  for (size_t i = 0; i < m_velocity.size(); ++i)
1085  {
1086  m_fields[m_velocity[i]]->SetHomo1DSpecVanVisc(SVV);
1087  }
1088  }
1089  }
1090 }
1091 
1093  const NekDouble velmag, Array<OneD, NekDouble> &diffcoeff,
1094  const Array<OneD, Array<OneD, NekDouble>> &vel)
1095 {
1096  size_t phystot = m_fields[0]->GetTotPoints();
1097  size_t nel = m_fields[0]->GetNumElmts();
1098  size_t nvel, cnt;
1099 
1101 
1102  Vmath::Fill(nel, velmag, diffcoeff, 1);
1103 
1104  if (vel != NullNekDoubleArrayOfArray)
1105  {
1106  Array<OneD, NekDouble> Velmag(phystot);
1107  nvel = vel.size();
1108  // calculate magnitude of v
1109  Vmath::Vmul(phystot, vel[0], 1, vel[0], 1, Velmag, 1);
1110  for (size_t n = 1; n < nvel; ++n)
1111  {
1112  Vmath::Vvtvp(phystot, vel[n], 1, vel[n], 1, Velmag, 1, Velmag, 1);
1113  }
1114  Vmath::Vsqrt(phystot, Velmag, 1, Velmag, 1);
1115 
1116  cnt = 0;
1118  // calculate mean value of vel mag.
1119  for (size_t i = 0; i < nel; ++i)
1120  {
1121  size_t nq = m_fields[0]->GetExp(i)->GetTotPoints();
1122  tmp = Velmag + cnt;
1123  diffcoeff[i] = m_fields[0]->GetExp(i)->Integral(tmp);
1124  Vmath::Fill(nq, 1.0, tmp, 1);
1125  NekDouble area = m_fields[0]->GetExp(i)->Integral(tmp);
1126  diffcoeff[i] = diffcoeff[i] / area;
1127  cnt += nq;
1128  }
1129  }
1130  else
1131  {
1132  nvel = m_expdim;
1133  }
1134 
1135  for (size_t e = 0; e < nel; e++)
1136  {
1137  LocalRegions::ExpansionSharedPtr exp = m_fields[0]->GetExp(e);
1138  NekDouble h = 0;
1139 
1140  // Find maximum length of edge.
1141  size_t nEdge = exp->GetGeom()->GetNumEdges();
1142  for (size_t i = 0; i < nEdge; ++i)
1143  {
1144  h = max(h, exp->GetGeom()->GetEdge(i)->GetVertex(0)->dist(
1145  *(exp->GetGeom()->GetEdge(i)->GetVertex(1))));
1146  }
1147 
1148  int p = 0;
1149  for (int i = 0; i < m_expdim; ++i)
1150  {
1151  p = max(p, exp->GetBasisNumModes(i) - 1);
1152  }
1153 
1154  diffcoeff[e] *= h / p;
1155  }
1156 }
1157 
1159  StdRegions::ConstFactorMap &factors,
1160  MultiRegions::VarFactorsMap &varFactorsMap)
1161 {
1162 
1163  if (m_useSpecVanVisc)
1164  {
1168  {
1169  if (m_IsSVVPowerKernel)
1170  {
1173  }
1174  else
1175  {
1176  varFactorsMap[StdRegions::eFactorSVVDGKerDiffCoeff] =
1178  }
1179  }
1180  }
1181 }
1182 } // 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
This class is the base class for Navier Stokes problems.
void SetBoundaryConditions(NekDouble time)
time dependent boundary conditions updating
MultiRegions::ExpListSharedPtr m_pressure
Pointer to field holding pressure field.
NekDouble m_kinvis
Kinematic viscosity.
bool m_SmoothAdvection
bool to identify if advection term smoothing is requested
virtual void v_InitObject(bool DeclareField=true) override
Init object for UnsteadySystem class.
ExtrapolateSharedPtr m_extrapolation
Array< OneD, int > m_velocity
int which identifies which components of m_fields contains the velocity (u,v,w);
void EvaluateAdvectionTerms(const Array< OneD, const Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, const NekDouble time)
EquationType m_equationType
equation type;
int m_nConvectiveFields
Number of fields to be convected;.
std::vector< SolverUtils::ForcingSharedPtr > m_forcing
Forcing terms.
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
void DefineOdeRhs(FuncPointerT func, ObjectPointerT obj)
void DefineImplicitSolve(FuncPointerT func, ObjectPointerT obj)
void AccumulateRegion(std::string, int iolevel=0)
Accumulate elapsed time for a region.
Definition: Timer.cpp:73
SolverUtils::AdvectionSharedPtr m_advObject
Advection term.
virtual SOLVER_UTILS_EXPORT bool v_PostIntegrate(int step) override
int m_spacedim
Spatial dimension (>= expansion dim).
int m_expdim
Expansion dimension.
LibUtilities::CommSharedPtr m_comm
Communicator.
NekDouble m_timestep
Time step size.
NekDouble m_time
Current time of simulation.
Array< OneD, MultiRegions::ExpListSharedPtr > m_fields
Array holding all dependent variables.
bool m_specHP_dealiasing
Flag to determine if dealisising is usde for the Spectral/hp element discretisation.
LibUtilities::SessionReaderSharedPtr m_session
The session reader.
enum HomogeneousType m_HomogeneousType
bool m_homogen_dealiasing
Flag to determine if dealiasing is used for homogeneous simulations.
SOLVER_UTILS_EXPORT int GetNcoeffs()
LibUtilities::FieldMetaDataMap m_fieldMetaDataMap
Map to identify relevant solver info to dump in output fields.
SOLVER_UTILS_EXPORT SessionFunctionSharedPtr GetFunction(std::string name, const MultiRegions::ExpListSharedPtr &field=MultiRegions::NullExpListSharedPtr, bool cache=false)
Get a SessionFunction by name.
SOLVER_UTILS_EXPORT int GetTotPoints()
Defines a forcing term to be explicitly applied.
Definition: Forcing.h:73
Base class for unsteady solvers.
LibUtilities::TimeIntegrationSchemeOperators m_ode
The time integration scheme operators to use.
LibUtilities::TimeIntegrationSchemeSharedPtr m_intScheme
Wrapper to the time integration scheme.
bool m_explicitDiffusion
Indicates if explicit or implicit treatment of diffusion is used.
virtual SOLVER_UTILS_EXPORT void v_DoInitialise() override
Sets up initial conditions.
virtual SOLVER_UTILS_EXPORT void v_GenerateSummary(SummaryList &s) override
Print a summary of time stepping parameters.
NekDouble m_greenFlux
Flux of the Stokes function solution.
virtual std::string v_GetExtrapolateStr(void)
MultiRegions::ExpListSharedPtr m_flowrateBnd
Flowrate reference surface.
Array< OneD, NekDouble > m_svvVarDiffCoeff
Array of coefficient if power kernel is used in SVV.
virtual void v_TransCoeffToPhys(void) override
Virtual function for transformation to physical space.
void SetUpPressureForcing(const Array< OneD, const Array< OneD, NekDouble >> &fields, Array< OneD, Array< OneD, NekDouble >> &Forcing, const NekDouble aii_Dt)
void EvaluateAdvection_SetPressureBCs(const Array< OneD, const Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, const NekDouble time)
NekDouble m_sVVDiffCoeffHomo1D
Diffusion coefficient of SVV modes in homogeneous 1D Direction.
virtual void v_TransPhysToCoeff(void) override
Virtual function for transformation to coefficient space.
NekDouble m_flowrate
Desired volumetric flowrate.
bool m_IsSVVPowerKernel
Identifier for Power Kernel otherwise DG kernel.
NekDouble MeasureFlowrate(const Array< OneD, Array< OneD, NekDouble >> &inarray)
Measure the volumetric flow rate through the volumetric flow rate reference surface.
virtual bool v_PostIntegrate(int step) override
NekDouble m_sVVCutoffRatio
cutt off ratio from which to start decayhing modes
NekDouble m_sVVDiffCoeff
Diffusion coefficient of SVV modes.
virtual void v_GenerateSummary(SolverUtils::SummaryList &s) override
Print a summary of time stepping parameters.
void SolveUnsteadyStokesSystem(const Array< OneD, const Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, const NekDouble time, const NekDouble a_iixDt)
Array< OneD, Array< OneD, NekDouble > > m_flowrateStokes
Stokes solution used to impose flowrate.
NekDouble m_alpha
Current flowrate correction.
bool m_useGJPStabilisation
bool to identify if GJP semi-implicit is active.
virtual void v_SolvePressure(const Array< OneD, NekDouble > &Forcing)
void SolveViscous(const Array< OneD, const Array< OneD, NekDouble >> &Forcing, const Array< OneD, const Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, const NekDouble aii_Dt)
void SetUpViscousForcing(const Array< OneD, const Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &Forcing, const NekDouble aii_Dt)
Array< OneD, Array< OneD, NekDouble > > m_F
virtual void v_EvaluateAdvection_SetPressureBCs(const Array< OneD, const Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, const NekDouble time)
void SetupFlowrate(NekDouble aii_dt)
Set up the Stokes solution used to impose constant flowrate through a boundary.
bool m_useSpecVanVisc
bool to identify if spectral vanishing viscosity is active.
virtual void v_SetUpViscousForcing(const Array< OneD, const Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &Forcing, const NekDouble aii_Dt)
virtual void v_SetUpPressureForcing(const Array< OneD, const Array< OneD, NekDouble >> &fields, Array< OneD, Array< OneD, NekDouble >> &Forcing, const NekDouble aii_Dt)
void SVVVarDiffCoeff(const NekDouble velmag, Array< OneD, NekDouble > &diffcoeff, const Array< OneD, Array< OneD, NekDouble >> &vel=NullNekDoubleArrayOfArray)
Array< OneD, NekDouble > m_diffCoeff
Diffusion coefficients (will be kinvis for velocities)
int m_flowrateSteps
Interval at which to record flowrate data.
NekDouble m_flowrateArea
Area of the boundary through which we are measuring the flowrate.
std::ofstream m_flowrateStream
Output stream to record flowrate.
virtual void v_InitObject(bool DeclareField=true) override
Init object for UnsteadySystem class.
void AppendSVVFactors(StdRegions::ConstFactorMap &factors, MultiRegions::VarFactorsMap &varFactorsMap)
NekDouble m_flowrateAiidt
Value of aii_dt used to compute Stokes flowrate solution.
virtual void v_SolveViscous(const Array< OneD, const Array< OneD, NekDouble >> &Forcing, const Array< OneD, const Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, const NekDouble aii_Dt)
void SolvePressure(const Array< OneD, NekDouble > &Forcing)
int m_planeID
Plane ID for cases with homogeneous expansion.
bool m_useHomo1DSpecVanVisc
bool to identify if spectral vanishing viscosity is active.
bool m_useGJPNormalVel
bool to identify if GJP normal Velocity should be applied in explicit approach
virtual Array< OneD, bool > v_GetSystemSingularChecks() override
int m_flowrateBndID
Boundary ID of the flowrate reference surface.
virtual void v_DoInitialise(void) override
Sets up initial conditions.
virtual std::string v_GetSubSteppingExtrapolateStr(const std::string &instr)
static void Dscal(const int &n, const double &alpha, double *x, const int &incx)
BLAS level 1: x = alpha x.
Definition: Blas.hpp:168
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:154
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< Equation > EquationSharedPtr
Definition: Equation.h:129
std::shared_ptr< Expansion > ExpansionSharedPtr
Definition: Expansion.h:68
MultiRegions::Direction const DirCartesianMap[]
Definition: ExpList.h:91
static VarFactorsMap NullVarFactorsMap
std::map< StdRegions::ConstFactorType, Array< OneD, NekDouble > > VarFactorsMap
std::shared_ptr< GJPStabilisation > GJPStabilisationSharedPtr
std::shared_ptr< ContField > ContFieldSharedPtr
Definition: ContField.h:289
std::vector< std::pair< std::string, std::string > > SummaryList
Definition: Misc.h:48
EquationSystemFactory & GetEquationSystemFactory()
void AddSummaryItem(SummaryList &l, const std::string &name, const std::string &value)
Adds a summary item to the summary info list.
Definition: Misc.cpp:49
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:172
std::map< ConstFactorType, NekDouble > ConstFactorMap
Definition: StdRegions.hpp:399
static VarCoeffMap NullVarCoeffMap
Definition: StdRegions.hpp:344
std::map< StdRegions::VarCoeffType, VarCoeffEntry > VarCoeffMap
Definition: StdRegions.hpp:343
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
@ eUnsteadyStokes
@ eUnsteadyNavierStokes
static Array< OneD, Array< OneD, NekDouble > > NullNekDoubleArrayOfArray
ExtrapolateFactory & GetExtrapolateFactory()
Definition: Extrapolate.cpp:48
static Array< OneD, NekDouble > NullNekDouble1DArray
double NekDouble
void Vsqrt(int n, const T *x, const int incx, T *y, const int incy)
sqrt y = sqrt(x)
Definition: Vmath.cpp:534
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 Svtvp(int n, const T alpha, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
svtvp (scalar times vector plus vector): z = alpha*x + y
Definition: Vmath.cpp:622
void Vabs(int n, const T *x, const int incx, T *y, const int incy)
vabs: y = |x|
Definition: Vmath.cpp:553
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 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:359
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.cpp:248
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:492
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
Definition: Vmath.cpp:45