Nektar++
SmoothedProfileMethod.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: SmoothedProfileMethod.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: Smoothed Profile Method for the Incompressible
33 // Navier Stokes equations
34 ///////////////////////////////////////////////////////////////////////////////
35 
38 #include <MultiRegions/ContField.h>
41 
42 using namespace std;
43 
44 namespace Nektar
45 {
46 using namespace MultiRegions;
47 
48 string SmoothedProfileMethod::className =
50  "SmoothedProfileMethod", SmoothedProfileMethod::create);
51 
52 /**
53  * @brief Construct a new Smoothed Profile Method object
54  *
55  * @param pSession
56  * @param pGraph
57  */
58 SmoothedProfileMethod::SmoothedProfileMethod(
61  : UnsteadySystem(pSession, pGraph),
62  VelocityCorrectionScheme(pSession, pGraph)
63 {
64 }
65 
66 /**
67  * @brief Destroy the Smoothed Profile Method object
68  *
69  */
71 {
72 }
73 
74 void SmoothedProfileMethod::v_InitObject(bool DeclareField)
75 {
77 
78  // Update implicit time-intregration class operators
80  this);
81 
82  // Number of dims as number of velocity vectors
83  size_t nvel = m_velocity.size();
84 
85  // Initialization of correction pressure and shape function
86  switch (nvel)
87  {
88  case 1:
90  {
91  SetUpExpansions<ContField>(nvel);
92  }
93  else if (m_projectionType == eDiscontinuous)
94  {
95  SetUpExpansions<DisContField>(nvel);
96  }
97  break;
98 
99  case 2:
101  {
102  SetUpExpansions<ContField>(nvel);
103  }
104  else if (m_projectionType == eDiscontinuous)
105  {
106  SetUpExpansions<DisContField>(nvel);
107  }
108  break;
109 
110  case 3:
112  {
114  {
115  SetUpExpansions<ContField>(nvel);
116  }
118  {
119  SetUpExpansions<ContField3DHomogeneous1D>(nvel);
120  }
123  {
124  SetUpExpansions<ContField3DHomogeneous2D>(nvel);
125  }
126  }
127  else if (m_projectionType == eDiscontinuous)
128  {
130  {
131  SetUpExpansions<DisContField>(nvel);
132  }
134  {
135  SetUpExpansions<DisContField3DHomogeneous1D>(nvel);
136  }
139  {
140  SetUpExpansions<DisContField3DHomogeneous2D>(nvel);
141  }
142  }
143  break;
144  }
145 
146  // Read 'm_phi' and its velocity
147  ASSERTL0(m_session->DefinesFunction("ShapeFunction"),
148  "ShapeFunction must be defined in the session file.")
149  ReadPhi();
150 
151  // Allocate the vector 'm_up'
152  size_t physTot = m_phi->GetTotPoints();
153  m_velName.push_back("Up");
154  if (nvel > 1)
155  {
156  m_velName.push_back("Vp");
157  }
158  if (nvel == 3)
159  {
160  m_velName.push_back("Wp");
161  }
162 
164  for (size_t i = 0; i < nvel; ++i)
165  {
166  m_up[i] = Array<OneD, NekDouble>(physTot, 0.0);
167  }
168 
169  // Make sure that m_phi and m_up are defined
170  UpdatePhiUp(0.0);
171 
172  // Get the time integration scheme.
174  if (m_session->DefinesTimeIntScheme())
175  {
176  timeInt = m_session->GetTimeIntScheme();
177  }
178  else
179  {
180  timeInt.method = m_session->GetSolverInfo("TimeIntegrationMethod");
181  timeInt.order = timeInt.method.back() - '0';
182 
183  // Remove everything past the IMEX.
184  timeInt.method = timeInt.method.substr(0, 4);
185  }
186 
187  // Select 'm_gamma0' depending on IMEX order
188  ASSERTL0(
189  boost::iequals(timeInt.method, "IMEX") && 1 <= timeInt.order &&
190  timeInt.order <= 4,
191  "The TimeIntegrationMethod scheme must be IMEX with order '1' to '4'.")
192 
193  switch (timeInt.order)
194  {
195  case 1:
196  m_gamma0 = 1.0;
197  break;
198 
199  case 2:
200  m_gamma0 = 3.0 / 2.0;
201  break;
202 
203  case 3:
204  m_gamma0 = 11.0 / 6.0;
205  break;
206 
207  case 4:
208  m_gamma0 = 25.0 / 12.0;
209  break;
210  }
211 
212  // Check if the aeroforces filter is active, negative if inactive
213  m_forcesFilter = -1;
214  for (size_t i = 0; i < m_session->GetFilters().size(); ++i)
215  {
216  if (boost::iequals(m_session->GetFilters()[i].first, "AeroForcesSPM"))
217  {
218  m_forcesFilter = i;
219  break;
220  }
221  }
222 }
223 
224 /**
225  * @brief Generates the summary of the current simulation
226  *
227  * @param s
228  */
230 {
232  SolverUtils::AddSummaryItem(s, "IB formulation",
233  "Smoothed Profile Method (SPM)");
234 }
235 
236 /**
237  * @brief Linear terms due to pressure and visosity are calculated here.
238  * After solving the velocity filed without taking into account the
239  * immersed boundaries, a new correction is applied through the force
240  * \f$f_s\f$:
241  *
242  * \f[ \mathbf{f_s} = \frac{\Phi^{n+1}(\mathbf{u_p}-\mathbf{u^*})}
243  * {\Delta t} \f]
244  *
245  * @param inarray
246  * @param outarray
247  * @param time
248  * @param a_iixDt
249  */
251  const Array<OneD, const Array<OneD, NekDouble>> &inarray,
252  Array<OneD, Array<OneD, NekDouble>> &outarray, const NekDouble time,
253  const NekDouble a_iixDt)
254 {
256  a_iixDt);
257 
258  size_t physTot = m_pressureP->GetNpoints();
259 
260  /* SPM correction of velocity */
261  // Update 'm_phi' and 'm_up' if needed (evaluated at next time step)
262  UpdatePhiUp(time + a_iixDt);
263  // Update calculation of IB forcing 'm_fs'
264  UpdateForcing(outarray, a_iixDt);
265  // Estimate forces only if requested
266  if (m_forcesFilter >= 0)
267  {
268  static_pointer_cast<FilterAeroForcesSPM>(
269  m_filters[m_forcesFilter].second)
270  ->CalculateForces(outarray, m_upPrev, m_phi, time, a_iixDt);
271  }
272  // Set BC conditions for pressure p_p
273  SetUpCorrectionPressure(outarray, m_F);
274  // Solve Poisson equation for pressure p_p
276  // Solve velocity in the next step with IB
277  SolveCorrectedVelocity(m_F, outarray, a_iixDt);
278 
279  // Add pressures to get final value
280  Vmath::Vadd(physTot, m_pressure->GetPhys(), 1, m_pressureP->GetPhys(), 1,
281  m_pressure->UpdatePhys(), 1);
282  m_pressure->FwdTrans(m_pressure->GetPhys(), m_pressure->UpdateCoeffs());
283 
284  // Add presure to outflow bc if using convective like BCs
285  m_extrapolation->AddPressureToOutflowBCs(m_kinvis);
286 }
287 
288 /**
289  * @brief Sets the forcing term of the equation for the correction pressure
290  * \f$p_p\f$:
291  *
292  * \f[ \nabla\cdot\mathbf{f_s} \f]
293  *
294  * @param fields
295  * @param Forcing
296  */
298  const Array<OneD, const Array<OneD, NekDouble>> &fields,
300 {
301  boost::ignore_unused(fields);
302 
303  size_t physTot = m_fs[0]->GetNpoints();
304  size_t nvel = m_velocity.size();
305 
306  // Set boundary conditions
308 
309  // Divergence of 'fs'
310  m_fields[m_velocity[0]]->PhysDeriv(eX, m_fs[0]->GetPhys(), Forcing[0]);
311 
312  // Using 'Forcing[1]' as storage
313  for (size_t i = 1; i < nvel; ++i)
314  {
315  size_t ind = m_velocity[i];
316  m_fields[ind]->PhysDeriv(DirCartesianMap[i], m_fs[i]->GetPhys(),
317  Forcing[1]);
318  Vmath::Vadd(physTot, Forcing[1], 1, Forcing[0], 1, Forcing[0], 1);
319  }
320 }
321 
322 /**
323  * @brief Solves the Poisson equation for the correction pressure
324  * \f$p_p\f$:
325  *
326  * \f[ \nabla^2 p_p = \nabla\cdot\mathbf{f_s} \f]
327  *
328  * @param Forcing
329  */
332 {
334  // Factor 'lambda=0' in Helmholtz equation to get the Poisson form
335  factors[StdRegions::eFactorLambda] = 0.0;
336 
337  // Solve the Poisson equation
338  m_pressureP->HelmSolve(Forcing, m_pressureP->UpdateCoeffs(), factors);
339 
340  // Update node values from coefficients
341  m_pressureP->BwdTrans(m_pressureP->GetCoeffs(), m_pressureP->UpdatePhys());
342 }
343 
344 /**
345  * @brief Corrects the velocity field so that the IBs are taken into
346  * account. Solves the explicit equation:
347  *
348  * \f[ \frac{\gamma_0(\mathbf{u_p}^{n+1} - \mathbf{u}^*)}{\Delta t} =
349  * \mathbf{f_s} - \nabla p_p \f]
350  *
351  * @param Forcing
352  * @param fields
353  * @param dt
354  */
358 {
359  size_t physTot = m_phi->GetNpoints();
360 
361  // Gradient of p_p
362  size_t nvel = m_velocity.size();
363  if (nvel == 2)
364  {
365  m_pressureP->PhysDeriv(m_pressureP->GetPhys(), Forcing[0], Forcing[1]);
366  }
367  else
368  {
369  m_pressureP->PhysDeriv(m_pressureP->GetPhys(), Forcing[0], Forcing[1],
370  Forcing[2]);
371  }
372 
373  // Velocity correction
374  for (size_t i = 0; i < nvel; ++i)
375  {
376  // Adding -(1-m_phi)*grad(p_p) instead of -grad(p_p) reduces the
377  // flux through the walls, but the flow is not incompressible
378  if (m_session->DefinesSolverInfo("ForceBoundary") &&
379  boost::iequals(m_session->GetSolverInfo("ForceBoundary"), "True"))
380  {
381  Vmath::Vvtvm(physTot, m_phi->GetPhys(), 1, Forcing[i], 1,
382  Forcing[i], 1, Forcing[i], 1);
383  Vmath::Vadd(physTot, m_fs[i]->GetPhys(), 1, Forcing[i], 1,
384  Forcing[i], 1);
385  }
386  else
387  {
388  Vmath::Vsub(physTot, m_fs[i]->GetPhys(), 1, Forcing[i], 1,
389  Forcing[i], 1);
390  }
391  Blas::Daxpy(physTot, dt / m_gamma0, Forcing[i], 1, fields[i], 1);
392  }
393 }
394 
395 /**
396  * @brief Updates the BCs for boundaries with Neumann or periodic BCs in
397  * the pressure:
398  *
399  * \f[ \frac{\partial p_p}{\partial\mathbf{n}} =
400  * \mathbf{f_s}\cdot\mathbf{n} \f]
401  */
403 {
404  size_t nvel = m_velocity.size();
407 
408  // Get the BC expansions
409  BndExp = m_pressureP->GetBndCondExpansions();
410  BndCond = m_pressureP->GetBndConditions();
411 
412  // For each boundary...
413  for (size_t b = 0; b < BndExp.size(); ++b)
414  {
415  // Only for BCs based on the derivative
416  if (BndCond[b]->GetBoundaryConditionType() ==
418  BndCond[b]->GetBoundaryConditionType() == SpatialDomains::ePeriodic)
419  {
420  // Calculate f_s values
422  for (size_t i = 0; i < nvel; ++i)
423  {
424  f_s[i] = m_fs[0]->GetBndCondExpansions()[b]->GetPhys();
425  }
426 
427  // BC is f_s * n
428  BndExp[b]->NormVectorIProductWRTBase(f_s, BndExp[b]->UpdatePhys());
429  }
430  }
431 }
432 
433 /**
434  * @brief Calculates the values of the shape function
435  *
436  * @param t
437  */
439 {
440  // Initialise 'm_up' and 'm_phi' during first step
441  if (t <= 0.0)
442  {
443  if (!m_filePhi)
444  {
445  // Update 'm_phi' only if it was provided as a function
446  m_phiEvaluator->Evaluate("Phi", m_phi->UpdatePhys(), t);
447  }
448 
449  // Initialize both variables for the first step
450  m_phiEvaluator->Evaluate(m_velName, m_up, t);
451 
452  // Initialise 'm_upPrev' in all cases
453  m_upPrev = m_up;
454  }
455  // If timedependent 'm_phi'
456  // Phi functions from files are not timedependent
457  else if (m_timeDependentPhi)
458  {
459  m_phiEvaluator->Evaluate("Phi", m_phi->UpdatePhys(), t);
460 
461  // And if velocities are timedependent as well
462  if (m_timeDependentUp)
463  {
464  // Store previous value of u_p during simulation
465  m_upPrev = m_up;
466  m_phiEvaluator->Evaluate(m_velName, m_up, t);
467  }
468  }
469 }
470 
471 /**
472  * @brief For a body with a velocity \f$\mathbf{u_p}\f$, the force
473  * \f$\mathbf{f_s}\f$ applied to the fluid ensures that the IBC are met:
474  *
475  * \f[ \mathbf{f_s} = \frac{\Phi^{n+1}\left(\mathbf{u_p}^{n+1} -
476  * \mathbf{u^*}\right)}{\Delta t} \f]
477  *
478  * @param fields
479  * @param dt
480  * @param f_s
481  */
483  const Array<OneD, const Array<OneD, NekDouble>> &fields, NekDouble dt)
484 {
485  size_t nvel = m_velocity.size();
486  size_t nq = m_phi->GetNpoints();
487 
488  for (size_t i = 0; i < nvel; ++i)
489  {
490  // In homogeneous cases, switch out of wave space
491  Array<OneD, NekDouble> tmpField(nq);
492  size_t ind = m_velocity[i];
493 
495  m_fields[ind]->GetWaveSpace())
496  {
497  m_fields[ind]->HomogeneousBwdTrans(nq, fields[i], tmpField);
498  m_fs[i]->HomogeneousBwdTrans(nq, m_fs[i]->GetPhys(),
499  m_fs[i]->UpdatePhys());
500  }
501  else
502  {
503  tmpField = fields[i];
504  }
505 
506  Vmath::Vsub(nq, m_up[i], 1, tmpField, 1, m_fs[i]->UpdatePhys(), 1);
507  Vmath::Vmul(nq, m_phi->GetPhys(), 1, m_fs[i]->GetPhys(), 1,
508  m_fs[i]->UpdatePhys(), 1);
509  Vmath::Smul(nq, m_gamma0 / dt, m_fs[i]->GetPhys(), 1,
510  m_fs[i]->UpdatePhys(), 1);
511 
512  // And go back to wave space if the 'if' was executed
514  m_fields[ind]->GetWaveSpace())
515  {
516  m_fs[i]->HomogeneousFwdTrans(nq, m_fs[i]->GetPhys(),
517  m_fs[i]->UpdatePhys());
518  }
519  }
520 }
521 
522 /**
523  * @brief True if the function is timedependent, false otherwise
524  *
525  * @param name
526  * @param type
527  * @param attribute
528  * @return string
529  */
531  string elemName)
532 {
533  // Get the handler of the function
534  TiXmlElement *function = GetFunctionHdl(funcName);
535 
536  // Go to the first element
537  TiXmlElement *functionDef = function->FirstChildElement();
538  ASSERTL0(functionDef, "At least one element must be defined in " + funcName)
539 
540  // And search the element with name 'elemName'
541  string varName = functionDef->Attribute("VAR");
542  while (functionDef && !boost::iequals(varName, elemName))
543  {
544  functionDef = functionDef->NextSiblingElement();
545  varName = functionDef->Attribute("VAR");
546  }
547 
548  ASSERTL0(functionDef,
549  "Variable " + elemName + " must be defined in " + funcName + ".");
550 
551  // And return the value of USERDEFINEDTYPE
552  string attr;
553  int err = functionDef->QueryStringAttribute("USERDEFINEDTYPE", &attr);
554  bool output = boost::iequals(attr, "TimeDependent");
555 
556  ASSERTL0((err == TIXML_NO_ATTRIBUTE) || (err == TIXML_SUCCESS && output),
557  "USERDEFINEDTYPE in " + elemName +
558  " must be TimeDependent if defined");
559 
560  return output;
561 }
562 
563 /**
564  * @brief Returns a handle to the requested function. Returns NULL if it
565  * does not exist
566  *
567  * @param functionName
568  * @return TiXmlElement*
569  */
570 TiXmlElement *SmoothedProfileMethod::GetFunctionHdl(string functionName)
571 {
572  // Get the handler of first function block
573  TiXmlElement *conds = m_session->GetElement("Nektar/Conditions");
574  TiXmlElement *function = conds->FirstChildElement("FUNCTION");
575 
576  // Loop over functions until the block 'name' is found
577  string functionType = function->Attribute("NAME");
578  while (function && !boost::iequals(functionType, functionName))
579  {
580  function = function->NextSiblingElement("FUNCTION");
581  functionType = function->Attribute("NAME");
582  }
583 
584  return function;
585 }
586 
588 {
589  // Function evaluator for Phi and Up
590  m_phiEvaluator = GetFunction("ShapeFunction");
591 
592  TiXmlElement *function = GetFunctionHdl("ShapeFunction");
593  TiXmlElement *child = function->FirstChildElement();
594  m_filePhi = false;
595 
596  // If defined by using a file
597  if (boost::iequals(child->ValueStr(), "F"))
598  {
599  // Get name of STL file
600  string fileName;
601  int status = child->QueryStringAttribute("FILE", &fileName);
602  ASSERTL0(status == TIXML_SUCCESS,
603  "An FLD file with the values "
604  "of the phi function has to be supplied.")
605  ASSERTL0(boost::iequals(fileName.substr(fileName.length() - 4), ".fld"),
606  "A valid FLD file must be supplied in the "
607  "'ShapeFunction' field.")
608 
609  // Get phi values from XML file (after "FieldConvert" the STL file)
610  // First, load the data
611  std::vector<LibUtilities::FieldDefinitionsSharedPtr> fieldDef;
612  std::vector<std::vector<NekDouble>> fieldData;
613  LibUtilities::FieldMetaDataMap fieldMetaData;
616  phiFile->Import(fileName, fieldDef, fieldData, fieldMetaData);
617 
618  // Only Phi field should be defined in the file
619  ASSERTL0(fieldData.size() == 1, "Only one field (phi) must be "
620  "defined in the FLD file.")
621 
622  // Extract Phi field to output
623  string tmp("phi");
624  m_phi->ExtractDataToCoeffs(fieldDef[0], fieldData[0], tmp,
625  m_phi->UpdateCoeffs());
626  m_phi->BwdTrans(m_phi->GetCoeffs(), m_phi->UpdatePhys());
627  m_filePhi = true;
628  m_timeDependentPhi = false;
629  m_timeDependentUp = false;
630  }
631  else
632  {
633  // Check if Phi is timedependent
634  m_timeDependentPhi = GetVarTimeDependence("ShapeFunction", "Phi");
635 
636  // If so, check if its velocity changes as well
637  m_timeDependentUp = GetVarTimeDependence("ShapeFunction", "Up");
638  switch (m_velocity.size())
639  {
640  case 2:
642  GetVarTimeDependence("ShapeFunction", "Vp");
643  break;
644  case 3:
646  GetVarTimeDependence("ShapeFunction", "Vp");
648  GetVarTimeDependence("ShapeFunction", "Wp");
649  break;
650  }
651  }
652 }
653 
654 } // namespace Nektar
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
MultiRegions::ExpListSharedPtr m_pressure
Pointer to field holding pressure field.
NekDouble m_kinvis
Kinematic viscosity.
ExtrapolateSharedPtr m_extrapolation
Array< OneD, int > m_velocity
int which identifies which components of m_fields contains the velocity (u,v,w);
static std::shared_ptr< FieldIO > CreateForFile(const LibUtilities::SessionReaderSharedPtr session, const std::string &filename)
Construct a FieldIO object for a given input filename.
Definition: FieldIO.cpp:226
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:198
void DefineImplicitSolve(FuncPointerT func, ObjectPointerT obj)
void SetUpCorrectionPressure(const Array< OneD, const Array< OneD, NekDouble >> &fields, Array< OneD, Array< OneD, NekDouble >> &Forcing)
Sets the forcing term of the equation for the correction pressure :
bool m_filePhi
Flag indicating that phi was defined in a file.
virtual void v_GenerateSummary(SolverUtils::SummaryList &s) override
Generates the summary of the current simulation.
void SetCorrectionPressureBCs()
Updates the BCs for boundaries with Neumann or periodic BCs in the pressure:
Array< OneD, Array< OneD, NekDouble > > m_up
Velocity of the immersed body(ies)
std::vector< std::string > m_velName
Vector storing the names of the components of \u_p.
NekDouble m_gamma0
Stiffly-stable scheme coefficient.
int m_forcesFilter
Position of "AeroForcesSPM" filter in 'm_session->GetFilters()'.
virtual ~SmoothedProfileMethod()
Destroy the Smoothed Profile Method object.
virtual void v_InitObject(bool DeclareField=true) override
Init object for UnsteadySystem class.
void SolveUnsteadyStokesSystem(const Array< OneD, const Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, const NekDouble time, const NekDouble a_iixDt)
bool m_timeDependentPhi
Flag that is true when phi depends on time.
void UpdatePhiUp(NekDouble time)
Calculates the values of the shape function.
SolverUtils::SessionFunctionSharedPtr m_phiEvaluator
Function that evaluates the values of \Phi.
TiXmlElement * GetFunctionHdl(std::string functionName)
Returns a handle to the requested function. Returns NULL if it does not exist.
void SolveCorrectedVelocity(Array< OneD, Array< OneD, NekDouble >> &Forcing, Array< OneD, Array< OneD, NekDouble >> &fields, NekDouble dt)
Corrects the velocity field so that the IBs are taken into account. Solves the explicit equation:
virtual void v_SolveUnsteadyStokesSystem(const Array< OneD, const Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, NekDouble time, NekDouble a_iixDt)
Linear terms due to pressure and visosity are calculated here. After solving the velocity filed witho...
bool m_timeDependentUp
Flag signaling if depends on time.
MultiRegions::ExpListSharedPtr m_pressureP
Correction pressure field for SPM.
bool GetVarTimeDependence(std::string funcName, std::string attrName)
True if the function is timedependent, false otherwise.
Array< OneD, Array< OneD, NekDouble > > m_upPrev
Array< OneD, MultiRegions::ExpListSharedPtr > m_fs
Forcing function 'f_s'.
void UpdateForcing(const Array< OneD, const Array< OneD, NekDouble >> &fields, NekDouble dt)
For a body with a velocity , the force applied to the fluid ensures that the IBC are met:
MultiRegions::ExpListSharedPtr m_phi
Shape function 'phi' as expansion list.
void SolveCorrectionPressure(const Array< OneD, NekDouble > &Forcing)
Solves the Poisson equation for the correction pressure :
Array< OneD, MultiRegions::ExpListSharedPtr > m_fields
Array holding all dependent variables.
LibUtilities::SessionReaderSharedPtr m_session
The session reader.
enum HomogeneousType m_HomogeneousType
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.
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.
std::vector< std::pair< std::string, FilterSharedPtr > > m_filters
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_F
virtual void v_InitObject(bool DeclareField=true) override
Init object for UnsteadySystem class.
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< FieldIO > FieldIOSharedPtr
Definition: FieldIO.h:327
std::map< std::string, std::string > FieldMetaDataMap
Definition: FieldIO.h:52
std::shared_ptr< SessionReader > SessionReaderSharedPtr
MultiRegions::Direction const DirCartesianMap[]
Definition: ExpList.h:91
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
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 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 Vvtvm(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)
vvtvm (vector times vector minus vector): z = w*x - y
Definition: Vmath.cpp:598
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 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.cpp:419