Nektar++
CompressibleFlowSystemImplicit.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: CompressibleFlowSystemImplicit.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
37
39
40using namespace std;
41
42namespace Nektar
43{
46 : UnsteadySystem(pSession, pGraph), CompressibleFlowSystem(pSession, pGraph)
47{
48}
49
50/**
51 * @brief Initialization object for CFSImplicit class.
52 */
53void CFSImplicit::v_InitObject(bool DeclareFields)
54{
56 m_explicitAdvection = false;
57 m_explicitDiffusion = false;
58
59 // Initialise implicit parameters
60 m_session->MatchSolverInfo("FLAGIMPLICITITSSTATISTICS", "True",
62
63 m_session->LoadParameter("JacobiFreeEps", m_jacobiFreeEps, 5.0E-8);
64
65 m_session->LoadParameter("nPadding", m_nPadding, 4);
66
67 m_session->LoadParameter("NewtonRelativeIteTol", m_newtonRelativeIteTol,
68 1.0E-12);
69 WARNINGL0(!m_session->DefinesParameter("NewtonAbsoluteIteTol"),
70 "Please specify NewtonRelativeIteTol instead of "
71 "NewtonAbsoluteIteTol in XML session file");
72
73 int ntmp;
74 m_session->LoadParameter("AdvectionJacFlag", ntmp, 1);
75 m_advectionJacFlag = (ntmp != 0);
76
77 m_session->LoadParameter("ViscousJacFlag", ntmp, 1);
78 m_viscousJacFlag = (ntmp != 0);
79
80 // Initialise implicit functors
83
85}
86
88{
89 int nvariables = m_fields.size();
90 int ntotal = m_fields[0]->GetNcoeffs() * nvariables;
91
92 std::string SolverType = "Newton";
93 if (m_session->DefinesSolverInfo("NonlinSysIterSolver"))
94 {
95 SolverType = m_session->GetSolverInfo("NonlinSysIterSolver");
96 }
98 "NekNonlinSys '" + SolverType + "' is not defined.\n");
99
100 // Create the key to hold settings for nonlin solver
102 // Load required LinSys parameters:
103 m_session->LoadParameter("NekLinSysMaxIterations",
105 m_session->LoadParameter("LinSysMaxStorage", key.m_LinSysMaxStorage, 30);
106 m_session->LoadParameter("GMRESMaxHessMatBand", key.m_KrylovMaxHessMatBand,
107 31);
108 m_session->MatchSolverInfo("GMRESLeftPrecon", "True",
109 key.m_NekLinSysLeftPrecon, false);
110 m_session->MatchSolverInfo("GMRESRightPrecon", "True",
111 key.m_NekLinSysRightPrecon, true);
112 // Load required NonLinSys parameters:
113 m_session->LoadParameter("NekNonlinSysMaxIterations",
115 m_session->LoadParameter("NonlinIterTolRelativeL2",
116 key.m_NonlinIterTolRelativeL2, 1.0E-3);
117 m_session->LoadParameter("LinSysRelativeTolInNonlin",
118 key.m_LinSysRelativeTolInNonlin, 5.0E-2);
119 m_session->LoadSolverInfo("LinSysIterSolverTypeInNonlin",
120 key.m_LinSysIterSolverTypeInNonlin, "GMRES");
121
122 int GMRESCentralDifference = 0;
123 m_session->LoadParameter("GMRESCentralDifference", GMRESCentralDifference,
124 0);
125 switch (GMRESCentralDifference)
126 {
127 case 1:
128 key.m_DifferenceFlag0 = true;
129 key.m_DifferenceFlag1 = false;
130 break;
131 case 2:
132 key.m_DifferenceFlag0 = true;
133 key.m_DifferenceFlag1 = true;
134 break;
135 default:
136 key.m_DifferenceFlag0 = false;
137 key.m_DifferenceFlag1 = false;
138 break;
139 }
140
141 // Initialize operator
145 this);
147
148 // Initialize trace
149 const auto locTraceToTraceMap = m_fields[0]->GetLocTraceToTraceMap();
150 locTraceToTraceMap->CalcLocTracePhysToTraceIDMap(m_fields[0]->GetTrace(),
151 m_spacedim);
152 for (int i = 1; i < nvariables; i++)
153 {
154 m_fields[i]->GetLocTraceToTraceMap()->SetLocTracePhysToTraceIDMap(
155 locTraceToTraceMap->GetLocTracephysToTraceIDMap());
156 }
157
158 // Initialize non-linear system
160 "Newton", m_session, m_comm->GetRowComm(), ntotal, key);
161 m_nonlinsol->SetSysOperators(nekSysOp);
162
163 // Initialize preconditioner
164 NekPreconCfsOperators preconOp;
166 this);
169 m_preconCfs->SetOperators(preconOp);
170}
171
173{
174 m_TotNewtonIts = 0;
175 m_TotLinIts = 0;
176 m_TotImpStages = 0;
178}
179
181 const NekDouble cpuTime)
182{
184
185 if (m_infosteps && m_session->GetComm()->GetSpaceComm()->GetRank() == 0 &&
186 !((step + 1) % m_infosteps) && m_flagImplicitItsStatistics)
187 {
188 cout << " &&"
189 << " TotImpStages= " << m_TotImpStages
190 << " TotNewtonIts= " << m_TotNewtonIts
191 << " TotLinearIts = " << m_TotLinIts << endl;
192 }
193}
194
196{
198
199 if (m_session->GetComm()->GetRank() == 0 && m_flagImplicitItsStatistics)
200 {
201 cout << "-------------------------------------------" << endl
202 << "Total Implicit Stages: " << m_TotImpStages << endl
203 << "Total Newton Its : " << m_TotNewtonIts << endl
204 << "Total Linear Its : " << m_TotLinIts << endl
205 << "-------------------------------------------" << endl;
206 }
207}
208
211 [[maybe_unused]] const bool &flag)
212{
214 unsigned int nvariables = m_fields.size();
215 unsigned int npoints = m_fields[0]->GetNcoeffs();
216 Array<OneD, Array<OneD, NekDouble>> in2D(nvariables);
217 Array<OneD, Array<OneD, NekDouble>> out2D(nvariables);
218 for (int i = 0; i < nvariables; ++i)
219 {
220 int offset = i * npoints;
221 in2D[i] = inarray + offset;
222 out2D[i] = out + offset;
223 }
224
225 timer.Start();
226 NonlinSysEvaluatorCoeff(in2D, out2D);
227 timer.Stop();
228 timer.AccumulateRegion("CFSImplicit::NonlinSysEvaluatorCoeff1D");
229}
230
232 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
234{
236 unsigned int nvariable = inarray.size();
237 unsigned int ncoeffs = m_fields[0]->GetNcoeffs();
238 unsigned int npoints = m_fields[0]->GetNpoints();
239
240 Array<OneD, Array<OneD, NekDouble>> inpnts(nvariable);
241
242 for (int i = 0; i < nvariable; ++i)
243 {
244 inpnts[i] = Array<OneD, NekDouble>(npoints, 0.0);
245 m_fields[i]->BwdTrans(inarray[i], inpnts[i]);
246 }
247
248 timer.Start();
249 DoOdeProjection(inpnts, inpnts, m_bndEvaluateTime);
250 timer.Stop();
251 timer.AccumulateRegion("CompressibleFlowSystem::DoOdeProjection", 1);
252
253 timer.Start();
254 DoOdeRhsCoeff(inpnts, out, m_bndEvaluateTime);
255 timer.Stop();
256 timer.AccumulateRegion("CFSImplicit::DoOdeRhsCoeff", 1);
257
258 for (int i = 0; i < nvariable; ++i)
259 {
260 Vmath::Svtvp(ncoeffs, -m_TimeIntegLambda, out[i], 1, inarray[i], 1,
261 out[i], 1);
262 Vmath::Vsub(ncoeffs, out[i], 1,
263 m_nonlinsol->GetRefSourceVec() + i * ncoeffs, 1, out[i], 1);
264 }
265}
266
268 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
269 Array<OneD, Array<OneD, NekDouble>> &outarray, const NekDouble time)
270{
271 int nvariables = inarray.size();
272 int ncoeffs = m_fields[0]->GetNcoeffs();
273
274 Array<OneD, Array<OneD, NekDouble>> tmpOut(nvariables);
275 for (int i = 0; i < nvariables; ++i)
276 {
277 tmpOut[i] = Array<OneD, NekDouble>(ncoeffs);
278 }
279
280 DoOdeRhsCoeff(inarray, tmpOut, time);
281
282 for (int i = 0; i < nvariables; ++i)
283 {
284 m_fields[i]->BwdTrans(tmpOut[i], outarray[i]);
285 }
286}
287
288/**
289 * @brief Compute the right-hand side.
290 */
292 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
293 Array<OneD, Array<OneD, NekDouble>> &outarray, const NekDouble time)
294{
296
297 int nvariables = inarray.size();
298 int nTracePts = GetTraceTotPoints();
299 int ncoeffs = GetNcoeffs();
300
301 m_bndEvaluateTime = time;
302
303 // Store forwards/backwards space along trace space
304 Array<OneD, Array<OneD, NekDouble>> Fwd(nvariables);
305 Array<OneD, Array<OneD, NekDouble>> Bwd(nvariables);
306
308 {
311 }
312 else
313 {
314 for (int i = 0; i < nvariables; ++i)
315 {
316 Fwd[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
317 Bwd[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
318 m_fields[i]->GetFwdBwdTracePhys(inarray[i], Fwd[i], Bwd[i]);
319 }
320 }
321
322 // Calculate advection
323 timer.Start();
324 DoAdvectionCoeff(inarray, outarray, time, Fwd, Bwd);
325 timer.Stop();
326 timer.AccumulateRegion("CFSImplicit::DoAdvectionCoeff", 2);
327
328 // Negate results
329 for (int i = 0; i < nvariables; ++i)
330 {
331 Vmath::Neg(ncoeffs, outarray[i], 1);
332 }
333
334 // Add diffusion terms
335 timer.Start();
336 DoDiffusionCoeff(inarray, outarray, Fwd, Bwd);
337 timer.Stop();
338 timer.AccumulateRegion("CFSImplicit::DoDiffusionCoeff", 2);
339
340 // Add forcing terms
341 for (auto &x : m_forcing)
342 {
343 x->ApplyCoeff(m_fields, inarray, outarray, time);
344 }
345
347 {
348 int nElements = m_fields[0]->GetExpSize();
349 int nq, offset;
350 NekDouble fac;
352
353 Array<OneD, NekDouble> tstep(nElements, 0.0);
354 GetElmtTimeStep(inarray, tstep);
355
356 // Loop over elements
357 for (int n = 0; n < nElements; ++n)
358 {
359 nq = m_fields[0]->GetExp(n)->GetNcoeffs();
360 offset = m_fields[0]->GetCoeff_Offset(n);
361 fac = tstep[n] / m_timestep;
362 for (int i = 0; i < nvariables; ++i)
363 {
364 Vmath::Smul(nq, fac, outarray[i] + offset, 1,
365 tmp = outarray[i] + offset, 1);
366 }
367 }
368 }
369}
370
371/**
372 * @brief Compute the advection terms for the right-hand side
373 */
375 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
376 Array<OneD, Array<OneD, NekDouble>> &outarray, const NekDouble time,
377 const Array<OneD, const Array<OneD, NekDouble>> &pFwd,
378 const Array<OneD, const Array<OneD, NekDouble>> &pBwd)
379{
380 int nvariables = inarray.size();
382
383 auto advWeakDGObject =
384 std::dynamic_pointer_cast<SolverUtils::AdvectionWeakDG>(m_advObject);
385 ASSERTL0(advWeakDGObject,
386 "Use WeakDG for implicit compressible flow solver!");
387 advWeakDGObject->AdvectCoeffs(nvariables, m_fields, advVel, inarray,
388 outarray, time, pFwd, pBwd);
389}
390
391/**
392 * @brief Add the diffusions terms to the right-hand side
393 * Similar to DoDiffusion() but with outarray in coefficient space
394 */
396 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
398 const Array<OneD, const Array<OneD, NekDouble>> &pFwd,
399 const Array<OneD, const Array<OneD, NekDouble>> &pBwd)
400{
401 v_DoDiffusionCoeff(inarray, outarray, pFwd, pBwd);
402}
403
405 const Array<OneD, const Array<OneD, NekDouble>> &inpnts,
406 Array<OneD, Array<OneD, NekDouble>> &outpnt, const NekDouble time,
407 const NekDouble lambda)
408{
409 unsigned int nvariables = inpnts.size();
410 unsigned int ncoeffs = m_fields[0]->GetNcoeffs();
411 unsigned int ntotal = nvariables * ncoeffs;
412
413 Array<OneD, NekDouble> inarray(ntotal);
414 Array<OneD, NekDouble> outarray(ntotal);
415 Array<OneD, NekDouble> tmpArray;
416
417 // Switch flag to make sure the physical shock capturing AV is updated
419
420 for (int i = 0; i < nvariables; ++i)
421 {
422 int noffset = i * ncoeffs;
423 tmpArray = inarray + noffset;
424 m_fields[i]->FwdTrans(inpnts[i], tmpArray);
425 }
426
427 DoImplicitSolveCoeff(inpnts, inarray, outarray, time, lambda);
428
429 for (int i = 0; i < nvariables; ++i)
430 {
431 int noffset = i * ncoeffs;
432 tmpArray = outarray + noffset;
433 m_fields[i]->BwdTrans(tmpArray, outpnt[i]);
434 }
435}
436
438 const Array<OneD, const Array<OneD, NekDouble>> &inpnts,
440 const NekDouble time, const NekDouble lambda)
441{
442 m_TimeIntegLambda = lambda;
443 m_bndEvaluateTime = time;
444 m_solutionPhys = inpnts;
445 unsigned int ntotal = inarray.size();
446
447 if (m_inArrayNorm < 0.0)
448 {
449 CalcRefValues(inarray);
450 }
451
453
454 m_TotNewtonIts += m_nonlinsol->SolveSystem(ntotal, inarray, out, 0, tol);
455
456 m_TotLinIts += m_nonlinsol->GetNtotLinSysIts();
457
459}
460
462{
463 unsigned int nvariables = m_fields.size();
464 unsigned int ntotal = inarray.size();
465 unsigned int npoints = ntotal / nvariables;
466
467 unsigned int nTotalGlobal = ntotal;
468 m_comm->GetSpaceComm()->AllReduce(nTotalGlobal,
470 unsigned int nTotalDOF = nTotalGlobal / nvariables;
471 NekDouble invTotalDOF = 1.0 / nTotalDOF;
472
473 m_inArrayNorm = 0.0;
474 m_magnitdEstimat = Array<OneD, NekDouble>(nvariables, 0.0);
475
476 for (int i = 0; i < nvariables; ++i)
477 {
478 int offset = i * npoints;
480 Vmath::Dot(npoints, inarray + offset, inarray + offset);
481 }
482 m_comm->GetSpaceComm()->AllReduce(m_magnitdEstimat,
484
485 for (int i = 0; i < nvariables; ++i)
486 {
488 }
489
490 for (int i = 2; i < nvariables - 1; ++i)
491 {
493 }
494
495 for (int i = 2; i < nvariables - 1; ++i)
496 {
498 }
499
500 for (int i = 0; i < nvariables; ++i)
501 {
502 m_magnitdEstimat[i] = sqrt(m_magnitdEstimat[i] * invTotalDOF);
503 }
504 if (m_comm->GetRank() == 0 && m_verbose)
505 {
506 for (int i = 0; i < nvariables; ++i)
507 {
508 cout << "m_magnitdEstimat[" << i << "] = " << m_magnitdEstimat[i]
509 << endl;
510 }
511 cout << "m_inArrayNorm = " << m_inArrayNorm << endl;
512 }
513}
514
517 [[maybe_unused]] const bool &flag)
518{
519 const Array<OneD, const NekDouble> solref = m_nonlinsol->GetRefSolution();
520 const Array<OneD, const NekDouble> resref = m_nonlinsol->GetRefResidual();
521
522 unsigned int ntotal = inarray.size();
523 NekDouble magninarray = Vmath::Dot(ntotal, inarray, inarray);
524 m_comm->GetSpaceComm()->AllReduce(magninarray,
526 NekDouble eps =
527 m_jacobiFreeEps * sqrt((sqrt(m_inArrayNorm) + 1.0) / magninarray);
528
529 Array<OneD, NekDouble> solplus{ntotal};
530 Array<OneD, NekDouble> resplus{ntotal};
531
532 Vmath::Svtvp(ntotal, eps, inarray, 1, solref, 1, solplus, 1);
533 NonlinSysEvaluatorCoeff1D(solplus, resplus, flag);
534 Vmath::Vsub(ntotal, resplus, 1, resref, 1, out, 1);
535 Vmath::Smul(ntotal, 1.0 / eps, out, 1, out, 1);
536}
537
539 Array<OneD, NekDouble> &outarray,
540 const bool &flag)
541{
542 LibUtilities::Timer timer, Gtimer;
543
544 Gtimer.Start();
545 if (m_preconCfs->UpdatePreconMatCheck(NullNekDouble1DArray,
547 {
548 int nvariables = m_solutionPhys.size();
549 int nphspnt = m_solutionPhys[nvariables - 1].size();
550 Array<OneD, Array<OneD, NekDouble>> intmp(nvariables);
551 for (int i = 0; i < nvariables; i++)
552 {
553 intmp[i] = Array<OneD, NekDouble>(nphspnt, 0.0);
554 }
555
556 timer.Start();
558 timer.Stop();
559 timer.AccumulateRegion("CompressibleFlowSystem::DoOdeProjection", 1);
560
561 timer.Start();
562 m_preconCfs->BuildPreconCfs(m_fields, intmp, m_bndEvaluateTime,
564 timer.Stop();
565 timer.AccumulateRegion("PreconCfsOp::BuildPreconCfs", 1);
566 }
567
568 timer.Start();
569 m_preconCfs->DoPreconCfs(m_fields, inarray, outarray, flag);
570 timer.Stop();
571 timer.AccumulateRegion("PreconCfsOp::DoPreconCfs", 1);
572
573 Gtimer.Stop();
574 Gtimer.AccumulateRegion("CFSImplicit::PreconCoeff");
575}
576
577template <typename DataType, typename TypeNekBlkMatSharedPtr>
579 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
580 const Array<OneD, const TensorOfArray2D<NekDouble>> &qfield,
582 TensorOfArray4D<DataType> &StdMatDataDBB,
583 TensorOfArray5D<DataType> &StdMatDataDBDB)
584{
585 if (StdMatDataDBB.size() == 0)
586 {
587 CalcVolJacStdMat(StdMatDataDBB, StdMatDataDBDB);
588 }
589
590 int nSpaceDim = m_graph->GetSpaceDimension();
591 int nvariable = inarray.size();
592 int npoints = m_fields[0]->GetTotPoints();
593 int nVar2 = nvariable * nvariable;
594 std::shared_ptr<LocalRegions::ExpansionVector> expvect =
595 m_fields[0]->GetExp();
596 int nTotElmt = (*expvect).size();
597
598 Array<OneD, NekDouble> mu(npoints, 0.0);
599 Array<OneD, NekDouble> DmuDT(npoints, 0.0);
601 {
602 CalcMuDmuDT(inarray, mu, DmuDT);
603 }
604
607 for (int i = 0; i < 3; i++)
608 {
609 normal3D[i] = Array<OneD, NekDouble>(3, 0.0);
610 }
611 normal3D[0][0] = 1.0;
612 normal3D[1][1] = 1.0;
613 normal3D[2][2] = 1.0;
615
616 DNekMatSharedPtr wspMat =
617 MemoryManager<DNekMat>::AllocateSharedPtr(nvariable, nvariable, 0.0);
619 nvariable - 1, nvariable, 0.0);
620
621 Array<OneD, DataType> GmatxData;
622 Array<OneD, DataType> MatData;
623
626 m_spacedim); // Nvar*Nvar*Ndir*Nelmt*Npnt
627 TensorOfArray3D<DataType> PntJacConsStd(
628 m_spacedim); // Nvar*Nvar*Ndir*Nelmt*Npnt
632 m_spacedim); // Nvar*Nvar*Ndir*Nelmt*Npnt
633 TensorOfArray4D<DataType> PntJacDervStd(
634 m_spacedim); // Nvar*Nvar*Ndir*Nelmt*Npnt
636 m_spacedim); // Nvar*Nvar*Ndir*Nelmt*Npnt
638 m_spacedim); // Nvar*Nvar*Ndir*Nelmt*Npnt
639 for (int ndir = 0; ndir < m_spacedim; ndir++)
640 {
641 PntJacDerv[ndir] = TensorOfArray3D<NekDouble>(m_spacedim);
642 PntJacDervStd[ndir] = TensorOfArray3D<DataType>(m_spacedim);
645 }
646
648 Array<OneD, NekDouble> locDmuDT;
649 Array<OneD, Array<OneD, NekDouble>> locVars(nvariable);
651 for (int ndir = 0; ndir < m_spacedim; ndir++)
652 {
653 locDerv[ndir] = Array<OneD, Array<OneD, NekDouble>>(nvariable);
654 }
655
656 int nElmtCoefOld = -1;
657 for (int ne = 0; ne < nTotElmt; ne++)
658 {
659 int nElmtCoef = (*expvect)[ne]->GetNcoeffs();
660 int nElmtCoef2 = nElmtCoef * nElmtCoef;
661 int nElmtPnt = (*expvect)[ne]->GetTotPoints();
662
663 int nQuot = nElmtCoef2 / m_nPadding;
664 int nRemd = nElmtCoef2 - nQuot * m_nPadding;
665 int nQuotPlus = nQuot;
666 if (nRemd > 0)
667 {
668 nQuotPlus++;
669 }
670 int nElmtCoef2Paded = nQuotPlus * m_nPadding;
671
672 if (nElmtPnt > PntJacCons[0].size() || nElmtCoef > nElmtCoefOld)
673 {
674 nElmtCoefOld = nElmtCoef;
675 for (int ndir = 0; ndir < 3; ndir++)
676 {
677 normalPnt[ndir] = Array<OneD, NekDouble>(npoints, 0.0);
678 }
679 tmppnts = Array<OneD, NekDouble>(nElmtPnt);
680 MatData = Array<OneD, DataType>(nElmtCoef2Paded * nVar2);
681 for (int ndir = 0; ndir < m_spacedim; ndir++)
682 {
683 ConsCurv[ndir] = Array<OneD, NekDouble>(nElmtPnt);
684 ConsStdd[ndir] = Array<OneD, NekDouble>(nElmtPnt);
685 PntJacCons[ndir] =
687 PntJacConsStd[ndir] =
689 for (int i = 0; i < nElmtPnt; i++)
690 {
691 PntJacCons[ndir][i] = Array<OneD, NekDouble>(nVar2);
692 PntJacConsStd[ndir][i] = Array<OneD, DataType>(nVar2);
693 }
694
695 for (int ndir1 = 0; ndir1 < m_spacedim; ndir1++)
696 {
697 PntJacDerv[ndir][ndir1] =
699 PntJacDervStd[ndir][ndir1] =
701 DervStdd[ndir][ndir1] = Array<OneD, NekDouble>(nElmtPnt);
702 DervCurv[ndir][ndir1] = Array<OneD, NekDouble>(nElmtPnt);
703 for (int i = 0; i < nElmtPnt; i++)
704 {
705 PntJacDerv[ndir][ndir1][i] =
707 PntJacDervStd[ndir][ndir1][i] =
709 }
710 }
711 }
712 }
713
714 int noffset = GetPhys_Offset(ne);
715 for (int j = 0; j < nvariable; j++)
716 {
717 locVars[j] = inarray[j] + noffset;
718 }
719
721 {
722 for (int nFluxDir = 0; nFluxDir < nSpaceDim; nFluxDir++)
723 {
724 normals = normal3D[nFluxDir];
725 GetFluxVectorJacDirElmt(nvariable, nElmtPnt, locVars, normals,
726 wspMat, PntJacCons[nFluxDir]);
727 }
728 }
729
731 {
732 for (int j = 0; j < nSpaceDim; j++)
733 {
734 for (int k = 0; k < nvariable; k++)
735 {
736 locDerv[j][k] = qfield[j][k] + noffset;
737 }
738 }
739 locmu = mu + noffset;
740 locDmuDT = DmuDT + noffset;
741 for (int nFluxDir = 0; nFluxDir < nSpaceDim; nFluxDir++)
742 {
743 normals = normal3D[nFluxDir];
744 MinusDiffusionFluxJacPoint(nvariable, nElmtPnt, locVars,
745 locDerv, locmu, locDmuDT, normals,
746 wspMatDrv, PntJacCons[nFluxDir]);
747 }
748 }
749
751 {
752 locmu = mu + noffset;
753 for (int nFluxDir = 0; nFluxDir < nSpaceDim; nFluxDir++)
754 {
755 Vmath::Fill(npoints, 1.0, normalPnt[nFluxDir], 1);
756 for (int nDervDir = 0; nDervDir < nSpaceDim; nDervDir++)
757 {
759 nvariable, nElmtPnt, nDervDir, locVars, locmu,
760 normalPnt, wspMatDrv, PntJacDerv[nFluxDir][nDervDir]);
761 }
762 Vmath::Fill(npoints, 0.0, normalPnt[nFluxDir], 1);
763 }
764 }
765
766 for (int n = 0; n < nvariable; n++)
767 {
768 for (int m = 0; m < nvariable; m++)
769 {
770 int nVarOffset = m + n * nvariable;
771 GmatxData = gmtxarray[m][n]->GetBlock(ne, ne)->GetPtr();
772
773 for (int ndStd0 = 0; ndStd0 < m_spacedim; ndStd0++)
774 {
775 Vmath::Zero(nElmtPnt, ConsStdd[ndStd0], 1);
776 }
777 for (int ndir = 0; ndir < m_spacedim; ndir++)
778 {
779 for (int i = 0; i < nElmtPnt; i++)
780 {
781 tmppnts[i] = PntJacCons[ndir][i][nVarOffset];
782 }
783 (*expvect)[ne]->AlignVectorToCollapsedDir(ndir, tmppnts,
784 ConsCurv);
785 for (int nd = 0; nd < m_spacedim; nd++)
786 {
787 Vmath::Vadd(nElmtPnt, ConsCurv[nd], 1, ConsStdd[nd], 1,
788 ConsStdd[nd], 1);
789 }
790 }
791
792 for (int ndir = 0; ndir < m_spacedim; ndir++)
793 {
794 (*expvect)[ne]->MultiplyByQuadratureMetric(
795 ConsStdd[ndir], ConsStdd[ndir]); // weight with metric
796 for (int i = 0; i < nElmtPnt; i++)
797 {
798 PntJacConsStd[ndir][i][nVarOffset] =
799 DataType(ConsStdd[ndir][i]);
800 }
801 }
802 }
803 }
804
806 {
807 for (int m = 0; m < nvariable; m++)
808 {
809 for (int n = 0; n < nvariable; n++)
810 {
811 int nVarOffset = m + n * nvariable;
812 for (int ndStd0 = 0; ndStd0 < m_spacedim; ndStd0++)
813 {
814 for (int ndStd1 = 0; ndStd1 < m_spacedim; ndStd1++)
815 {
816 Vmath::Zero(nElmtPnt, DervStdd[ndStd0][ndStd1], 1);
817 }
818 }
819 for (int nd0 = 0; nd0 < m_spacedim; nd0++)
820 {
821 for (int nd1 = 0; nd1 < m_spacedim; nd1++)
822 {
823 for (int i = 0; i < nElmtPnt; i++)
824 {
825 tmppnts[i] =
826 PntJacDerv[nd0][nd1][i][nVarOffset];
827 }
828
829 (*expvect)[ne]->AlignVectorToCollapsedDir(
830 nd0, tmppnts, ConsCurv);
831 for (int nd = 0; nd < m_spacedim; nd++)
832 {
833 (*expvect)[ne]->AlignVectorToCollapsedDir(
834 nd1, ConsCurv[nd], DervCurv[nd]);
835 }
836
837 for (int ndStd0 = 0; ndStd0 < m_spacedim; ndStd0++)
838 {
839 for (int ndStd1 = 0; ndStd1 < m_spacedim;
840 ndStd1++)
841 {
842 Vmath::Vadd(nElmtPnt,
843 DervCurv[ndStd0][ndStd1], 1,
844 DervStdd[ndStd0][ndStd1], 1,
845 DervStdd[ndStd0][ndStd1], 1);
846 }
847 }
848 }
849 }
850 for (int nd0 = 0; nd0 < m_spacedim; nd0++)
851 {
852 for (int nd1 = 0; nd1 < m_spacedim; nd1++)
853 {
854 (*expvect)[ne]->MultiplyByQuadratureMetric(
855 DervStdd[nd0][nd1],
856 DervStdd[nd0][nd1]); // weight with metric
857 for (int i = 0; i < nElmtPnt; i++)
858 {
859 PntJacDervStd[nd0][nd1][i][nVarOffset] =
860 -DataType(DervStdd[nd0][nd1][i]);
861 }
862 }
863 }
864 }
865 }
866 }
867
868 Vmath::Zero(nElmtCoef2Paded * nVar2, MatData, 1);
869 DataType one = 1.0;
870 for (int ndir = 0; ndir < m_spacedim; ndir++)
871 {
872 for (int i = 0; i < nElmtPnt; i++)
873 {
874 Blas::Ger(nElmtCoef2Paded, nVar2, one,
875 &StdMatDataDBB[ne][ndir][i][0], 1,
876 &PntJacConsStd[ndir][i][0], 1, &MatData[0],
877 nElmtCoef2Paded);
878 }
879 }
880
882 {
883 for (int nd0 = 0; nd0 < m_spacedim; nd0++)
884 {
885 for (int nd1 = 0; nd1 < m_spacedim; nd1++)
886 {
887 for (int i = 0; i < nElmtPnt; i++)
888 {
889 Blas::Ger(nElmtCoef2Paded, nVar2, one,
890 &StdMatDataDBDB[ne][nd0][nd1][i][0], 1,
891 &PntJacDervStd[nd0][nd1][i][0], 1,
892 &MatData[0], nElmtCoef2Paded);
893 }
894 }
895 }
896 }
897
899
900 for (int n = 0; n < nvariable; n++)
901 {
902 for (int m = 0; m < nvariable; m++)
903 {
904 int nVarOffset = m + n * nvariable;
905 GmatxData = gmtxarray[m][n]->GetBlock(ne, ne)->GetPtr();
906 Vmath::Vcopy(nElmtCoef2,
907 tmpA = MatData + nVarOffset * nElmtCoef2Paded, 1,
908 GmatxData, 1);
909 }
910 }
911 }
912}
913
914template <typename DataType>
916 TensorOfArray5D<DataType> &StdMatDataDBDB)
917{
918 std::shared_ptr<LocalRegions::ExpansionVector> expvect =
919 m_fields[0]->GetExp();
920 int nTotElmt = (*expvect).size();
921
922 StdMatDataDBB = TensorOfArray4D<DataType>(nTotElmt);
923 StdMatDataDBDB = TensorOfArray5D<DataType>(nTotElmt);
924
925 vector<DNekMatSharedPtr> VectStdDerivBase0;
926 vector<TensorOfArray3D<DataType>> VectStdDerivBase_Base;
927 vector<TensorOfArray4D<DataType>> VectStdDervBase_DervBase;
928 DNekMatSharedPtr MatStdDerivBase0;
931 for (int ne = 0; ne < nTotElmt; ne++)
932 {
934 stdExp = (*expvect)[ne]->GetStdExp();
936 stdExp->DetShapeType(), *stdExp);
937 MatStdDerivBase0 = stdExp->GetStdMatrix(matkey);
938
939 int nTotStdExp = VectStdDerivBase0.size();
940 int nFoundStdExp = -1;
941 for (int i = 0; i < nTotStdExp; i++)
942 {
943 if ((*VectStdDerivBase0[i]) == (*MatStdDerivBase0))
944 {
945 nFoundStdExp = i;
946 }
947 }
948 if (nFoundStdExp >= 0)
949 {
950 StdMatDataDBB[ne] = VectStdDerivBase_Base[nFoundStdExp];
951 StdMatDataDBDB[ne] = VectStdDervBase_DervBase[nFoundStdExp];
952 }
953 else
954 {
955 int nElmtCoef = (*expvect)[ne]->GetNcoeffs();
956 int nElmtCoef2 = nElmtCoef * nElmtCoef;
957 int nElmtPnt = (*expvect)[ne]->GetTotPoints();
958
959 int nQuot = nElmtCoef2 / m_nPadding;
960 int nRemd = nElmtCoef2 - nQuot * m_nPadding;
961 int nQuotPlus = nQuot;
962 if (nRemd > 0)
963 {
964 nQuotPlus++;
965 }
966 int nPaded = nQuotPlus * m_nPadding;
967
968 ArrayStdMat[0] = MatStdDerivBase0;
969 if (m_spacedim > 1)
970 {
972 StdRegions::eDerivBase1, stdExp->DetShapeType(), *stdExp);
973 ArrayStdMat[1] = stdExp->GetStdMatrix(matkey);
974
975 if (m_spacedim > 2)
976 {
978 stdExp->DetShapeType(),
979 *stdExp);
980 ArrayStdMat[2] = stdExp->GetStdMatrix(matkey);
981 }
982 }
983 for (int nd0 = 0; nd0 < m_spacedim; nd0++)
984 {
985 ArrayStdMatData[nd0] = ArrayStdMat[nd0]->GetPtr();
986 }
987
989 stdExp->DetShapeType(), *stdExp);
990 DNekMatSharedPtr BwdMat = stdExp->GetStdMatrix(matkey);
991 Array<OneD, NekDouble> BwdMatData = BwdMat->GetPtr();
992
995
996 for (int nd0 = 0; nd0 < m_spacedim; nd0++)
997 {
998 tmpStdDBB[nd0] = Array<OneD, Array<OneD, DataType>>(nElmtPnt);
999 for (int i = 0; i < nElmtPnt; i++)
1000 {
1001 tmpStdDBB[nd0][i] = Array<OneD, DataType>(nPaded, 0.0);
1002 for (int nc1 = 0; nc1 < nElmtCoef; nc1++)
1003 {
1004 int noffset = nc1 * nElmtCoef;
1005 for (int nc0 = 0; nc0 < nElmtCoef; nc0++)
1006 {
1007 tmpStdDBB[nd0][i][nc0 + noffset] = DataType(
1008 ArrayStdMatData[nd0][i * nElmtCoef + nc0] *
1009 BwdMatData[i * nElmtCoef + nc1]);
1010 }
1011 }
1012 }
1013
1014 tmpStdDBDB[nd0] = TensorOfArray3D<DataType>(m_spacedim);
1015 for (int nd1 = 0; nd1 < m_spacedim; nd1++)
1016 {
1017 tmpStdDBDB[nd0][nd1] =
1019 for (int i = 0; i < nElmtPnt; i++)
1020 {
1021 tmpStdDBDB[nd0][nd1][i] =
1022 Array<OneD, DataType>(nPaded, 0.0);
1023 for (int nc1 = 0; nc1 < nElmtCoef; nc1++)
1024 {
1025 int noffset = nc1 * nElmtCoef;
1026 for (int nc0 = 0; nc0 < nElmtCoef; nc0++)
1027 {
1028 tmpStdDBDB[nd0][nd1][i][nc0 + noffset] =
1029 DataType(
1030 ArrayStdMatData[nd0]
1031 [i * nElmtCoef + nc0] *
1032 ArrayStdMatData[nd1]
1033 [i * nElmtCoef + nc1]);
1034 }
1035 }
1036 }
1037 }
1038 }
1039 VectStdDerivBase0.push_back(MatStdDerivBase0);
1040 VectStdDerivBase_Base.push_back(tmpStdDBB);
1041 VectStdDervBase_DervBase.push_back(tmpStdDBDB);
1042
1043 StdMatDataDBB[ne] = tmpStdDBB;
1044 StdMatDataDBDB[ne] = tmpStdDBDB;
1045 }
1046 }
1047}
1048
1049template <typename DataType, typename TypeNekBlkMatSharedPtr>
1051 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
1056 Array<OneD, Array<OneD, DataType>> &TraceJacDerivSign,
1057 TensorOfArray5D<DataType> &TraceIPSymJacArray)
1058{
1059 int nvariables = inarray.size();
1060
1061 LibUtilities::Timer timer;
1062 timer.Start();
1063 GetTraceJac(inarray, qfield, TraceJac, TraceJacDeriv, TraceJacDerivSign,
1064 TraceIPSymJacArray);
1065 timer.Stop();
1066 timer.AccumulateRegion("CFSImplicit::GetTraceJac", 10);
1067
1070
1071 timer.Start();
1072 m_advObject->AddTraceJacToMat(nvariables, m_spacedim, m_fields, TraceJac,
1073 gmtxarray, tmpJac, tmpSign);
1074 timer.Stop();
1075 timer.AccumulateRegion("Advection::AddTraceJacToMap", 10);
1076}
1077
1078template <typename DataType, typename TypeNekBlkMatSharedPtr>
1081 TypeNekBlkMatSharedPtr &gmtVar,
1082 [[maybe_unused]] const DataType &tmpDataType)
1083{
1084 int n1d = gmtxarray.size();
1085 int n2d = gmtxarray[0].size();
1086 int nConvectiveFields = n1d;
1087
1088 ASSERTL0(n1d == n2d, "ElmtVarInvMtrx requires n1d==n2d");
1089
1092
1093 gmtxarray[0][0]->GetBlockSizes(rowSizes, colSizes);
1094 int nTotElmt = rowSizes.size();
1095 int nElmtCoef = rowSizes[0] - 1;
1096 int nElmtCoef0 = -1;
1097 int blocksize = -1;
1098
1099 Array<OneD, unsigned int> tmprow(1);
1100 TypeNekBlkMatSharedPtr tmpGmtx;
1101
1102 Array<OneD, DataType> GMatData, ElmtMatData;
1103 Array<OneD, DataType> tmpArray1, tmpArray2;
1104
1105 for (int nelmt = 0; nelmt < nTotElmt; nelmt++)
1106 {
1107 int nrows = gmtxarray[0][0]->GetBlock(nelmt, nelmt)->GetRows();
1108 int ncols = gmtxarray[0][0]->GetBlock(nelmt, nelmt)->GetColumns();
1109 ASSERTL0(nrows == ncols, "ElmtVarInvMtrx requires nrows==ncols");
1110
1111 nElmtCoef = nrows;
1112
1113 if (nElmtCoef0 != nElmtCoef)
1114 {
1115 nElmtCoef0 = nElmtCoef;
1116 int nElmtCoefVar = nElmtCoef0 * nConvectiveFields;
1117 blocksize = nElmtCoefVar * nElmtCoefVar;
1118 tmprow[0] = nElmtCoefVar;
1119 AllocateNekBlkMatDig(tmpGmtx, tmprow, tmprow);
1120 GMatData = tmpGmtx->GetBlock(0, 0)->GetPtr();
1121 }
1122
1123 for (int n = 0; n < nConvectiveFields; n++)
1124 {
1125 for (int m = 0; m < nConvectiveFields; m++)
1126 {
1127 ElmtMatData = gmtxarray[m][n]->GetBlock(nelmt, nelmt)->GetPtr();
1128
1129 for (int ncl = 0; ncl < nElmtCoef; ncl++)
1130 {
1131 int Goffset =
1132 (n * nElmtCoef + ncl) * nConvectiveFields * nElmtCoef +
1133 m * nElmtCoef;
1134 int Eoffset = ncl * nElmtCoef;
1135
1136 Vmath::Vcopy(nElmtCoef, tmpArray1 = ElmtMatData + Eoffset,
1137 1, tmpArray2 = GMatData + Goffset, 1);
1138 }
1139 }
1140 }
1141
1142 tmpGmtx->GetBlock(0, 0)->Invert();
1143
1144 for (int m = 0; m < nConvectiveFields; m++)
1145 {
1146 for (int n = 0; n < nConvectiveFields; n++)
1147 {
1148 ElmtMatData = gmtxarray[m][n]->GetBlock(nelmt, nelmt)->GetPtr();
1149
1150 for (int ncl = 0; ncl < nElmtCoef; ncl++)
1151 {
1152 int Goffset =
1153 (n * nElmtCoef + ncl) * nConvectiveFields * nElmtCoef +
1154 m * nElmtCoef;
1155 int Eoffset = ncl * nElmtCoef;
1156
1157 Vmath::Vcopy(nElmtCoef, tmpArray1 = GMatData + Goffset, 1,
1158 tmpArray2 = ElmtMatData + Eoffset, 1);
1159 }
1160 }
1161 }
1162 ElmtMatData = gmtVar->GetBlock(nelmt, nelmt)->GetPtr();
1163 Vmath::Vcopy(blocksize, GMatData, 1, ElmtMatData, 1);
1164 }
1165 return;
1166}
1167
1168template <typename DataType, typename TypeNekBlkMatSharedPtr>
1170 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
1173 [[maybe_unused]] Array<OneD, TypeNekBlkMatSharedPtr> &TraceJacDeriv,
1174 [[maybe_unused]] Array<OneD, Array<OneD, DataType>> &TraceJacDerivSign,
1175 TensorOfArray5D<DataType> &TraceIPSymJacArray)
1176{
1177 int nvariables = inarray.size();
1178 int nTracePts = GetTraceTotPoints();
1179
1180 // Store forwards/backwards space along trace space
1181 Array<OneD, Array<OneD, NekDouble>> Fwd(nvariables);
1182 Array<OneD, Array<OneD, NekDouble>> Bwd(nvariables);
1183
1184 TypeNekBlkMatSharedPtr FJac, BJac;
1185 Array<OneD, unsigned int> n_blks1(nTracePts, nvariables);
1186
1187 if (TraceJac.size() > 0)
1188 {
1189 FJac = TraceJac[0];
1190 BJac = TraceJac[1];
1191 }
1192 else
1193 {
1195
1196 AllocateNekBlkMatDig(FJac, n_blks1, n_blks1);
1197 AllocateNekBlkMatDig(BJac, n_blks1, n_blks1);
1198 }
1199
1201 {
1204 }
1205 else
1206 {
1207 for (int i = 0; i < nvariables; ++i)
1208 {
1209 Fwd[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1210 Bwd[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1211 m_fields[i]->GetFwdBwdTracePhys(inarray[i], Fwd[i], Bwd[i]);
1212 }
1213 }
1214
1216
1217 NumCalcRiemFluxJac(nvariables, m_fields, AdvVel, inarray, qfield,
1218 m_bndEvaluateTime, Fwd, Bwd, FJac, BJac,
1219 TraceIPSymJacArray);
1220
1221 TraceJac[0] = FJac;
1222 TraceJac[1] = BJac;
1223}
1224
1225template <typename DataType, typename TypeNekBlkMatSharedPtr>
1227 const int nConvectiveFields,
1229 const Array<OneD, const Array<OneD, NekDouble>> &AdvVel,
1230 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
1231 TensorOfArray3D<NekDouble> &qfield, const NekDouble &time,
1232 const Array<OneD, const Array<OneD, NekDouble>> &Fwd,
1233 const Array<OneD, const Array<OneD, NekDouble>> &Bwd,
1234 TypeNekBlkMatSharedPtr &FJac, TypeNekBlkMatSharedPtr &BJac,
1235 [[maybe_unused]] TensorOfArray5D<DataType> &TraceIPSymJacArray)
1236{
1237 const NekDouble PenaltyFactor2 = 0.0;
1238 int nvariables = nConvectiveFields;
1239 int npoints = GetNpoints();
1240 int nTracePts = GetTraceTotPoints();
1241 int nDim = m_spacedim;
1242
1243 Array<OneD, int> nonZeroIndex;
1244
1245 Array<OneD, Array<OneD, NekDouble>> tmpinarry(nvariables);
1246 for (int i = 0; i < nvariables; i++)
1247 {
1248 tmpinarry[i] = Array<OneD, NekDouble>(npoints, 0.0);
1249 Vmath::Vcopy(npoints, inarray[i], 1, tmpinarry[i], 1);
1250 }
1251
1252 // DmuDT of artificial diffusion is neglected
1253 // TODO: to consider the Jacobian of AV seperately
1256
1257 Array<OneD, Array<OneD, NekDouble>> numflux(nvariables);
1258 for (int i = 0; i < nvariables; ++i)
1259 {
1260 numflux[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1261 }
1262
1264 fields[0]->GetTraceMap();
1265 TensorOfArray3D<NekDouble> qBwd(nDim);
1266 TensorOfArray3D<NekDouble> qFwd(nDim);
1267 if (m_viscousJacFlag)
1268 {
1269 for (int nd = 0; nd < nDim; ++nd)
1270 {
1271 qBwd[nd] = Array<OneD, Array<OneD, NekDouble>>(nConvectiveFields);
1272 qFwd[nd] = Array<OneD, Array<OneD, NekDouble>>(nConvectiveFields);
1273 for (int i = 0; i < nConvectiveFields; ++i)
1274 {
1275 qBwd[nd][i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1276 qFwd[nd][i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1277
1278 fields[i]->GetFwdBwdTracePhys(qfield[nd][i], qFwd[nd][i],
1279 qBwd[nd][i], true, true, false);
1280 TraceMap->GetAssemblyCommDG()->PerformExchange(qFwd[nd][i],
1281 qBwd[nd][i]);
1282 }
1283 }
1284 }
1285
1286 CalcTraceNumericalFlux(nConvectiveFields, nDim, npoints, nTracePts,
1287 PenaltyFactor2, fields, AdvVel, inarray, time,
1288 qfield, Fwd, Bwd, qFwd, qBwd, MuVarTrace,
1289 nonZeroIndex, numflux);
1290
1291 int nFields = nvariables;
1292 Array<OneD, Array<OneD, NekDouble>> plusFwd(nFields), plusBwd(nFields);
1293 Array<OneD, Array<OneD, NekDouble>> Jacvect(nFields);
1294 Array<OneD, Array<OneD, NekDouble>> FwdBnd(nFields);
1295 Array<OneD, Array<OneD, NekDouble>> plusflux(nFields);
1296 for (int i = 0; i < nFields; i++)
1297 {
1298 Jacvect[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1299 plusFwd[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1300 plusBwd[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1301 plusflux[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1302 FwdBnd[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1303 }
1304
1305 for (int i = 0; i < nFields; i++)
1306 {
1307 Vmath::Vcopy(nTracePts, Fwd[i], 1, plusFwd[i], 1);
1308 Vmath::Vcopy(nTracePts, Bwd[i], 1, plusBwd[i], 1);
1309 }
1310
1311 NekDouble eps = 1.0E-6;
1312
1313 Array<OneD, DataType> tmpMatData;
1314 // Fwd Jacobian
1315 for (int i = 0; i < nFields; i++)
1316 {
1317 NekDouble epsvar = eps * m_magnitdEstimat[i];
1318 NekDouble oepsvar = 1.0 / epsvar;
1319 Vmath::Sadd(nTracePts, epsvar, Fwd[i], 1, plusFwd[i], 1);
1320
1321 if (m_bndConds.size())
1322 {
1323 for (int i = 0; i < nFields; i++)
1324 {
1325 Vmath::Vcopy(nTracePts, plusFwd[i], 1, FwdBnd[i], 1);
1326 }
1327 // Loop over user-defined boundary conditions
1328 for (auto &x : m_bndConds)
1329 {
1330 x->Apply(FwdBnd, tmpinarry, time);
1331 }
1332 }
1333
1334 for (int j = 0; j < nFields; j++)
1335 {
1336 m_fields[j]->FillBwdWithBoundCond(plusFwd[j], plusBwd[j]);
1337 }
1338
1339 CalcTraceNumericalFlux(nConvectiveFields, nDim, npoints, nTracePts,
1340 PenaltyFactor2, fields, AdvVel, inarray, time,
1341 qfield, plusFwd, plusBwd, qFwd, qBwd, MuVarTrace,
1342 nonZeroIndex, plusflux);
1343
1344 for (int n = 0; n < nFields; n++)
1345 {
1346 Vmath::Vsub(nTracePts, plusflux[n], 1, numflux[n], 1, Jacvect[n],
1347 1);
1348 Vmath::Smul(nTracePts, oepsvar, Jacvect[n], 1, Jacvect[n], 1);
1349 }
1350 for (int j = 0; j < nTracePts; j++)
1351 {
1352 tmpMatData = FJac->GetBlock(j, j)->GetPtr();
1353 for (int n = 0; n < nFields; n++)
1354 {
1355 tmpMatData[n + i * nFields] = DataType(Jacvect[n][j]);
1356 }
1357 }
1358
1359 Vmath::Vcopy(nTracePts, Fwd[i], 1, plusFwd[i], 1);
1360 }
1361
1362 // Reset the boundary conditions
1363 if (m_bndConds.size())
1364 {
1365 for (int i = 0; i < nFields; i++)
1366 {
1367 Vmath::Vcopy(nTracePts, Fwd[i], 1, FwdBnd[i], 1);
1368 }
1369 // Loop over user-defined boundary conditions
1370 for (auto &x : m_bndConds)
1371 {
1372 x->Apply(FwdBnd, tmpinarry, time);
1373 }
1374 }
1375
1376 for (int i = 0; i < nFields; i++)
1377 {
1378 Vmath::Vcopy(nTracePts, Bwd[i], 1, plusBwd[i], 1);
1379 }
1380
1381 for (int i = 0; i < nFields; i++)
1382 {
1383 NekDouble epsvar = eps * m_magnitdEstimat[i];
1384 NekDouble oepsvar = 1.0 / epsvar;
1385
1386 Vmath::Sadd(nTracePts, epsvar, Bwd[i], 1, plusBwd[i], 1);
1387
1388 for (int j = 0; j < nFields; j++)
1389 {
1390 m_fields[j]->FillBwdWithBoundCond(Fwd[j], plusBwd[j]);
1391 }
1392
1393 CalcTraceNumericalFlux(nConvectiveFields, nDim, npoints, nTracePts,
1394 PenaltyFactor2, fields, AdvVel, inarray, time,
1395 qfield, Fwd, plusBwd, qFwd, qBwd, MuVarTrace,
1396 nonZeroIndex, plusflux);
1397
1398 for (int n = 0; n < nFields; n++)
1399 {
1400 Vmath::Vsub(nTracePts, plusflux[n], 1, numflux[n], 1, Jacvect[n],
1401 1);
1402 Vmath::Smul(nTracePts, oepsvar, Jacvect[n], 1, Jacvect[n], 1);
1403 }
1404 for (int j = 0; j < nTracePts; j++)
1405 {
1406 tmpMatData = BJac->GetBlock(j, j)->GetPtr();
1407 for (int n = 0; n < nFields; n++)
1408 {
1409 tmpMatData[n + i * nFields] = DataType(Jacvect[n][j]);
1410 }
1411 }
1412
1413 Vmath::Vcopy(nTracePts, Bwd[i], 1, plusBwd[i], 1);
1414 }
1415}
1416
1418 const int nConvectiveFields, [[maybe_unused]] const int nDim,
1419 [[maybe_unused]] const int nPts, const int nTracePts,
1420 [[maybe_unused]] const NekDouble PenaltyFactor2,
1422 const Array<OneD, const Array<OneD, NekDouble>> &AdvVel,
1423 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
1424 [[maybe_unused]] const NekDouble time, TensorOfArray3D<NekDouble> &qfield,
1425 const Array<OneD, const Array<OneD, NekDouble>> &vFwd,
1426 const Array<OneD, const Array<OneD, NekDouble>> &vBwd,
1427 [[maybe_unused]] const Array<OneD, const TensorOfArray2D<NekDouble>> &qFwd,
1428 [[maybe_unused]] const Array<OneD, const TensorOfArray2D<NekDouble>> &qBwd,
1429 [[maybe_unused]] const Array<OneD, NekDouble> &MuVarTrace,
1430 Array<OneD, int> &nonZeroIndex,
1431 Array<OneD, Array<OneD, NekDouble>> &traceflux)
1432{
1434 {
1435 auto advWeakDGObject =
1436 std::dynamic_pointer_cast<SolverUtils::AdvectionWeakDG>(
1437 m_advObject);
1438 ASSERTL0(advWeakDGObject,
1439 "Use WeakDG for implicit compressible flow solver!");
1440 advWeakDGObject->AdvectTraceFlux(nConvectiveFields, m_fields, AdvVel,
1441 inarray, traceflux, m_bndEvaluateTime,
1442 vFwd, vBwd);
1443 }
1444 else
1445 {
1446 for (int i = 0; i < nConvectiveFields; i++)
1447 {
1448 traceflux[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1449 }
1450 }
1451
1452 if (m_viscousJacFlag)
1453 {
1454 Array<OneD, Array<OneD, NekDouble>> visflux(nConvectiveFields);
1455 for (int i = 0; i < nConvectiveFields; i++)
1456 {
1457 visflux[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1458 }
1459
1460 string diffName;
1461 m_session->LoadSolverInfo("DiffusionType", diffName, "InteriorPenalty");
1462 if (diffName == "InteriorPenalty")
1463 {
1464 m_diffusion->DiffuseTraceFlux(fields, inarray, qfield,
1466 vFwd, vBwd, nonZeroIndex);
1467 }
1468 else
1469 {
1470 ASSERTL1(false, "LDGNS not yet validated for implicit compressible "
1471 "flow solver");
1472 // For LDGNS, the array size should be nConvectiveFields - 1
1473 Array<OneD, Array<OneD, NekDouble>> inBwd(nConvectiveFields - 1);
1474 Array<OneD, Array<OneD, NekDouble>> inFwd(nConvectiveFields - 1);
1475 for (int i = 0; i < nConvectiveFields - 1; ++i)
1476 {
1477 inBwd[i] = vBwd[i];
1478 inFwd[i] = vFwd[i];
1479 }
1480 m_diffusion->DiffuseTraceFlux(fields, inarray, qfield,
1482 inFwd, inBwd, nonZeroIndex);
1483 }
1484 for (int i = 0; i < nConvectiveFields; i++)
1485 {
1486 Vmath::Vsub(nTracePts, traceflux[i], 1, visflux[i], 1, traceflux[i],
1487 1);
1488 }
1489 }
1490}
1491
1493 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
1496 Array<OneD, SNekBlkMatSharedPtr> &TraceJacDeriv,
1497 Array<OneD, Array<OneD, NekSingle>> &TraceJacDerivSign,
1498 TensorOfArray4D<NekSingle> &TraceJacArray,
1499 [[maybe_unused]] TensorOfArray4D<NekSingle> &TraceJacDerivArray,
1500 TensorOfArray5D<NekSingle> &TraceIPSymJacArray)
1501{
1503
1504 if (m_viscousJacFlag)
1505 {
1506 CalcPhysDeriv(inarray, qfield);
1507 }
1508
1509 NekSingle zero = 0.0;
1510 Fill2DArrayOfBlkDiagonalMat(gmtxarray, zero);
1511
1512 LibUtilities::Timer timer;
1513 timer.Start();
1514 AddMatNSBlkDiagVol(inarray, qfield, gmtxarray, m_stdSMatDataDBB,
1516 timer.Stop();
1517 timer.AccumulateRegion("CFSImplicit::AddMatNSBlkDiagVol", 2);
1518
1519 timer.Start();
1520 AddMatNSBlkDiagBnd(inarray, qfield, gmtxarray, TraceJac, TraceJacDeriv,
1521 TraceJacDerivSign, TraceIPSymJacArray);
1522 timer.Stop();
1523 timer.AccumulateRegion("CFSImplicit::AddMatNSBlkDiagBnd", 2);
1524
1525 MultiplyElmtInvMassPlusSource<NekSingle>(gmtxarray, m_TimeIntegLambda);
1526
1527 timer.Start();
1528 ElmtVarInvMtrx(gmtxarray, gmtVar, zero);
1529 timer.Stop();
1530 timer.AccumulateRegion("CFSImplicit::ElmtVarInvMtrx", 2);
1531
1532 TransTraceJacMatToArray(TraceJac, TraceJacArray);
1533}
1534
1536 [[maybe_unused]] const int nConvectiveFields,
1537 [[maybe_unused]] const int nElmtPnt,
1538 [[maybe_unused]] const Array<OneD, const Array<OneD, NekDouble>> &locVars,
1539 [[maybe_unused]] const TensorOfArray3D<NekDouble> &locDerv,
1540 [[maybe_unused]] const Array<OneD, NekDouble> &locmu,
1541 [[maybe_unused]] const Array<OneD, NekDouble> &locDmuDT,
1542 [[maybe_unused]] const Array<OneD, NekDouble> &normals,
1543 [[maybe_unused]] DNekMatSharedPtr &wspMat,
1544 [[maybe_unused]] Array<OneD, Array<OneD, NekDouble>> &PntJacArray)
1545{
1546 // Do nothing by default
1547}
1548
1549template <typename DataType, typename TypeNekBlkMatSharedPtr>
1552 const NekDouble dtlamda)
1553{
1555 std::shared_ptr<LocalRegions::ExpansionVector> pexp = explist->GetExp();
1556 int nTotElmt = (*pexp).size();
1557 int nConvectiveFields = m_fields.size();
1558
1559 NekDouble Negdtlamda = -dtlamda;
1560
1561 Array<OneD, NekDouble> pseudotimefactor(nTotElmt, 0.0);
1562 Vmath::Fill(nTotElmt, Negdtlamda, pseudotimefactor, 1);
1563
1564 Array<OneD, DataType> GMatData;
1565 for (int m = 0; m < nConvectiveFields; m++)
1566 {
1567 for (int n = 0; n < nConvectiveFields; n++)
1568 {
1569 for (int nelmt = 0; nelmt < nTotElmt; nelmt++)
1570 {
1571 GMatData = gmtxarray[m][n]->GetBlock(nelmt, nelmt)->GetPtr();
1572 DataType factor = DataType(pseudotimefactor[nelmt]);
1573
1574 Vmath::Smul(GMatData.size(), factor, GMatData, 1, GMatData, 1);
1575 }
1576 }
1577 }
1578
1579 DNekMatSharedPtr MassMat;
1580 Array<OneD, NekDouble> BwdMatData, MassMatData, tmp;
1582 Array<OneD, DataType> MassMatDataDataType;
1584
1585 for (int nelmt = 0; nelmt < nTotElmt; nelmt++)
1586 {
1587 int nelmtcoef = GetNcoeffs(nelmt);
1588 int nelmtpnts = GetTotPoints(nelmt);
1589 LibUtilities::ShapeType ElmtTypeNow =
1590 explist->GetExp(nelmt)->DetShapeType();
1591
1592 if (tmp.size() != nelmtcoef || (ElmtTypeNow != ElmtTypePrevious))
1593 {
1595 stdExp = explist->GetExp(nelmt)->GetStdExp();
1597 stdExp->DetShapeType(), *stdExp);
1598
1599 DNekMatSharedPtr BwdMat = stdExp->GetStdMatrix(matkey);
1600 BwdMatData = BwdMat->GetPtr();
1601
1602 if (nelmtcoef != tmp.size())
1603 {
1604 tmp = Array<OneD, NekDouble>(nelmtcoef, 0.0);
1606 nelmtcoef, nelmtcoef, 0.0);
1607 MassMatData = MassMat->GetPtr();
1608 MassMatDataDataType =
1609 Array<OneD, DataType>(nelmtcoef * nelmtcoef);
1610 }
1611
1612 ElmtTypePrevious = ElmtTypeNow;
1613 }
1614
1615 for (int np = 0; np < nelmtcoef; np++)
1616 {
1617 explist->GetExp(nelmt)->IProductWRTBase(BwdMatData + np * nelmtpnts,
1618 tmp);
1619 Vmath::Vcopy(nelmtcoef, tmp, 1, tmp2 = MassMatData + np * nelmtcoef,
1620 1);
1621 }
1622 for (int i = 0; i < MassMatData.size(); i++)
1623 {
1624 MassMatDataDataType[i] = DataType(MassMatData[i]);
1625 }
1626
1627 for (int m = 0; m < nConvectiveFields; m++)
1628 {
1629 GMatData = gmtxarray[m][m]->GetBlock(nelmt, nelmt)->GetPtr();
1630 Vmath::Vadd(MassMatData.size(), MassMatDataDataType, 1, GMatData, 1,
1631 GMatData, 1);
1632 }
1633 }
1634 return;
1635}
1636
1637template <typename DataType, typename TypeNekBlkMatSharedPtr>
1640 TensorOfArray4D<DataType> &TraceJacArray)
1641{
1642 int nFwdBwd, nDiagBlks, nvar0Jac, nvar1Jac;
1643
1646 nFwdBwd = TraceJac.size();
1647 TraceJac[0]->GetBlockSizes(rowSizes, colSizes);
1648 nDiagBlks = rowSizes.size();
1649 nvar0Jac = rowSizes[1] - rowSizes[0];
1650 nvar1Jac = colSizes[1] - colSizes[0];
1651
1652 if (0 == TraceJacArray.size())
1653 {
1654 TraceJacArray = TensorOfArray4D<DataType>(nFwdBwd);
1655 for (int nlr = 0; nlr < nFwdBwd; nlr++)
1656 {
1657 TraceJacArray[nlr] = TensorOfArray3D<DataType>(nvar0Jac);
1658 for (int m = 0; m < nvar0Jac; m++)
1659 {
1660 TraceJacArray[nlr][m] =
1662 for (int n = 0; n < nvar1Jac; n++)
1663 {
1664 TraceJacArray[nlr][m][n] = Array<OneD, DataType>(nDiagBlks);
1665 }
1666 }
1667 }
1668 }
1669
1670 for (int nlr = 0; nlr < nFwdBwd; nlr++)
1671 {
1672 const TypeNekBlkMatSharedPtr tmpMat = TraceJac[nlr];
1673 TensorOfArray3D<DataType> tmpaa = TraceJacArray[nlr];
1674 TranSamesizeBlkDiagMatIntoArray(tmpMat, tmpaa);
1675 }
1676
1677 return;
1678}
1679
1681 [[maybe_unused]] const MultiRegions::ExpListSharedPtr &explist,
1682 [[maybe_unused]] const Array<OneD, const Array<OneD, NekDouble>> &normals,
1683 [[maybe_unused]] const int nDervDir,
1684 [[maybe_unused]] const Array<OneD, const Array<OneD, NekDouble>> &inarray,
1685 [[maybe_unused]] TensorOfArray5D<NekDouble> &ElmtJacArray,
1686 [[maybe_unused]] const int nFluxDir)
1687{
1688 NEKERROR(ErrorUtil::efatal, "v_GetFluxDerivJacDirctn not coded");
1689}
1690
1692 [[maybe_unused]] const int nConvectiveFields,
1693 [[maybe_unused]] const int nElmtPnt, [[maybe_unused]] const int nDervDir,
1694 [[maybe_unused]] const Array<OneD, const Array<OneD, NekDouble>> &locVars,
1695 [[maybe_unused]] const Array<OneD, NekDouble> &locmu,
1696 [[maybe_unused]] const Array<OneD, const Array<OneD, NekDouble>> &locnormal,
1697 [[maybe_unused]] DNekMatSharedPtr &wspMat,
1698 [[maybe_unused]] Array<OneD, Array<OneD, NekDouble>> &PntJacArray)
1699{
1700 NEKERROR(ErrorUtil::efatal, "v_GetFluxDerivJacDirctn not coded");
1701}
1702
1704 [[maybe_unused]] const MultiRegions::ExpListSharedPtr &explist,
1705 [[maybe_unused]] const Array<OneD, const Array<OneD, NekDouble>> &normals,
1706 [[maybe_unused]] const int nDervDir,
1707 [[maybe_unused]] const Array<OneD, const Array<OneD, NekDouble>> &inarray,
1708 [[maybe_unused]] TensorOfArray2D<DNekMatSharedPtr> &ElmtJac)
1709{
1710}
1711
1713 const int nConvectiveFields, const int nElmtPnt,
1714 const Array<OneD, const Array<OneD, NekDouble>> &locVars,
1715 const Array<OneD, NekDouble> &normals, DNekMatSharedPtr &wspMat,
1716 Array<OneD, Array<OneD, NekDouble>> &PntJacArray)
1717{
1718 Array<OneD, NekDouble> wspMatData = wspMat->GetPtr();
1719
1720 int matsize = nConvectiveFields * nConvectiveFields;
1721
1722 Array<OneD, NekDouble> pointVar(nConvectiveFields);
1723
1724 for (int npnt = 0; npnt < nElmtPnt; npnt++)
1725 {
1726 for (int j = 0; j < nConvectiveFields; j++)
1727 {
1728 pointVar[j] = locVars[j][npnt];
1729 }
1730
1731 GetFluxVectorJacPoint(nConvectiveFields, pointVar, normals, wspMat);
1732
1733 Vmath::Vcopy(matsize, wspMatData, 1, PntJacArray[npnt], 1);
1734 }
1735 return;
1736}
1737
1739 const int nConvectiveFields, const Array<OneD, NekDouble> &conservVar,
1740 const Array<OneD, NekDouble> &normals, DNekMatSharedPtr &fluxJac)
1741{
1742 int nvariables = conservVar.size();
1743 const int nvariables3D = 5;
1744 int expDim = m_spacedim;
1745
1746 NekDouble fsw, efix_StegerWarming;
1747 efix_StegerWarming = 0.0;
1748 fsw = 0.0; // exact flux Jacobian if fsw=0.0
1749 if (nvariables > expDim + 2)
1750 {
1751 NEKERROR(ErrorUtil::efatal, "nvariables > expDim+2 case not coded")
1752 }
1753
1754 Array<OneD, NekDouble> fluxJacData;
1755 ;
1756 fluxJacData = fluxJac->GetPtr();
1757
1758 if (nConvectiveFields == nvariables3D)
1759 {
1760 PointFluxJacobianPoint(conservVar, normals, fluxJac, efix_StegerWarming,
1761 fsw);
1762 }
1763 else
1764 {
1765 DNekMatSharedPtr PointFJac3D =
1767 nvariables3D, 0.0);
1768
1769 Array<OneD, NekDouble> PointFJac3DData;
1770 PointFJac3DData = PointFJac3D->GetPtr();
1771
1772 Array<OneD, NekDouble> PointFwd(nvariables3D, 0.0);
1773
1774 Array<OneD, unsigned int> index(nvariables);
1775
1776 index[nvariables - 1] = 4;
1777 for (int i = 0; i < nvariables - 1; i++)
1778 {
1779 index[i] = i;
1780 }
1781
1782 int nj = 0;
1783 int nk = 0;
1784 for (int j = 0; j < nvariables; j++)
1785 {
1786 nj = index[j];
1787 PointFwd[nj] = conservVar[j];
1788 }
1789
1790 PointFluxJacobianPoint(PointFwd, normals, PointFJac3D,
1791 efix_StegerWarming, fsw);
1792
1793 for (int j = 0; j < nvariables; j++)
1794 {
1795 nj = index[j];
1796 for (int k = 0; k < nvariables; k++)
1797 {
1798 nk = index[k];
1799 fluxJacData[j + k * nConvectiveFields] =
1800 PointFJac3DData[nj + nk * nvariables3D];
1801 }
1802 }
1803 }
1804}
1805
1806template <typename DataType, typename TypeNekBlkMatSharedPtr>
1808 const TypeNekBlkMatSharedPtr &BlkMat, TensorOfArray3D<DataType> &MatArray)
1809{
1812 BlkMat->GetBlockSizes(rowSizes, colSizes);
1813 int nDiagBlks = rowSizes.size();
1814 int nvar0 = rowSizes[1] - rowSizes[0];
1815 int nvar1 = colSizes[1] - colSizes[0];
1816
1817 Array<OneD, DataType> ElmtMatData;
1818
1819 for (int i = 0; i < nDiagBlks; i++)
1820 {
1821 ElmtMatData = BlkMat->GetBlock(i, i)->GetPtr();
1822 for (int n = 0; n < nvar1; n++)
1823 {
1824 int noffset = n * nvar0;
1825 for (int m = 0; m < nvar0; m++)
1826 {
1827 MatArray[m][n][i] = ElmtMatData[m + noffset];
1828 }
1829 }
1830 }
1831}
1832
1833template <typename DataType, typename TypeNekBlkMatSharedPtr>
1836 const DataType valu)
1837{
1838 int n1d = gmtxarray.size();
1839
1840 for (int n1 = 0; n1 < n1d; ++n1)
1841 {
1842 Fill1DArrayOfBlkDiagonalMat(gmtxarray[n1], valu);
1843 }
1844}
1845
1846template <typename DataType, typename TypeNekBlkMatSharedPtr>
1848 Array<OneD, TypeNekBlkMatSharedPtr> &gmtxarray, const DataType valu)
1849{
1850 int n1d = gmtxarray.size();
1851
1854
1855 Array<OneD, DataType> loc_mat_arr;
1856
1857 for (int n1 = 0; n1 < n1d; ++n1)
1858 {
1859 gmtxarray[n1]->GetBlockSizes(rowSizes, colSizes);
1860 int nelmts = rowSizes.size();
1861
1862 for (int i = 0; i < nelmts; ++i)
1863 {
1864 loc_mat_arr = gmtxarray[n1]->GetBlock(i, i)->GetPtr();
1865
1866 int nrows = gmtxarray[n1]->GetBlock(i, i)->GetRows();
1867 int ncols = gmtxarray[n1]->GetBlock(i, i)->GetColumns();
1868
1869 Vmath::Fill(nrows * ncols, valu, loc_mat_arr, 1);
1870 }
1871 }
1872}
1873
1874// Currently duplacate in compressibleFlowSys
1875// if fsw=+-1 calculate the steger-Warming flux vector splitting flux Jacobian
1876// if fsw=0 calculate the Jacobian of the exact flux
1877// efix is the numerical flux entropy fix parameter
1879 const Array<OneD, NekDouble> &normals,
1880 DNekMatSharedPtr &FJac,
1881 const NekDouble efix,
1882 const NekDouble fsw)
1883{
1884 Array<OneD, NekDouble> FJacData = FJac->GetPtr();
1885 const int nvariables3D = 5;
1886
1887 NekDouble ro, vx, vy, vz, ps, gama, ae;
1888 NekDouble a, a2, h, h0, v2, vn, eps, eps2;
1889 NekDouble nx, ny, nz;
1890 NekDouble sn, osn, nxa, nya, nza, vna;
1891 NekDouble l1, l4, l5, al1, al4, al5, x1, x2, x3, y1;
1892 NekDouble c1, d1, c2, d2, c3, d3, c4, d4, c5, d5;
1893 NekDouble sml_ssf = 1.0E-12;
1894
1895 NekDouble fExactorSplt = 2.0 - abs(fsw); // if fsw=+-1 calculate
1896
1897 NekDouble rhoL = Fwd[0];
1898 NekDouble rhouL = Fwd[1];
1899 NekDouble rhovL = Fwd[2];
1900 NekDouble rhowL = Fwd[3];
1901 NekDouble EL = Fwd[4];
1902
1903 ro = rhoL;
1904 vx = rhouL / rhoL;
1905 vy = rhovL / rhoL;
1906 vz = rhowL / rhoL;
1907
1908 // Internal energy (per unit mass)
1909 NekDouble eL = (EL - 0.5 * (rhouL * vx + rhovL * vy + rhowL * vz)) / rhoL;
1910
1911 ps = m_varConv->Geteos()->GetPressure(rhoL, eL);
1912 gama = m_gamma;
1913
1914 ae = gama - 1.0;
1915 v2 = vx * vx + vy * vy + vz * vz;
1916 a2 = gama * ps / ro;
1917 h = a2 / ae;
1918
1919 h0 = h + 0.5 * v2;
1920 a = sqrt(a2);
1921
1922 nx = normals[0];
1923 ny = normals[1];
1924 nz = normals[2];
1925 vn = nx * vx + ny * vy + nz * vz;
1926 sn = std::max(sqrt(nx * nx + ny * ny + nz * nz), sml_ssf);
1927 osn = 1.0 / sn;
1928
1929 nxa = nx * osn;
1930 nya = ny * osn;
1931 nza = nz * osn;
1932 vna = vn * osn;
1933 l1 = vn;
1934 l4 = vn + sn * a;
1935 l5 = vn - sn * a;
1936
1937 eps = efix * sn;
1938 eps2 = eps * eps;
1939
1940 al1 = sqrt(l1 * l1 + eps2);
1941 al4 = sqrt(l4 * l4 + eps2);
1942 al5 = sqrt(l5 * l5 + eps2);
1943
1944 l1 = 0.5 * (fExactorSplt * l1 + fsw * al1);
1945 l4 = 0.5 * (fExactorSplt * l4 + fsw * al4);
1946 l5 = 0.5 * (fExactorSplt * l5 + fsw * al5);
1947
1948 x1 = 0.5 * (l4 + l5);
1949 x2 = 0.5 * (l4 - l5);
1950 x3 = x1 - l1;
1951 y1 = 0.5 * v2;
1952 c1 = ae * x3 / a2;
1953 d1 = x2 / a;
1954
1955 int nVar0 = 0;
1956 int nVar1 = nvariables3D;
1957 int nVar2 = 2 * nvariables3D;
1958 int nVar3 = 3 * nvariables3D;
1959 int nVar4 = 4 * nvariables3D;
1960 FJacData[nVar0] = c1 * y1 - d1 * vna + l1;
1961 FJacData[nVar1] = -c1 * vx + d1 * nxa;
1962 FJacData[nVar2] = -c1 * vy + d1 * nya;
1963 FJacData[nVar3] = -c1 * vz + d1 * nza;
1964 FJacData[nVar4] = c1;
1965 c2 = c1 * vx + d1 * nxa * ae;
1966 d2 = x3 * nxa + d1 * vx;
1967 FJacData[1 + nVar0] = c2 * y1 - d2 * vna;
1968 FJacData[1 + nVar1] = -c2 * vx + d2 * nxa + l1;
1969 FJacData[1 + nVar2] = -c2 * vy + d2 * nya;
1970 FJacData[1 + nVar3] = -c2 * vz + d2 * nza;
1971 FJacData[1 + nVar4] = c2;
1972 c3 = c1 * vy + d1 * nya * ae;
1973 d3 = x3 * nya + d1 * vy;
1974 FJacData[2 + nVar0] = c3 * y1 - d3 * vna;
1975 FJacData[2 + nVar1] = -c3 * vx + d3 * nxa;
1976 FJacData[2 + nVar2] = -c3 * vy + d3 * nya + l1;
1977 FJacData[2 + nVar3] = -c3 * vz + d3 * nza;
1978 FJacData[2 + nVar4] = c3;
1979 c4 = c1 * vz + d1 * nza * ae;
1980 d4 = x3 * nza + d1 * vz;
1981 FJacData[3 + nVar0] = c4 * y1 - d4 * vna;
1982 FJacData[3 + nVar1] = -c4 * vx + d4 * nxa;
1983 FJacData[3 + nVar2] = -c4 * vy + d4 * nya;
1984 FJacData[3 + nVar3] = -c4 * vz + d4 * nza + l1;
1985 FJacData[3 + nVar4] = c4;
1986 c5 = c1 * h0 + d1 * vna * ae;
1987 d5 = x3 * vna + d1 * h0;
1988 FJacData[4 + nVar0] = c5 * y1 - d5 * vna;
1989 FJacData[4 + nVar1] = -c5 * vx + d5 * nxa;
1990 FJacData[4 + nVar2] = -c5 * vy + d5 * nya;
1991 FJacData[4 + nVar3] = -c5 * vz + d5 * nza;
1992 FJacData[4 + nVar4] = c5 + l1;
1993}
1994
1996{
1997 bool flag =
1998 (m_time + m_timestep > m_fintime && m_fintime > 0.0) ||
2000 return flag || m_preconCfs->UpdatePreconMatCheck(NullNekDouble1DArray,
2002}
2003
2004} // 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 WARNINGL0(condition, msg)
Definition: ErrorUtil.hpp:215
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:242
size_type size() const
Returns the array's size.
void CalcVolJacStdMat(TensorOfArray4D< DataType > &StdMatDataDBB, TensorOfArray5D< DataType > &StdMatDataDBDB)
void NumCalcRiemFluxJac(const int nConvectiveFields, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, const Array< OneD, NekDouble > > &AdvVel, const Array< OneD, const Array< OneD, NekDouble > > &inarray, TensorOfArray3D< NekDouble > &qfield, const NekDouble &time, const Array< OneD, const Array< OneD, NekDouble > > &Fwd, const Array< OneD, const Array< OneD, NekDouble > > &Bwd, TypeNekBlkMatSharedPtr &FJac, TypeNekBlkMatSharedPtr &BJac, TensorOfArray5D< DataType > &TraceIPSymJacArray)
void DoOdeImplicitRhs(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble time)
void AddMatNSBlkDiagVol(const Array< OneD, const Array< OneD, NekDouble > > &inarray, const Array< OneD, const TensorOfArray2D< NekDouble > > &qfield, Array< OneD, Array< OneD, TypeNekBlkMatSharedPtr > > &gmtxarray, TensorOfArray4D< DataType > &StdMatDataDBB, TensorOfArray5D< DataType > &StdMatDataDBDB)
void GetFluxDerivJacDirctnElmt(const int nConvectiveFields, const int nElmtPnt, const int nDervDir, const Array< OneD, const Array< OneD, NekDouble > > &locVars, const Array< OneD, NekDouble > &locmu, const Array< OneD, const Array< OneD, NekDouble > > &locnormal, DNekMatSharedPtr &wspMat, Array< OneD, Array< OneD, NekDouble > > &PntJacArray)
void CalcTraceNumericalFlux(const int nConvectiveFields, const int nDim, const int nPts, const int nTracePts, const NekDouble PenaltyFactor2, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, const Array< OneD, NekDouble > > &AdvVel, const Array< OneD, const Array< OneD, NekDouble > > &inarray, const NekDouble time, TensorOfArray3D< NekDouble > &qfield, const Array< OneD, const Array< OneD, NekDouble > > &vFwd, const Array< OneD, const Array< OneD, NekDouble > > &vBwd, const Array< OneD, const TensorOfArray2D< NekDouble > > &qFwd, const Array< OneD, const TensorOfArray2D< NekDouble > > &qBwd, const Array< OneD, NekDouble > &MuVarTrace, Array< OneD, int > &nonZeroIndex, Array< OneD, Array< OneD, NekDouble > > &traceflux)
LibUtilities::NekNonlinSysSharedPtr m_nonlinsol
void DoImplicitSolve(const Array< OneD, const Array< OneD, NekDouble > > &inpnts, Array< OneD, Array< OneD, NekDouble > > &outpnt, const NekDouble time, const NekDouble lambda)
void DoImplicitSolveCoeff(const Array< OneD, const Array< OneD, NekDouble > > &inpnts, const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out, const NekDouble time, const NekDouble lambda)
void GetFluxVectorJacDirElmt(const int nConvectiveFields, const int nElmtPnt, const Array< OneD, const Array< OneD, NekDouble > > &locVars, const Array< OneD, NekDouble > &normals, DNekMatSharedPtr &wspMat, Array< OneD, Array< OneD, NekDouble > > &PntJacArray)
void ElmtVarInvMtrx(Array< OneD, Array< OneD, TypeNekBlkMatSharedPtr > > &gmtxarray, TypeNekBlkMatSharedPtr &gmtVar, const DataType &tmpDatatype)
void CalcPreconMatBRJCoeff(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, SNekBlkMatSharedPtr > > &gmtxarray, SNekBlkMatSharedPtr &gmtVar, Array< OneD, SNekBlkMatSharedPtr > &TraceJac, Array< OneD, SNekBlkMatSharedPtr > &TraceJacDeriv, Array< OneD, Array< OneD, NekSingle > > &TraceJacDerivSign, TensorOfArray4D< NekSingle > &TraceJacArray, TensorOfArray4D< NekSingle > &TraceJacDerivArray, TensorOfArray5D< NekSingle > &TraceIPSymJacArray)
virtual void v_MinusDiffusionFluxJacPoint(const int nConvectiveFields, const int nElmtPnt, const Array< OneD, const Array< OneD, NekDouble > > &locVars, const TensorOfArray3D< NekDouble > &locDerv, const Array< OneD, NekDouble > &locmu, const Array< OneD, NekDouble > &locDmuDT, const Array< OneD, NekDouble > &normals, DNekMatSharedPtr &wspMat, Array< OneD, Array< OneD, NekDouble > > &PntJacArray)
void PointFluxJacobianPoint(const Array< OneD, NekDouble > &Fwd, const Array< OneD, NekDouble > &normals, DNekMatSharedPtr &FJac, const NekDouble efix, const NekDouble fsw)
void v_DoSolve() override
Solves an unsteady problem.
CFSImplicit(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
void GetTraceJac(const Array< OneD, const Array< OneD, NekDouble > > &inarray, TensorOfArray3D< NekDouble > &qfield, Array< OneD, TypeNekBlkMatSharedPtr > &TraceJac, Array< OneD, TypeNekBlkMatSharedPtr > &TraceJacDeriv, Array< OneD, Array< OneD, DataType > > &TraceJacDerivSign, TensorOfArray5D< DataType > &TraceIPSymJacArray)
void PreconCoeff(const Array< OneD, NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const bool &flag)
void MultiplyElmtInvMassPlusSource(Array< OneD, Array< OneD, TypeNekBlkMatSharedPtr > > &gmtxarray, const NekDouble dtlamda)
void CalcRefValues(const Array< OneD, const NekDouble > &inarray)
void TransTraceJacMatToArray(const Array< OneD, TypeNekBlkMatSharedPtr > &TraceJac, TensorOfArray4D< DataType > &TraceJacDerivArray)
void v_PrintStatusInformation(const int step, const NekDouble cpuTime) override
Print Status Information.
void CalcPhysDeriv(const Array< OneD, const Array< OneD, NekDouble > > &inarray, TensorOfArray3D< NekDouble > &qfield)
void MinusDiffusionFluxJacPoint(const int nConvectiveFields, const int nElmtPnt, const Array< OneD, const Array< OneD, NekDouble > > &locVars, const TensorOfArray3D< NekDouble > &locDerv, const Array< OneD, NekDouble > &locmu, const Array< OneD, NekDouble > &locDmuDT, const Array< OneD, NekDouble > &normals, DNekMatSharedPtr &wspMat, Array< OneD, Array< OneD, NekDouble > > &PntJacArray)
void CalcMuDmuDT(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, NekDouble > &mu, Array< OneD, NekDouble > &DmuDT)
void NonlinSysEvaluatorCoeff(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &out)
Array< OneD, Array< OneD, NekDouble > > m_solutionPhys
void DoOdeRhsCoeff(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble time)
Compute the right-hand side.
void DoDiffusionCoeff(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const Array< OneD, const Array< OneD, NekDouble > > &pFwd, const Array< OneD, const Array< OneD, NekDouble > > &pBwd)
Add the diffusions terms to the right-hand side Similar to DoDiffusion() but with outarray in coeffic...
void AllocateNekBlkMatDig(SNekBlkMatSharedPtr &mat, const Array< OneD, unsigned int > nrow, const Array< OneD, unsigned int > ncol)
virtual void v_GetFluxDerivJacDirctnElmt(const int nConvectiveFields, const int nElmtPnt, const int nDervDir, const Array< OneD, const Array< OneD, NekDouble > > &locVars, const Array< OneD, NekDouble > &locmu, const Array< OneD, const Array< OneD, NekDouble > > &locnormal, DNekMatSharedPtr &wspMat, Array< OneD, Array< OneD, NekDouble > > &PntJacArray)
TensorOfArray4D< NekSingle > m_stdSMatDataDBB
void TranSamesizeBlkDiagMatIntoArray(const TypeNekBlkMatSharedPtr &BlkMat, TensorOfArray3D< DataType > &MatArray)
virtual void v_GetFluxDerivJacDirctn(const MultiRegions::ExpListSharedPtr &explist, const Array< OneD, const Array< OneD, NekDouble > > &normals, const int nDervDir, const Array< OneD, const Array< OneD, NekDouble > > &inarray, TensorOfArray5D< NekDouble > &ElmtJacArray, const int nFluxDir)
void v_PrintSummaryStatistics(const NekDouble intTime) override
Print Summary Statistics.
virtual void v_DoDiffusionCoeff(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const Array< OneD, const Array< OneD, NekDouble > > &pFwd, const Array< OneD, const Array< OneD, NekDouble > > &pBwd)
void GetFluxVectorJacPoint(const int nConvectiveFields, const Array< OneD, NekDouble > &conservVar, const Array< OneD, NekDouble > &normals, DNekMatSharedPtr &fluxJac)
TensorOfArray5D< NekSingle > m_stdSMatDataDBDB
void NonlinSysEvaluatorCoeff1D(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out, const bool &flag=true)
void MatrixMultiplyMatrixFreeCoeff(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out, const bool &flag=false)
NekDouble m_TimeIntegLambda
coefff of spacial derivatives(rhs or m_F in GLM) in calculating the residual of the whole equation(us...
void Fill2DArrayOfBlkDiagonalMat(Array< OneD, Array< OneD, TypeNekBlkMatSharedPtr > > &gmtxarray, const DataType valu)
Array< OneD, NekDouble > m_magnitdEstimat
Estimate the magnitude of each conserved varibles.
void AddMatNSBlkDiagBnd(const Array< OneD, const Array< OneD, NekDouble > > &inarray, TensorOfArray3D< NekDouble > &qfield, TensorOfArray2D< TypeNekBlkMatSharedPtr > &gmtxarray, Array< OneD, TypeNekBlkMatSharedPtr > &TraceJac, Array< OneD, TypeNekBlkMatSharedPtr > &TraceJacDeriv, Array< OneD, Array< OneD, DataType > > &TraceJacDerivSign, TensorOfArray5D< DataType > &TraceIPSymJacArray)
void Fill1DArrayOfBlkDiagonalMat(Array< OneD, TypeNekBlkMatSharedPtr > &gmtxarray, const DataType valu)
void v_InitObject(bool DeclareFields=true) override
Initialization object for CFSImplicit class.
void DoAdvectionCoeff(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble time, const Array< OneD, const Array< OneD, NekDouble > > &pFwd, const Array< OneD, const Array< OneD, NekDouble > > &pBwd)
Compute the advection terms for the right-hand side.
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 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...
SolverUtils::DiffusionSharedPtr m_diffusion
void v_InitObject(bool DeclareFields=true) override
Initialization object for CompressibleFlowSystem class.
std::vector< CFSBndCondSharedPtr > m_bndConds
VariableConverterSharedPtr m_varConv
std::vector< SolverUtils::ForcingSharedPtr > m_forcing
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:143
NekDouble m_NonlinIterTolRelativeL2
Definition: NekSys.h:217
NekDouble m_LinSysRelativeTolInNonlin
Definition: NekSys.h:218
std::string m_LinSysIterSolverTypeInNonlin
Definition: NekSys.h:225
void DefineNekSysResEval(FuncPointerT func, ObjectPointerT obj)
Definition: NekSys.h:99
void DefineNekSysLhsEval(FuncPointerT func, ObjectPointerT obj)
Definition: NekSys.h:106
void DefineNekSysPrecon(FuncPointerT func, ObjectPointerT obj)
Definition: NekSys.h:113
void DefineOdeRhs(FuncPointerT func, ObjectPointerT obj)
void DefineImplicitSolve(FuncPointerT func, ObjectPointerT obj)
void AccumulateRegion(std::string, int iolevel=0)
Accumulate elapsed time for a region.
Definition: Timer.cpp:70
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
void DefineCalcPreconMatBRJCoeff(FuncPointerT func, ObjectPointerT obj)
Definition: PreconCfsOp.h:88
SolverUtils::AdvectionSharedPtr m_advObject
Advection term.
int m_spacedim
Spatial dimension (>= expansion dim).
SpatialDomains::MeshGraphSharedPtr m_graph
Pointer to graph defining mesh.
LibUtilities::CommSharedPtr m_comm
Communicator.
NekDouble m_timestep
Time step size.
int m_infosteps
Number of time steps between outputting status information.
NekDouble m_time
Current time of simulation.
SOLVER_UTILS_EXPORT int GetTraceTotPoints()
Array< OneD, MultiRegions::ExpListSharedPtr > m_fields
Array holding all dependent variables.
NekDouble m_fintime
Finish time of the simulation.
NekDouble m_checktime
Time between checkpoints.
LibUtilities::SessionReaderSharedPtr m_session
The session reader.
enum HomogeneousType m_HomogeneousType
SOLVER_UTILS_EXPORT int GetNpoints()
SOLVER_UTILS_EXPORT int GetNcoeffs()
SOLVER_UTILS_EXPORT int GetPhys_Offset(int n)
SOLVER_UTILS_EXPORT int GetTotPoints()
Base class for unsteady solvers.
LibUtilities::TimeIntegrationSchemeOperators m_ode
The time integration scheme operators to use.
bool m_explicitAdvection
Indicates if explicit or implicit treatment of advection is used.
bool m_explicitDiffusion
Indicates if explicit or implicit treatment of diffusion is used.
virtual SOLVER_UTILS_EXPORT void v_PrintSummaryStatistics(const NekDouble intTime)
Print Summary Statistics.
virtual SOLVER_UTILS_EXPORT void v_PrintStatusInformation(const int step, const NekDouble cpuTime)
Print Status Information.
SOLVER_UTILS_EXPORT void v_DoSolve() override
Solves an unsteady problem.
static void Ger(const int &m, const int &n, const double &alpha, const double *x, const int &incx, const double *y, const int &incy, double *a, const int &lda)
BLAS level 2: Matrix vector multiply A = alpha*x*y**T + A where A[m x n].
Definition: Blas.hpp:335
NekNonlinSysFactory & GetNekNonlinSysFactory()
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< AssemblyMapDG > AssemblyMapDGSharedPtr
Definition: AssemblyMapDG.h:46
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:174
std::shared_ptr< StdExpansion > StdExpansionSharedPtr
PreconCfsFactory & GetPreconCfsFactory()
Declaration of the boundary condition factory singleton.
Definition: PreconCfs.cpp:42
std::shared_ptr< SNekBlkMat > SNekBlkMatSharedPtr
static Array< OneD, Array< OneD, NekDouble > > NullNekDoubleArrayOfArray
static Array< OneD, Array< OneD, Array< OneD, NekDouble > > > NullNekDoubleTensorOfArray3D
static Array< OneD, NekDouble > NullNekDouble1DArray
std::shared_ptr< DNekMat > DNekMatSharedPtr
Definition: NekTypeDefs.hpp:75
double NekDouble
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 Dot(int n, const T *w, const T *x)
dot product
Definition: Vmath.hpp:761
void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Add vector z = x+y.
Definition: Vmath.hpp:180
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
Definition: Vmath.hpp:100
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.hpp:273
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
Definition: Vmath.hpp:54
void Sadd(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Add vector y = alpha + x.
Definition: Vmath.hpp:194
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.hpp:825
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.hpp:220
scalarT< T > abs(scalarT< T > in)
Definition: scalar.hpp:298
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294