Nektar++
UnsteadyAdvectionDiffusion.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: UnsteadyAdvectionDiffusion.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: Unsteady advection-diffusion solve routines
32//
33///////////////////////////////////////////////////////////////////////////////
34
35#include <iostream>
36
37#include <boost/core/ignore_unused.hpp>
38
41
42namespace Nektar
43{
44using namespace LibUtilities;
45
48 "UnsteadyAdvectionDiffusion", UnsteadyAdvectionDiffusion::create);
49
53 : UnsteadySystem(pSession, pGraph), AdvectionSystem(pSession, pGraph)
54{
55 m_planeNumber = 0;
56}
57
58/**
59 * @brief Initialisation object for the unsteady linear advection
60 * diffusion equation.
61 */
63{
64 AdvectionSystem::v_InitObject(DeclareFields);
65
66 m_session->LoadParameter("wavefreq", m_waveFreq, 0.0);
67 m_session->LoadParameter("epsilon", m_epsilon, 1.0);
68
69 // turn on substepping
70 m_session->MatchSolverInfo("Extrapolation", "SubStepping",
71 m_subSteppingScheme, false);
72
73 // Define Velocity fields
75 std::vector<std::string> vel;
76 vel.push_back("Vx");
77 vel.push_back("Vy");
78 vel.push_back("Vz");
79 vel.resize(m_spacedim);
80
81 GetFunction("AdvectionVelocity")->Evaluate(vel, m_velocity);
82
83 m_session->MatchSolverInfo("SpectralVanishingViscosity", "True",
84 m_useSpecVanVisc, false);
85
86 // check to see if it is explicity turned off
87 m_session->MatchSolverInfo("GJPStabilisation", "False",
89
90 // if GJPStabilisation set to False bool will be true and
91 // if not false so negate/revese bool
93
94 m_session->LoadParameter("GJPJumpScale", m_GJPJumpScale, 1.0);
95
97 {
98 m_session->LoadParameter("SVVCutoffRatio", m_sVVCutoffRatio, 0.75);
99 m_session->LoadParameter("SVVDiffCoeff", m_sVVDiffCoeff, 0.1);
100 }
101
102 // Type of advection and diffusion classes to be used
103 switch (m_projectionType)
104 {
105 // Discontinuous field
107 {
108 // Do not forwards transform initial condition
109 m_homoInitialFwd = false;
110
111 // Advection term
112 std::string advName;
113 std::string riemName;
114 m_session->LoadSolverInfo("AdvectionType", advName, "WeakDG");
116 advName, advName);
117 m_advObject->SetFluxVector(
119 m_session->LoadSolverInfo("UpwindType", riemName, "Upwind");
122 riemName, m_session);
123 m_riemannSolver->SetScalar(
125 m_advObject->SetRiemannSolver(m_riemannSolver);
126 m_advObject->InitObject(m_session, m_fields);
127
128 // Diffusion term
130 {
131 std::string diffName;
132 m_session->LoadSolverInfo("DiffusionType", diffName, "LDG");
134 diffName, diffName);
135 m_diffusion->SetFluxVector(
137 m_diffusion->InitObject(m_session, m_fields);
138 }
139
141 "SubSteppingScheme is not set up for DG projection");
142 break;
143 }
144 // Continuous field
147 {
148 // Advection term
149 std::string advName;
150 m_session->LoadSolverInfo("AdvectionType", advName,
151 "NonConservative");
153 advName, advName);
154 m_advObject->SetFluxVector(
156
157 if (advName.compare("WeakDG") == 0)
158 {
159 std::string riemName;
160 m_session->LoadSolverInfo("UpwindType", riemName, "Upwind");
163 riemName, m_session);
164 m_riemannSolver->SetScalar(
166 m_advObject->SetRiemannSolver(m_riemannSolver);
167 m_advObject->InitObject(m_session, m_fields);
168 }
169
170 // In case of Galerkin explicit diffusion gives an error
172 {
173 ASSERTL0(false, "Explicit Galerkin diffusion not set up.");
174 }
175 // In case of Galerkin implicit diffusion: do nothing
176 break;
177 }
178 default:
179 {
180 ASSERTL0(false, "Unsupported projection type.");
181 break;
182 }
183 }
184
185 // Forcing terms
186 m_forcing = SolverUtils::Forcing::Load(m_session, shared_from_this(),
187 m_fields, m_fields.size());
188
190 this);
193
194 if (m_subSteppingScheme) // Substepping
195 {
197 "Projection must be set to Mixed_CG_Discontinuous for "
198 "substepping");
200 }
201}
202
203/**
204 * @brief Unsteady linear advection diffusion equation destructor.
205 */
207{
208}
209
210/**
211 * @brief Get the normal velocity for the unsteady linear advection
212 * diffusion equation.
213 */
215{
216 return GetNormalVel(m_velocity);
217}
218
220 const Array<OneD, const Array<OneD, NekDouble>> &velfield)
221{
222 // Number of trace (interface) points
223 int i;
224 int nTracePts = GetTraceNpoints();
225
226 // Auxiliary variable to compute the normal velocity
227 Array<OneD, NekDouble> tmp(nTracePts);
228 m_traceVn = Array<OneD, NekDouble>(nTracePts, 0.0);
229
230 // Reset the normal velocity
231 Vmath::Zero(nTracePts, m_traceVn, 1);
232
233 for (i = 0; i < velfield.size(); ++i)
234 {
235 m_fields[0]->ExtractTracePhys(velfield[i], tmp);
236
237 Vmath::Vvtvp(nTracePts, m_traceNormals[i], 1, tmp, 1, m_traceVn, 1,
238 m_traceVn, 1);
239 }
240
241 return m_traceVn;
242}
243
244/**
245 * @brief Compute the right-hand side for the unsteady linear advection
246 * diffusion problem.
247 *
248 * @param inarray Given fields.
249 * @param outarray Calculated solution.
250 * @param time Time.
251 */
253 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
254 Array<OneD, Array<OneD, NekDouble>> &outarray, const NekDouble time)
255{
256 // Number of fields (variables of the problem)
257 int nVariables = inarray.size();
258
259 // Number of solution points
260 int nSolutionPts = GetNpoints();
261
262 // RHS computation using the new advection base class
263 m_advObject->Advect(nVariables, m_fields, m_velocity, inarray, outarray,
264 time);
265
266 // Negate the RHS
267 for (int i = 0; i < nVariables; ++i)
268 {
269 Vmath::Neg(nSolutionPts, outarray[i], 1);
270 }
271
273 {
274 Array<OneD, Array<OneD, NekDouble>> outarrayDiff(nVariables);
275 for (int i = 0; i < nVariables; ++i)
276 {
277 outarrayDiff[i] = Array<OneD, NekDouble>(nSolutionPts, 0.0);
278 }
279
280 m_diffusion->Diffuse(nVariables, m_fields, inarray, outarrayDiff);
281
282 for (int i = 0; i < nVariables; ++i)
283 {
284 Vmath::Vadd(nSolutionPts, &outarrayDiff[i][0], 1, &outarray[i][0],
285 1, &outarray[i][0], 1);
286 }
287 }
288
289 // Add forcing terms
290 for (auto &x : m_forcing)
291 {
292 // set up non-linear terms
293 x->Apply(m_fields, inarray, outarray, time);
294 }
295}
296
297/**
298 * @brief Compute the projection for the unsteady advection
299 * diffusion problem.
300 *
301 * @param inarray Given fields.
302 * @param outarray Calculated solution.
303 * @param time Time.
304 */
306 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
307 Array<OneD, Array<OneD, NekDouble>> &outarray, const NekDouble time)
308{
309 int i;
310 int nvariables = inarray.size();
312 switch (m_projectionType)
313 {
315 {
316 // Just copy over array
317 if (inarray != outarray)
318 {
319 int npoints = GetNpoints();
320
321 for (i = 0; i < nvariables; ++i)
322 {
323 Vmath::Vcopy(npoints, inarray[i], 1, outarray[i], 1);
324 }
325 }
326 break;
327 }
330 {
332
333 for (i = 0; i < nvariables; ++i)
334 {
335 m_fields[i]->FwdTrans(inarray[i], coeffs);
336 m_fields[i]->BwdTrans(coeffs, outarray[i]);
337 }
338 break;
339 }
340 default:
341 {
342 ASSERTL0(false, "Unknown projection scheme");
343 break;
344 }
345 }
346}
347
348/* @brief Compute the diffusion term implicitly.
349 *
350 * @param inarray Given fields.
351 * @param outarray Calculated solution.
352 * @param time Time.
353 * @param lambda Diffusion coefficient.
354 */
356 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
357 Array<OneD, Array<OneD, NekDouble>> &outarray, const NekDouble time,
358 const NekDouble lambda)
359{
360 int nvariables = inarray.size();
361 int nq = m_fields[0]->GetNpoints();
362
365
366 // Add factor is GJP turned on
368 {
370 }
371
373 {
376 }
378 {
380 }
381
383 for (int n = 0; n < nvariables; ++n)
384 {
385 F[n] = Array<OneD, NekDouble>(nq);
386 }
387
388 // We solve ( \nabla^2 - HHlambda ) Y[i] = rhs [i]
389 // inarray = input: \hat{rhs} -> output: \hat{Y}
390 // outarray = output: nabla^2 \hat{Y}
391 // where \hat = modal coeffs
392 for (int i = 0; i < nvariables; ++i)
393 {
394 // Multiply 1.0/timestep/lambda
395 Vmath::Smul(nq, -factors[StdRegions::eFactorLambda], inarray[i], 1,
396 F[i], 1);
397 }
398
399 // Setting boundary conditions
401
402 for (int i = 0; i < nvariables; ++i)
403 {
404 // Solve a system of equations with Helmholtz solver
405 m_fields[i]->HelmSolve(F[i], m_fields[i]->UpdateCoeffs(), factors);
406
407 m_fields[i]->BwdTrans(m_fields[i]->GetCoeffs(), outarray[i]);
408 }
409}
410
411/**
412 * @brief Return the flux vector for the advection part.
413 *
414 * @param physfield Fields.
415 * @param flux Resulting flux.
416 */
418 const Array<OneD, Array<OneD, NekDouble>> &physfield,
420{
421 ASSERTL1(flux[0].size() == m_velocity.size(),
422 "Dimension of flux array and velocity array do not match");
423
424 const int nq = m_fields[0]->GetNpoints();
425
426 for (int i = 0; i < flux.size(); ++i)
427 {
428 for (int j = 0; j < flux[0].size(); ++j)
429 {
430 Vmath::Vmul(nq, physfield[i], 1, m_velocity[j], 1, flux[i][j], 1);
431 }
432 }
433}
434
435/**
436 * @brief Return the flux vector for the diffusion part.
437 *
438 * @param i Equation number.
439 * @param j Spatial direction.
440 * @param physfield Fields.
441 * @param derivatives First order derivatives.
442 * @param flux Resulting flux.
443 */
445 const Array<OneD, Array<OneD, NekDouble>> &inarray,
446 const Array<OneD, Array<OneD, Array<OneD, NekDouble>>> &qfield,
447 Array<OneD, Array<OneD, Array<OneD, NekDouble>>> &viscousTensor)
448{
449 boost::ignore_unused(inarray);
450
451 unsigned int nDim = qfield.size();
452 unsigned int nConvectiveFields = qfield[0].size();
453 unsigned int nPts = qfield[0][0].size();
454 for (unsigned int j = 0; j < nDim; ++j)
455 {
456 for (unsigned int i = 0; i < nConvectiveFields; ++i)
457 {
458 Vmath::Smul(nPts, m_epsilon, qfield[j][i], 1, viscousTensor[j][i],
459 1);
460 }
461 }
462}
463
465{
468 {
470 s, "GJP Stab. Impl. ",
471 m_session->GetSolverInfo("GJPStabilisation"));
472 SolverUtils::AddSummaryItem(s, "GJP Stab. JumpScale", m_GJPJumpScale);
473 }
474}
475
476/**
477 * Perform the extrapolation.
478 */
480{
482 {
483 SubStepAdvance(step, m_time);
484 }
485
486 return false;
487}
488
489/**
490 *
491 */
493{
494 int n;
495 int nsubsteps;
496
497 NekDouble dt;
498
499 Array<OneD, Array<OneD, NekDouble>> fields, velfields;
500
501 static int ncalls = 1;
502 int nint = std::min(ncalls++, m_intSteps);
503
505
506 LibUtilities::CommSharedPtr comm = m_session->GetComm();
507
508 // Get the proper time step with CFL control
509 dt = GetSubstepTimeStep();
510
511 nsubsteps = (m_timestep > dt) ? ((int)(m_timestep / dt) + 1) : 1;
512 nsubsteps = std::max(m_minsubsteps, nsubsteps);
513
514 dt = m_timestep / nsubsteps;
515
516 if (m_infosteps && !((nstep + 1) % m_infosteps) && comm->GetRank() == 0)
517 {
518 std::cout << "Sub-integrating using " << nsubsteps
519 << " steps over Dt = " << m_timestep
520 << " (SubStep CFL=" << m_cflSafetyFactor << ")" << std::endl;
521 }
522
523 const TripleArray &solutionVector = m_intScheme->GetSolutionVector();
524
525 for (int m = 0; m < nint; ++m)
526 {
527 // We need to update the fields held by the m_intScheme
528 fields = solutionVector[m];
529
530 // Initialise NS solver which is set up to use a GLM method
531 // with calls to EvaluateAdvection_SetPressureBCs and
532 // SolveUnsteadyStokesSystem
533 m_subStepIntegrationScheme->InitializeScheme(dt, fields, time,
535
536 for (n = 0; n < nsubsteps; ++n)
537 {
538 fields = m_subStepIntegrationScheme->TimeIntegrate(n, dt);
539 }
540
541 // Reset time integrated solution in m_intScheme
542 m_intScheme->SetSolutionVector(m, fields);
543 }
544}
545
546/**
547 *
548 */
550{
551 int n_element = m_fields[0]->GetExpSize();
552
553 const Array<OneD, int> ExpOrder = m_fields[0]->EvalBasisNumModesMaxPerExp();
554 Array<OneD, int> ExpOrderList(n_element, ExpOrder);
555
556 const NekDouble cLambda = 0.2; // Spencer book pag. 317
557
558 Array<OneD, NekDouble> tstep(n_element, 0.0);
559 Array<OneD, NekDouble> stdVelocity(n_element, 0.0);
560
561 stdVelocity = GetMaxStdVelocity(m_velocity);
562
563 for (int el = 0; el < n_element; ++el)
564 {
565 tstep[el] =
566 m_cflSafetyFactor / (stdVelocity[el] * cLambda *
567 (ExpOrder[el] - 1) * (ExpOrder[el] - 1));
568 }
569
570 NekDouble TimeStep = Vmath::Vmin(n_element, tstep, 1);
571 m_session->GetComm()->AllReduce(TimeStep, LibUtilities::ReduceMin);
572
573 return TimeStep;
574}
575
577 const LibUtilities::TimeIntegrationSchemeSharedPtr &IntegrationScheme)
578{
579 // Set to 1 for first step and it will then be increased in
580 // time advance routines
581 unsigned int order = IntegrationScheme->GetOrder();
582
583 // Set to 1 for first step and it will then be increased in
584 // time advance routines
585 if ((IntegrationScheme->GetName() == "Euler" &&
586 IntegrationScheme->GetVariant() == "Backward") ||
587 (IntegrationScheme->GetName() == "BDFImplicit" &&
588 (order == 1 || order == 2)))
589 {
590 // Note RK first order SSP is just Forward Euler.
593 "RungeKutta", "SSP", order, std::vector<NekDouble>());
594 }
595 else
596 {
598 "Integration method not suitable: "
599 "Options include BackwardEuler or BDFImplicitOrder1");
600 }
601
602 m_intSteps = IntegrationScheme->GetNumIntegrationPhases();
603
604 // set explicit time-integration class operators
609}
610
611/**
612 * Explicit Advection terms used by SubStepAdvance time integration
613 */
615 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
616 Array<OneD, Array<OneD, NekDouble>> &outarray, const NekDouble time)
617{
618 int i;
619 int nVariables = inarray.size();
620
621 /// Get the number of coefficients
622 int ncoeffs = m_fields[0]->GetNcoeffs();
623
624 /// Define an auxiliary variable to compute the RHS
625 Array<OneD, Array<OneD, NekDouble>> WeakAdv(nVariables);
626 WeakAdv[0] = Array<OneD, NekDouble>(ncoeffs * nVariables);
627 for (i = 1; i < nVariables; ++i)
628 {
629 WeakAdv[i] = WeakAdv[i - 1] + ncoeffs;
630 }
631
632 // Currently assume velocity field is time independent and does not
633 // therefore need extrapolating. RHS computation using the advection base
634 // class
635 m_advObject->Advect(nVariables, m_fields, m_velocity, inarray, outarray,
636 time);
637
638 for (i = 0; i < nVariables; ++i)
639 {
640 m_fields[i]->IProductWRTBase(outarray[i], WeakAdv[i]);
641 // negation requried due to sign of DoAdvection term to be consistent
642 Vmath::Neg(ncoeffs, WeakAdv[i], 1);
643 }
644
645 AddAdvectionPenaltyFlux(m_velocity, inarray, WeakAdv);
646
647 /// Operations to compute the RHS
648 for (i = 0; i < nVariables; ++i)
649 {
650 // Negate the RHS
651 Vmath::Neg(ncoeffs, WeakAdv[i], 1);
652
653 /// Multiply the flux by the inverse of the mass matrix
654 m_fields[i]->MultiplyByElmtInvMass(WeakAdv[i], WeakAdv[i]);
655
656 /// Store in outarray the physical values of the RHS
657 m_fields[i]->BwdTrans(WeakAdv[i], outarray[i]);
658 }
659}
660
661/**
662 * Projection used by SubStepAdvance time integration
663 */
665 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
666 Array<OneD, Array<OneD, NekDouble>> &outarray, const NekDouble time)
667{
668 boost::ignore_unused(time);
669
670 ASSERTL1(inarray.size() == outarray.size(),
671 "Inarray and outarray of different sizes ");
672
673 for (int i = 0; i < inarray.size(); ++i)
674 {
675 Vmath::Vcopy(inarray[i].size(), inarray[i], 1, outarray[i], 1);
676 }
677}
678
680 const Array<OneD, const Array<OneD, NekDouble>> &velfield,
681 const Array<OneD, const Array<OneD, NekDouble>> &physfield,
683{
684 ASSERTL1(physfield.size() == Outarray.size(),
685 "Physfield and outarray are of different dimensions");
686
687 int i;
688
689 /// Number of trace points
690 int nTracePts = m_fields[0]->GetTrace()->GetNpoints();
691
692 /// Forward state array
693 Array<OneD, NekDouble> Fwd(3 * nTracePts);
694
695 /// Backward state array
696 Array<OneD, NekDouble> Bwd = Fwd + nTracePts;
697
698 /// upwind numerical flux state array
699 Array<OneD, NekDouble> numflux = Bwd + nTracePts;
700
701 /// Normal velocity array
703
704 for (i = 0; i < physfield.size(); ++i)
705 {
706 /// Extract forwards/backwards trace spaces
707 /// Note: Needs to have correct i value to get boundary conditions
708 m_fields[i]->GetFwdBwdTracePhys(physfield[i], Fwd, Bwd);
709
710 /// Upwind between elements
711 m_fields[0]->GetTrace()->Upwind(Vn, Fwd, Bwd, numflux);
712
713 /// Construct difference between numflux and Fwd,Bwd
714 Vmath::Vsub(nTracePts, numflux, 1, Fwd, 1, Fwd, 1);
715 Vmath::Vsub(nTracePts, numflux, 1, Bwd, 1, Bwd, 1);
716
717 /// Calculate the numerical fluxes multipling Fwd, Bwd and
718 /// numflux by the normal advection velocity
719 Vmath::Vmul(nTracePts, Fwd, 1, Vn, 1, Fwd, 1);
720 Vmath::Vmul(nTracePts, Bwd, 1, Vn, 1, Bwd, 1);
721
722 m_fields[0]->AddFwdBwdTraceIntegral(Fwd, Bwd, Outarray[i]);
723 }
724}
725
727 const Array<OneD, Array<OneD, NekDouble>> inarray)
728{
729
730 int n_points_0 = m_fields[0]->GetExp(0)->GetTotPoints();
731 int n_element = m_fields[0]->GetExpSize();
732 int nvel = inarray.size();
733 int cnt;
734
735 ASSERTL0(nvel >= 2, "Method not implemented for 1D");
736
737 NekDouble pntVelocity;
738
739 // Getting the standard velocity vector on the 2D normal space
740 Array<OneD, Array<OneD, NekDouble>> stdVelocity(nvel);
741 Array<OneD, NekDouble> maxV(n_element, 0.0);
743
744 for (int i = 0; i < nvel; ++i)
745 {
746 stdVelocity[i] = Array<OneD, NekDouble>(n_points_0);
747 }
748
749 if (nvel == 2)
750 {
751 cnt = 0.0;
752 for (int el = 0; el < n_element; ++el)
753 {
754 int n_points = m_fields[0]->GetExp(el)->GetTotPoints();
755 ptsKeys = m_fields[0]->GetExp(el)->GetPointsKeys();
756
757 // reset local space if necessary
758 if (n_points != n_points_0)
759 {
760 for (int j = 0; j < nvel; ++j)
761 {
762 stdVelocity[j] = Array<OneD, NekDouble>(n_points);
763 }
764 n_points_0 = n_points;
765 }
766
768 ->GetExp(el)
769 ->GetGeom()
770 ->GetMetricInfo()
771 ->GetDerivFactors(ptsKeys);
772
773 if (m_fields[0]
774 ->GetExp(el)
775 ->GetGeom()
776 ->GetMetricInfo()
777 ->GetGtype() == SpatialDomains::eDeformed)
778 {
779 for (int i = 0; i < n_points; i++)
780 {
781 stdVelocity[0][i] = gmat[0][i] * inarray[0][i + cnt] +
782 gmat[2][i] * inarray[1][i + cnt];
783
784 stdVelocity[1][i] = gmat[1][i] * inarray[0][i + cnt] +
785 gmat[3][i] * inarray[1][i + cnt];
786 }
787 }
788 else
789 {
790 for (int i = 0; i < n_points; i++)
791 {
792 stdVelocity[0][i] = gmat[0][0] * inarray[0][i + cnt] +
793 gmat[2][0] * inarray[1][i + cnt];
794
795 stdVelocity[1][i] = gmat[1][0] * inarray[0][i + cnt] +
796 gmat[3][0] * inarray[1][i + cnt];
797 }
798 }
799
800 cnt += n_points;
801
802 for (int i = 0; i < n_points; i++)
803 {
804 pntVelocity = stdVelocity[0][i] * stdVelocity[0][i] +
805 stdVelocity[1][i] * stdVelocity[1][i];
806
807 if (pntVelocity > maxV[el])
808 {
809 maxV[el] = pntVelocity;
810 }
811 }
812 maxV[el] = sqrt(maxV[el]);
813 }
814 }
815 else
816 {
817 cnt = 0;
818 for (int el = 0; el < n_element; ++el)
819 {
820
821 int n_points = m_fields[0]->GetExp(el)->GetTotPoints();
822 ptsKeys = m_fields[0]->GetExp(el)->GetPointsKeys();
823
824 // reset local space if necessary
825 if (n_points != n_points_0)
826 {
827 for (int j = 0; j < nvel; ++j)
828 {
829 stdVelocity[j] = Array<OneD, NekDouble>(n_points);
830 }
831 n_points_0 = n_points;
832 }
833
835 ->GetExp(el)
836 ->GetGeom()
837 ->GetMetricInfo()
838 ->GetDerivFactors(ptsKeys);
839
840 if (m_fields[0]
841 ->GetExp(el)
842 ->GetGeom()
843 ->GetMetricInfo()
844 ->GetGtype() == SpatialDomains::eDeformed)
845 {
846 for (int i = 0; i < n_points; i++)
847 {
848 stdVelocity[0][i] = gmat[0][i] * inarray[0][i + cnt] +
849 gmat[3][i] * inarray[1][i + cnt] +
850 gmat[6][i] * inarray[2][i + cnt];
851
852 stdVelocity[1][i] = gmat[1][i] * inarray[0][i + cnt] +
853 gmat[4][i] * inarray[1][i + cnt] +
854 gmat[7][i] * inarray[2][i + cnt];
855
856 stdVelocity[2][i] = gmat[2][i] * inarray[0][i + cnt] +
857 gmat[5][i] * inarray[1][i + cnt] +
858 gmat[8][i] * inarray[2][i + cnt];
859 }
860 }
861 else
862 {
863 for (int i = 0; i < n_points; i++)
864 {
865 stdVelocity[0][i] = gmat[0][0] * inarray[0][i + cnt] +
866 gmat[3][0] * inarray[1][i + cnt] +
867 gmat[6][0] * inarray[2][i + cnt];
868
869 stdVelocity[1][i] = gmat[1][0] * inarray[0][i + cnt] +
870 gmat[4][0] * inarray[1][i + cnt] +
871 gmat[7][0] * inarray[2][i + cnt];
872
873 stdVelocity[2][i] = gmat[2][0] * inarray[0][i + cnt] +
874 gmat[5][0] * inarray[1][i + cnt] +
875 gmat[8][0] * inarray[2][i + cnt];
876 }
877 }
878
879 cnt += n_points;
880
881 for (int i = 0; i < n_points; i++)
882 {
883 pntVelocity = stdVelocity[0][i] * stdVelocity[0][i] +
884 stdVelocity[1][i] * stdVelocity[1][i] +
885 stdVelocity[2][i] * stdVelocity[2][i];
886
887 if (pntVelocity > maxV[el])
888 {
889 maxV[el] = pntVelocity;
890 }
891 }
892
893 maxV[el] = sqrt(maxV[el]);
894 // cout << maxV[el]*maxV[el] << endl;
895 }
896 }
897
898 return maxV;
899}
900} // 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
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
void DefineProjection(FuncPointerT func, ObjectPointerT obj)
void DefineOdeRhs(FuncPointerT func, ObjectPointerT obj)
void DefineImplicitSolve(FuncPointerT func, ObjectPointerT obj)
A base class for PDEs which include an advection component.
SolverUtils::AdvectionSharedPtr m_advObject
Advection term.
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 int GetTraceNpoints()
NekDouble m_timestep
Time step size.
NekDouble m_time
Current time of simulation.
Array< OneD, MultiRegions::ExpListSharedPtr > m_fields
Array holding all dependent variables.
SOLVER_UTILS_EXPORT int GetExpSize()
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.
SOLVER_UTILS_EXPORT int GetNpoints()
SOLVER_UTILS_EXPORT int GetNcoeffs()
enum MultiRegions::ProjectionType m_projectionType
Type of projection; e.g continuous or discontinuous.
SOLVER_UTILS_EXPORT void SetBoundaryConditions(NekDouble time)
Evaluates the boundary conditions at the given time.
SOLVER_UTILS_EXPORT SessionFunctionSharedPtr GetFunction(std::string name, const MultiRegions::ExpListSharedPtr &field=MultiRegions::NullExpListSharedPtr, bool cache=false)
Get a SessionFunction by name.
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.
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.
bool m_homoInitialFwd
Flag to determine if simulation should start in homogeneous forward transformed state.
UnsteadyAdvectionDiffusion(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
Session reader.
SolverUtils::DiffusionSharedPtr m_diffusion
void DoOdeProjection(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble time)
Perform the projection.
Array< OneD, NekDouble > & GetNormalVelocity()
Get the normal velocity based on m_velocity.
virtual bool v_PreIntegrate(int step) override
PreIntegration step for substepping.
virtual void v_InitObject(bool DeclareFields=true) override
Initialise the object.
void DoOdeRhs(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble time)
Compute the RHS.
Array< OneD, Array< OneD, NekDouble > > m_velocity
void SetUpSubSteppingTimeIntegration(const LibUtilities::TimeIntegrationSchemeSharedPtr &IntegrationScheme)
void DoImplicitSolve(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, NekDouble time, NekDouble lambda)
Solve implicitly the diffusion term.
void AddAdvectionPenaltyFlux(const Array< OneD, const Array< OneD, NekDouble > > &velfield, const Array< OneD, const Array< OneD, NekDouble > > &physfield, Array< OneD, Array< OneD, NekDouble > > &Outarray)
std::vector< SolverUtils::ForcingSharedPtr > m_forcing
Forcing terms.
Array< OneD, NekDouble > & GetNormalVel(const Array< OneD, const Array< OneD, NekDouble > > &velfield)
Get the normal velocity based on input velfield.
void GetFluxVectorAdv(const Array< OneD, Array< OneD, NekDouble > > &physfield, Array< OneD, Array< OneD, Array< OneD, NekDouble > > > &flux)
Evaluate the flux at each solution point for the advection part.
static SolverUtils::EquationSystemSharedPtr create(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
Creates an instance of this class.
void SubStepAdvection(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble time)
void SubStepAdvance(int nstep, NekDouble time)
static std::string className
Name of class.
Array< OneD, NekDouble > GetMaxStdVelocity(const Array< OneD, Array< OneD, NekDouble > > inarray)
SolverUtils::RiemannSolverSharedPtr m_riemannSolver
void GetFluxVectorDiff(const Array< OneD, Array< OneD, NekDouble > > &inarray, const Array< OneD, Array< OneD, Array< OneD, NekDouble > > > &qfield, Array< OneD, Array< OneD, Array< OneD, NekDouble > > > &viscousTensor)
Evaluate the flux at each solution point for the diffusion part.
virtual void v_GenerateSummary(SolverUtils::SummaryList &s) override
Print Summary.
void SubStepProjection(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble time)
LibUtilities::TimeIntegrationSchemeSharedPtr m_subStepIntegrationScheme
LibUtilities::TimeIntegrationSchemeOperators m_subStepIntegrationOps
TimeIntegrationSchemeFactory & GetTimeIntegrationSchemeFactory()
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::vector< PointsKey > PointsKeyVector
Definition: Points.h:236
std::shared_ptr< TimeIntegrationScheme > TimeIntegrationSchemeSharedPtr
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:57
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
DiffusionFactory & GetDiffusionFactory()
Definition: Diffusion.cpp:41
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
RiemannSolverFactory & GetRiemannSolverFactory()
@ eDeformed
Geometry is curved or has non-constant factors.
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:176
std::map< ConstFactorType, NekDouble > ConstFactorMap
Definition: StdRegions.hpp:408
StdRegions::ConstFactorMap factors
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
double NekDouble
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.
Definition: Vmath.cpp:207
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
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 Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1191
void Vsub(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Subtract vector z = x-y.
Definition: Vmath.cpp:414
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294