Nektar++
CompressibleFlowSystem.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: CompressibleFlowSystem.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: Compressible flow system base class with auxiliary functions
32//
33///////////////////////////////////////////////////////////////////////////////
34
36
38
39using namespace std;
40
41namespace Nektar
42{
46 : UnsteadySystem(pSession, pGraph), AdvectionSystem(pSession, pGraph)
47{
48}
49
50/**
51 * @brief Initialization object for CompressibleFlowSystem class.
52 */
54{
55 AdvectionSystem::v_InitObject(DeclareFields);
56
57 for (size_t i = 0; i < m_fields.size(); i++)
58 {
59 // Use BwdTrans to make sure initial condition is in solution space
60 m_fields[i]->BwdTrans(m_fields[i]->GetCoeffs(),
61 m_fields[i]->UpdatePhys());
62 }
63
66
67 ASSERTL0(m_session->DefinesSolverInfo("UPWINDTYPE"),
68 "No UPWINDTYPE defined in session.");
69
70 // Do not forwards transform initial condition
71 m_homoInitialFwd = false;
72
73 // Set up locations of velocity vector.
76 for (int i = 0; i < m_spacedim; ++i)
77 {
78 m_vecLocs[0][i] = 1 + i;
79 }
80
81 // Loading parameters from session file
83
84 // Setting up advection and diffusion operators
86
87 // Create artificial diffusion with laplacian operator
88 if (m_shockCaptureType == "NonSmooth")
89 {
92 }
93
94 // Forcing terms for the sponge region
96 m_fields, m_fields.size());
97
98 // User-defined boundary conditions
99 size_t cnt = 0;
100 for (size_t n = 0; n < (size_t)m_fields[0]->GetBndConditions().size(); ++n)
101 {
102 std::string type = m_fields[0]->GetBndConditions()[n]->GetUserDefined();
103
104 if (m_fields[0]->GetBndConditions()[n]->GetBoundaryConditionType() ==
106 {
107 continue;
108 }
109
110 if (!type.empty())
111 {
113 type, m_session, m_fields, m_traceNormals, m_spacedim, n, cnt));
114 }
115 cnt += m_fields[0]->GetBndCondExpansions()[n]->GetExpSize();
116 }
117
120
122}
123
124/**
125 * @brief Load CFS parameters from the session file
126 */
128{
129 // Get gamma parameter from session file.
130 m_session->LoadParameter("Gamma", m_gamma, 1.4);
131
132 // Shock capture
133 m_session->LoadSolverInfo("ShockCaptureType", m_shockCaptureType, "Off");
134
135 // Check if the shock capture type is supported
136 std::string err_msg = "Warning, ShockCaptureType = " + m_shockCaptureType +
137 " is not supported by this solver";
139
140 // Load parameters for exponential filtering
141 m_session->MatchSolverInfo("ExponentialFiltering", "True", m_useFiltering,
142 false);
143 if (m_useFiltering)
144 {
145 m_session->LoadParameter("FilterAlpha", m_filterAlpha, 36);
146 m_session->LoadParameter("FilterExponent", m_filterExponent, 16);
147 m_session->LoadParameter("FilterCutoff", m_filterCutoff, 0);
148 }
149
150 // Load CFL for local time-stepping (for steady state)
151 m_session->MatchSolverInfo("LocalTimeStep", "True", m_useLocalTimeStep,
152 false);
154 {
156 "Local time stepping requires CFL parameter.");
157 }
158}
159
160/**
161 * @brief Create advection and diffusion objects for CFS
162 */
164{
165 // Check if projection type is correct
167 "Unsupported projection type.");
168
169 string advName, riemName;
170 m_session->LoadSolverInfo("AdvectionType", advName, "WeakDG");
171
174
176 {
177 m_advObject->SetFluxVector(
179 }
180 else
181 {
183 this);
184 }
185
186 // Setting up Riemann solver for advection operator
187 m_session->LoadSolverInfo("UpwindType", riemName, "Average");
188
191 riemName, m_session);
192
193 // Setting up parameters for advection operator Riemann solver
194 riemannSolver->SetParam("gamma", &CompressibleFlowSystem::GetGamma, this);
195 riemannSolver->SetAuxVec("vecLocs", &CompressibleFlowSystem::GetVecLocs,
196 this);
197 riemannSolver->SetVector("N", &CompressibleFlowSystem::GetNormals, this);
198
199 // Concluding initialisation of advection / diffusion operators
200 m_advObject->SetRiemannSolver(riemannSolver);
201 m_advObject->InitObject(m_session, m_fields);
202}
203
204/**
205 * @brief Compute the right-hand side.
206 */
208 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
209 Array<OneD, Array<OneD, NekDouble>> &outarray, const NekDouble time)
210{
212
213 size_t nvariables = inarray.size();
214 size_t nTracePts = GetTraceTotPoints();
215 size_t npoints = GetNpoints();
216
217 m_bndEvaluateTime = time;
218
219 // Store forwards/backwards space along trace space
220 Array<OneD, Array<OneD, NekDouble>> Fwd(nvariables);
221 Array<OneD, Array<OneD, NekDouble>> Bwd(nvariables);
222
224 {
227 }
228 else
229 {
230 for (size_t i = 0; i < nvariables; ++i)
231 {
232 Fwd[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
233 Bwd[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
234 m_fields[i]->GetFwdBwdTracePhys(inarray[i], Fwd[i], Bwd[i]);
235 }
236 }
237
238 // Calculate advection
239 timer.Start();
240 DoAdvection(inarray, outarray, time, Fwd, Bwd);
241 timer.Stop();
242 timer.AccumulateRegion("DoAdvection");
243
244 // Negate results
245 for (size_t i = 0; i < nvariables; ++i)
246 {
247 Vmath::Neg(npoints, outarray[i], 1);
248 }
249
250 // Add diffusion terms
251 timer.Start();
252 DoDiffusion(inarray, outarray, Fwd, Bwd);
253 timer.Stop();
254 timer.AccumulateRegion("DoDiffusion");
255
256 // Add forcing terms
257 for (auto &x : m_forcing)
258 {
259 x->Apply(m_fields, inarray, outarray, time);
260 }
261
263 {
264 size_t nElements = m_fields[0]->GetExpSize();
265 int nq, offset;
266 NekDouble fac;
268
269 Array<OneD, NekDouble> tstep(nElements, 0.0);
270 GetElmtTimeStep(inarray, tstep);
271
272 // Loop over elements
273 for (size_t n = 0; n < nElements; ++n)
274 {
275 nq = m_fields[0]->GetExp(n)->GetTotPoints();
276 offset = m_fields[0]->GetPhys_Offset(n);
277 fac = tstep[n] / m_timestep;
278 for (size_t i = 0; i < nvariables; ++i)
279 {
280 Vmath::Smul(nq, fac, outarray[i] + offset, 1,
281 tmp = outarray[i] + offset, 1);
282 }
283 }
284 }
285}
286
287/**
288 * @brief Compute the projection and call the method for imposing the
289 * boundary conditions in case of discontinuous projection.
290 */
292 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
293 Array<OneD, Array<OneD, NekDouble>> &outarray, const NekDouble time)
294{
295 switch (m_projectionType)
296 {
298 {
299 // Just copy over array
300 size_t nvariables = inarray.size();
301 size_t npoints = GetNpoints();
302
303 for (size_t i = 0; i < nvariables; ++i)
304 {
305 Vmath::Vcopy(npoints, inarray[i], 1, outarray[i], 1);
306 if (m_useFiltering)
307 {
308 m_fields[i]->ExponentialFilter(outarray[i], m_filterAlpha,
311 }
312 }
313 SetBoundaryConditions(outarray, time);
314 break;
315 }
318 {
319 NEKERROR(ErrorUtil::efatal, "No Continuous Galerkin for full "
320 "compressible Navier-Stokes equations");
321 break;
322 }
323 default:
324 NEKERROR(ErrorUtil::efatal, "Unknown projection scheme");
325 break;
326 }
327}
328
329/**
330 * @brief Compute the advection terms for the right-hand side
331 */
333 const Array<OneD, Array<OneD, NekDouble>> &inarray,
334 Array<OneD, Array<OneD, NekDouble>> &outarray, const NekDouble time,
335 const Array<OneD, Array<OneD, NekDouble>> &pFwd,
336 const Array<OneD, Array<OneD, NekDouble>> &pBwd)
337{
338 int nvariables = inarray.size();
340
341 m_advObject->Advect(nvariables, m_fields, advVel, inarray, outarray, time,
342 pFwd, pBwd);
343}
344
345/**
346 * @brief Add the diffusions terms to the right-hand side
347 */
349 const Array<OneD, Array<OneD, NekDouble>> &inarray,
351 const Array<OneD, Array<OneD, NekDouble>> &pFwd,
352 const Array<OneD, Array<OneD, NekDouble>> &pBwd)
353{
354 v_DoDiffusion(inarray, outarray, pFwd, pBwd);
355}
356
358 Array<OneD, Array<OneD, NekDouble>> &physarray, NekDouble time)
359{
360 size_t nTracePts = GetTraceTotPoints();
361 size_t nvariables = physarray.size();
362
363 Array<OneD, Array<OneD, NekDouble>> Fwd(nvariables);
364 for (size_t i = 0; i < nvariables; ++i)
365 {
366 Fwd[i] = Array<OneD, NekDouble>(nTracePts);
367 m_fields[i]->ExtractTracePhys(physarray[i], Fwd[i]);
368 }
369
370 if (m_bndConds.size())
371 {
372 // Loop over user-defined boundary conditions
373 for (auto &x : m_bndConds)
374 {
375 x->Apply(Fwd, physarray, time);
376 }
377 }
378}
379/**
380 * @brief Set up a weight on physical boundaries for boundary condition
381 * applications
382 */
384{
385 if (m_bndConds.size())
386 {
387 // Loop over user-defined boundary conditions
388 for (auto &x : m_bndConds)
389 {
390 x->ApplyBwdWeight();
391 }
392 }
393}
394
395/**
396 * @brief Return the flux vector for the compressible Euler equations.
397 *
398 * @param physfield Fields.
399 * @param flux Resulting flux.
400 */
402 const Array<OneD, const Array<OneD, NekDouble>> &physfield,
404{
405 size_t nVariables = physfield.size();
406 size_t nPts = physfield[0].size();
407
408 constexpr unsigned short maxVel = 3;
409 constexpr unsigned short maxFld = 5;
410
411 // hardcoding done for performance reasons
412 ASSERTL1(nVariables <= maxFld, "GetFluxVector, hard coded max fields");
413
414 for (size_t p = 0; p < nPts; ++p)
415 {
416 // local storage
417 std::array<NekDouble, maxFld> fieldTmp;
418 std::array<NekDouble, maxVel> velocity;
419
420 // rearrenge and load data
421 for (size_t f = 0; f < nVariables; ++f)
422 {
423 fieldTmp[f] = physfield[f][p]; // load
424 }
425
426 // 1 / rho
427 NekDouble oneOrho = 1.0 / fieldTmp[0];
428
429 for (size_t d = 0; d < m_spacedim; ++d)
430 {
431 // Flux vector for the rho equation
432 flux[0][d][p] = fieldTmp[d + 1]; // store
433 // compute velocity
434 velocity[d] = fieldTmp[d + 1] * oneOrho;
435 }
436
437 NekDouble pressure = m_varConv->GetPressure(fieldTmp.data());
438 NekDouble ePlusP = fieldTmp[m_spacedim + 1] + pressure;
439 for (size_t f = 0; f < m_spacedim; ++f)
440 {
441 // Flux vector for the velocity fields
442 for (size_t d = 0; d < m_spacedim; ++d)
443 {
444 flux[f + 1][d][p] = velocity[d] * fieldTmp[f + 1]; // store
445 }
446
447 // Add pressure to appropriate field
448 flux[f + 1][f][p] += pressure;
449
450 // Flux vector for energy
451 flux[m_spacedim + 1][f][p] = ePlusP * velocity[f]; // store
452 }
453 }
454}
455
456/**
457 * @brief Return the flux vector for the compressible Euler equations
458 * by using the de-aliasing technique.
459 *
460 * @param physfield Fields.
461 * @param flux Resulting flux.
462 */
464 const Array<OneD, const Array<OneD, NekDouble>> &physfield,
466{
467 int i, j;
468 size_t nq = physfield[0].size();
469 size_t nVariables = m_fields.size();
470
471 // Factor to rescale 1d points in dealiasing
472 NekDouble OneDptscale = 2;
473 nq = m_fields[0]->Get1DScaledTotPoints(OneDptscale);
474
477
478 Array<OneD, Array<OneD, NekDouble>> physfield_interp(nVariables);
479 TensorOfArray3D<NekDouble> flux_interp(nVariables);
480
481 for (size_t i = 0; i < nVariables; ++i)
482 {
483 physfield_interp[i] = Array<OneD, NekDouble>(nq);
485 m_fields[0]->PhysInterp1DScaled(OneDptscale, physfield[i],
486 physfield_interp[i]);
487
488 for (j = 0; j < m_spacedim; ++j)
489 {
490 flux_interp[i][j] = Array<OneD, NekDouble>(nq);
491 }
492 }
493
494 // Flux vector for the rho equation
495 for (i = 0; i < m_spacedim; ++i)
496 {
498
499 // Galerkin project solution back to original space
500 m_fields[0]->PhysGalerkinProjection1DScaled(
501 OneDptscale, physfield_interp[i + 1], flux[0][i]);
502 }
503
504 m_varConv->GetVelocityVector(physfield_interp, velocity);
505 m_varConv->GetPressure(physfield_interp, pressure);
506
507 // Evaluation of flux vector for the velocity fields
508 for (i = 0; i < m_spacedim; ++i)
509 {
510 for (j = 0; j < m_spacedim; ++j)
511 {
512 Vmath::Vmul(nq, velocity[j], 1, physfield_interp[i + 1], 1,
513 flux_interp[i + 1][j], 1);
514 }
515
516 // Add pressure to appropriate field
517 Vmath::Vadd(nq, flux_interp[i + 1][i], 1, pressure, 1,
518 flux_interp[i + 1][i], 1);
519 }
520
521 // Galerkin project solution back to original space
522 for (i = 0; i < m_spacedim; ++i)
523 {
524 for (j = 0; j < m_spacedim; ++j)
525 {
526 m_fields[0]->PhysGalerkinProjection1DScaled(
527 OneDptscale, flux_interp[i + 1][j], flux[i + 1][j]);
528 }
529 }
530
531 // Evaluation of flux vector for energy
532 Vmath::Vadd(nq, physfield_interp[m_spacedim + 1], 1, pressure, 1, pressure,
533 1);
534
535 for (j = 0; j < m_spacedim; ++j)
536 {
537 Vmath::Vmul(nq, velocity[j], 1, pressure, 1,
538 flux_interp[m_spacedim + 1][j], 1);
539
540 // Galerkin project solution back to original space
541 m_fields[0]->PhysGalerkinProjection1DScaled(
542 OneDptscale, flux_interp[m_spacedim + 1][j],
543 flux[m_spacedim + 1][j]);
544 }
545}
546
547/**
548 * @brief Calculate the maximum timestep on each element
549 * subject to CFL restrictions.
550 */
552 [[maybe_unused]] const Array<OneD, const Array<OneD, NekDouble>> &inarray,
554{
555 size_t nElements = m_fields[0]->GetExpSize();
556
557 // Change value of m_timestep (in case it is set to zero)
558 NekDouble tmp = m_timestep;
559 m_timestep = 1.0;
560
561 Array<OneD, NekDouble> cfl(nElements);
562 cfl = GetElmtCFLVals();
563
564 // Factors to compute the time-step limit
566
567 // Loop over elements to compute the time-step limit for each element
568 for (size_t n = 0; n < nElements; ++n)
569 {
570 tstep[n] = m_cflSafetyFactor * alpha / cfl[n];
571 }
572
573 // Restore value of m_timestep
574 m_timestep = tmp;
575}
576
577/**
578 * @brief Calculate the maximum timestep subject to CFL restrictions.
579 */
581 const Array<OneD, const Array<OneD, NekDouble>> &inarray)
582{
583 int nElements = m_fields[0]->GetExpSize();
584 Array<OneD, NekDouble> tstep(nElements, 0.0);
585
586 GetElmtTimeStep(inarray, tstep);
587
588 // Get the minimum time-step limit and return the time-step
589 NekDouble TimeStep = Vmath::Vmin(nElements, tstep, 1);
590 m_comm->GetSpaceComm()->AllReduce(TimeStep, LibUtilities::ReduceMin);
591
592 return TimeStep;
593}
594
596{
598 if (m_session->DefinesSolverInfo("ICTYPE"))
599 {
600 if (boost::iequals(m_session->GetSolverInfo("ICTYPE"),
601 "IsentropicVortex"))
602 {
603 SolverUtils::AddSummaryItem(s, "Problem Type", "IsentropicVortex");
604 }
605 else if (boost::iequals(m_session->GetSolverInfo("ICTYPE"),
606 "RinglebFlow"))
607 {
608 SolverUtils::AddSummaryItem(s, "Problem Type", "RinglebFlow");
609 }
610 else
611 {
612 NEKERROR(ErrorUtil::efatal, "unknow initial condition");
613 }
614 }
615}
616
617/**
618 * @brief Set up logic for residual calculation.
619 */
621 NekDouble initialtime, bool dumpInitialConditions,
622 [[maybe_unused]] const int domain)
623{
624 if (m_session->DefinesSolverInfo("ICTYPE") &&
625 boost::iequals(m_session->GetSolverInfo("ICTYPE"), "IsentropicVortex"))
626 {
627 // Forward transform to fill the coefficient space
628 for (int i = 0; i < m_fields.size(); ++i)
629 {
630 EvaluateIsentropicVortex(i, m_fields[i]->UpdatePhys(), initialtime);
631 m_fields[i]->SetPhysState(true);
632 m_fields[i]->FwdTrans(m_fields[i]->GetPhys(),
633 m_fields[i]->UpdateCoeffs());
634 }
635 }
636 else
637 {
638 EquationSystem::v_SetInitialConditions(initialtime, false);
639 m_nchk--; // Note: m_nchk has been incremented in EquationSystem.
640
641 // insert white noise in initial condition
642 NekDouble Noise;
643 int phystot = m_fields[0]->GetTotPoints();
644 Array<OneD, NekDouble> noise(phystot);
645
646 m_session->LoadParameter("Noise", Noise, 0.0);
647 int m_nConvectiveFields = m_fields.size();
648
649 if (Noise > 0.0)
650 {
651 int seed = -m_comm->GetSpaceComm()->GetRank() * m_nConvectiveFields;
652 for (int i = 0; i < m_nConvectiveFields; i++)
653 {
654 Vmath::FillWhiteNoise(phystot, Noise, noise, 1, seed);
655 --seed;
656 Vmath::Vadd(phystot, m_fields[i]->GetPhys(), 1, noise, 1,
657 m_fields[i]->UpdatePhys(), 1);
658 m_fields[i]->FwdTransLocalElmt(m_fields[i]->GetPhys(),
659 m_fields[i]->UpdateCoeffs());
660 }
661 }
662 }
663
664 if (dumpInitialConditions && m_nchk == 0 && m_checksteps &&
665 !m_comm->IsParallelInTime())
666 {
668 }
669 else if (dumpInitialConditions && m_nchk == 0 && m_comm->IsParallelInTime())
670 {
671 std::string newdir = m_sessionName + ".pit";
672 if (!fs::is_directory(newdir))
673 {
674 fs::create_directory(newdir);
675 }
676 if (m_comm->GetTimeComm()->GetRank() == 0)
677 {
678 WriteFld(newdir + "/" + m_sessionName + "_0.fld");
679 }
680 }
681 m_nchk++;
682}
683
685 unsigned int field, Array<OneD, NekDouble> &outfield, const NekDouble time)
686{
687
688 if (!m_session->DefinesFunction("ExactSolution") &&
689 m_session->DefinesSolverInfo("ICTYPE"))
690 {
691 if (boost::iequals(m_session->GetSolverInfo("ICTYPE"),
692 "IsentropicVortex"))
693 {
694 EvaluateIsentropicVortex(field, outfield, time);
695 }
696 else if (boost::iequals(m_session->GetSolverInfo("ICTYPE"),
697 "RinglebFlow"))
698 {
699 GetExactRinglebFlow(field, outfield);
700 }
701 }
702 else
703 {
704 EquationSystem::v_EvaluateExactSolution(field, outfield, time);
705 }
706}
707
708/**
709 * @brief Compute the advection velocity in the standard space
710 * for each element of the expansion.
711 */
713 const NekDouble SpeedSoundFactor)
714{
715 size_t nTotQuadPoints = GetTotPoints();
716 size_t n_element = m_fields[0]->GetExpSize();
717 size_t expdim = m_fields[0]->GetGraph()->GetMeshDimension();
718 size_t nfields = m_fields.size();
719 int offset;
721
722 Array<OneD, Array<OneD, NekDouble>> physfields(nfields);
723 for (size_t i = 0; i < nfields; ++i)
724 {
725 physfields[i] = m_fields[i]->GetPhys();
726 }
727
728 Array<OneD, NekDouble> stdV(n_element, 0.0);
729
730 // Getting the velocity vector on the 2D normal space
734 Array<OneD, NekDouble> soundspeed(nTotQuadPoints);
736
737 for (int i = 0; i < m_spacedim; ++i)
738 {
739 velocity[i] = Array<OneD, NekDouble>(nTotQuadPoints);
740 stdVelocity[i] = Array<OneD, NekDouble>(nTotQuadPoints, 0.0);
741 stdSoundSpeed[i] = Array<OneD, NekDouble>(nTotQuadPoints, 0.0);
742 }
743
744 m_varConv->GetVelocityVector(physfields, velocity);
745 m_varConv->GetSoundSpeed(physfields, soundspeed);
746
747 for (size_t el = 0; el < n_element; ++el)
748 {
749 ptsKeys = m_fields[0]->GetExp(el)->GetPointsKeys();
750 offset = m_fields[0]->GetPhys_Offset(el);
751 int nq = m_fields[0]->GetExp(el)->GetTotPoints();
752
753 const SpatialDomains::GeomFactorsSharedPtr metricInfo =
754 m_fields[0]->GetExp(el)->GetGeom()->GetMetricInfo();
755 const Array<TwoD, const NekDouble> &gmat =
756 m_fields[0]
757 ->GetExp(el)
758 ->GetGeom()
759 ->GetMetricInfo()
760 ->GetDerivFactors(ptsKeys);
761
762 // Convert to standard element
763 // consider soundspeed in all directions
764 // (this might overestimate the cfl)
765 if (metricInfo->GetGtype() == SpatialDomains::eDeformed)
766 {
767 // d xi/ dx = gmat = 1/J * d x/d xi
768 for (size_t i = 0; i < expdim; ++i)
769 {
770 Vmath::Vmul(nq, gmat[i], 1, velocity[0] + offset, 1,
771 tmp = stdVelocity[i] + offset, 1);
772 Vmath::Vmul(nq, gmat[i], 1, soundspeed + offset, 1,
773 tmp = stdSoundSpeed[i] + offset, 1);
774 for (size_t j = 1; j < expdim; ++j)
775 {
776 Vmath::Vvtvp(nq, gmat[expdim * j + i], 1,
777 velocity[j] + offset, 1,
778 stdVelocity[i] + offset, 1,
779 tmp = stdVelocity[i] + offset, 1);
780 Vmath::Vvtvp(nq, gmat[expdim * j + i], 1,
781 soundspeed + offset, 1,
782 stdSoundSpeed[i] + offset, 1,
783 tmp = stdSoundSpeed[i] + offset, 1);
784 }
785 }
786 }
787 else
788 {
789 for (size_t i = 0; i < expdim; ++i)
790 {
791 Vmath::Smul(nq, gmat[i][0], velocity[0] + offset, 1,
792 tmp = stdVelocity[i] + offset, 1);
793 Vmath::Smul(nq, gmat[i][0], soundspeed + offset, 1,
794 tmp = stdSoundSpeed[i] + offset, 1);
795 for (size_t j = 1; j < expdim; ++j)
796 {
797 Vmath::Svtvp(nq, gmat[expdim * j + i][0],
798 velocity[j] + offset, 1,
799 stdVelocity[i] + offset, 1,
800 tmp = stdVelocity[i] + offset, 1);
801 Vmath::Svtvp(nq, gmat[expdim * j + i][0],
802 soundspeed + offset, 1,
803 stdSoundSpeed[i] + offset, 1,
804 tmp = stdSoundSpeed[i] + offset, 1);
805 }
806 }
807 }
808
809 NekDouble vel;
810 for (size_t i = 0; i < nq; ++i)
811 {
812 NekDouble pntVelocity = 0.0;
813 for (size_t j = 0; j < expdim; ++j)
814 {
815 // Add sound speed
816 vel = std::abs(stdVelocity[j][offset + i]) +
817 SpeedSoundFactor * std::abs(stdSoundSpeed[j][offset + i]);
818 pntVelocity += vel * vel;
819 }
820 pntVelocity = sqrt(pntVelocity);
821 if (pntVelocity > stdV[el])
822 {
823 stdV[el] = pntVelocity;
824 }
825 }
826 }
827
828 return stdV;
829}
830
831/**
832 * @brief Set the denominator to compute the time step when a cfl
833 * control is employed. This function is no longer used but is still
834 * here for being utilised in the future.
835 *
836 * @param n Order of expansion element by element.
837 */
839{
840 ASSERTL0(n <= 20, "Illegal modes dimension for CFL calculation "
841 "(P has to be less then 20)");
842
843 NekDouble CFLDG[21] = {2.0000, 6.0000, 11.8424, 19.1569, 27.8419,
844 37.8247, 49.0518, 61.4815, 75.0797, 89.8181,
845 105.6700, 122.6200, 140.6400, 159.7300, 179.8500,
846 201.0100, 223.1800, 246.3600, 270.5300, 295.6900,
847 321.8300}; // CFLDG 1D [0-20]
848 NekDouble CFL = 0.0;
849
851 {
852 CFL = CFLDG[n];
853 }
854 else
855 {
856 NEKERROR(ErrorUtil::efatal, "Continuous Galerkin stability "
857 "coefficients not introduced yet.");
858 }
859
860 return CFL;
861}
862
863/**
864 * @brief Compute the vector of denominators to compute the time step
865 * when a cfl control is employed. This function is no longer used but
866 * is still here for being utilised in the future.
867 *
868 * @param ExpOrder Order of expansion element by element.
869 */
871 const Array<OneD, int> &ExpOrder)
872{
873 int i;
874 Array<OneD, NekDouble> returnval(m_fields[0]->GetExpSize(), 0.0);
875 for (i = 0; i < m_fields[0]->GetExpSize(); i++)
876 {
877 returnval[i] = GetStabilityLimit(ExpOrder[i]);
878 }
879 return returnval;
880}
881
883 std::vector<Array<OneD, NekDouble>> &fieldcoeffs,
884 std::vector<std::string> &variables)
885{
886 bool extraFields;
887 m_session->MatchSolverInfo("OutputExtraFields", "True", extraFields, true);
888 if (extraFields)
889 {
890 const int nPhys = m_fields[0]->GetNpoints();
891 const int nCoeffs = m_fields[0]->GetNcoeffs();
893
894 for (int i = 0; i < m_fields.size(); ++i)
895 {
896 tmp[i] = m_fields[i]->GetPhys();
897 }
898
901 for (int i = 0; i < m_spacedim; ++i)
902 {
904 velFwd[i] = Array<OneD, NekDouble>(nCoeffs);
905 }
906
907 Array<OneD, NekDouble> pressure(nPhys), temperature(nPhys);
908 Array<OneD, NekDouble> entropy(nPhys);
909 Array<OneD, NekDouble> soundspeed(nPhys), mach(nPhys);
910 Array<OneD, NekDouble> sensor(nPhys), SensorKappa(nPhys);
911
912 m_varConv->GetVelocityVector(tmp, velocity);
913 m_varConv->GetPressure(tmp, pressure);
914 m_varConv->GetTemperature(tmp, temperature);
915 m_varConv->GetEntropy(tmp, entropy);
916 m_varConv->GetSoundSpeed(tmp, soundspeed);
917 m_varConv->GetMach(tmp, soundspeed, mach);
918
919 int sensorOffset;
920 m_session->LoadParameter("SensorOffset", sensorOffset, 1);
921 m_varConv->GetSensor(m_fields[0], tmp, sensor, SensorKappa,
922 sensorOffset);
923
924 Array<OneD, NekDouble> pFwd(nCoeffs), TFwd(nCoeffs);
925 Array<OneD, NekDouble> sFwd(nCoeffs);
926 Array<OneD, NekDouble> aFwd(nCoeffs), mFwd(nCoeffs);
927 Array<OneD, NekDouble> sensFwd(nCoeffs);
928
929 string velNames[3] = {"u", "v", "w"};
930 for (int i = 0; i < m_spacedim; ++i)
931 {
932 m_fields[0]->FwdTransLocalElmt(velocity[i], velFwd[i]);
933 variables.push_back(velNames[i]);
934 fieldcoeffs.push_back(velFwd[i]);
935 }
936
937 m_fields[0]->FwdTransLocalElmt(pressure, pFwd);
938 m_fields[0]->FwdTransLocalElmt(temperature, TFwd);
939 m_fields[0]->FwdTransLocalElmt(entropy, sFwd);
940 m_fields[0]->FwdTransLocalElmt(soundspeed, aFwd);
941 m_fields[0]->FwdTransLocalElmt(mach, mFwd);
942 m_fields[0]->FwdTransLocalElmt(sensor, sensFwd);
943
944 variables.push_back("p");
945 variables.push_back("T");
946 variables.push_back("s");
947 variables.push_back("a");
948 variables.push_back("Mach");
949 variables.push_back("Sensor");
950 fieldcoeffs.push_back(pFwd);
951 fieldcoeffs.push_back(TFwd);
952 fieldcoeffs.push_back(sFwd);
953 fieldcoeffs.push_back(aFwd);
954 fieldcoeffs.push_back(mFwd);
955 fieldcoeffs.push_back(sensFwd);
956
958 {
959 // reuse pressure
960 Array<OneD, NekDouble> sensorFwd(nCoeffs);
961 m_artificialDiffusion->GetArtificialViscosity(tmp, pressure);
962 m_fields[0]->FwdTransLocalElmt(pressure, sensorFwd);
963
964 variables.push_back("ArtificialVisc");
965 fieldcoeffs.push_back(sensorFwd);
966 }
967 }
968}
969
970/**
971 *
972 */
974 const Array<OneD, const Array<OneD, NekDouble>> &physfield,
976{
977 m_varConv->GetPressure(physfield, pressure);
978}
979
980/**
981 *
982 */
984 const Array<OneD, const Array<OneD, NekDouble>> &physfield,
985 Array<OneD, NekDouble> &density)
986{
987 density = physfield[0];
988}
989
990/**
991 *
992 */
994 const Array<OneD, const Array<OneD, NekDouble>> &physfield,
996{
997 m_varConv->GetVelocityVector(physfield, velocity);
998}
999
1002{
1003 const size_t nPoints = GetTotPoints();
1004 const size_t nFields = m_fields.size();
1006 Array<OneD, Array<OneD, NekDouble>> inarray(nFields);
1007 for (size_t i = 0; i < nFields; ++i)
1008 {
1009 rhs[i] = Array<OneD, NekDouble>(nPoints, 0.0);
1010 inarray[i] = m_fields[i]->UpdatePhys();
1011 }
1012
1013 DoOdeRhs(inarray, rhs, m_time);
1014
1015 // Holds L2 errors.
1017 Array<OneD, NekDouble> RHSL2(nFields);
1018 Array<OneD, NekDouble> residual(nFields);
1019
1020 for (size_t i = 0; i < nFields; ++i)
1021 {
1022 tmp = rhs[i];
1023
1024 Vmath::Vmul(nPoints, tmp, 1, tmp, 1, tmp, 1);
1025 residual[i] = Vmath::Vsum(nPoints, tmp, 1);
1026 }
1027
1028 m_comm->GetSpaceComm()->AllReduce(residual, LibUtilities::ReduceSum);
1029
1030 NekDouble onPoints = 1.0 / NekDouble(nPoints);
1031 for (size_t i = 0; i < nFields; ++i)
1032 {
1033 L2[i] = sqrt(residual[i] * onPoints);
1034 }
1035}
1036
1037/**
1038 *
1039 */
1041 unsigned int field, Array<OneD, NekDouble> &outfield, NekDouble time,
1042 const int o)
1043{
1044 NekDouble beta, u0, v0, x0, y0;
1045
1046 int nTotQuadPoints = GetTotPoints();
1047 Array<OneD, NekDouble> x(nTotQuadPoints);
1048 Array<OneD, NekDouble> y(nTotQuadPoints);
1049 Array<OneD, NekDouble> z(nTotQuadPoints);
1051
1052 m_fields[0]->GetCoords(x, y, z);
1053
1054 for (int i = 0; i < m_spacedim + 2; ++i)
1055 {
1056 u[i] = Array<OneD, NekDouble>(nTotQuadPoints);
1057 }
1058 m_session->LoadParameter("IsentropicBeta", beta, 5.0);
1059 m_session->LoadParameter("IsentropicU0", u0, 1.0);
1060 m_session->LoadParameter("IsentropicV0", v0, 0.5);
1061 m_session->LoadParameter("IsentropicX0", x0, 5.0);
1062 m_session->LoadParameter("IsentropicY0", y0, 0.0);
1063
1064 // Flow parameters
1065 NekDouble r, xbar, ybar, tmp;
1066 NekDouble fac = 1.0 / (16.0 * m_gamma * M_PI * M_PI);
1067
1068 // In 3D zero rhow field.
1069 if (m_spacedim == 3)
1070 {
1071 Vmath::Zero(nTotQuadPoints, &u[3][o], 1);
1072 }
1073
1074 // Fill storage
1075 for (int i = 0; i < nTotQuadPoints; ++i)
1076 {
1077 xbar = x[i] - u0 * time - x0;
1078 ybar = y[i] - v0 * time - y0;
1079 r = sqrt(xbar * xbar + ybar * ybar);
1080 tmp = beta * exp(1 - r * r);
1081 u[0][i + o] =
1082 pow(1.0 - (m_gamma - 1.0) * tmp * tmp * fac, 1.0 / (m_gamma - 1.0));
1083 u[1][i + o] = u[0][i + o] * (u0 - tmp * ybar / (2 * M_PI));
1084 u[2][i + o] = u[0][i + o] * (v0 + tmp * xbar / (2 * M_PI));
1085 u[m_spacedim + 1][i + o] =
1086 pow(u[0][i + o], m_gamma) / (m_gamma - 1.0) +
1087 0.5 * (u[1][i + o] * u[1][i + o] + u[2][i + o] * u[2][i + o]) /
1088 u[0][i + o];
1089 }
1090 Vmath::Vcopy(nTotQuadPoints, u[field].get(), 1, outfield.get(), 1);
1091}
1092
1093/**
1094 * @brief Compute the exact solution for the Ringleb flow problem.
1095 */
1097 int field, Array<OneD, NekDouble> &outarray)
1098{
1099 int nTotQuadPoints = GetTotPoints();
1100
1101 Array<OneD, NekDouble> rho(nTotQuadPoints, 100.0);
1102 Array<OneD, NekDouble> rhou(nTotQuadPoints);
1103 Array<OneD, NekDouble> rhov(nTotQuadPoints);
1104 Array<OneD, NekDouble> E(nTotQuadPoints);
1105 Array<OneD, NekDouble> x(nTotQuadPoints);
1106 Array<OneD, NekDouble> y(nTotQuadPoints);
1107 Array<OneD, NekDouble> z(nTotQuadPoints);
1108
1109 m_fields[0]->GetCoords(x, y, z);
1110
1111 // Flow parameters
1112 NekDouble c, k, phi, r, J, VV, pp, sint, P, ss;
1113 NekDouble J11, J12, J21, J22, det;
1114 NekDouble Fx, Fy;
1115 NekDouble xi, yi;
1116 NekDouble dV;
1117 NekDouble dtheta;
1118 NekDouble par1;
1119 NekDouble theta = M_PI / 4.0;
1120 NekDouble kExt = 0.7;
1121 NekDouble V = kExt * sin(theta);
1122 NekDouble toll = 1.0e-8;
1123 NekDouble errV = 1.0;
1124 NekDouble errTheta = 1.0;
1125 NekDouble gamma = m_gamma;
1126 NekDouble gamma_1_2 = (gamma - 1.0) / 2.0;
1127
1128 for (int i = 0; i < nTotQuadPoints; ++i)
1129 {
1130 while ((abs(errV) > toll) || (abs(errTheta) > toll))
1131 {
1132 VV = V * V;
1133 sint = sin(theta);
1134 c = sqrt(1.0 - gamma_1_2 * VV);
1135 k = V / sint;
1136 phi = 1.0 / k;
1137 pp = phi * phi;
1138 J = 1.0 / c + 1.0 / (3.0 * c * c * c) +
1139 1.0 / (5.0 * c * c * c * c * c) -
1140 0.5 * log((1.0 + c) / (1.0 - c));
1141
1142 r = pow(c, 1.0 / gamma_1_2);
1143 xi = 1.0 / (2.0 * r) * (1.0 / VV - 2.0 * pp) + J / 2.0;
1144 yi = phi / (r * V) * sqrt(1.0 - VV * pp);
1145 par1 = 25.0 - 5.0 * VV;
1146 ss = sint * sint;
1147
1148 Fx = xi - x[i];
1149 Fy = yi - y[i];
1150
1151 J11 =
1152 39062.5 / pow(par1, 3.5) * (1.0 / VV - 2.0 / VV * ss) * V +
1153 1562.5 / pow(par1, 2.5) *
1154 (-2.0 / (VV * V) + 4.0 / (VV * V) * ss) +
1155 12.5 / pow(par1, 1.5) * V + 312.5 / pow(par1, 2.5) * V +
1156 7812.5 / pow(par1, 3.5) * V -
1157 0.25 *
1158 (-1.0 / pow(par1, 0.5) * V / (1.0 - 0.2 * pow(par1, 0.5)) -
1159 (1.0 + 0.2 * pow(par1, 0.5)) /
1160 pow((1.0 - 0.2 * pow(par1, 0.5)), 2.0) /
1161 pow(par1, 0.5) * V) /
1162 (1.0 + 0.2 * pow(par1, 0.5)) * (1.0 - 0.2 * pow(par1, 0.5));
1163
1164 J12 = -6250.0 / pow(par1, 2.5) / VV * sint * cos(theta);
1165 J21 = -6250.0 / (VV * V) * sint / pow(par1, 2.5) *
1166 pow((1.0 - ss), 0.5) +
1167 78125.0 / V * sint / pow(par1, 3.5) * pow((1.0 - ss), 0.5);
1168
1169 // the matrix is singular when theta = pi/2
1170 if (abs(y[i]) < toll && abs(cos(theta)) < toll)
1171 {
1172 J22 = -39062.5 / pow(par1, 3.5) / V +
1173 3125 / pow(par1, 2.5) / (VV * V) +
1174 12.5 / pow(par1, 1.5) * V + 312.5 / pow(par1, 2.5) * V +
1175 7812.5 / pow(par1, 3.5) * V -
1176 0.25 *
1177 (-1.0 / pow(par1, 0.5) * V /
1178 (1.0 - 0.2 * pow(par1, 0.5)) -
1179 (1.0 + 0.2 * pow(par1, 0.5)) /
1180 pow((1.0 - 0.2 * pow(par1, 0.5)), 2.0) /
1181 pow(par1, 0.5) * V) /
1182 (1.0 + 0.2 * pow(par1, 0.5)) *
1183 (1.0 - 0.2 * pow(par1, 0.5));
1184
1185 // dV = -dV/dx * Fx
1186 dV = -1.0 / J22 * Fx;
1187 dtheta = 0.0;
1188 theta = M_PI / 2.0;
1189 }
1190 else
1191 {
1192 J22 = 3125.0 / VV * cos(theta) / pow(par1, 2.5) *
1193 pow((1.0 - ss), 0.5) -
1194 3125.0 / VV * ss / pow(par1, 2.5) / pow((1.0 - ss), 0.5) *
1195 cos(theta);
1196
1197 det = -1.0 / (J11 * J22 - J12 * J21);
1198
1199 // [dV dtheta]' = -[invJ]*[Fx Fy]'
1200 dV = det * (J22 * Fx - J12 * Fy);
1201 dtheta = det * (-J21 * Fx + J11 * Fy);
1202 }
1203
1204 V = V + dV;
1205 theta = theta + dtheta;
1206
1207 errV = abs(dV);
1208 errTheta = abs(dtheta);
1209 }
1210
1211 c = sqrt(1.0 - gamma_1_2 * VV);
1212 r = pow(c, 1.0 / gamma_1_2);
1213
1214 rho[i] = r;
1215 rhou[i] = rho[i] * V * cos(theta);
1216 rhov[i] = rho[i] * V * sin(theta);
1217 P = (c * c) * rho[i] / gamma;
1218 E[i] = P / (gamma - 1.0) +
1219 0.5 * (rhou[i] * rhou[i] / rho[i] + rhov[i] * rhov[i] / rho[i]);
1220
1221 // Resetting the guess value
1222 errV = 1.0;
1223 errTheta = 1.0;
1224 theta = M_PI / 4.0;
1225 V = kExt * sin(theta);
1226 }
1227
1228 switch (field)
1229 {
1230 case 0:
1231 outarray = rho;
1232 break;
1233 case 1:
1234 outarray = rhou;
1235 break;
1236 case 2:
1237 outarray = rhov;
1238 break;
1239 case 3:
1240 outarray = E;
1241 break;
1242 default:
1243 ASSERTL0(false, "Error in variable number!");
1244 break;
1245 }
1246}
1247} // namespace Nektar
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:208
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
Definition: ErrorUtil.hpp:202
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:242
void GetFluxVector(const Array< OneD, const Array< OneD, NekDouble > > &physfield, TensorOfArray3D< NekDouble > &flux)
Return the flux vector for the compressible Euler equations.
CompressibleFlowSystem(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
void GetElmtTimeStep(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, NekDouble > &tstep)
Calculate the maximum timestep on each element subject to CFL restrictions.
void SetBoundaryConditions(Array< OneD, Array< OneD, NekDouble > > &physarray, NekDouble time)
void DoOdeProjection(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble time)
Compute the projection and call the method for imposing the boundary conditions in case of discontinu...
virtual bool v_SupportsShockCaptType(const std::string type) const =0
MultiRegions::ExpListSharedPtr v_GetPressure() override
Array< OneD, NekDouble > GetStabilityLimitVector(const Array< OneD, int > &ExpOrder)
Function to calculate the stability limit for DG/CG (a vector of them).
void InitAdvection()
Create advection and diffusion objects for CFS.
NekDouble v_GetTimeStep(const Array< OneD, const Array< OneD, NekDouble > > &inarray) override
Calculate the maximum timestep subject to CFL restrictions.
const Array< OneD, const Array< OneD, NekDouble > > & GetNormals()
void v_GenerateSummary(SolverUtils::SummaryList &s) override
Print a summary of time stepping parameters.
virtual void v_DoDiffusion(const Array< OneD, Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const Array< OneD, Array< OneD, NekDouble > > &pFwd, const Array< OneD, Array< OneD, NekDouble > > &pBwd)=0
void v_SetInitialConditions(NekDouble initialtime=0.0, bool dumpInitialConditions=true, const int domain=0) override
Set up logic for residual calculation.
void GetExactRinglebFlow(int field, Array< OneD, NekDouble > &outarray)
Ringleb Flow Test Case.
void v_InitObject(bool DeclareFields=true) override
Initialization object for CompressibleFlowSystem class.
void v_GetDensity(const Array< OneD, const Array< OneD, NekDouble > > &physfield, Array< OneD, NekDouble > &density) override
void EvaluateIsentropicVortex(unsigned int field, Array< OneD, NekDouble > &outfield, NekDouble time, const int o=0)
Isentropic Vortex Test Case.
NekDouble GetStabilityLimit(int n)
Function to calculate the stability limit for DG/CG.
void GetFluxVectorDeAlias(const Array< OneD, const Array< OneD, NekDouble > > &physfield, TensorOfArray3D< NekDouble > &flux)
Return the flux vector for the compressible Euler equations by using the de-aliasing technique.
std::vector< CFSBndCondSharedPtr > m_bndConds
Array< OneD, Array< OneD, NekDouble > > m_vecLocs
void v_ExtraFldOutput(std::vector< Array< OneD, NekDouble > > &fieldcoeffs, std::vector< std::string > &variables) override
VariableConverterSharedPtr m_varConv
const Array< OneD, const Array< OneD, NekDouble > > & GetVecLocs()
void SetBoundaryConditionsBwdWeight()
Set up a weight on physical boundaries for boundary condition applications.
std::vector< SolverUtils::ForcingSharedPtr > m_forcing
ArtificialDiffusionSharedPtr m_artificialDiffusion
Array< OneD, NekDouble > v_GetMaxStdVelocity(const NekDouble SpeedSoundFactor) override
Compute the advection velocity in the standard space for each element of the expansion.
void DoAdvection(const Array< OneD, Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble time, const Array< OneD, Array< OneD, NekDouble > > &pFwd, const Array< OneD, Array< OneD, NekDouble > > &pBwd)
Compute the advection terms for the right-hand side.
void InitialiseParameters()
Load CFS parameters from the session file.
void DoDiffusion(const Array< OneD, Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const Array< OneD, Array< OneD, NekDouble > > &pFwd, const Array< OneD, Array< OneD, NekDouble > > &pBwd)
Add the diffusions terms to the right-hand side.
void DoOdeRhs(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble time)
Compute the right-hand side.
void v_SteadyStateResidual(int step, Array< OneD, NekDouble > &L2) override
void v_EvaluateExactSolution(unsigned int field, Array< OneD, NekDouble > &outfield, const NekDouble time=0.0) override
void v_GetVelocity(const Array< OneD, const Array< OneD, NekDouble > > &physfield, Array< OneD, Array< OneD, NekDouble > > &velocity) override
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:143
void DefineProjection(FuncPointerT func, ObjectPointerT obj)
void DefineOdeRhs(FuncPointerT func, ObjectPointerT obj)
void AccumulateRegion(std::string, int iolevel=0)
Accumulate elapsed time for a region.
Definition: Timer.cpp:70
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
A base class for PDEs which include an advection component.
SolverUtils::AdvectionSharedPtr m_advObject
Advection term.
SOLVER_UTILS_EXPORT Array< OneD, NekDouble > GetElmtCFLVals(const bool FlagAcousticCFL=true)
SOLVER_UTILS_EXPORT void v_InitObject(bool DeclareField=true) override
Initialisation object for EquationSystem.
int m_spacedim
Spatial dimension (>= expansion dim).
virtual SOLVER_UTILS_EXPORT void v_SetInitialConditions(NekDouble initialtime=0.0, bool dumpInitialConditions=true, const int domain=0)
SpatialDomains::MeshGraphSharedPtr m_graph
Pointer to graph defining mesh.
LibUtilities::CommSharedPtr m_comm
Communicator.
NekDouble m_timestep
Time step size.
NekDouble m_time
Current time of simulation.
SOLVER_UTILS_EXPORT int GetTraceTotPoints()
Array< OneD, MultiRegions::ExpListSharedPtr > m_fields
Array holding all dependent variables.
SOLVER_UTILS_EXPORT void Checkpoint_Output(const int n)
Write checkpoint file of m_fields.
virtual SOLVER_UTILS_EXPORT void v_EvaluateExactSolution(unsigned int field, Array< OneD, NekDouble > &outfield, const NekDouble time)
SOLVER_UTILS_EXPORT void WriteFld(const std::string &outname)
Write field data to the given filename.
SOLVER_UTILS_EXPORT int GetExpSize()
std::string m_sessionName
Name of the session.
bool m_specHP_dealiasing
Flag to determine if dealisising is usde for the Spectral/hp element discretisation.
LibUtilities::SessionReaderSharedPtr m_session
The session reader.
Array< OneD, Array< OneD, NekDouble > > m_traceNormals
Array holding trace normals for DG simulations in the forwards direction.
enum HomogeneousType m_HomogeneousType
SOLVER_UTILS_EXPORT int GetNpoints()
int m_nchk
Number of checkpoints written so far.
enum MultiRegions::ProjectionType m_projectionType
Type of projection; e.g continuous or discontinuous.
int m_checksteps
Number of steps between checkpoints.
SOLVER_UTILS_EXPORT int GetTotPoints()
static SOLVER_UTILS_EXPORT std::vector< ForcingSharedPtr > Load(const LibUtilities::SessionReaderSharedPtr &pSession, const std::weak_ptr< EquationSystem > &pEquation, const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const unsigned int &pNumForcingFields=0)
Definition: Forcing.cpp:118
Base class for unsteady solvers.
LibUtilities::TimeIntegrationSchemeOperators m_ode
The time integration scheme operators to use.
NekDouble m_cflSafetyFactor
CFL safety factor (comprise between 0 to 1).
SOLVER_UTILS_EXPORT NekDouble MaxTimeStepEstimator()
Get the maximum timestep estimator for cfl control.
SOLVER_UTILS_EXPORT void v_GenerateSummary(SummaryList &s) override
Print a summary of time stepping parameters.
bool m_homoInitialFwd
Flag to determine if simulation should start in homogeneous forward transformed state.
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::vector< PointsKey > PointsKeyVector
Definition: Points.h:231
@ beta
Gauss Radau pinned at x=-1,.
Definition: PointsType.h:59
@ P
Monomial polynomials .
Definition: BasisType.h:62
const std::vector< NekDouble > velocity
std::shared_ptr< RiemannSolver > RiemannSolverSharedPtr
A shared pointer to an EquationSystem object.
AdvectionFactory & GetAdvectionFactory()
Gets the factory for initialising advection objects.
Definition: Advection.cpp:43
std::vector< std::pair< std::string, std::string > > SummaryList
Definition: Misc.h:46
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
RiemannSolverFactory & GetRiemannSolverFactory()
std::shared_ptr< GeomFactors > GeomFactorsSharedPtr
Pointer to a GeomFactors object.
Definition: GeomFactors.h:60
@ eDeformed
Geometry is curved or has non-constant factors.
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:174
std::vector< double > z(NPUPPER)
std::vector< double > d(NPUPPER *NPUPPER)
CFSBndCondFactory & GetCFSBndCondFactory()
Declaration of the boundary condition factory singleton.
Definition: CFSBndCond.cpp:41
static Array< OneD, Array< OneD, NekDouble > > NullNekDoubleArrayOfArray
ArtificialDiffusionFactory & GetArtificialDiffusionFactory()
Declaration of the artificial diffusion factory singleton.
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.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 Neg(int n, T *x, const int incx)
Negate x = -x.
Definition: Vmath.hpp:292
T Vmin(int n, const T *x, const int incx)
Return the minimum element in x - called vmin to avoid conflict with min.
Definition: Vmath.hpp:725
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
T Vsum(int n, const T *x, const int incx)
Subtract return sum(x)
Definition: Vmath.hpp:608
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 FillWhiteNoise(int n, const T eps, T *x, const int incx, int outseed)
Fills a vector with white noise.
Definition: Vmath.cpp:154
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.hpp:825
scalarT< T > abs(scalarT< T > in)
Definition: scalar.hpp:298
scalarT< T > log(scalarT< T > in)
Definition: scalar.hpp:303
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294