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,
65
66 m_session->LoadParameter("nPadding", m_nPadding, 4);
67
68 int ntmp;
69 m_session->LoadParameter("AdvectionJacFlag", ntmp, 1);
70 m_advectionJacFlag = (ntmp != 0);
71
72 m_session->LoadParameter("ViscousJacFlag", ntmp, 1);
73 m_viscousJacFlag = (ntmp != 0);
74
75 // Initialise implicit functors
78
80}
81
83{
84 int nvariables = m_fields.size();
85 int ntotal = m_fields[0]->GetNcoeffs() * nvariables;
86
87 std::string SolverType = "Newton";
88 if (m_session->DefinesSolverInfo("NonlinSysIterSolver"))
89 {
90 SolverType = m_session->GetSolverInfo("NonlinSysIterSolver");
91 }
94 "NekNonlinSys '" + SolverType + "' is not defined.\n");
95
96 // Create the key to hold settings for nonlin solver
98 // Load required LinSys parameters:
99 m_session->LoadParameter("NekLinSysMaxIterations",
101 m_session->LoadParameter("LinSysMaxStorage", key.m_LinSysMaxStorage, 30);
102 m_session->LoadParameter("LinSysRelativeTolInNonlin",
103 key.m_NekLinSysTolerance, 5.0E-2);
104 m_session->LoadParameter("GMRESMaxHessMatBand", key.m_KrylovMaxHessMatBand,
105 31);
106 m_session->MatchSolverInfo("GMRESLeftPrecon", "True",
107 key.m_NekLinSysLeftPrecon, false);
108 m_session->MatchSolverInfo("GMRESRightPrecon", "True",
109 key.m_NekLinSysRightPrecon, true);
110 int GMRESCentralDifference = 0;
111 m_session->LoadParameter("GMRESCentralDifference", GMRESCentralDifference,
112 0);
113 key.m_GMRESCentralDifference = (bool)GMRESCentralDifference;
114 // Load required NonLinSys parameters:
115 m_session->LoadParameter("NekNonlinSysMaxIterations",
117 m_session->LoadParameter("NewtonRelativeIteTol",
118 key.m_NekNonLinSysTolerance, 1.0E-12);
119 WARNINGL0(!m_session->DefinesParameter("NewtonAbsoluteIteTol"),
120 "Please specify NewtonRelativeIteTol instead of "
121 "NewtonAbsoluteIteTol in XML session file");
122 m_session->LoadParameter("NonlinIterTolRelativeL2",
123 key.m_NonlinIterTolRelativeL2, 1.0E-3);
124 m_session->LoadSolverInfo("LinSysIterSolverTypeInNonlin",
125 key.m_LinSysIterSolverTypeInNonlin, "GMRES");
126
127 // Initialize operator
131 this);
133
134 // Initialize trace
135 const auto locTraceToTraceMap = m_fields[0]->GetLocTraceToTraceMap();
136 locTraceToTraceMap->CalcLocTracePhysToTraceIDMap(m_fields[0]->GetTrace(),
137 m_spacedim);
138 for (int i = 1; i < nvariables; i++)
139 {
140 m_fields[i]->GetLocTraceToTraceMap()->SetLocTracePhysToTraceIDMap(
141 locTraceToTraceMap->GetLocTracephysToTraceIDMap());
142 }
143
144 // Initialize non-linear system
146 "Newton", m_session, m_comm->GetRowComm(), ntotal, key);
147 m_nonlinsol->SetSysOperators(nekSysOp);
148
149 // Initialize preconditioner
150 NekPreconCfsOperators preconOp;
152 this);
155 m_preconCfs->SetOperators(preconOp);
156}
157
159{
160 m_TotNewtonIts = 0;
161 m_TotLinIts = 0;
162 m_TotImpStages = 0;
164}
165
167 const NekDouble cpuTime)
168{
170
171 if (m_infosteps && m_session->GetComm()->GetSpaceComm()->GetRank() == 0 &&
172 !((step + 1) % m_infosteps) && m_flagImplicitItsStatistics)
173 {
174 cout << " &&"
175 << " TotImpStages= " << m_TotImpStages
176 << " TotNewtonIts= " << m_TotNewtonIts
177 << " TotLinearIts = " << m_TotLinIts << endl;
178 }
179}
180
182{
184
185 if (m_session->GetComm()->GetRank() == 0 && m_flagImplicitItsStatistics)
186 {
187 cout << "-------------------------------------------" << endl
188 << "Total Implicit Stages: " << m_TotImpStages << endl
189 << "Total Newton Its : " << m_TotNewtonIts << endl
190 << "Total Linear Its : " << m_TotLinIts << endl
191 << "-------------------------------------------" << endl;
192 }
193}
194
197 const bool &flag)
198{
200 unsigned int nvariables = m_fields.size();
201 unsigned int ncoeffs = m_fields[0]->GetNcoeffs();
202 Array<OneD, Array<OneD, NekDouble>> in2D(nvariables);
203 Array<OneD, Array<OneD, NekDouble>> out2D(nvariables);
204 for (int i = 0; i < nvariables; ++i)
205 {
206 int offset = i * ncoeffs;
207 in2D[i] = inarray + offset;
208 out2D[i] = out + offset;
209 }
210
211 timer.Start();
212 NonlinSysEvaluatorCoeff(in2D, out2D, flag);
213 timer.Stop();
214 timer.AccumulateRegion("CFSImplicit::NonlinSysEvaluatorCoeff1D");
215}
216
218 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
219 Array<OneD, Array<OneD, NekDouble>> &out, const bool &flag)
220{
222 unsigned int nvariable = inarray.size();
223 unsigned int ncoeffs = m_fields[0]->GetNcoeffs();
224 unsigned int npoints = m_fields[0]->GetNpoints();
225
226 Array<OneD, Array<OneD, NekDouble>> inpnts(nvariable);
227
228 for (int i = 0; i < nvariable; ++i)
229 {
230 inpnts[i] = Array<OneD, NekDouble>(npoints, 0.0);
231 m_fields[i]->BwdTrans(inarray[i], inpnts[i]);
232 }
233
234 timer.Start();
235 DoOdeProjection(inpnts, inpnts, m_bndEvaluateTime);
236 timer.Stop();
237 timer.AccumulateRegion("CompressibleFlowSystem::DoOdeProjection", 1);
238
239 timer.Start();
240 DoOdeRhsCoeff(inpnts, out, m_bndEvaluateTime);
241 timer.Stop();
242 timer.AccumulateRegion("CFSImplicit::DoOdeRhsCoeff", 1);
243
244 for (int i = 0; i < nvariable; ++i)
245 {
246 Vmath::Svtvp(ncoeffs, -m_TimeIntegLambda, out[i], 1, inarray[i], 1,
247 out[i], 1);
248 if (flag)
249 {
250 Vmath::Vsub(ncoeffs, out[i], 1,
251 m_nonlinsol->GetRefSourceVec() + i * ncoeffs, 1, out[i],
252 1);
253 }
254 }
255}
256
258 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
259 Array<OneD, Array<OneD, NekDouble>> &outarray, const NekDouble time)
260{
261 int nvariables = inarray.size();
262 int ncoeffs = m_fields[0]->GetNcoeffs();
263
264 Array<OneD, Array<OneD, NekDouble>> tmpOut(nvariables);
265 for (int i = 0; i < nvariables; ++i)
266 {
267 tmpOut[i] = Array<OneD, NekDouble>(ncoeffs);
268 }
269
270 DoOdeRhsCoeff(inarray, tmpOut, time);
271
272 for (int i = 0; i < nvariables; ++i)
273 {
274 m_fields[i]->BwdTrans(tmpOut[i], outarray[i]);
275 }
276}
277
278/**
279 * @brief Compute the right-hand side.
280 */
282 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
283 Array<OneD, Array<OneD, NekDouble>> &outarray, const NekDouble time)
284{
285 ASSERTL0(
287 "Do not use Local Time-Stepping with implicit time-discretization");
288
290
291 int nvariables = inarray.size();
292 int nTracePts = GetTraceTotPoints();
293 int ncoeffs = GetNcoeffs();
294
295 m_bndEvaluateTime = time;
296
297 // Store forwards/backwards space along trace space
298 Array<OneD, Array<OneD, NekDouble>> Fwd(nvariables);
299 Array<OneD, Array<OneD, NekDouble>> Bwd(nvariables);
300
302 {
305 }
306 else
307 {
308 for (int i = 0; i < nvariables; ++i)
309 {
310 Fwd[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
311 Bwd[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
312 m_fields[i]->GetFwdBwdTracePhys(inarray[i], Fwd[i], Bwd[i]);
313 }
314 }
315
316 // Calculate advection
317 timer.Start();
318 DoAdvectionCoeff(inarray, outarray, time, Fwd, Bwd);
319 timer.Stop();
320 timer.AccumulateRegion("CFSImplicit::DoAdvectionCoeff", 2);
321
322 // Negate results
323 for (int i = 0; i < nvariables; ++i)
324 {
325 Vmath::Neg(ncoeffs, outarray[i], 1);
326 }
327
328 // Add diffusion terms
329 timer.Start();
330 DoDiffusionCoeff(inarray, outarray, Fwd, Bwd);
331 timer.Stop();
332 timer.AccumulateRegion("CFSImplicit::DoDiffusionCoeff", 2);
333
334 // Add forcing terms
335 for (auto &x : m_forcing)
336 {
337 x->ApplyCoeff(m_fields, inarray, outarray, time);
338 }
339}
340
341/**
342 * @brief Compute the advection terms for the right-hand side
343 */
345 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
346 Array<OneD, Array<OneD, NekDouble>> &outarray, const NekDouble time,
347 const Array<OneD, const Array<OneD, NekDouble>> &pFwd,
348 const Array<OneD, const Array<OneD, NekDouble>> &pBwd)
349{
350 int nvariables = inarray.size();
352
353 auto advWeakDGObject =
354 std::dynamic_pointer_cast<SolverUtils::AdvectionWeakDG>(m_advObject);
355 ASSERTL0(advWeakDGObject,
356 "Use WeakDG for implicit compressible flow solver!");
357 advWeakDGObject->AdvectCoeffs(nvariables, m_fields, advVel, inarray,
358 outarray, time, pFwd, pBwd);
359}
360
361/**
362 * @brief Add the diffusions terms to the right-hand side
363 * Similar to DoDiffusion() but with outarray in coefficient space
364 */
366 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
368 const Array<OneD, const Array<OneD, NekDouble>> &pFwd,
369 const Array<OneD, const Array<OneD, NekDouble>> &pBwd)
370{
371 v_DoDiffusionCoeff(inarray, outarray, pFwd, pBwd);
372}
373
375 const Array<OneD, const Array<OneD, NekDouble>> &inpnts,
376 Array<OneD, Array<OneD, NekDouble>> &outpnt, const NekDouble time,
377 const NekDouble lambda)
378{
379 unsigned int nvariables = inpnts.size();
380 unsigned int ncoeffs = m_fields[0]->GetNcoeffs();
381 unsigned int ntotal = nvariables * ncoeffs;
382
383 Array<OneD, NekDouble> inarray(ntotal);
384 Array<OneD, NekDouble> outarray(ntotal);
385 Array<OneD, NekDouble> tmpArray;
386 Array<OneD, Array<OneD, NekDouble>> tmpIn(nvariables);
387 Array<OneD, Array<OneD, NekDouble>> tmpOut(nvariables);
388 Array<OneD, Array<OneD, NekDouble>> tmpoutarray(nvariables);
389 // Switch flag to make sure the physical shock capturing AV is updated
391 if (m_ALESolver)
392 {
394 }
395 else
396 {
397 tmpIn = inpnts;
398 }
399 for (int i = 0; i < nvariables; ++i)
400 {
401 int noffset = i * ncoeffs;
402 tmpArray = inarray + noffset;
403 m_fields[i]->FwdTrans(tmpIn[i], tmpArray);
404 }
405
406 DoImplicitSolveCoeff(tmpIn, inarray, outarray, time, lambda);
407
408 if (m_ALESolver)
409 {
410
411 for (int i = 0; i < nvariables; ++i)
412 {
413 tmpOut[i] = Array<OneD, NekDouble>(tmpIn[0].size(), 0.0);
414 tmpoutarray[i] = Array<OneD, NekDouble>(ncoeffs, 0.0);
415 }
416 for (int i = 0; i < nvariables; ++i)
417 {
418 int noffset = i * ncoeffs;
419 tmpArray = outarray + noffset;
420 m_fields[i]->BwdTrans(tmpArray, tmpOut[i]);
421 }
423 for (int i = 0; i < nvariables; ++i)
424 {
425 m_fields[i]->FwdTrans(tmpOut[i], tmpoutarray[i]);
426 m_fields[i]->GeneralMatrixOp(mkey, tmpoutarray[i], outpnt[i]);
427 }
428 }
429 else
430 {
431 for (int i = 0; i < nvariables; ++i)
432 {
433 int noffset = i * ncoeffs;
434 tmpArray = outarray + noffset;
435 m_fields[i]->BwdTrans(tmpArray, outpnt[i]);
436 }
437 }
438}
439
441 const Array<OneD, const Array<OneD, NekDouble>> &inpnts,
443 const NekDouble time, const NekDouble lambda)
444{
445 m_TimeIntegLambda = lambda;
446 m_bndEvaluateTime = time;
447 m_solutionPhys = inpnts;
448 unsigned int ntotal = inarray.size();
449
450 if (m_inArrayNorm < 0.0)
451 {
452 CalcRefValues(inarray);
453
454 m_nonlinsol->SetRhsMagnitude(m_inArrayNorm);
455 }
456
457 m_TotNewtonIts += m_nonlinsol->SolveSystem(ntotal, inarray, out);
458
459 m_TotLinIts += m_nonlinsol->GetNtotLinSysIts();
460
462}
463
465{
466 unsigned int nvariables = m_fields.size();
467 unsigned int ntotal = inarray.size();
468 unsigned int npoints = ntotal / nvariables;
469
470 unsigned int nTotalGlobal = ntotal;
471 m_comm->GetSpaceComm()->AllReduce(nTotalGlobal,
473 unsigned int nTotalDOF = nTotalGlobal / nvariables;
474 NekDouble invTotalDOF = 1.0 / nTotalDOF;
475
476 m_inArrayNorm = 0.0;
477 m_magnitdEstimat = Array<OneD, NekDouble>(nvariables, 0.0);
478
479 for (int i = 0; i < nvariables; ++i)
480 {
481 int offset = i * npoints;
483 Vmath::Dot(npoints, inarray + offset, inarray + offset);
484 }
485 m_comm->GetSpaceComm()->AllReduce(m_magnitdEstimat,
487
488 for (int i = 0; i < nvariables; ++i)
489 {
491 }
492
493 for (int i = 2; i < nvariables - 1; ++i)
494 {
496 }
497
498 for (int i = 2; i < nvariables - 1; ++i)
499 {
501 }
502
503 for (int i = 0; i < nvariables; ++i)
504 {
505 m_magnitdEstimat[i] = sqrt(m_magnitdEstimat[i] * invTotalDOF);
506 }
507 if (m_comm->GetRank() == 0 && m_verbose)
508 {
509 for (int i = 0; i < nvariables; ++i)
510 {
511 cout << "m_magnitdEstimat[" << i << "] = " << m_magnitdEstimat[i]
512 << endl;
513 }
514 cout << "m_inArrayNorm = " << m_inArrayNorm << endl;
515 }
516}
517
520 const bool &centralDifferenceFlag)
521{
522 const Array<OneD, const NekDouble> solref = m_nonlinsol->GetRefSolution();
523
524 unsigned int ntotal = inarray.size();
525 NekDouble magninarray = Vmath::Dot(ntotal, inarray, inarray);
526 m_comm->GetSpaceComm()->AllReduce(magninarray,
528 NekDouble eps =
529 m_jacobiFreeEps * sqrt((sqrt(m_inArrayNorm) + 1.0) / magninarray);
530
531 Array<OneD, NekDouble> solplus{ntotal};
532 Array<OneD, NekDouble> resplus{ntotal};
533 Vmath::Svtvp(ntotal, eps, inarray, 1, solref, 1, solplus, 1);
534 NonlinSysEvaluatorCoeff1D(solplus, resplus, !centralDifferenceFlag);
535
536 if (centralDifferenceFlag)
537 {
538 Array<OneD, NekDouble> solminus{ntotal};
539 Array<OneD, NekDouble> resminus{ntotal};
540 Vmath::Svtvp(ntotal, -1.0 * eps, inarray, 1, solref, 1, solminus, 1);
541 NonlinSysEvaluatorCoeff1D(solminus, resminus, false);
542 Vmath::Vsub(ntotal, resplus, 1, resminus, 1, out, 1);
543 Vmath::Smul(ntotal, 0.5 / eps, out, 1, out, 1);
544 }
545 else
546 {
547 const Array<OneD, const NekDouble> resref =
548 m_nonlinsol->GetRefResidual();
549
550 Vmath::Vsub(ntotal, resplus, 1, resref, 1, out, 1);
551 Vmath::Smul(ntotal, 1.0 / eps, out, 1, out, 1);
552 }
553}
554
556 Array<OneD, NekDouble> &outarray,
557 const bool &flag)
558{
559 LibUtilities::Timer timer, Gtimer;
560
561 Gtimer.Start();
562 if (m_preconCfs->UpdatePreconMatCheck(NullNekDouble1DArray,
564 {
565 int nvariables = m_solutionPhys.size();
566 int nphspnt = m_solutionPhys[nvariables - 1].size();
567 Array<OneD, Array<OneD, NekDouble>> intmp(nvariables);
568 for (int i = 0; i < nvariables; i++)
569 {
570 intmp[i] = Array<OneD, NekDouble>(nphspnt, 0.0);
571 }
572
573 timer.Start();
575 timer.Stop();
576 timer.AccumulateRegion("CompressibleFlowSystem::DoOdeProjection", 1);
577
578 timer.Start();
579 m_preconCfs->BuildPreconCfs(m_fields, intmp, m_bndEvaluateTime,
581 timer.Stop();
582 timer.AccumulateRegion("PreconCfsOp::BuildPreconCfs", 1);
583 }
584
585 timer.Start();
586 m_preconCfs->DoPreconCfs(m_fields, inarray, outarray, flag);
587 timer.Stop();
588 timer.AccumulateRegion("PreconCfsOp::DoPreconCfs", 1);
589
590 Gtimer.Stop();
591 Gtimer.AccumulateRegion("CFSImplicit::PreconCoeff");
592}
593
594template <typename DataType, typename TypeNekBlkMatSharedPtr>
596 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
597 const Array<OneD, const TensorOfArray2D<NekDouble>> &qfield,
599 TensorOfArray4D<DataType> &StdMatDataDBB,
600 TensorOfArray5D<DataType> &StdMatDataDBDB)
601{
602 if (StdMatDataDBB.size() == 0)
603 {
604 CalcVolJacStdMat(StdMatDataDBB, StdMatDataDBDB);
605 }
606
607 int nSpaceDim = m_graph->GetSpaceDimension();
608 int nvariable = inarray.size();
609 int npoints = m_fields[0]->GetTotPoints();
610 int nVar2 = nvariable * nvariable;
611 std::shared_ptr<LocalRegions::ExpansionVector> expvect =
612 m_fields[0]->GetExp();
613 int nTotElmt = (*expvect).size();
614
615 Array<OneD, NekDouble> mu(npoints, 0.0);
616 Array<OneD, NekDouble> DmuDT(npoints, 0.0);
618 {
619 CalcMuDmuDT(inarray, mu, DmuDT);
620 }
621
624 for (int i = 0; i < 3; i++)
625 {
626 normal3D[i] = Array<OneD, NekDouble>(3, 0.0);
627 }
628 normal3D[0][0] = 1.0;
629 normal3D[1][1] = 1.0;
630 normal3D[2][2] = 1.0;
632
633 DNekMatSharedPtr wspMat =
634 MemoryManager<DNekMat>::AllocateSharedPtr(nvariable, nvariable, 0.0);
636 nvariable - 1, nvariable, 0.0);
637
638 Array<OneD, DataType> GmatxData;
639 Array<OneD, DataType> MatData;
640
643 m_spacedim); // Nvar*Nvar*Ndir*Nelmt*Npnt
644 TensorOfArray3D<DataType> PntJacConsStd(
645 m_spacedim); // Nvar*Nvar*Ndir*Nelmt*Npnt
649 m_spacedim); // Nvar*Nvar*Ndir*Nelmt*Npnt
650 TensorOfArray4D<DataType> PntJacDervStd(
651 m_spacedim); // Nvar*Nvar*Ndir*Nelmt*Npnt
653 m_spacedim); // Nvar*Nvar*Ndir*Nelmt*Npnt
655 m_spacedim); // Nvar*Nvar*Ndir*Nelmt*Npnt
656 for (int ndir = 0; ndir < m_spacedim; ndir++)
657 {
658 PntJacDerv[ndir] = TensorOfArray3D<NekDouble>(m_spacedim);
659 PntJacDervStd[ndir] = TensorOfArray3D<DataType>(m_spacedim);
662 }
663
665 Array<OneD, NekDouble> locDmuDT;
666 Array<OneD, Array<OneD, NekDouble>> locVars(nvariable);
668 for (int ndir = 0; ndir < m_spacedim; ndir++)
669 {
670 locDerv[ndir] = Array<OneD, Array<OneD, NekDouble>>(nvariable);
671 }
672
673 int nElmtCoefOld = -1;
674 for (int ne = 0; ne < nTotElmt; ne++)
675 {
676 int nElmtCoef = (*expvect)[ne]->GetNcoeffs();
677 int nElmtCoef2 = nElmtCoef * nElmtCoef;
678 int nElmtPnt = (*expvect)[ne]->GetTotPoints();
679
680 int nQuot = nElmtCoef2 / m_nPadding;
681 int nRemd = nElmtCoef2 - nQuot * m_nPadding;
682 int nQuotPlus = nQuot;
683 if (nRemd > 0)
684 {
685 nQuotPlus++;
686 }
687 int nElmtCoef2Paded = nQuotPlus * m_nPadding;
688
689 if (nElmtPnt > PntJacCons[0].size() || nElmtCoef > nElmtCoefOld)
690 {
691 nElmtCoefOld = nElmtCoef;
692 for (int ndir = 0; ndir < 3; ndir++)
693 {
694 normalPnt[ndir] = Array<OneD, NekDouble>(npoints, 0.0);
695 }
696 tmppnts = Array<OneD, NekDouble>(nElmtPnt);
697 MatData = Array<OneD, DataType>(nElmtCoef2Paded * nVar2);
698 for (int ndir = 0; ndir < m_spacedim; ndir++)
699 {
700 ConsCurv[ndir] = Array<OneD, NekDouble>(nElmtPnt);
701 ConsStdd[ndir] = Array<OneD, NekDouble>(nElmtPnt);
702 PntJacCons[ndir] =
704 PntJacConsStd[ndir] =
706 for (int i = 0; i < nElmtPnt; i++)
707 {
708 PntJacCons[ndir][i] = Array<OneD, NekDouble>(nVar2);
709 PntJacConsStd[ndir][i] = Array<OneD, DataType>(nVar2);
710 }
711
712 for (int ndir1 = 0; ndir1 < m_spacedim; ndir1++)
713 {
714 PntJacDerv[ndir][ndir1] =
716 PntJacDervStd[ndir][ndir1] =
718 DervStdd[ndir][ndir1] = Array<OneD, NekDouble>(nElmtPnt);
719 DervCurv[ndir][ndir1] = Array<OneD, NekDouble>(nElmtPnt);
720 for (int i = 0; i < nElmtPnt; i++)
721 {
722 PntJacDerv[ndir][ndir1][i] =
724 PntJacDervStd[ndir][ndir1][i] =
726 }
727 }
728 }
729 }
730
731 int noffset = GetPhys_Offset(ne);
732 for (int j = 0; j < nvariable; j++)
733 {
734 locVars[j] = inarray[j] + noffset;
735 }
736
738 {
739 for (int nFluxDir = 0; nFluxDir < nSpaceDim; nFluxDir++)
740 {
741 normals = normal3D[nFluxDir];
742 GetFluxVectorJacDirElmt(nvariable, nElmtPnt, locVars, normals,
743 wspMat, PntJacCons[nFluxDir]);
744 }
745 }
746
748 {
749 for (int j = 0; j < nSpaceDim; j++)
750 {
751 for (int k = 0; k < nvariable; k++)
752 {
753 locDerv[j][k] = qfield[j][k] + noffset;
754 }
755 }
756 locmu = mu + noffset;
757 locDmuDT = DmuDT + noffset;
758 for (int nFluxDir = 0; nFluxDir < nSpaceDim; nFluxDir++)
759 {
760 normals = normal3D[nFluxDir];
761 MinusDiffusionFluxJacPoint(nvariable, nElmtPnt, locVars,
762 locDerv, locmu, locDmuDT, normals,
763 wspMatDrv, PntJacCons[nFluxDir]);
764 }
765 }
766
768 {
769 locmu = mu + noffset;
770 for (int nFluxDir = 0; nFluxDir < nSpaceDim; nFluxDir++)
771 {
772 Vmath::Fill(npoints, 1.0, normalPnt[nFluxDir], 1);
773 for (int nDervDir = 0; nDervDir < nSpaceDim; nDervDir++)
774 {
776 nvariable, nElmtPnt, nDervDir, locVars, locmu,
777 normalPnt, wspMatDrv, PntJacDerv[nFluxDir][nDervDir]);
778 }
779 Vmath::Fill(npoints, 0.0, normalPnt[nFluxDir], 1);
780 }
781 }
782
783 for (int n = 0; n < nvariable; n++)
784 {
785 for (int m = 0; m < nvariable; m++)
786 {
787 int nVarOffset = m + n * nvariable;
788 GmatxData = gmtxarray[m][n]->GetBlock(ne, ne)->GetPtr();
789
790 for (int ndStd0 = 0; ndStd0 < m_spacedim; ndStd0++)
791 {
792 Vmath::Zero(nElmtPnt, ConsStdd[ndStd0], 1);
793 }
794 for (int ndir = 0; ndir < m_spacedim; ndir++)
795 {
796 for (int i = 0; i < nElmtPnt; i++)
797 {
798 tmppnts[i] = PntJacCons[ndir][i][nVarOffset];
799 }
800 (*expvect)[ne]->AlignVectorToCollapsedDir(ndir, tmppnts,
801 ConsCurv);
802 for (int nd = 0; nd < m_spacedim; nd++)
803 {
804 Vmath::Vadd(nElmtPnt, ConsCurv[nd], 1, ConsStdd[nd], 1,
805 ConsStdd[nd], 1);
806 }
807 }
808
809 for (int ndir = 0; ndir < m_spacedim; ndir++)
810 {
811 (*expvect)[ne]->MultiplyByQuadratureMetric(
812 ConsStdd[ndir], ConsStdd[ndir]); // weight with metric
813 for (int i = 0; i < nElmtPnt; i++)
814 {
815 PntJacConsStd[ndir][i][nVarOffset] =
816 DataType(ConsStdd[ndir][i]);
817 }
818 }
819 }
820 }
821
823 {
824 for (int m = 0; m < nvariable; m++)
825 {
826 for (int n = 0; n < nvariable; n++)
827 {
828 int nVarOffset = m + n * nvariable;
829 for (int ndStd0 = 0; ndStd0 < m_spacedim; ndStd0++)
830 {
831 for (int ndStd1 = 0; ndStd1 < m_spacedim; ndStd1++)
832 {
833 Vmath::Zero(nElmtPnt, DervStdd[ndStd0][ndStd1], 1);
834 }
835 }
836 for (int nd0 = 0; nd0 < m_spacedim; nd0++)
837 {
838 for (int nd1 = 0; nd1 < m_spacedim; nd1++)
839 {
840 for (int i = 0; i < nElmtPnt; i++)
841 {
842 tmppnts[i] =
843 PntJacDerv[nd0][nd1][i][nVarOffset];
844 }
845
846 (*expvect)[ne]->AlignVectorToCollapsedDir(
847 nd0, tmppnts, ConsCurv);
848 for (int nd = 0; nd < m_spacedim; nd++)
849 {
850 (*expvect)[ne]->AlignVectorToCollapsedDir(
851 nd1, ConsCurv[nd], DervCurv[nd]);
852 }
853
854 for (int ndStd0 = 0; ndStd0 < m_spacedim; ndStd0++)
855 {
856 for (int ndStd1 = 0; ndStd1 < m_spacedim;
857 ndStd1++)
858 {
859 Vmath::Vadd(nElmtPnt,
860 DervCurv[ndStd0][ndStd1], 1,
861 DervStdd[ndStd0][ndStd1], 1,
862 DervStdd[ndStd0][ndStd1], 1);
863 }
864 }
865 }
866 }
867 for (int nd0 = 0; nd0 < m_spacedim; nd0++)
868 {
869 for (int nd1 = 0; nd1 < m_spacedim; nd1++)
870 {
871 (*expvect)[ne]->MultiplyByQuadratureMetric(
872 DervStdd[nd0][nd1],
873 DervStdd[nd0][nd1]); // weight with metric
874 for (int i = 0; i < nElmtPnt; i++)
875 {
876 PntJacDervStd[nd0][nd1][i][nVarOffset] =
877 -DataType(DervStdd[nd0][nd1][i]);
878 }
879 }
880 }
881 }
882 }
883 }
884
885 Vmath::Zero(nElmtCoef2Paded * nVar2, MatData, 1);
886 DataType one = 1.0;
887 for (int ndir = 0; ndir < m_spacedim; ndir++)
888 {
889 for (int i = 0; i < nElmtPnt; i++)
890 {
891 Blas::Ger(nElmtCoef2Paded, nVar2, one,
892 &StdMatDataDBB[ne][ndir][i][0], 1,
893 &PntJacConsStd[ndir][i][0], 1, &MatData[0],
894 nElmtCoef2Paded);
895 }
896 }
897
899 {
900 for (int nd0 = 0; nd0 < m_spacedim; nd0++)
901 {
902 for (int nd1 = 0; nd1 < m_spacedim; nd1++)
903 {
904 for (int i = 0; i < nElmtPnt; i++)
905 {
906 Blas::Ger(nElmtCoef2Paded, nVar2, one,
907 &StdMatDataDBDB[ne][nd0][nd1][i][0], 1,
908 &PntJacDervStd[nd0][nd1][i][0], 1,
909 &MatData[0], nElmtCoef2Paded);
910 }
911 }
912 }
913 }
914
916
917 for (int n = 0; n < nvariable; n++)
918 {
919 for (int m = 0; m < nvariable; m++)
920 {
921 int nVarOffset = m + n * nvariable;
922 GmatxData = gmtxarray[m][n]->GetBlock(ne, ne)->GetPtr();
923 Vmath::Vcopy(nElmtCoef2,
924 tmpA = MatData + nVarOffset * nElmtCoef2Paded, 1,
925 GmatxData, 1);
926 }
927 }
928 }
929}
930
931template <typename DataType>
933 TensorOfArray5D<DataType> &StdMatDataDBDB)
934{
935 std::shared_ptr<LocalRegions::ExpansionVector> expvect =
936 m_fields[0]->GetExp();
937 int nTotElmt = (*expvect).size();
938
939 StdMatDataDBB = TensorOfArray4D<DataType>(nTotElmt);
940 StdMatDataDBDB = TensorOfArray5D<DataType>(nTotElmt);
941
942 vector<DNekMatSharedPtr> VectStdDerivBase0;
943 vector<TensorOfArray3D<DataType>> VectStdDerivBase_Base;
944 vector<TensorOfArray4D<DataType>> VectStdDervBase_DervBase;
945 DNekMatSharedPtr MatStdDerivBase0;
948 for (int ne = 0; ne < nTotElmt; ne++)
949 {
951 stdExp = (*expvect)[ne]->GetStdExp();
953 stdExp->DetShapeType(), *stdExp);
954 MatStdDerivBase0 = stdExp->GetStdMatrix(matkey);
955
956 int nTotStdExp = VectStdDerivBase0.size();
957 int nFoundStdExp = -1;
958 for (int i = 0; i < nTotStdExp; i++)
959 {
960 if ((*VectStdDerivBase0[i]) == (*MatStdDerivBase0))
961 {
962 nFoundStdExp = i;
963 }
964 }
965 if (nFoundStdExp >= 0)
966 {
967 StdMatDataDBB[ne] = VectStdDerivBase_Base[nFoundStdExp];
968 StdMatDataDBDB[ne] = VectStdDervBase_DervBase[nFoundStdExp];
969 }
970 else
971 {
972 int nElmtCoef = (*expvect)[ne]->GetNcoeffs();
973 int nElmtCoef2 = nElmtCoef * nElmtCoef;
974 int nElmtPnt = (*expvect)[ne]->GetTotPoints();
975
976 int nQuot = nElmtCoef2 / m_nPadding;
977 int nRemd = nElmtCoef2 - nQuot * m_nPadding;
978 int nQuotPlus = nQuot;
979 if (nRemd > 0)
980 {
981 nQuotPlus++;
982 }
983 int nPaded = nQuotPlus * m_nPadding;
984
985 ArrayStdMat[0] = MatStdDerivBase0;
986 if (m_spacedim > 1)
987 {
989 StdRegions::eDerivBase1, stdExp->DetShapeType(), *stdExp);
990 ArrayStdMat[1] = stdExp->GetStdMatrix(matkey);
991
992 if (m_spacedim > 2)
993 {
995 stdExp->DetShapeType(),
996 *stdExp);
997 ArrayStdMat[2] = stdExp->GetStdMatrix(matkey);
998 }
999 }
1000 for (int nd0 = 0; nd0 < m_spacedim; nd0++)
1001 {
1002 ArrayStdMatData[nd0] = ArrayStdMat[nd0]->GetPtr();
1003 }
1004
1006 stdExp->DetShapeType(), *stdExp);
1007 DNekMatSharedPtr BwdMat = stdExp->GetStdMatrix(matkey);
1008 Array<OneD, NekDouble> BwdMatData = BwdMat->GetPtr();
1009
1012
1013 for (int nd0 = 0; nd0 < m_spacedim; nd0++)
1014 {
1015 tmpStdDBB[nd0] = Array<OneD, Array<OneD, DataType>>(nElmtPnt);
1016 for (int i = 0; i < nElmtPnt; i++)
1017 {
1018 tmpStdDBB[nd0][i] = Array<OneD, DataType>(nPaded, 0.0);
1019 for (int nc1 = 0; nc1 < nElmtCoef; nc1++)
1020 {
1021 int noffset = nc1 * nElmtCoef;
1022 for (int nc0 = 0; nc0 < nElmtCoef; nc0++)
1023 {
1024 tmpStdDBB[nd0][i][nc0 + noffset] = DataType(
1025 ArrayStdMatData[nd0][i * nElmtCoef + nc0] *
1026 BwdMatData[i * nElmtCoef + nc1]);
1027 }
1028 }
1029 }
1030
1031 tmpStdDBDB[nd0] = TensorOfArray3D<DataType>(m_spacedim);
1032 for (int nd1 = 0; nd1 < m_spacedim; nd1++)
1033 {
1034 tmpStdDBDB[nd0][nd1] =
1036 for (int i = 0; i < nElmtPnt; i++)
1037 {
1038 tmpStdDBDB[nd0][nd1][i] =
1039 Array<OneD, DataType>(nPaded, 0.0);
1040 for (int nc1 = 0; nc1 < nElmtCoef; nc1++)
1041 {
1042 int noffset = nc1 * nElmtCoef;
1043 for (int nc0 = 0; nc0 < nElmtCoef; nc0++)
1044 {
1045 tmpStdDBDB[nd0][nd1][i][nc0 + noffset] =
1046 DataType(
1047 ArrayStdMatData[nd0]
1048 [i * nElmtCoef + nc0] *
1049 ArrayStdMatData[nd1]
1050 [i * nElmtCoef + nc1]);
1051 }
1052 }
1053 }
1054 }
1055 }
1056 VectStdDerivBase0.push_back(MatStdDerivBase0);
1057 VectStdDerivBase_Base.push_back(tmpStdDBB);
1058 VectStdDervBase_DervBase.push_back(tmpStdDBDB);
1059
1060 StdMatDataDBB[ne] = tmpStdDBB;
1061 StdMatDataDBDB[ne] = tmpStdDBDB;
1062 }
1063 }
1064}
1065
1066template <typename DataType, typename TypeNekBlkMatSharedPtr>
1068 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
1073 Array<OneD, Array<OneD, DataType>> &TraceJacDerivSign,
1074 TensorOfArray5D<DataType> &TraceIPSymJacArray)
1075{
1076 int nvariables = inarray.size();
1077
1078 LibUtilities::Timer timer;
1079 timer.Start();
1080 GetTraceJac(inarray, qfield, TraceJac, TraceJacDeriv, TraceJacDerivSign,
1081 TraceIPSymJacArray);
1082 timer.Stop();
1083 timer.AccumulateRegion("CFSImplicit::GetTraceJac", 10);
1084
1087
1088 timer.Start();
1089 m_advObject->AddTraceJacToMat(nvariables, m_spacedim, m_fields, TraceJac,
1090 gmtxarray, tmpJac, tmpSign);
1091 timer.Stop();
1092 timer.AccumulateRegion("Advection::AddTraceJacToMap", 10);
1093}
1094
1095template <typename DataType, typename TypeNekBlkMatSharedPtr>
1098 TypeNekBlkMatSharedPtr &gmtVar,
1099 [[maybe_unused]] const DataType &tmpDataType)
1100{
1101 int n1d = gmtxarray.size();
1102 int n2d = gmtxarray[0].size();
1103 int nConvectiveFields = n1d;
1104
1105 ASSERTL0(n1d == n2d, "ElmtVarInvMtrx requires n1d==n2d");
1106
1109
1110 gmtxarray[0][0]->GetBlockSizes(rowSizes, colSizes);
1111 int nTotElmt = rowSizes.size();
1112 int nElmtCoef = rowSizes[0] - 1;
1113 int nElmtCoef0 = -1;
1114 int blocksize = -1;
1115
1116 Array<OneD, unsigned int> tmprow(1);
1117 TypeNekBlkMatSharedPtr tmpGmtx;
1118
1119 Array<OneD, DataType> GMatData, ElmtMatData;
1120 Array<OneD, DataType> tmpArray1, tmpArray2;
1121
1122 for (int nelmt = 0; nelmt < nTotElmt; nelmt++)
1123 {
1124 int nrows = gmtxarray[0][0]->GetBlock(nelmt, nelmt)->GetRows();
1125 int ncols = gmtxarray[0][0]->GetBlock(nelmt, nelmt)->GetColumns();
1126 ASSERTL0(nrows == ncols, "ElmtVarInvMtrx requires nrows==ncols");
1127
1128 nElmtCoef = nrows;
1129
1130 if (nElmtCoef0 != nElmtCoef)
1131 {
1132 nElmtCoef0 = nElmtCoef;
1133 int nElmtCoefVar = nElmtCoef0 * nConvectiveFields;
1134 blocksize = nElmtCoefVar * nElmtCoefVar;
1135 tmprow[0] = nElmtCoefVar;
1136 AllocateNekBlkMatDig(tmpGmtx, tmprow, tmprow);
1137 GMatData = tmpGmtx->GetBlock(0, 0)->GetPtr();
1138 }
1139
1140 for (int n = 0; n < nConvectiveFields; n++)
1141 {
1142 for (int m = 0; m < nConvectiveFields; m++)
1143 {
1144 ElmtMatData = gmtxarray[m][n]->GetBlock(nelmt, nelmt)->GetPtr();
1145
1146 for (int ncl = 0; ncl < nElmtCoef; ncl++)
1147 {
1148 int Goffset =
1149 (n * nElmtCoef + ncl) * nConvectiveFields * nElmtCoef +
1150 m * nElmtCoef;
1151 int Eoffset = ncl * nElmtCoef;
1152
1153 Vmath::Vcopy(nElmtCoef, tmpArray1 = ElmtMatData + Eoffset,
1154 1, tmpArray2 = GMatData + Goffset, 1);
1155 }
1156 }
1157 }
1158
1159 tmpGmtx->GetBlock(0, 0)->Invert();
1160
1161 for (int m = 0; m < nConvectiveFields; m++)
1162 {
1163 for (int n = 0; n < nConvectiveFields; n++)
1164 {
1165 ElmtMatData = gmtxarray[m][n]->GetBlock(nelmt, nelmt)->GetPtr();
1166
1167 for (int ncl = 0; ncl < nElmtCoef; ncl++)
1168 {
1169 int Goffset =
1170 (n * nElmtCoef + ncl) * nConvectiveFields * nElmtCoef +
1171 m * nElmtCoef;
1172 int Eoffset = ncl * nElmtCoef;
1173
1174 Vmath::Vcopy(nElmtCoef, tmpArray1 = GMatData + Goffset, 1,
1175 tmpArray2 = ElmtMatData + Eoffset, 1);
1176 }
1177 }
1178 }
1179 ElmtMatData = gmtVar->GetBlock(nelmt, nelmt)->GetPtr();
1180 Vmath::Vcopy(blocksize, GMatData, 1, ElmtMatData, 1);
1181 }
1182 return;
1183}
1184
1185template <typename DataType, typename TypeNekBlkMatSharedPtr>
1187 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
1190 [[maybe_unused]] Array<OneD, TypeNekBlkMatSharedPtr> &TraceJacDeriv,
1191 [[maybe_unused]] Array<OneD, Array<OneD, DataType>> &TraceJacDerivSign,
1192 TensorOfArray5D<DataType> &TraceIPSymJacArray)
1193{
1194 int nvariables = inarray.size();
1195 int nTracePts = GetTraceTotPoints();
1196
1197 // Store forwards/backwards space along trace space
1198 Array<OneD, Array<OneD, NekDouble>> Fwd(nvariables);
1199 Array<OneD, Array<OneD, NekDouble>> Bwd(nvariables);
1200
1201 TypeNekBlkMatSharedPtr FJac, BJac;
1202 Array<OneD, unsigned int> n_blks1(nTracePts, nvariables);
1203
1204 if (TraceJac.size() > 0)
1205 {
1206 FJac = TraceJac[0];
1207 BJac = TraceJac[1];
1208 }
1209 else
1210 {
1212
1213 AllocateNekBlkMatDig(FJac, n_blks1, n_blks1);
1214 AllocateNekBlkMatDig(BJac, n_blks1, n_blks1);
1215 }
1216
1218 {
1221 }
1222 else
1223 {
1224 for (int i = 0; i < nvariables; ++i)
1225 {
1226 Fwd[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1227 Bwd[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1228 m_fields[i]->GetFwdBwdTracePhys(inarray[i], Fwd[i], Bwd[i]);
1229 }
1230 }
1231
1233
1234 NumCalcRiemFluxJac(nvariables, m_fields, AdvVel, inarray, qfield,
1235 m_bndEvaluateTime, Fwd, Bwd, FJac, BJac,
1236 TraceIPSymJacArray);
1237
1238 TraceJac[0] = FJac;
1239 TraceJac[1] = BJac;
1240}
1241
1242template <typename DataType, typename TypeNekBlkMatSharedPtr>
1244 const int nConvectiveFields,
1246 const Array<OneD, const Array<OneD, NekDouble>> &AdvVel,
1247 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
1248 TensorOfArray3D<NekDouble> &qfield, const NekDouble &time,
1249 const Array<OneD, const Array<OneD, NekDouble>> &Fwd,
1250 const Array<OneD, const Array<OneD, NekDouble>> &Bwd,
1251 TypeNekBlkMatSharedPtr &FJac, TypeNekBlkMatSharedPtr &BJac,
1252 [[maybe_unused]] TensorOfArray5D<DataType> &TraceIPSymJacArray)
1253{
1254 const NekDouble PenaltyFactor2 = 0.0;
1255 int nvariables = nConvectiveFields;
1256 int npoints = GetNpoints();
1257 int nTracePts = GetTraceTotPoints();
1258 int nDim = m_spacedim;
1259
1260 Array<OneD, int> nonZeroIndex;
1261
1262 Array<OneD, Array<OneD, NekDouble>> tmpinarry(nvariables);
1263 for (int i = 0; i < nvariables; i++)
1264 {
1265 tmpinarry[i] = Array<OneD, NekDouble>(npoints, 0.0);
1266 Vmath::Vcopy(npoints, inarray[i], 1, tmpinarry[i], 1);
1267 }
1268
1269 // DmuDT of artificial diffusion is neglected
1270 // TODO: to consider the Jacobian of AV seperately
1273
1274 Array<OneD, Array<OneD, NekDouble>> numflux(nvariables);
1275 for (int i = 0; i < nvariables; ++i)
1276 {
1277 numflux[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1278 }
1279
1281 fields[0]->GetTraceMap();
1282 TensorOfArray3D<NekDouble> qBwd(nDim);
1283 TensorOfArray3D<NekDouble> qFwd(nDim);
1284 if (m_viscousJacFlag)
1285 {
1286 for (int nd = 0; nd < nDim; ++nd)
1287 {
1288 qBwd[nd] = Array<OneD, Array<OneD, NekDouble>>(nConvectiveFields);
1289 qFwd[nd] = Array<OneD, Array<OneD, NekDouble>>(nConvectiveFields);
1290 for (int i = 0; i < nConvectiveFields; ++i)
1291 {
1292 qBwd[nd][i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1293 qFwd[nd][i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1294
1295 fields[i]->GetFwdBwdTracePhys(qfield[nd][i], qFwd[nd][i],
1296 qBwd[nd][i], true, true, false);
1297 TraceMap->GetAssemblyCommDG()->PerformExchange(qFwd[nd][i],
1298 qBwd[nd][i]);
1299 }
1300 }
1301 }
1302
1303 CalcTraceNumericalFlux(nConvectiveFields, nDim, npoints, nTracePts,
1304 PenaltyFactor2, fields, AdvVel, inarray, time,
1305 qfield, Fwd, Bwd, qFwd, qBwd, MuVarTrace,
1306 nonZeroIndex, numflux);
1307
1308 int nFields = nvariables;
1309 Array<OneD, Array<OneD, NekDouble>> plusFwd(nFields), plusBwd(nFields);
1310 Array<OneD, Array<OneD, NekDouble>> Jacvect(nFields);
1311 Array<OneD, Array<OneD, NekDouble>> FwdBnd(nFields);
1312 Array<OneD, Array<OneD, NekDouble>> plusflux(nFields);
1313 for (int i = 0; i < nFields; i++)
1314 {
1315 Jacvect[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1316 plusFwd[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1317 plusBwd[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1318 plusflux[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1319 FwdBnd[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1320 }
1321
1322 for (int i = 0; i < nFields; i++)
1323 {
1324 Vmath::Vcopy(nTracePts, Fwd[i], 1, plusFwd[i], 1);
1325 Vmath::Vcopy(nTracePts, Bwd[i], 1, plusBwd[i], 1);
1326 }
1327
1328 NekDouble eps = 1.0E-6;
1329
1330 Array<OneD, DataType> tmpMatData;
1331 // Fwd Jacobian
1332 for (int i = 0; i < nFields; i++)
1333 {
1334 NekDouble epsvar = eps * m_magnitdEstimat[i];
1335 NekDouble oepsvar = 1.0 / epsvar;
1336 Vmath::Sadd(nTracePts, epsvar, Fwd[i], 1, plusFwd[i], 1);
1337
1338 if (m_bndConds.size())
1339 {
1340 for (int i = 0; i < nFields; i++)
1341 {
1342 Vmath::Vcopy(nTracePts, plusFwd[i], 1, FwdBnd[i], 1);
1343 }
1344 // Loop over user-defined boundary conditions
1345 for (auto &x : m_bndConds)
1346 {
1347 x->Apply(FwdBnd, tmpinarry, time);
1348 }
1349 }
1350
1351 for (int j = 0; j < nFields; j++)
1352 {
1353 m_fields[j]->FillBwdWithBoundCond(plusFwd[j], plusBwd[j]);
1354 }
1355
1356 CalcTraceNumericalFlux(nConvectiveFields, nDim, npoints, nTracePts,
1357 PenaltyFactor2, fields, AdvVel, inarray, time,
1358 qfield, plusFwd, plusBwd, qFwd, qBwd, MuVarTrace,
1359 nonZeroIndex, plusflux);
1360
1361 for (int n = 0; n < nFields; n++)
1362 {
1363 Vmath::Vsub(nTracePts, plusflux[n], 1, numflux[n], 1, Jacvect[n],
1364 1);
1365 Vmath::Smul(nTracePts, oepsvar, Jacvect[n], 1, Jacvect[n], 1);
1366 }
1367 for (int j = 0; j < nTracePts; j++)
1368 {
1369 tmpMatData = FJac->GetBlock(j, j)->GetPtr();
1370 for (int n = 0; n < nFields; n++)
1371 {
1372 tmpMatData[n + i * nFields] = DataType(Jacvect[n][j]);
1373 }
1374 }
1375
1376 Vmath::Vcopy(nTracePts, Fwd[i], 1, plusFwd[i], 1);
1377 }
1378
1379 // Reset the boundary conditions
1380 if (m_bndConds.size())
1381 {
1382 for (int i = 0; i < nFields; i++)
1383 {
1384 Vmath::Vcopy(nTracePts, Fwd[i], 1, FwdBnd[i], 1);
1385 }
1386 // Loop over user-defined boundary conditions
1387 for (auto &x : m_bndConds)
1388 {
1389 x->Apply(FwdBnd, tmpinarry, time);
1390 }
1391 }
1392
1393 for (int i = 0; i < nFields; i++)
1394 {
1395 Vmath::Vcopy(nTracePts, Bwd[i], 1, plusBwd[i], 1);
1396 }
1397
1398 for (int i = 0; i < nFields; i++)
1399 {
1400 NekDouble epsvar = eps * m_magnitdEstimat[i];
1401 NekDouble oepsvar = 1.0 / epsvar;
1402
1403 Vmath::Sadd(nTracePts, epsvar, Bwd[i], 1, plusBwd[i], 1);
1404
1405 for (int j = 0; j < nFields; j++)
1406 {
1407 m_fields[j]->FillBwdWithBoundCond(Fwd[j], plusBwd[j]);
1408 }
1409
1410 CalcTraceNumericalFlux(nConvectiveFields, nDim, npoints, nTracePts,
1411 PenaltyFactor2, fields, AdvVel, inarray, time,
1412 qfield, Fwd, plusBwd, qFwd, qBwd, MuVarTrace,
1413 nonZeroIndex, plusflux);
1414
1415 for (int n = 0; n < nFields; n++)
1416 {
1417 Vmath::Vsub(nTracePts, plusflux[n], 1, numflux[n], 1, Jacvect[n],
1418 1);
1419 Vmath::Smul(nTracePts, oepsvar, Jacvect[n], 1, Jacvect[n], 1);
1420 }
1421 for (int j = 0; j < nTracePts; j++)
1422 {
1423 tmpMatData = BJac->GetBlock(j, j)->GetPtr();
1424 for (int n = 0; n < nFields; n++)
1425 {
1426 tmpMatData[n + i * nFields] = DataType(Jacvect[n][j]);
1427 }
1428 }
1429
1430 Vmath::Vcopy(nTracePts, Bwd[i], 1, plusBwd[i], 1);
1431 }
1432}
1433
1435 const int nConvectiveFields, [[maybe_unused]] const int nDim,
1436 [[maybe_unused]] const int nPts, const int nTracePts,
1437 [[maybe_unused]] const NekDouble PenaltyFactor2,
1439 const Array<OneD, const Array<OneD, NekDouble>> &AdvVel,
1440 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
1441 [[maybe_unused]] const NekDouble time, TensorOfArray3D<NekDouble> &qfield,
1442 const Array<OneD, const Array<OneD, NekDouble>> &vFwd,
1443 const Array<OneD, const Array<OneD, NekDouble>> &vBwd,
1444 [[maybe_unused]] const Array<OneD, const TensorOfArray2D<NekDouble>> &qFwd,
1445 [[maybe_unused]] const Array<OneD, const TensorOfArray2D<NekDouble>> &qBwd,
1446 [[maybe_unused]] const Array<OneD, NekDouble> &MuVarTrace,
1447 Array<OneD, int> &nonZeroIndex,
1448 Array<OneD, Array<OneD, NekDouble>> &traceflux)
1449{
1451 {
1452 auto advWeakDGObject =
1453 std::dynamic_pointer_cast<SolverUtils::AdvectionWeakDG>(
1454 m_advObject);
1455 ASSERTL0(advWeakDGObject,
1456 "Use WeakDG for implicit compressible flow solver!");
1457 advWeakDGObject->AdvectTraceFlux(nConvectiveFields, m_fields, AdvVel,
1458 inarray, traceflux, m_bndEvaluateTime,
1459 vFwd, vBwd);
1460 }
1461 else
1462 {
1463 for (int i = 0; i < nConvectiveFields; i++)
1464 {
1465 traceflux[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1466 }
1467 }
1468
1469 if (m_viscousJacFlag)
1470 {
1471 Array<OneD, Array<OneD, NekDouble>> visflux(nConvectiveFields);
1472 for (int i = 0; i < nConvectiveFields; i++)
1473 {
1474 visflux[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1475 }
1476
1477 string diffName;
1478 m_session->LoadSolverInfo("DiffusionType", diffName, "InteriorPenalty");
1479 if (diffName == "InteriorPenalty")
1480 {
1481 m_diffusion->DiffuseTraceFlux(fields, inarray, qfield,
1483 vFwd, vBwd, nonZeroIndex);
1484 }
1485 else
1486 {
1487 ASSERTL1(false, "LDGNS not yet validated for implicit compressible "
1488 "flow solver");
1489 // For LDGNS, the array size should be nConvectiveFields - 1
1490 Array<OneD, Array<OneD, NekDouble>> inBwd(nConvectiveFields - 1);
1491 Array<OneD, Array<OneD, NekDouble>> inFwd(nConvectiveFields - 1);
1492 for (int i = 0; i < nConvectiveFields - 1; ++i)
1493 {
1494 inBwd[i] = vBwd[i];
1495 inFwd[i] = vFwd[i];
1496 }
1497 m_diffusion->DiffuseTraceFlux(fields, inarray, qfield,
1499 inFwd, inBwd, nonZeroIndex);
1500 }
1501 for (int i = 0; i < nConvectiveFields; i++)
1502 {
1503 Vmath::Vsub(nTracePts, traceflux[i], 1, visflux[i], 1, traceflux[i],
1504 1);
1505 }
1506 }
1507}
1508
1510 const Array<OneD, const Array<OneD, NekDouble>> &inarray,
1513 Array<OneD, SNekBlkMatSharedPtr> &TraceJacDeriv,
1514 Array<OneD, Array<OneD, NekSingle>> &TraceJacDerivSign,
1515 TensorOfArray4D<NekSingle> &TraceJacArray,
1516 [[maybe_unused]] TensorOfArray4D<NekSingle> &TraceJacDerivArray,
1517 TensorOfArray5D<NekSingle> &TraceIPSymJacArray)
1518{
1520
1521 if (m_viscousJacFlag)
1522 {
1523 CalcPhysDeriv(inarray, qfield);
1524 }
1525
1526 NekSingle zero = 0.0;
1527 Fill2DArrayOfBlkDiagonalMat(gmtxarray, zero);
1528
1529 LibUtilities::Timer timer;
1530 timer.Start();
1531 AddMatNSBlkDiagVol(inarray, qfield, gmtxarray, m_stdSMatDataDBB,
1533 timer.Stop();
1534 timer.AccumulateRegion("CFSImplicit::AddMatNSBlkDiagVol", 2);
1535
1536 timer.Start();
1537 AddMatNSBlkDiagBnd(inarray, qfield, gmtxarray, TraceJac, TraceJacDeriv,
1538 TraceJacDerivSign, TraceIPSymJacArray);
1539 timer.Stop();
1540 timer.AccumulateRegion("CFSImplicit::AddMatNSBlkDiagBnd", 2);
1541
1542 MultiplyElmtInvMassPlusSource<NekSingle>(gmtxarray, m_TimeIntegLambda);
1543
1544 timer.Start();
1545 ElmtVarInvMtrx(gmtxarray, gmtVar, zero);
1546 timer.Stop();
1547 timer.AccumulateRegion("CFSImplicit::ElmtVarInvMtrx", 2);
1548
1549 TransTraceJacMatToArray(TraceJac, TraceJacArray);
1550}
1551
1553 [[maybe_unused]] const int nConvectiveFields,
1554 [[maybe_unused]] const int nElmtPnt,
1555 [[maybe_unused]] const Array<OneD, const Array<OneD, NekDouble>> &locVars,
1556 [[maybe_unused]] const TensorOfArray3D<NekDouble> &locDerv,
1557 [[maybe_unused]] const Array<OneD, NekDouble> &locmu,
1558 [[maybe_unused]] const Array<OneD, NekDouble> &locDmuDT,
1559 [[maybe_unused]] const Array<OneD, NekDouble> &normals,
1560 [[maybe_unused]] DNekMatSharedPtr &wspMat,
1561 [[maybe_unused]] Array<OneD, Array<OneD, NekDouble>> &PntJacArray)
1562{
1563 // Do nothing by default
1564}
1565
1566template <typename DataType, typename TypeNekBlkMatSharedPtr>
1569 const NekDouble dtlamda)
1570{
1572 std::shared_ptr<LocalRegions::ExpansionVector> pexp = explist->GetExp();
1573 int nTotElmt = (*pexp).size();
1574 int nConvectiveFields = m_fields.size();
1575
1576 NekDouble Negdtlamda = -dtlamda;
1577
1578 Array<OneD, NekDouble> pseudotimefactor(nTotElmt, 0.0);
1579 Vmath::Fill(nTotElmt, Negdtlamda, pseudotimefactor, 1);
1580
1581 Array<OneD, DataType> GMatData;
1582 for (int m = 0; m < nConvectiveFields; m++)
1583 {
1584 for (int n = 0; n < nConvectiveFields; n++)
1585 {
1586 for (int nelmt = 0; nelmt < nTotElmt; nelmt++)
1587 {
1588 GMatData = gmtxarray[m][n]->GetBlock(nelmt, nelmt)->GetPtr();
1589 DataType factor = DataType(pseudotimefactor[nelmt]);
1590
1591 Vmath::Smul(GMatData.size(), factor, GMatData, 1, GMatData, 1);
1592 }
1593 }
1594 }
1595
1596 DNekMatSharedPtr MassMat;
1597 Array<OneD, NekDouble> BwdMatData, MassMatData, tmp;
1599 Array<OneD, DataType> MassMatDataDataType;
1601
1602 for (int nelmt = 0; nelmt < nTotElmt; nelmt++)
1603 {
1604 int nelmtcoef = GetNcoeffs(nelmt);
1605 int nelmtpnts = GetTotPoints(nelmt);
1606 LibUtilities::ShapeType ElmtTypeNow =
1607 explist->GetExp(nelmt)->DetShapeType();
1608
1609 if (tmp.size() != nelmtcoef || (ElmtTypeNow != ElmtTypePrevious))
1610 {
1612 stdExp = explist->GetExp(nelmt)->GetStdExp();
1614 stdExp->DetShapeType(), *stdExp);
1615
1616 DNekMatSharedPtr BwdMat = stdExp->GetStdMatrix(matkey);
1617 BwdMatData = BwdMat->GetPtr();
1618
1619 if (nelmtcoef != tmp.size())
1620 {
1621 tmp = Array<OneD, NekDouble>(nelmtcoef, 0.0);
1623 nelmtcoef, nelmtcoef, 0.0);
1624 MassMatData = MassMat->GetPtr();
1625 MassMatDataDataType =
1626 Array<OneD, DataType>(nelmtcoef * nelmtcoef);
1627 }
1628
1629 ElmtTypePrevious = ElmtTypeNow;
1630 }
1631
1632 for (int np = 0; np < nelmtcoef; np++)
1633 {
1634 explist->GetExp(nelmt)->IProductWRTBase(BwdMatData + np * nelmtpnts,
1635 tmp);
1636 Vmath::Vcopy(nelmtcoef, tmp, 1, tmp2 = MassMatData + np * nelmtcoef,
1637 1);
1638 }
1639 for (int i = 0; i < MassMatData.size(); i++)
1640 {
1641 MassMatDataDataType[i] = DataType(MassMatData[i]);
1642 }
1643
1644 for (int m = 0; m < nConvectiveFields; m++)
1645 {
1646 GMatData = gmtxarray[m][m]->GetBlock(nelmt, nelmt)->GetPtr();
1647 Vmath::Vadd(MassMatData.size(), MassMatDataDataType, 1, GMatData, 1,
1648 GMatData, 1);
1649 }
1650 }
1651 return;
1652}
1653
1654template <typename DataType, typename TypeNekBlkMatSharedPtr>
1657 TensorOfArray4D<DataType> &TraceJacArray)
1658{
1659 int nFwdBwd, nDiagBlks, nvar0Jac, nvar1Jac;
1660
1663 nFwdBwd = TraceJac.size();
1664 TraceJac[0]->GetBlockSizes(rowSizes, colSizes);
1665 nDiagBlks = rowSizes.size();
1666 nvar0Jac = rowSizes[1] - rowSizes[0];
1667 nvar1Jac = colSizes[1] - colSizes[0];
1668
1669 if (0 == TraceJacArray.size())
1670 {
1671 TraceJacArray = TensorOfArray4D<DataType>(nFwdBwd);
1672 for (int nlr = 0; nlr < nFwdBwd; nlr++)
1673 {
1674 TraceJacArray[nlr] = TensorOfArray3D<DataType>(nvar0Jac);
1675 for (int m = 0; m < nvar0Jac; m++)
1676 {
1677 TraceJacArray[nlr][m] =
1679 for (int n = 0; n < nvar1Jac; n++)
1680 {
1681 TraceJacArray[nlr][m][n] = Array<OneD, DataType>(nDiagBlks);
1682 }
1683 }
1684 }
1685 }
1686
1687 for (int nlr = 0; nlr < nFwdBwd; nlr++)
1688 {
1689 const TypeNekBlkMatSharedPtr tmpMat = TraceJac[nlr];
1690 TensorOfArray3D<DataType> tmpaa = TraceJacArray[nlr];
1691 TranSamesizeBlkDiagMatIntoArray(tmpMat, tmpaa);
1692 }
1693
1694 return;
1695}
1696
1698 [[maybe_unused]] const MultiRegions::ExpListSharedPtr &explist,
1699 [[maybe_unused]] const Array<OneD, const Array<OneD, NekDouble>> &normals,
1700 [[maybe_unused]] const int nDervDir,
1701 [[maybe_unused]] const Array<OneD, const Array<OneD, NekDouble>> &inarray,
1702 [[maybe_unused]] TensorOfArray5D<NekDouble> &ElmtJacArray,
1703 [[maybe_unused]] const int nFluxDir)
1704{
1705 NEKERROR(ErrorUtil::efatal, "v_GetFluxDerivJacDirctn not coded");
1706}
1707
1709 [[maybe_unused]] const int nConvectiveFields,
1710 [[maybe_unused]] const int nElmtPnt, [[maybe_unused]] const int nDervDir,
1711 [[maybe_unused]] const Array<OneD, const Array<OneD, NekDouble>> &locVars,
1712 [[maybe_unused]] const Array<OneD, NekDouble> &locmu,
1713 [[maybe_unused]] const Array<OneD, const Array<OneD, NekDouble>> &locnormal,
1714 [[maybe_unused]] DNekMatSharedPtr &wspMat,
1715 [[maybe_unused]] Array<OneD, Array<OneD, NekDouble>> &PntJacArray)
1716{
1717 NEKERROR(ErrorUtil::efatal, "v_GetFluxDerivJacDirctn not coded");
1718}
1719
1721 [[maybe_unused]] const MultiRegions::ExpListSharedPtr &explist,
1722 [[maybe_unused]] const Array<OneD, const Array<OneD, NekDouble>> &normals,
1723 [[maybe_unused]] const int nDervDir,
1724 [[maybe_unused]] const Array<OneD, const Array<OneD, NekDouble>> &inarray,
1725 [[maybe_unused]] TensorOfArray2D<DNekMatSharedPtr> &ElmtJac)
1726{
1727}
1728
1730 const int nConvectiveFields, const int nElmtPnt,
1731 const Array<OneD, const Array<OneD, NekDouble>> &locVars,
1732 const Array<OneD, NekDouble> &normals, DNekMatSharedPtr &wspMat,
1733 Array<OneD, Array<OneD, NekDouble>> &PntJacArray)
1734{
1735 Array<OneD, NekDouble> wspMatData = wspMat->GetPtr();
1736
1737 int matsize = nConvectiveFields * nConvectiveFields;
1738
1739 Array<OneD, NekDouble> pointVar(nConvectiveFields);
1740
1741 for (int npnt = 0; npnt < nElmtPnt; npnt++)
1742 {
1743 for (int j = 0; j < nConvectiveFields; j++)
1744 {
1745 pointVar[j] = locVars[j][npnt];
1746 }
1747
1748 GetFluxVectorJacPoint(nConvectiveFields, pointVar, normals, wspMat);
1749
1750 Vmath::Vcopy(matsize, wspMatData, 1, PntJacArray[npnt], 1);
1751 }
1752 return;
1753}
1754
1756 const int nConvectiveFields, const Array<OneD, NekDouble> &conservVar,
1757 const Array<OneD, NekDouble> &normals, DNekMatSharedPtr &fluxJac)
1758{
1759 int nvariables = conservVar.size();
1760 const int nvariables3D = 5;
1761 int expDim = m_spacedim;
1762
1763 NekDouble fsw, efix_StegerWarming;
1764 efix_StegerWarming = 0.0;
1765 fsw = 0.0; // exact flux Jacobian if fsw=0.0
1766 if (nvariables > expDim + 2)
1767 {
1768 NEKERROR(ErrorUtil::efatal, "nvariables > expDim+2 case not coded")
1769 }
1770
1771 Array<OneD, NekDouble> fluxJacData;
1772 ;
1773 fluxJacData = fluxJac->GetPtr();
1774
1775 if (nConvectiveFields == nvariables3D)
1776 {
1777 PointFluxJacobianPoint(conservVar, normals, fluxJac, efix_StegerWarming,
1778 fsw);
1779 }
1780 else
1781 {
1782 DNekMatSharedPtr PointFJac3D =
1784 nvariables3D, 0.0);
1785
1786 Array<OneD, NekDouble> PointFJac3DData;
1787 PointFJac3DData = PointFJac3D->GetPtr();
1788
1789 Array<OneD, NekDouble> PointFwd(nvariables3D, 0.0);
1790
1791 Array<OneD, unsigned int> index(nvariables);
1792
1793 index[nvariables - 1] = 4;
1794 for (int i = 0; i < nvariables - 1; i++)
1795 {
1796 index[i] = i;
1797 }
1798
1799 int nj = 0;
1800 int nk = 0;
1801 for (int j = 0; j < nvariables; j++)
1802 {
1803 nj = index[j];
1804 PointFwd[nj] = conservVar[j];
1805 }
1806
1807 PointFluxJacobianPoint(PointFwd, normals, PointFJac3D,
1808 efix_StegerWarming, fsw);
1809
1810 for (int j = 0; j < nvariables; j++)
1811 {
1812 nj = index[j];
1813 for (int k = 0; k < nvariables; k++)
1814 {
1815 nk = index[k];
1816 fluxJacData[j + k * nConvectiveFields] =
1817 PointFJac3DData[nj + nk * nvariables3D];
1818 }
1819 }
1820 }
1821}
1822
1823template <typename DataType, typename TypeNekBlkMatSharedPtr>
1825 const TypeNekBlkMatSharedPtr &BlkMat, TensorOfArray3D<DataType> &MatArray)
1826{
1829 BlkMat->GetBlockSizes(rowSizes, colSizes);
1830 int nDiagBlks = rowSizes.size();
1831 int nvar0 = rowSizes[1] - rowSizes[0];
1832 int nvar1 = colSizes[1] - colSizes[0];
1833
1834 Array<OneD, DataType> ElmtMatData;
1835
1836 for (int i = 0; i < nDiagBlks; i++)
1837 {
1838 ElmtMatData = BlkMat->GetBlock(i, i)->GetPtr();
1839 for (int n = 0; n < nvar1; n++)
1840 {
1841 int noffset = n * nvar0;
1842 for (int m = 0; m < nvar0; m++)
1843 {
1844 MatArray[m][n][i] = ElmtMatData[m + noffset];
1845 }
1846 }
1847 }
1848}
1849
1850template <typename DataType, typename TypeNekBlkMatSharedPtr>
1853 const DataType valu)
1854{
1855 int n1d = gmtxarray.size();
1856
1857 for (int n1 = 0; n1 < n1d; ++n1)
1858 {
1859 Fill1DArrayOfBlkDiagonalMat(gmtxarray[n1], valu);
1860 }
1861}
1862
1863template <typename DataType, typename TypeNekBlkMatSharedPtr>
1865 Array<OneD, TypeNekBlkMatSharedPtr> &gmtxarray, const DataType valu)
1866{
1867 int n1d = gmtxarray.size();
1868
1871
1872 Array<OneD, DataType> loc_mat_arr;
1873
1874 for (int n1 = 0; n1 < n1d; ++n1)
1875 {
1876 gmtxarray[n1]->GetBlockSizes(rowSizes, colSizes);
1877 int nelmts = rowSizes.size();
1878
1879 for (int i = 0; i < nelmts; ++i)
1880 {
1881 loc_mat_arr = gmtxarray[n1]->GetBlock(i, i)->GetPtr();
1882
1883 int nrows = gmtxarray[n1]->GetBlock(i, i)->GetRows();
1884 int ncols = gmtxarray[n1]->GetBlock(i, i)->GetColumns();
1885
1886 Vmath::Fill(nrows * ncols, valu, loc_mat_arr, 1);
1887 }
1888 }
1889}
1890
1891// Currently duplacate in compressibleFlowSys
1892// if fsw=+-1 calculate the steger-Warming flux vector splitting flux Jacobian
1893// if fsw=0 calculate the Jacobian of the exact flux
1894// efix is the numerical flux entropy fix parameter
1896 const Array<OneD, NekDouble> &normals,
1897 DNekMatSharedPtr &FJac,
1898 const NekDouble efix,
1899 const NekDouble fsw)
1900{
1901 Array<OneD, NekDouble> FJacData = FJac->GetPtr();
1902 const int nvariables3D = 5;
1903
1904 NekDouble ro, vx, vy, vz, ps, gama, ae;
1905 NekDouble a, a2, h, h0, v2, vn, eps, eps2;
1906 NekDouble nx, ny, nz;
1907 NekDouble sn, osn, nxa, nya, nza, vna;
1908 NekDouble l1, l4, l5, al1, al4, al5, x1, x2, x3, y1;
1909 NekDouble c1, d1, c2, d2, c3, d3, c4, d4, c5, d5;
1910 NekDouble sml_ssf = 1.0E-12;
1911
1912 NekDouble fExactorSplt = 2.0 - abs(fsw); // if fsw=+-1 calculate
1913
1914 NekDouble rhoL = Fwd[0];
1915 NekDouble rhouL = Fwd[1];
1916 NekDouble rhovL = Fwd[2];
1917 NekDouble rhowL = Fwd[3];
1918 NekDouble EL = Fwd[4];
1919
1920 ro = rhoL;
1921 vx = rhouL / rhoL;
1922 vy = rhovL / rhoL;
1923 vz = rhowL / rhoL;
1924
1925 // Internal energy (per unit mass)
1926 NekDouble eL = (EL - 0.5 * (rhouL * vx + rhovL * vy + rhowL * vz)) / rhoL;
1927
1928 ps = m_varConv->Geteos()->GetPressure(rhoL, eL);
1929 gama = m_gamma;
1930
1931 ae = gama - 1.0;
1932 v2 = vx * vx + vy * vy + vz * vz;
1933 a2 = gama * ps / ro;
1934 h = a2 / ae;
1935
1936 h0 = h + 0.5 * v2;
1937 a = sqrt(a2);
1938
1939 nx = normals[0];
1940 ny = normals[1];
1941 nz = normals[2];
1942 vn = nx * vx + ny * vy + nz * vz;
1943 sn = std::max(sqrt(nx * nx + ny * ny + nz * nz), sml_ssf);
1944 osn = 1.0 / sn;
1945
1946 nxa = nx * osn;
1947 nya = ny * osn;
1948 nza = nz * osn;
1949 vna = vn * osn;
1950 l1 = vn;
1951 l4 = vn + sn * a;
1952 l5 = vn - sn * a;
1953
1954 eps = efix * sn;
1955 eps2 = eps * eps;
1956
1957 al1 = sqrt(l1 * l1 + eps2);
1958 al4 = sqrt(l4 * l4 + eps2);
1959 al5 = sqrt(l5 * l5 + eps2);
1960
1961 l1 = 0.5 * (fExactorSplt * l1 + fsw * al1);
1962 l4 = 0.5 * (fExactorSplt * l4 + fsw * al4);
1963 l5 = 0.5 * (fExactorSplt * l5 + fsw * al5);
1964
1965 x1 = 0.5 * (l4 + l5);
1966 x2 = 0.5 * (l4 - l5);
1967 x3 = x1 - l1;
1968 y1 = 0.5 * v2;
1969 c1 = ae * x3 / a2;
1970 d1 = x2 / a;
1971
1972 int nVar0 = 0;
1973 int nVar1 = nvariables3D;
1974 int nVar2 = 2 * nvariables3D;
1975 int nVar3 = 3 * nvariables3D;
1976 int nVar4 = 4 * nvariables3D;
1977 FJacData[nVar0] = c1 * y1 - d1 * vna + l1;
1978 FJacData[nVar1] = -c1 * vx + d1 * nxa;
1979 FJacData[nVar2] = -c1 * vy + d1 * nya;
1980 FJacData[nVar3] = -c1 * vz + d1 * nza;
1981 FJacData[nVar4] = c1;
1982 c2 = c1 * vx + d1 * nxa * ae;
1983 d2 = x3 * nxa + d1 * vx;
1984 FJacData[1 + nVar0] = c2 * y1 - d2 * vna;
1985 FJacData[1 + nVar1] = -c2 * vx + d2 * nxa + l1;
1986 FJacData[1 + nVar2] = -c2 * vy + d2 * nya;
1987 FJacData[1 + nVar3] = -c2 * vz + d2 * nza;
1988 FJacData[1 + nVar4] = c2;
1989 c3 = c1 * vy + d1 * nya * ae;
1990 d3 = x3 * nya + d1 * vy;
1991 FJacData[2 + nVar0] = c3 * y1 - d3 * vna;
1992 FJacData[2 + nVar1] = -c3 * vx + d3 * nxa;
1993 FJacData[2 + nVar2] = -c3 * vy + d3 * nya + l1;
1994 FJacData[2 + nVar3] = -c3 * vz + d3 * nza;
1995 FJacData[2 + nVar4] = c3;
1996 c4 = c1 * vz + d1 * nza * ae;
1997 d4 = x3 * nza + d1 * vz;
1998 FJacData[3 + nVar0] = c4 * y1 - d4 * vna;
1999 FJacData[3 + nVar1] = -c4 * vx + d4 * nxa;
2000 FJacData[3 + nVar2] = -c4 * vy + d4 * nya;
2001 FJacData[3 + nVar3] = -c4 * vz + d4 * nza + l1;
2002 FJacData[3 + nVar4] = c4;
2003 c5 = c1 * h0 + d1 * vna * ae;
2004 d5 = x3 * vna + d1 * h0;
2005 FJacData[4 + nVar0] = c5 * y1 - d5 * vna;
2006 FJacData[4 + nVar1] = -c5 * vx + d5 * nxa;
2007 FJacData[4 + nVar2] = -c5 * vy + d5 * nya;
2008 FJacData[4 + nVar3] = -c5 * vz + d5 * nza;
2009 FJacData[4 + nVar4] = c5 + l1;
2010}
2011
2013{
2014 bool flag =
2015 (m_time + m_timestep > m_fintime && m_fintime > 0.0) ||
2017 return flag || m_preconCfs->UpdatePreconMatCheck(NullNekDouble1DArray,
2019}
2020
2022 int spaceDim, Array<OneD, MultiRegions::ExpListSharedPtr> &fields)
2023{
2024 m_ImplicitALESolver = true;
2025 fields[0]->GetGraph()->GetMovement()->SetImplicitALEFlag(
2027 m_spaceDim = spaceDim;
2028 m_fieldsALE = fields;
2029
2030 // Initialise grid velocities as 0s
2033 for (int i = 0; i < spaceDim; ++i)
2034 {
2035 m_gridVelocity[i] =
2036 Array<OneD, NekDouble>(fields[0]->GetTotPoints(), 0.0);
2038 Array<OneD, NekDouble>(fields[0]->GetTrace()->GetTotPoints(), 0.0);
2039 }
2040 ALEHelper::InitObject(spaceDim, fields);
2041}
2042
2043} // 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 NonlinSysEvaluatorCoeff(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &out, const bool &flag)
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)
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 NonlinSysEvaluatorCoeff1D(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out, const bool &flag)
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)
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)
void v_ALEInitObject(int spaceDim, Array< OneD, MultiRegions::ExpListSharedPtr > &fields) override
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
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 MatrixMultiplyMatrixFreeCoeff(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out, const bool &centralDifferenceFlag)
LibUtilities::NekNonlinSysIterSharedPtr m_nonlinsol
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 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.
NekDouble m_NonlinIterTolRelativeL2
Definition: NekSys.h:221
std::string m_LinSysIterSolverTypeInNonlin
Definition: NekSys.h:222
void DefineNekSysResEval(FuncPointerT func, ObjectPointerT obj)
Definition: NekSys.h:100
void DefineNekSysLhsEval(FuncPointerT func, ObjectPointerT obj)
Definition: NekSys.h:107
void DefineNekSysPrecon(FuncPointerT func, ObjectPointerT obj)
Definition: NekSys.h:114
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.
Describes a matrix with ordering defined by a local to global map.
void DefineCalcPreconMatBRJCoeff(FuncPointerT func, ObjectPointerT obj)
Definition: PreconCfsOp.h:88
Array< OneD, MultiRegions::ExpListSharedPtr > m_fieldsALE
Definition: ALEHelper.h:89
SOLVER_UTILS_EXPORT void InitObject(int spaceDim, Array< OneD, MultiRegions::ExpListSharedPtr > &fields)
Definition: ALEHelper.cpp:48
Array< OneD, Array< OneD, NekDouble > > m_gridVelocityTrace
Definition: ALEHelper.h:91
SOLVER_UTILS_EXPORT void ALEDoElmtInvMassBwdTrans(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray)
Definition: ALEHelper.cpp:149
Array< OneD, Array< OneD, NekDouble > > m_gridVelocity
Definition: ALEHelper.h:90
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
NekNonlinSysIterFactory & GetNekNonlinSysIterFactory()
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.
static const NekDouble kNekMachineEpsilon
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
STL namespace.
scalarT< T > abs(scalarT< T > in)
Definition: scalar.hpp:298
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294