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->GenerateHOPBCMap(m_session);
170 }
171}
172
173/**
174 * @brief Set up the Stokes solution used to impose constant flowrate
175 * through a boundary.
176 *
177 * This routine solves a Stokes equation using a unit forcing direction,
178 * specified by the user to be in the desired flow direction. This field can
179 * then be used to correct the end of each timestep to impose a constant
180 * volumetric flow rate through a user-defined boundary.
181 *
182 * There are three modes of operation:
183 *
184 * - Standard two-dimensional or three-dimensional simulations (e.g. pipes
185 * or channels)
186 * - 3DH1D simulations where the forcing is not in the homogeneous
187 * direction (e.g. channel flow, where the y-direction of the 2D mesh
188 * is perpendicular to the wall);
189 * - 3DH1D simulations where the forcing is in the homogeneous direction
190 * (e.g. pipe flow in the z-direction).
191 *
192 * In the first two cases, the user should define:
193 * - the `Flowrate` parameter, which dictates the volumetric flux through
194 * the reference area
195 * - tag a boundary region with the `Flowrate` user-defined type to define
196 * the reference area
197 * - define a `FlowrateForce` function with components `ForceX`, `ForceY`
198 * and `ForceZ` that defines a unit forcing in the appropriate direction.
199 *
200 * In the latter case, the user should define only the `Flowrate`; the
201 * reference area is taken to be the homogeneous plane and the force is
202 * assumed to be the unit z-vector \f$ \hat{e}_z \f$.
203 *
204 * This routine solves a single timestep of the Stokes problem
205 * (premultiplied by the backwards difference coefficient):
206 *
207 * \f[ \frac{\partial\mathbf{u}}{\partial t} = -\nabla p +
208 * \nu\nabla^2\mathbf{u} + \mathbf{f} \f]
209 *
210 * with a zero initial condition to obtain a field \f$ \mathbf{u}_s \f$. The
211 * flowrate is then corrected at each timestep \f$ n \f$ by adding the
212 * correction \f$ \alpha\mathbf{u}_s \f$ where
213 *
214 * \f[ \alpha = \frac{\overline{Q} - Q(\mathbf{u^n})}{Q(\mathbf{u}_s)} \f]
215 *
216 * where \f$ Q(\cdot)\f$ is the volumetric flux through the appropriate
217 * surface or line, which is implemented in
218 * VelocityCorrectionScheme::MeasureFlowrate. For more details, see chapter
219 * 3.2 of the thesis of D. Moxey (University of Warwick, 2011).
220 */
222{
223 m_flowrateBndID = -1;
224 m_flowrateArea = 0.0;
225
227 m_fields[0]->GetBndConditions();
228
229 std::string forces[] = {"X", "Y", "Z"};
230 Array<OneD, NekDouble> flowrateForce(m_spacedim, 0.0);
231
232 // Set up flowrate forces.
233 bool defined = true;
234 for (int i = 0; i < m_spacedim; ++i)
235 {
236 std::string varName = std::string("Force") + forces[i];
237 defined = m_session->DefinesFunction("FlowrateForce", varName);
238
239 if (!defined && m_HomogeneousType == eHomogeneous1D)
240 {
241 break;
242 }
243
244 ASSERTL0(defined,
245 "A 'FlowrateForce' function must defined with components "
246 "[ForceX, ...] to define direction of flowrate forcing");
247
249 m_session->GetFunction("FlowrateForce", varName);
250 flowrateForce[i] = ffunc->Evaluate();
251 }
252
253 // Define flag for case with homogeneous expansion and forcing not in the
254 // z-direction
255 m_homd1DFlowinPlane = false;
256 if (defined && m_HomogeneousType == eHomogeneous1D)
257 {
258 m_homd1DFlowinPlane = true;
259 }
260
261 // For 3DH1D simulations, if force isn't defined then assume in
262 // z-direction.
263 if (!defined)
264 {
265 flowrateForce[2] = 1.0;
266 }
267
268 // Find the boundary condition that is tagged as the flowrate boundary.
269 for (size_t i = 0; i < bcs.size(); ++i)
270 {
271 if (boost::iequals(bcs[i]->GetUserDefined(), "Flowrate"))
272 {
273 m_flowrateBndID = i;
274 break;
275 }
276 }
277
278 int tmpBr = m_flowrateBndID;
279 m_comm->AllReduce(tmpBr, LibUtilities::ReduceMax);
281 "One boundary region must be marked using the 'Flowrate' "
282 "user-defined type to monitor the volumetric flowrate.");
283
284 // Extract an appropriate expansion list to represents the boundary.
285 if (m_flowrateBndID >= 0)
286 {
287 // For a boundary, extract the boundary itself.
288 m_flowrateBnd = m_fields[0]->GetBndCondExpansions()[m_flowrateBndID];
289 }
291 {
292 // For 3DH1D simulations with no force specified, find the mean
293 // (0th) plane.
294 Array<OneD, unsigned int> zIDs = m_fields[0]->GetZIDs();
295 int tmpId = -1;
296
297 for (size_t i = 0; i < zIDs.size(); ++i)
298 {
299 if (zIDs[i] == 0)
300 {
301 tmpId = i;
302 break;
303 }
304 }
305
306 ASSERTL1(tmpId <= 0, "Should be either at location 0 or -1 if not "
307 "found");
308
309 if (tmpId != -1)
310 {
311 m_flowrateBnd = m_fields[0]->GetPlane(tmpId);
312 }
313 }
314
315 // At this point, some processors may not have m_flowrateBnd
316 // set if they don't contain the appropriate boundary. To
317 // calculate the area, we integrate 1.0 over the boundary
318 // (which has been set up with the appropriate subcommunicator
319 // to avoid deadlock), and then communicate this to the other
320 // processors with an AllReduce.
321 if (m_flowrateBnd)
322 {
323 Array<OneD, NekDouble> inArea(m_flowrateBnd->GetNpoints(), 1.0);
324 m_flowrateArea = m_flowrateBnd->Integral(inArea);
325 }
327
328 // In homogeneous case with forcing not aligned to the z-direction,
329 // redefine m_flowrateBnd so it is a 1D expansion
332 {
333 // For 3DH1D simulations with no force specified, find the mean
334 // (0th) plane.
335 Array<OneD, unsigned int> zIDs = m_fields[0]->GetZIDs();
336 m_planeID = -1;
337
338 for (size_t i = 0; i < zIDs.size(); ++i)
339 {
340 if (zIDs[i] == 0)
341 {
342 m_planeID = i;
343 break;
344 }
345 }
346
347 ASSERTL1(m_planeID <= 0, "Should be either at location 0 or -1 "
348 "if not found");
349
350 if (m_planeID != -1)
351 {
353 m_fields[0]->GetBndCondExpansions()[m_flowrateBndID]->GetPlane(
354 m_planeID);
355 }
356 }
357
358 // Set up some storage for the Stokes solution (to be stored in
359 // m_flowrateStokes) and its initial condition (inTmp), which holds the
360 // unit forcing.
361 int nqTot = m_fields[0]->GetNpoints();
364
365 for (int i = 0; i < m_spacedim; ++i)
366 {
367 inTmp[i] = Array<OneD, NekDouble>(nqTot, flowrateForce[i] * aii_dt);
369
371 {
372 Array<OneD, NekDouble> inTmp2(nqTot);
373 m_fields[i]->HomogeneousFwdTrans(nqTot, inTmp[i], inTmp2);
374 m_fields[i]->SetWaveSpace(true);
375 inTmp[i] = inTmp2;
376 }
377
378 Vmath::Zero(m_fields[i]->GetNcoeffs(), m_fields[i]->UpdateCoeffs(), 1);
379 }
380
381 // Create temporary extrapolation object to avoid issues with
382 // m_extrapolation for HOPBCs using higher order timestepping schemes.
383 // Zero pressure BCs in Neumann boundaries that may have been
384 // set in the advection step.
386 m_pressure->GetBndConditions();
388 m_pressure->GetBndCondExpansions();
389 for (size_t n = 0; n < PBndConds.size(); ++n)
390 {
391 if (PBndConds[n]->GetBoundaryConditionType() ==
393 {
394 Vmath::Zero(PBndExp[n]->GetNcoeffs(), PBndExp[n]->UpdateCoeffs(),
395 1);
396 }
397 }
398
399 // Finally, calculate the solution and the flux of the Stokes
400 // solution. We set m_greenFlux to maximum numeric limit, which signals
401 // to SolveUnsteadyStokesSystem that we don't need to apply a flowrate
402 // force.
403 m_greenFlux = numeric_limits<NekDouble>::max();
404 m_flowrateAiidt = aii_dt;
405
406 // Save the number of convective field in case it is not set
407 // to spacedim. Only need velocity components for stokes forcing
408 int SaveNConvectiveFields = m_nConvectiveFields;
410 SolveUnsteadyStokesSystem(inTmp, m_flowrateStokes, 0.0, aii_dt);
411 m_nConvectiveFields = SaveNConvectiveFields;
413
414 // If the user specified IO_FlowSteps, open a handle to store output.
415 if (m_comm->GetRank() == 0 && m_flowrateSteps &&
416 !m_flowrateStream.is_open())
417 {
418 std::string filename = m_session->GetSessionName();
419 filename += ".prs";
420 m_flowrateStream.open(filename.c_str());
421 m_flowrateStream.setf(ios::scientific, ios::floatfield);
422 m_flowrateStream << "# step time dP" << endl
423 << "# -------------------------------------------"
424 << endl;
425 }
426
427 // Replace pressure BCs with those evaluated from advection step
428 m_extrapolation->CopyPressureHBCsToPbndExp();
429}
430
431/**
432 * @brief Measure the volumetric flow rate through the volumetric flow rate
433 * reference surface.
434 *
435 * This routine computes the volumetric flow rate
436 *
437 * \f[
438 * Q(\mathbf{u}) = \frac{1}{\mu(R)} \int_R \mathbf{u} \cdot d\mathbf{s}
439 * \f]
440 *
441 * through the boundary region \f$ R \f$.
442 */
444 const Array<OneD, Array<OneD, NekDouble>> &inarray)
445{
446 NekDouble flowrate = 0.0;
447
448 if (m_flowrateBnd && m_flowrateBndID >= 0)
449 {
450 // If we're an actual boundary, calculate the vector flux through
451 // the boundary.
453
455 {
456 // General case
457 for (int i = 0; i < m_spacedim; ++i)
458 {
459 m_fields[i]->ExtractPhysToBnd(m_flowrateBndID, inarray[i],
460 boundary[i]);
461 }
462 flowrate = m_flowrateBnd->VectorFlux(boundary);
463 }
464 else if (m_planeID == 0)
465 {
466 // Homogeneous with forcing in plane. Calculate flux only on
467 // the meanmode - calculateFlux necessary for hybrid
468 // parallelisation.
469 for (int i = 0; i < m_spacedim; ++i)
470 {
471 m_fields[i]->GetPlane(m_planeID)->ExtractPhysToBnd(
472 m_flowrateBndID, inarray[i], boundary[i]);
473 }
474
475 // the flowrate is calculated on the mean mode so it needs to be
476 // multiplied by LZ to be consistent with the general case.
477 flowrate = m_flowrateBnd->VectorFlux(boundary) *
478 m_session->GetParameter("LZ");
479 }
480 }
482 {
483 // 3DH1D case with no Flowrate boundary defined: compute flux
484 // through the zero-th (mean) plane.
485 flowrate = m_flowrateBnd->Integral(inarray[2]);
486 }
487
488 // Communication to obtain the total flowrate
490 {
491 m_comm->GetColumnComm()->AllReduce(flowrate, LibUtilities::ReduceSum);
492 }
493 else
494 {
495 m_comm->GetSpaceComm()->AllReduce(flowrate, LibUtilities::ReduceSum);
496 }
497 return flowrate / m_flowrateArea;
498}
499
501{
502 if (m_flowrateSteps > 0)
503 {
504 if (m_comm->GetRank() == 0 && (step + 1) % m_flowrateSteps == 0)
505 {
506 m_flowrateStream << setw(8) << step << setw(16) << m_time
507 << setw(16) << m_alpha << endl;
508 }
509 }
510
512}
513
514/**
515 * Destructor
516 */
518{
519}
520
521/**
522 *
523 */
525{
527 SolverUtils::AddSummaryItem(s, "Splitting Scheme",
528 "Velocity correction (strong press. form)");
529
530 if (m_extrapolation->GetSubStepName().size())
531 {
532 SolverUtils::AddSummaryItem(s, "Substepping",
533 m_extrapolation->GetSubStepName());
534 }
535
536 string dealias = m_homogen_dealiasing ? "Homogeneous1D" : "";
538 {
539 dealias += (dealias == "" ? "" : " + ") + string("spectral/hp");
540 }
541 if (dealias != "")
542 {
543 SolverUtils::AddSummaryItem(s, "Dealiasing", dealias);
544 }
545
546 string smoothing = m_useSpecVanVisc ? "spectral/hp" : "";
547 if (smoothing != "")
548 {
550 {
552 s, "Smoothing-SpecHP",
553 "SVV (" + smoothing + " Exp Kernel(cut-off = " +
554 boost::lexical_cast<string>(m_sVVCutoffRatio) +
555 ", diff coeff = " +
556 boost::lexical_cast<string>(m_sVVDiffCoeff) + "))");
557 }
558 else
559 {
561 {
563 s, "Smoothing-SpecHP",
564 "SVV (" + smoothing + " Power Kernel (Power ratio =" +
565 boost::lexical_cast<string>(m_sVVCutoffRatio) +
566 ", diff coeff = " +
567 boost::lexical_cast<string>(m_sVVDiffCoeff) +
568 "*Uh/p))");
569 }
570 else
571 {
573 s, "Smoothing-SpecHP",
574 "SVV (" + smoothing + " DG Kernel (diff coeff = " +
575 boost::lexical_cast<string>(m_sVVDiffCoeff) +
576 "*Uh/p))");
577 }
578 }
579 }
580
582 {
584 s, "Smoothing-Homo1D",
585 "SVV (Homogeneous1D - Exp Kernel(cut-off = " +
586 boost::lexical_cast<string>(m_sVVCutoffRatioHomo1D) +
587 ", diff coeff = " +
588 boost::lexical_cast<string>(m_sVVDiffCoeffHomo1D) + "))");
589 }
590
592 {
594 s, "GJP Stab. Impl. ",
595 m_session->GetSolverInfo("GJPStabilisation"));
596 SolverUtils::AddSummaryItem(s, "GJP Stab. JumpScale", m_GJPJumpScale);
597
598 if (boost::iequals(m_session->GetSolverInfo("GJPStabilisation"),
599 "Explicit"))
600 {
602 s, "GJP Normal Velocity",
603 m_session->GetSolverInfo("GJPNormalVelocity"));
604 }
605 }
606}
607
608/**
609 *
610 */
611void VelocityCorrectionScheme::v_DoInitialise(bool dumpInitialConditions)
612{
614
615 for (int i = 0; i < m_nConvectiveFields; ++i)
616 {
618 }
619
620 m_flowrateAiidt = 0.0;
621
622 AdvectionSystem::v_DoInitialise(dumpInitialConditions);
623
624 // Set up Field Meta Data for output files
625 m_fieldMetaDataMap["Kinvis"] = boost::lexical_cast<std::string>(m_kinvis);
626 m_fieldMetaDataMap["TimeStep"] =
627 boost::lexical_cast<std::string>(m_timestep);
628
629 // set boundary conditions here so that any normal component
630 // correction are imposed before they are imposed on initial
631 // field below
633
634 // Ensure the initial conditions have correct BCs
635 for (size_t i = 0; i < m_fields.size(); ++i)
636 {
637 m_fields[i]->ImposeDirichletConditions(m_fields[i]->UpdateCoeffs());
638 m_fields[i]->LocalToGlobal();
639 m_fields[i]->GlobalToLocal();
640 m_fields[i]->BwdTrans(m_fields[i]->GetCoeffs(),
641 m_fields[i]->UpdatePhys());
642 }
643}
644
645/**
646 *
647 */
649{
650 size_t nfields = m_fields.size() - 1;
651 for (size_t k = 0; k < nfields; ++k)
652 {
653 // Backward Transformation in physical space for time evolution
654 m_fields[k]->BwdTrans(m_fields[k]->GetCoeffs(),
655 m_fields[k]->UpdatePhys());
656 }
657}
658
659/**
660 *
661 */
663{
664
665 size_t nfields = m_fields.size() - 1;
666 for (size_t k = 0; k < nfields; ++k)
667 {
668 // Forward Transformation in physical space for time evolution
669 m_fields[k]->FwdTransLocalElmt(m_fields[k]->GetPhys(),
670 m_fields[k]->UpdateCoeffs());
671 }
672}
673
674/**
675 *
676 */
678{
679 int vVar = m_session->GetVariables().size();
680 Array<OneD, bool> vChecks(vVar, false);
681 vChecks[vVar - 1] = true;
682 return vChecks;
683}
684
685/**
686 *
687 */
689{
690 return m_session->GetVariables().size() - 1;
691}
692
693/**
694 * Explicit part of the method - Advection, Forcing + HOPBCs
695 */
697 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
698 Array<OneD, Array<OneD, NekDouble>> &outarray, const NekDouble time)
699{
701 timer.Start();
702 EvaluateAdvectionTerms(inarray, outarray, time);
703 timer.Stop();
704 timer.AccumulateRegion("Advection Terms");
705
706 // Smooth advection
708 {
709 for (int i = 0; i < m_nConvectiveFields; ++i)
710 {
711 m_pressure->SmoothField(outarray[i]);
712 }
713 }
714
715 // Add forcing terms
716 for (auto &x : m_forcing)
717 {
718 x->Apply(m_fields, inarray, outarray, time);
719 }
720
721 // Calculate High-Order pressure boundary conditions
722 timer.Start();
723 m_extrapolation->EvaluatePressureBCs(inarray, outarray, m_kinvis);
724 timer.Stop();
725 timer.AccumulateRegion("Pressure BCs");
726}
727
728/**
729 * Implicit part of the method - Poisson + nConv*Helmholtz
730 */
732 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
733 Array<OneD, Array<OneD, NekDouble>> &outarray, const NekDouble time,
734 const NekDouble aii_Dt)
735{
736 boost::ignore_unused(time);
737
738 // Set up flowrate if we're starting for the first time or the value of
739 // aii_Dt has changed.
740 if (m_flowrate > 0.0 && (aii_Dt != m_flowrateAiidt))
741 {
742 SetupFlowrate(aii_Dt);
743 }
744
745 size_t physTot = m_fields[0]->GetTotPoints();
746
747 // Substep the pressure boundary condition if using substepping
748 m_extrapolation->SubStepSetPressureBCs(inarray, aii_Dt, m_kinvis);
749
750 // Set up forcing term for pressure Poisson equation
752 timer.Start();
753 SetUpPressureForcing(inarray, m_F, aii_Dt);
754 timer.Stop();
755 timer.AccumulateRegion("Pressure Forcing");
756
757 // Solve Pressure System
758 timer.Start();
759 SolvePressure(m_F[0]);
760 timer.Stop();
761 timer.AccumulateRegion("Pressure Solve");
762
763 // Set up forcing term for Helmholtz problems
764 timer.Start();
765 SetUpViscousForcing(inarray, m_F, aii_Dt);
766 timer.Stop();
767 timer.AccumulateRegion("Viscous Forcing");
768
769 // Solve velocity system
770 timer.Start();
771 SolveViscous(m_F, inarray, outarray, aii_Dt);
772 timer.Stop();
773 timer.AccumulateRegion("Viscous Solve");
774
775 // Apply flowrate correction
776 if (m_flowrate > 0.0 && m_greenFlux != numeric_limits<NekDouble>::max())
777 {
778 NekDouble currentFlux = MeasureFlowrate(outarray);
779 m_alpha = (m_flowrate - currentFlux) / m_greenFlux;
780
781 for (int i = 0; i < m_spacedim; ++i)
782 {
783 Vmath::Svtvp(physTot, m_alpha, m_flowrateStokes[i], 1, outarray[i],
784 1, outarray[i], 1);
785 // Enusre coeff space is updated for next time step
786 m_fields[i]->FwdTransLocalElmt(outarray[i],
787 m_fields[i]->UpdateCoeffs());
788 // Impsoe symmetry of flow on coeff space (good to enfore
789 // periodicity).
790 m_fields[i]->LocalToGlobal();
791 m_fields[i]->GlobalToLocal();
792 }
793 }
794}
795
796/**
797 * Forcing term for Poisson solver solver
798 */
800 const Array<OneD, const Array<OneD, NekDouble>> &fields,
802{
803 size_t i;
804 size_t physTot = m_fields[0]->GetTotPoints();
805 size_t nvel = m_velocity.size();
806
807 m_fields[0]->PhysDeriv(eX, fields[0], Forcing[0]);
808
809 for (i = 1; i < nvel; ++i)
810 {
811 // Use Forcing[1] as storage since it is not needed for the pressure
812 m_fields[i]->PhysDeriv(DirCartesianMap[i], fields[i], Forcing[1]);
813 Vmath::Vadd(physTot, Forcing[1], 1, Forcing[0], 1, Forcing[0], 1);
814 }
815
816 Vmath::Smul(physTot, 1.0 / aii_Dt, Forcing[0], 1, Forcing[0], 1);
817}
818
819/**
820 * Forcing term for Helmholtz solver
821 */
823 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
825{
826 NekDouble aii_dtinv = 1.0 / aii_Dt;
827 size_t phystot = m_fields[0]->GetTotPoints();
828
829 // Grad p
830 m_pressure->BwdTrans(m_pressure->GetCoeffs(), m_pressure->UpdatePhys());
831
832 int nvel = m_velocity.size();
833 if (nvel == 2)
834 {
835 m_pressure->PhysDeriv(m_pressure->GetPhys(), Forcing[m_velocity[0]],
836 Forcing[m_velocity[1]]);
837 }
838 else
839 {
840 m_pressure->PhysDeriv(m_pressure->GetPhys(), Forcing[m_velocity[0]],
842 }
843
844 // zero convective fields.
845 for (int i = nvel; i < m_nConvectiveFields; ++i)
846 {
847 Vmath::Zero(phystot, Forcing[i], 1);
848 }
849
850 // Subtract inarray/(aii_dt) and divide by kinvis. Kinvis will
851 // need to be updated for the convected fields.
852 for (int i = 0; i < m_nConvectiveFields; ++i)
853 {
854 Blas::Daxpy(phystot, -aii_dtinv, inarray[i], 1, Forcing[i], 1);
855 Blas::Dscal(phystot, 1.0 / m_diffCoeff[i], &(Forcing[i])[0], 1);
856 }
857}
858
859/**
860 * Solve pressure system
861 */
864{
866 // Setup coefficient for equation
868
869 // Solver Pressure Poisson Equation
870 m_pressure->HelmSolve(Forcing, m_pressure->UpdateCoeffs(), factors);
871
872 // Add presure to outflow bc if using convective like BCs
873 m_extrapolation->AddPressureToOutflowBCs(m_kinvis);
874}
875
876/**
877 * Solve velocity system
878 */
881 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
882 Array<OneD, Array<OneD, NekDouble>> &outarray, const NekDouble aii_Dt)
883{
887
888 AppendSVVFactors(factors, varFactorsMap);
889 ComputeGJPNormalVelocity(inarray, varCoeffMap);
890
891 // Solve Helmholtz system and put in Physical space
892 for (int i = 0; i < m_nConvectiveFields; ++i)
893 {
894 // Add diffusion coefficient to GJP matrix operator (Implicit part)
896 {
898 }
899
900 // Setup coefficients for equation
901 factors[StdRegions::eFactorLambda] = 1.0 / aii_Dt / m_diffCoeff[i];
902 m_fields[i]->HelmSolve(Forcing[i], m_fields[i]->UpdateCoeffs(), factors,
903 varCoeffMap, varFactorsMap);
904 m_fields[i]->BwdTrans(m_fields[i]->GetCoeffs(), outarray[i]);
905 }
906}
907
909{
910
911 m_session->MatchSolverInfo("SpectralVanishingViscosity", "PowerKernel",
912 m_useSpecVanVisc, false);
913
915 {
917 }
918 else
919 {
920 m_session->MatchSolverInfo("SpectralVanishingViscositySpectralHP",
921 "PowerKernel", m_useSpecVanVisc, false);
922 }
923
925 {
926 m_IsSVVPowerKernel = true;
927 }
928 else
929 {
930 m_session->MatchSolverInfo("SpectralVanishingViscosity", "DGKernel",
931 m_useSpecVanVisc, false);
933 {
935 }
936 else
937 {
938 m_session->MatchSolverInfo("SpectralVanishingViscositySpectralHP",
939 "DGKernel", m_useSpecVanVisc, false);
940 }
941
943 {
944 m_IsSVVPowerKernel = false;
945 }
946 }
947
948 // set up varcoeff kernel if PowerKernel or DG is specified
950 {
953 if (m_session->DefinesFunction("SVVVelocityMagnitude"))
954 {
955 if (m_comm->GetRank() == 0)
956 {
957 cout << "Seting up SVV velocity from "
958 "SVVVelocityMagnitude section in session file"
959 << endl;
960 }
961 size_t nvel = m_velocity.size();
962 size_t phystot = m_fields[0]->GetTotPoints();
963 SVVVelFields = Array<OneD, Array<OneD, NekDouble>>(nvel);
964 vector<string> vars;
965 for (size_t i = 0; i < nvel; ++i)
966 {
967 SVVVelFields[i] = Array<OneD, NekDouble>(phystot);
968 vars.push_back(m_session->GetVariable(m_velocity[i]));
969 }
970
971 // Load up files into m_fields;
972 GetFunction("SVVVelocityMagnitude")->Evaluate(vars, SVVVelFields);
973 }
974
976 SVVVarDiffCoeff(1.0, m_svvVarDiffCoeff, SVVVelFields);
977 m_session->LoadParameter("SVVDiffCoeff", m_sVVDiffCoeff, 1.0);
978 }
979 else
980 {
982 m_session->LoadParameter("SVVDiffCoeff", m_sVVDiffCoeff, 0.1);
983 }
984
985 // Load parameters for Spectral Vanishing Viscosity
986 if (m_useSpecVanVisc == false)
987 {
988 m_session->MatchSolverInfo("SpectralVanishingViscosity", "True",
989 m_useSpecVanVisc, false);
990 if (m_useSpecVanVisc == false)
991 {
992 m_session->MatchSolverInfo("SpectralVanishingViscosity",
993 "ExpKernel", m_useSpecVanVisc, false);
994 }
996
997 if (m_useSpecVanVisc == false)
998 {
999 m_session->MatchSolverInfo("SpectralVanishingViscositySpectralHP",
1000 "True", m_useSpecVanVisc, false);
1001 if (m_useSpecVanVisc == false)
1002 {
1003 m_session->MatchSolverInfo(
1004 "SpectralVanishingViscositySpectralHP", "ExpKernel",
1005 m_useSpecVanVisc, false);
1006 }
1007 }
1008 }
1009
1010 // Case of only Homo1D kernel
1011 if (m_session->DefinesSolverInfo("SpectralVanishingViscosityHomo1D"))
1012 {
1013 m_session->MatchSolverInfo("SpectralVanishingViscosityHomo1D", "True",
1014 m_useHomo1DSpecVanVisc, false);
1015 if (m_useHomo1DSpecVanVisc == false)
1016 {
1017 m_session->MatchSolverInfo("SpectralVanishingViscosityHomo1D",
1018 "ExpKernel", m_useHomo1DSpecVanVisc,
1019 false);
1020 }
1021 }
1022
1023 m_session->LoadParameter("SVVCutoffRatio", m_sVVCutoffRatio, 0.75);
1024 m_session->LoadParameter("SVVCutoffRatioHomo1D", m_sVVCutoffRatioHomo1D,
1026 m_session->LoadParameter("SVVDiffCoeffHomo1D", m_sVVDiffCoeffHomo1D,
1028
1030 {
1031 ASSERTL0(
1033 "Expect to have three velocity fields with homogenous expansion");
1034
1036 {
1038 planes = m_fields[0]->GetZIDs();
1039
1040 size_t num_planes = planes.size();
1041 Array<OneD, NekDouble> SVV(num_planes, 0.0);
1042 NekDouble fac;
1043 size_t kmodes = m_fields[0]->GetHomogeneousBasis()->GetNumModes();
1044 size_t pstart;
1045
1046 pstart = m_sVVCutoffRatioHomo1D * kmodes;
1047
1048 for (size_t n = 0; n < num_planes; ++n)
1049 {
1050 if (planes[n] > pstart)
1051 {
1052 fac = (NekDouble)((planes[n] - kmodes) *
1053 (planes[n] - kmodes)) /
1054 ((NekDouble)((planes[n] - pstart) *
1055 (planes[n] - pstart)));
1056 SVV[n] = m_sVVDiffCoeffHomo1D * exp(-fac) / m_kinvis;
1057 }
1058 }
1059
1060 for (size_t i = 0; i < m_velocity.size(); ++i)
1061 {
1062 m_fields[m_velocity[i]]->SetHomo1DSpecVanVisc(SVV);
1063 }
1064 }
1065 }
1066}
1067
1069 const NekDouble velmag, Array<OneD, NekDouble> &diffcoeff,
1070 const Array<OneD, Array<OneD, NekDouble>> &vel)
1071{
1072 size_t phystot = m_fields[0]->GetTotPoints();
1073 size_t nel = m_fields[0]->GetNumElmts();
1074 size_t nvel, cnt;
1075
1077
1078 Vmath::Fill(nel, velmag, diffcoeff, 1);
1079
1080 if (vel != NullNekDoubleArrayOfArray)
1081 {
1082 Array<OneD, NekDouble> Velmag(phystot);
1083 nvel = vel.size();
1084 // calculate magnitude of v
1085 Vmath::Vmul(phystot, vel[0], 1, vel[0], 1, Velmag, 1);
1086 for (size_t n = 1; n < nvel; ++n)
1087 {
1088 Vmath::Vvtvp(phystot, vel[n], 1, vel[n], 1, Velmag, 1, Velmag, 1);
1089 }
1090 Vmath::Vsqrt(phystot, Velmag, 1, Velmag, 1);
1091
1092 cnt = 0;
1094 // calculate mean value of vel mag.
1095 for (size_t i = 0; i < nel; ++i)
1096 {
1097 size_t nq = m_fields[0]->GetExp(i)->GetTotPoints();
1098 tmp = Velmag + cnt;
1099 diffcoeff[i] = m_fields[0]->GetExp(i)->Integral(tmp);
1100 Vmath::Fill(nq, 1.0, tmp, 1);
1101 NekDouble area = m_fields[0]->GetExp(i)->Integral(tmp);
1102 diffcoeff[i] = diffcoeff[i] / area;
1103 cnt += nq;
1104 }
1105 }
1106 else
1107 {
1108 nvel = m_expdim;
1109 }
1110
1111 for (size_t e = 0; e < nel; e++)
1112 {
1113 LocalRegions::ExpansionSharedPtr exp = m_fields[0]->GetExp(e);
1114 NekDouble h = 0;
1115
1116 // Find maximum length of edge.
1117 size_t nEdge = exp->GetGeom()->GetNumEdges();
1118 for (size_t i = 0; i < nEdge; ++i)
1119 {
1120 h = max(h, exp->GetGeom()->GetEdge(i)->GetVertex(0)->dist(
1121 *(exp->GetGeom()->GetEdge(i)->GetVertex(1))));
1122 }
1123
1124 int p = 0;
1125 for (int i = 0; i < m_expdim; ++i)
1126 {
1127 p = max(p, exp->GetBasisNumModes(i) - 1);
1128 }
1129
1130 diffcoeff[e] *= h / p;
1131 }
1132}
1133
1136 MultiRegions::VarFactorsMap &varFactorsMap)
1137{
1138
1139 if (m_useSpecVanVisc)
1140 {
1144 {
1146 {
1149 }
1150 else
1151 {
1154 }
1155 }
1156 }
1157}
1158
1159/*
1160 * Calculate Normal velocity on Trace (boundary of elements)
1161 * for GJP stabilisation.
1162 * We only use this for explicit stabilisation. The Semi-Implicit
1163 * operator uses a constant u_{norm} = 1.0
1164 */
1166 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
1167 StdRegions::VarCoeffMap &varcoeffs)
1168{
1170 {
1172 std::dynamic_pointer_cast<MultiRegions::ContField>(m_fields[0]);
1173
1175 cfield->GetGJPForcing();
1176
1177 int nTracePts = GJPData->GetNumTracePts();
1178 Array<OneD, NekDouble> unorm(nTracePts, 1.0);
1179 Array<OneD, NekDouble> Fwd(nTracePts), Bwd(nTracePts);
1181 GJPData->GetTraceNormals();
1182
1183 m_fields[0]->GetFwdBwdTracePhys(inarray[0], Fwd, Bwd, true, true);
1184 Vmath::Vmul(nTracePts, Fwd, 1, traceNormals[0], 1, unorm, 1);
1185
1186 // Evaluate u.n on trace
1187 for (int f = 1; f < m_fields[0]->GetCoordim(0); ++f)
1188 {
1189 m_fields[0]->GetFwdBwdTracePhys(inarray[f], Fwd, Bwd, true, true);
1190 Vmath::Vvtvp(nTracePts, Fwd, 1, traceNormals[f], 1, unorm, 1, unorm,
1191 1);
1192 }
1193 Vmath::Vabs(nTracePts, unorm, 1, unorm, 1);
1194 varcoeffs[StdRegions::eVarCoeffGJPNormVel] = unorm;
1195 }
1196}
1197} // 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);
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:198
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:144
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:72
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.
virtual 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.
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.
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.
virtual 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.
virtual bool v_PostIntegrate(int step) override
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.
virtual 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)
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.
void SolvePressure(const Array< OneD, NekDouble > &Forcing)
virtual 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
virtual 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:151
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:137
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:90
static VarFactorsMap NullVarFactorsMap
std::map< StdRegions::ConstFactorType, Array< OneD, NekDouble > > VarFactorsMap
std::shared_ptr< GJPStabilisation > GJPStabilisationSharedPtr
std::shared_ptr< ContField > ContFieldSharedPtr
Definition: ContField.h:270
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:176
std::map< ConstFactorType, NekDouble > ConstFactorMap
Definition: StdRegions.hpp:408
static VarCoeffMap NullVarCoeffMap
Definition: StdRegions.hpp:353
std::map< StdRegions::VarCoeffType, VarCoeffEntry > VarCoeffMap
Definition: StdRegions.hpp:352
StdRegions::ConstFactorMap factors
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
@ 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.cpp:529
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:207
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:617
void Vabs(int n, const T *x, const int incx, T *y, const int incy)
vabs: y = |x|
Definition: Vmath.cpp:548
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:569
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:354
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:245
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:487
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
Definition: Vmath.cpp:43