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