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