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