Nektar++
CompressibleFlowSystemImplicit.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File CFSImplicit.cpp
4 //
5 // For more information, please see: http://www.nektar.info
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining a
14 // copy of this software and associated documentation files (the "Software"),
15 // to deal in the Software without restriction, including without limitation
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 // and/or sell copies of the Software, and to permit persons to whom the
18 // Software is furnished to do so, subject to the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 // DEALINGS IN THE SOFTWARE.
30 //
31 // Description: Compressible flow system base class with auxiliary functions
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
35 #include <boost/core/ignore_unused.hpp>
36 
38 
40 
41 using namespace std;
42 
43 namespace Nektar
44 {
45  CFSImplicit::CFSImplicit(
48  : UnsteadySystem(pSession, pGraph),
49  CompressibleFlowSystem(pSession, pGraph)
50  {
51  }
52 
53  /**
54  * @brief Initialization object for CFSImplicit class.
55  */
57  {
59  m_explicitAdvection = false;
60  m_explicitDiffusion = false;
61 
62  // initialise implicit parameters
63  m_session->LoadParameter ("JacobiFreeEps", m_jacobiFreeEps, 5.0E-8);
64 
65  int ntmp;
66  m_session->LoadParameter("AdvectionJacFlag", ntmp, 1);
67  m_advectionJacFlag = (0==ntmp)? false:true;
68 
69  m_session->LoadParameter("ViscousJacFlag", ntmp, 1);
70  m_viscousJacFlag = (0==ntmp)? false:true;
71 
72  // initialise implicit functors
74 
76 
77  m_flagImplicitSolver = true;
78  }
79 
81  {
82  std::string SolverType = "Newton";
83  if (m_session->DefinesSolverInfo("NonlinSysIterSolver"))
84  {
85  SolverType = m_session->GetSolverInfo("NonlinSysIterSolver");
86  }
88  ModuleExists(SolverType), "NekNonlinSys '" + SolverType +
89  "' is not defined.\n");
90  int ntotal = m_fields[0]->GetNcoeffs() * m_fields.size();
91 
93 
94  key.m_NonlinIterTolRelativeL2 = 1.0E-3;
95  key.m_LinSysRelativeTolInNonlin = 5.0E-2;
97  key.m_NekLinSysMaxIterations = 30;
98  key.m_LinSysMaxStorage = 30;
99 
101  SolverType, m_session, m_comm, ntotal, key);
102 
104  nekSysOp.DefineNekSysResEval(&CFSImplicit::
106  nekSysOp.DefineNekSysLhsEval(&CFSImplicit::
108  nekSysOp.DefineNekSysPrecon(
109  &CFSImplicit::PreconCoeff, this);
110 
111  int nvariables = m_fields.size();
112  const MultiRegions::LocTraceToTraceMapSharedPtr locTraceToTraceMap =
113  m_fields[0]->GetLocTraceToTraceMap();
114 
115  locTraceToTraceMap->CalcLocTracePhysToTraceIDMap(
116  m_fields[0]->GetTrace(),m_spacedim);
117  for (int i = 1; i < nvariables; i++)
118  {
119  m_fields[i]->GetLocTraceToTraceMap()
120  ->SetLocTracePhysToTraceIDMap(
121  locTraceToTraceMap->GetLocTracephysToTraceIDMap());
122  }
123 
125  "PreconCfsBRJ", m_fields, m_session, m_comm);
126  NekPreconCfsOperators tmpPreconOp;
128  CalcPreconMatBRJCoeff, this);
129  m_preconCfs->SetOperators(tmpPreconOp);
130 
131  m_session->LoadParameter("NewtonAbsoluteIteTol",
132  m_newtonAbsoluteIteTol, 1.0E-12);
133 
134  m_session->LoadParameter("nPadding", m_nPadding, 4);
135 
136  m_nonlinsol->SetSysOperators(nekSysOp);
137  }
138 
139  /**
140  * @brief Destructor for CFSImplicit class.
141  */
143  {
144  }
145 
147  const Array<OneD, const NekDouble> &inarray,
149  const bool &flag)
150  {
151  const Array<OneD, const NekDouble> refsource
152  = m_nonlinsol->GetRefSourceVec();
153  NonlinSysEvaluatorCoeff(inarray, out, flag, refsource);
154  }
155 
157  const Array<OneD, const NekDouble> &inarray,
159  const bool &flag,
160  const Array<OneD, const NekDouble> &source)
161  {
162  boost::ignore_unused(flag);
163  unsigned int nvariables = m_fields.size();
164  unsigned int npoints = m_fields[0]->GetNcoeffs();
165  Array<OneD, Array<OneD, NekDouble>> in2D(nvariables);
166  Array<OneD, Array<OneD, NekDouble>> out2D(nvariables);
167  Array<OneD, Array<OneD, NekDouble>> source2D(nvariables);
168  for (int i = 0; i < nvariables; ++i)
169  {
170  int offset = i * npoints;
171  in2D[i] = inarray + offset;
172  out2D[i] = out + offset;
173  source2D[i] = source + offset;
174  }
175  NonlinSysEvaluatorCoeff(in2D, out2D, source2D);
176  }
177 
179  const Array<OneD, const Array<OneD, NekDouble>> &inarray,
181  const Array<OneD, const Array<OneD, NekDouble>> &source)
182  {
183  unsigned int nvariable = inarray.size();
184  unsigned int ncoeffs = inarray[nvariable - 1].size();
185  unsigned int npoints = m_fields[0]->GetNpoints();
186 
187  Array<OneD, Array<OneD, NekDouble>> inpnts(nvariable);
188 
189  for (int i = 0; i < nvariable; ++i)
190  {
191  inpnts[i] = Array<OneD, NekDouble>(npoints, 0.0);
192  m_fields[i]->BwdTrans(inarray[i], inpnts[i]);
193  }
194 
195  DoOdeProjection(inpnts, inpnts, m_bndEvaluateTime);
196  DoOdeRhsCoeff(inpnts, out, m_bndEvaluateTime);
197 
198  for (int i = 0; i < nvariable; ++i)
199  {
200  Vmath::Svtvp(ncoeffs, -m_TimeIntegLambda, out[i], 1,
201  inarray[i], 1, out[i], 1);
202  }
203 
204  if (NullNekDoubleArrayOfArray != source)
205  {
206  for (int i = 0; i < nvariable; ++i)
207  {
208  Vmath::Vsub(ncoeffs, out[i], 1,
209  source[i], 1, out[i], 1);
210  }
211  }
212  return;
213  }
214 
215  /**
216  * @brief Compute the right-hand side.
217  */
219  const Array<OneD, const Array<OneD, NekDouble>> &inarray,
220  Array<OneD, Array<OneD, NekDouble>> &outarray,
221  const NekDouble time)
222  {
223  int nvariables = inarray.size();
224  int nTracePts = GetTraceTotPoints();
225  int ncoeffs = GetNcoeffs();
226  // Store forwards/backwards space along trace space
227  Array<OneD, Array<OneD, NekDouble>> Fwd (nvariables);
228  Array<OneD, Array<OneD, NekDouble>> Bwd (nvariables);
229 
231  {
234  }
235  else
236  {
237  for (int i = 0; i < nvariables; ++i)
238  {
239  Fwd[i] = Array<OneD, NekDouble> (nTracePts, 0.0);
240  Bwd[i] = Array<OneD, NekDouble> (nTracePts, 0.0);
241  m_fields[i]->GetFwdBwdTracePhys(inarray[i], Fwd[i], Bwd[i]);
242  }
243  }
244 
245  // Calculate advection
246  DoAdvectionCoeff(inarray, outarray, time, Fwd, Bwd);
247 
248  // Negate results
249  for (int i = 0; i < nvariables; ++i)
250  {
251  Vmath::Neg(ncoeffs, outarray[i], 1);
252  }
253 
254  DoDiffusionCoeff(inarray, outarray, Fwd, Bwd);
255 
256  // Add forcing terms
257  for (auto &x : m_forcing)
258  {
259  x->ApplyCoeff(m_fields, inarray, outarray, time);
260  }
261 
262  if (m_useLocalTimeStep)
263  {
264  int nElements = m_fields[0]->GetExpSize();
265  int nq, offset;
266  NekDouble fac;
268 
269  Array<OneD, NekDouble> tstep(nElements, 0.0);
270  GetElmtTimeStep(inarray, tstep);
271 
272  // Loop over elements
273  for (int n = 0; n < nElements; ++n)
274  {
275  nq = m_fields[0]->GetExp(n)->GetNcoeffs();
276  offset = m_fields[0]->GetCoeff_Offset(n);
277  fac = tstep[n] / m_timestep;
278  for (int i = 0; i < nvariables; ++i)
279  {
280  Vmath::Smul(nq, fac, outarray[i] + offset, 1,
281  tmp = outarray[i] + offset, 1);
282  }
283  }
284  }
285  }
286 
287  /**
288  * @brief Compute the advection terms for the right-hand side
289  */
291  const Array<OneD, const Array<OneD, NekDouble>> &inarray,
292  Array<OneD, Array<OneD, NekDouble>> &outarray,
293  const NekDouble time,
294  const Array<OneD, const Array<OneD, NekDouble>> &pFwd,
295  const Array<OneD, const Array<OneD, NekDouble>> &pBwd)
296  {
297  int nvariables = inarray.size();
299 
300  m_advObject->AdvectCoeffs(nvariables, m_fields, advVel, inarray,
301  outarray, time, pFwd, pBwd);
302  }
303 
305  const Array<OneD, const Array<OneD, NekDouble>> &inpnts,
307  const NekDouble time,
308  const NekDouble lambda)
309  {
310  unsigned int nvariables = inpnts.size();
311  unsigned int ncoeffs = m_fields[0]->GetNcoeffs();
312  unsigned int ntotal = nvariables * ncoeffs;
313 
314  Array<OneD, NekDouble> inarray(ntotal);
315  Array<OneD, NekDouble> out(ntotal);
316  Array<OneD, NekDouble> tmpArray;
317 
318  for (int i = 0; i < nvariables; ++i)
319  {
320  int noffset = i * ncoeffs;
321  tmpArray = inarray + noffset;
322  m_fields[i]->FwdTrans(inpnts[i], tmpArray);
323  }
324 
325  DoImplicitSolveCoeff(inpnts, inarray, out, time, lambda);
326 
327  for (int i = 0; i < nvariables; ++i)
328  {
329  int noffset = i * ncoeffs;
330  tmpArray = out + noffset;
331  m_fields[i]->BwdTrans(tmpArray, outpnt[i]);
332  }
333  }
334 
336  const Array<OneD, const Array<OneD, NekDouble>> &inpnts,
337  const Array<OneD, const NekDouble> &inarray,
339  const NekDouble time,
340  const NekDouble lambda)
341  {
342  boost::ignore_unused(inpnts);
343 
344  m_TimeIntegLambda = lambda;
345  m_bndEvaluateTime = time;
346  m_solutionPhys = inpnts;
347  unsigned int ntotal = inarray.size();
348 
349  if (m_inArrayNorm < 0.0)
350  {
351  CalcRefValues(inarray);
352  }
353 
354  NekDouble tol2 = m_inArrayNorm
356 
357  m_nonlinsol->v_SetupNekNonlinSystem(ntotal, inarray, inarray, 0);
358 
359  m_TotNewtonIts += m_nonlinsol->SolveSystem(ntotal,inarray,
360  out, 0, tol2);
361 
362  m_TotLinIts += m_nonlinsol->GetNtotLinSysIts();
363 
364  m_TotImpStages++;
365  m_StagesPerStep++;
366  }
367 
369  const Array<OneD, const NekDouble> &inarray)
370  {
371  unsigned int nvariables = m_fields.size();
372  unsigned int ntotal = inarray.size();
373  unsigned int npoints = ntotal/nvariables;
374 
375  unsigned int nTotalGlobal = ntotal;
376  m_comm->AllReduce(nTotalGlobal, Nektar::LibUtilities::ReduceSum);
377  unsigned int nTotalDOF = nTotalGlobal / nvariables;
378  NekDouble invTotalDOF = 1.0 / nTotalDOF;
379 
380  m_inArrayNorm = 0.0;
381  m_magnitdEstimat = Array<OneD, NekDouble> (nvariables, 0.0);
382 
383  for (int i = 0; i < nvariables; ++i)
384  {
385  int offset = i * npoints;
386  m_magnitdEstimat[i] = Vmath::Dot(npoints, inarray + offset,
387  inarray + offset);
388  }
390 
391  for (int i = 0; i < nvariables; ++i)
392  {
394  }
395 
396  for (int i = 2; i < nvariables - 1; ++i)
397  {
399  }
400  for (int i = 2; i < nvariables - 1; ++i)
401  {
403  }
404 
405  for (int i = 0; i < nvariables; ++i)
406  {
407  m_magnitdEstimat[i] = sqrt(m_magnitdEstimat[i] * invTotalDOF);
408  }
409  if (m_root && m_verbose)
410  {
411  for (int i = 0; i < nvariables; ++i)
412  {
413  cout << "m_magnitdEstimat[" << i << "] = "
414  << m_magnitdEstimat[i] << endl;
415  }
416  cout << "m_inArrayNorm = " << m_inArrayNorm << endl;
417  }
418  }
419 
421  const Array<OneD, NekDouble> &inarray,
422  Array<OneD, NekDouble> &outarray,
423  const bool &flag)
424  {
425  if (m_preconCfs->UpdatePreconMatCheck(NullNekDouble1DArray,
427  {
428  int nvariables = m_solutionPhys.size();
429 
430  int nphspnt = m_solutionPhys[nvariables - 1].size();
431  Array<OneD, Array<OneD, NekDouble>> intmp(nvariables);
432  for(int i = 0; i < nvariables; i++)
433  {
434  intmp[i] = Array<OneD, NekDouble>(nphspnt,0.0);
435  }
436 
438 
439  m_preconCfs->BuildPreconCfs(m_fields, intmp, m_bndEvaluateTime,
441  }
442 
443  m_flagUpdatePreconMat = false;
444 
445  m_preconCfs->DoPreconCfs(m_fields, inarray, outarray, flag);
446  }
447 
448  template<typename DataType, typename TypeNekBlkMatSharedPtr>
450  const Array<OneD, const Array<OneD, NekDouble>> &inarray,
451  const Array<OneD, const TensorOfArray2D<NekDouble>> &qfield,
453  TensorOfArray4D<DataType> &StdMatDataDBB,
454  TensorOfArray5D<DataType> &StdMatDataDBDB)
455  {
456  if (StdMatDataDBB.size() == 0)
457  {
458  CalcVolJacStdMat(StdMatDataDBB,StdMatDataDBDB);
459  }
460 
461  int nSpaceDim = m_graph->GetSpaceDimension();
462  int nvariable = inarray.size();
463  int npoints = m_fields[0]->GetTotPoints();
464  int nVar2 = nvariable*nvariable;
465  std::shared_ptr<LocalRegions::ExpansionVector> expvect =
466  m_fields[0]->GetExp();
467  int nTotElmt = (*expvect).size();
468 
469  Array<OneD, NekDouble > mu (npoints, 0.0);
470  Array<OneD, NekDouble > DmuDT (npoints, 0.0);
471  if(m_viscousJacFlag)
472  {
473  CalcMuDmuDT(inarray,mu,DmuDT);
474  }
475 
476  Array<OneD, NekDouble> normals;
478  for(int i = 0; i < 3; i++)
479  {
480  normal3D[i] = Array<OneD, NekDouble>(3,0.0);
481  }
482  normal3D[0][0] = 1.0;
483  normal3D[1][1] = 1.0;
484  normal3D[2][2] = 1.0;
486 
487  DNekMatSharedPtr wspMat =
488  MemoryManager<DNekMat>::AllocateSharedPtr(nvariable,nvariable,0.0);
489  DNekMatSharedPtr wspMatDrv =
490  MemoryManager<DNekMat>::AllocateSharedPtr(nvariable-1,nvariable,0.0);
491 
492  Array<OneD, DataType> GmatxData;
493  Array<OneD, DataType> MatData;
494 
495  Array<OneD, NekDouble> tmppnts;
496  TensorOfArray3D<NekDouble> PntJacCons(m_spacedim); // Nvar*Nvar*Ndir*Nelmt*Npnt
497  TensorOfArray3D<DataType> PntJacConsStd(m_spacedim); // Nvar*Nvar*Ndir*Nelmt*Npnt
500  TensorOfArray4D<NekDouble> PntJacDerv(m_spacedim); // Nvar*Nvar*Ndir*Nelmt*Npnt
501  TensorOfArray4D<DataType> PntJacDervStd(m_spacedim); // Nvar*Nvar*Ndir*Nelmt*Npnt
502  TensorOfArray3D<NekDouble> DervStdd(m_spacedim); // Nvar*Nvar*Ndir*Nelmt*Npnt
503  TensorOfArray3D<NekDouble> DervCurv(m_spacedim); // Nvar*Nvar*Ndir*Nelmt*Npnt
504  for(int ndir=0; ndir<m_spacedim;ndir++)
505  {
506  PntJacDerv[ndir] = TensorOfArray3D<NekDouble>(m_spacedim);
507  PntJacDervStd[ndir] = TensorOfArray3D<DataType>(m_spacedim);
510  }
511 
513  Array<OneD, NekDouble> locDmuDT;
514  Array<OneD, Array<OneD, NekDouble>> locVars(nvariable);
516  for(int ndir=0; ndir<m_spacedim;ndir++)
517  {
518  locDerv[ndir] = Array<OneD, Array<OneD, NekDouble>>(nvariable);
519  }
520 
521  int nElmtCoefOld = -1;
522  for(int ne=0; ne<nTotElmt;ne++)
523  {
524  int nElmtCoef = (*expvect)[ne]->GetNcoeffs();
525  int nElmtCoef2 = nElmtCoef*nElmtCoef;
526  int nElmtPnt = (*expvect)[ne]->GetTotPoints();
527 
528  int nQuot = nElmtCoef2/m_nPadding;
529  int nRemd = nElmtCoef2- nQuot*m_nPadding;
530  int nQuotPlus=nQuot;
531  if(nRemd>0)
532  {
533  nQuotPlus++;
534  }
535  int nElmtCoef2Paded = nQuotPlus*m_nPadding;
536 
537  if(nElmtPnt>PntJacCons[0].size()||nElmtCoef>nElmtCoefOld)
538  {
539  nElmtCoefOld = nElmtCoef;
540  for(int ndir=0; ndir<3;ndir++)
541  {
542  normalPnt[ndir] = Array<OneD, NekDouble>(npoints,0.0);
543  }
544  tmppnts = Array<OneD, NekDouble> (nElmtPnt);
545  MatData = Array<OneD, DataType> (nElmtCoef2Paded*nVar2);
546  for(int ndir=0; ndir<m_spacedim;ndir++)
547  {
548  ConsCurv[ndir] = Array<OneD, NekDouble> (nElmtPnt);
549  ConsStdd[ndir] = Array<OneD, NekDouble> (nElmtPnt);
550  PntJacCons[ndir] = Array<OneD, Array<OneD, NekDouble>> (nElmtPnt);
551  PntJacConsStd[ndir] = Array<OneD, Array<OneD, DataType>> (nElmtPnt);
552  for(int i=0; i<nElmtPnt;i++)
553  {
554  PntJacCons[ndir][i] = Array<OneD, NekDouble>(nVar2);
555  PntJacConsStd[ndir][i] = Array<OneD, DataType>(nVar2);
556  }
557 
558  for(int ndir1=0; ndir1<m_spacedim;ndir1++)
559  {
560  PntJacDerv[ndir][ndir1] = Array<OneD, Array<OneD, NekDouble>> (nElmtPnt);
561  PntJacDervStd[ndir][ndir1] = Array<OneD, Array<OneD, DataType>> (nElmtPnt);
562  DervStdd[ndir][ndir1] = Array<OneD, NekDouble> (nElmtPnt);
563  DervCurv[ndir][ndir1] = Array<OneD, NekDouble> (nElmtPnt);
564  for(int i=0; i<nElmtPnt;i++)
565  {
566  PntJacDerv[ndir][ndir1][i] =
567  Array<OneD, NekDouble>(nVar2);
568  PntJacDervStd[ndir][ndir1][i] =
569  Array<OneD, DataType>(nVar2);
570  }
571  }
572  }
573  }
574 
575  int noffset = GetPhys_Offset(ne);
576  for(int j = 0; j < nvariable; j++)
577  {
578  locVars[j] = inarray[j]+noffset;
579  }
580 
582  {
583  for(int nFluxDir = 0; nFluxDir < nSpaceDim; nFluxDir++)
584  {
585  normals = normal3D[nFluxDir];
586  GetFluxVectorJacDirElmt(nvariable,nElmtPnt,locVars,
587  normals,wspMat,PntJacCons[nFluxDir]);
588  }
589  }
590 
591  if(m_viscousJacFlag)
592  {
593  for(int j = 0; j < nSpaceDim; j++)
594  {
595  for(int k = 0; k < nvariable; k++)
596  {
597  locDerv[j][k] = qfield[j][k]+noffset;
598  }
599  }
600  locmu = mu + noffset;
601  locDmuDT = DmuDT + noffset;
602  for(int nFluxDir = 0; nFluxDir < nSpaceDim; nFluxDir++)
603  {
604  normals = normal3D[nFluxDir];
605  MinusDiffusionFluxJacPoint(nvariable,nElmtPnt,
606  locVars,locDerv,locmu,locDmuDT,normals,wspMatDrv,
607  PntJacCons[nFluxDir]);
608  }
609  }
610 
611  if(m_viscousJacFlag)
612  {
613  locmu = mu + noffset;
614  for(int nFluxDir = 0; nFluxDir < nSpaceDim; nFluxDir++)
615  {
616  Vmath::Fill(npoints,1.0,normalPnt[nFluxDir],1);
617  for(int nDervDir = 0; nDervDir < nSpaceDim; nDervDir++)
618  {
619  GetFluxDerivJacDirctnElmt(nvariable,nElmtPnt,nDervDir,
620  locVars,locmu,normalPnt,wspMatDrv,
621  PntJacDerv[nFluxDir][nDervDir]);
622  }
623  Vmath::Fill(npoints,0.0,normalPnt[nFluxDir],1);
624  }
625  }
626 
627  for(int n=0; n<nvariable;n++)
628  {
629  for(int m=0; m<nvariable;m++)
630  {
631  int nVarOffset = m+n*nvariable;
632  GmatxData = gmtxarray[m][n]->GetBlock(ne,ne)->GetPtr();
633 
634  for(int ndStd0 =0;ndStd0<m_spacedim;ndStd0++)
635  {
636  Vmath::Zero(nElmtPnt,ConsStdd[ndStd0],1);
637  }
638  for(int ndir =0;ndir<m_spacedim;ndir++)
639  {
640  for(int i=0; i<nElmtPnt;i++)
641  {
642  tmppnts[i] = PntJacCons[ndir][i][nVarOffset];
643  }
644  (*expvect)[ne]->AlignVectorToCollapsedDir(ndir,
645  tmppnts,ConsCurv);
646  for(int nd =0;nd<m_spacedim;nd++)
647  {
648  Vmath::Vadd(nElmtPnt,ConsCurv[nd],1,ConsStdd[nd],1,
649  ConsStdd[nd],1);
650  }
651  }
652 
653  for(int ndir =0;ndir<m_spacedim;ndir++)
654  {
655  (*expvect)[ne]->MultiplyByQuadratureMetric(
656  ConsStdd[ndir],ConsStdd[ndir]); // weight with metric
657  for(int i=0; i<nElmtPnt;i++)
658  {
659  PntJacConsStd[ndir][i][nVarOffset] =
660  DataType(ConsStdd[ndir][i]);
661  }
662  }
663  }
664  }
665 
666  if(m_viscousJacFlag)
667  {
668  for(int m=0; m<nvariable;m++)
669  {
670  for(int n=0; n<nvariable;n++)
671  {
672  int nVarOffset = m+n*nvariable;
673  for(int ndStd0 =0;ndStd0<m_spacedim;ndStd0++)
674  {
675  for(int ndStd1 =0;ndStd1<m_spacedim;ndStd1++)
676  {
677  Vmath::Zero(nElmtPnt,
678  DervStdd[ndStd0][ndStd1],1);
679  }
680  }
681  for(int nd0 =0;nd0<m_spacedim;nd0++)
682  {
683  for(int nd1 =0;nd1<m_spacedim;nd1++)
684  {
685  for(int i=0; i<nElmtPnt;i++)
686  {
687  tmppnts[i] =
688  PntJacDerv[nd0][nd1][i][nVarOffset];
689  }
690 
691  (*expvect)[ne]->AlignVectorToCollapsedDir(
692  nd0,tmppnts,ConsCurv);
693  for(int nd =0;nd<m_spacedim;nd++)
694  {
695  (*expvect)[ne]->
696  AlignVectorToCollapsedDir(nd1,
697  ConsCurv[nd],DervCurv[nd]);
698  }
699 
700  for(int ndStd0 =0;ndStd0<m_spacedim;ndStd0++)
701  {
702  for(int ndStd1 =0;ndStd1<m_spacedim;ndStd1++)
703  {
704  Vmath::Vadd(nElmtPnt,
705  DervCurv[ndStd0][ndStd1],1,
706  DervStdd[ndStd0][ndStd1],1,
707  DervStdd[ndStd0][ndStd1],1);
708  }
709  }
710  }
711  }
712  for(int nd0 =0;nd0<m_spacedim;nd0++)
713  {
714  for(int nd1 =0;nd1<m_spacedim;nd1++)
715  {
716  (*expvect)[ne]->
717  MultiplyByQuadratureMetric(
718  DervStdd[nd0][nd1],
719  DervStdd[nd0][nd1]); // weight with metric
720  for(int i=0; i<nElmtPnt;i++)
721  {
722  PntJacDervStd[nd0][nd1][i][nVarOffset] =
723  -DataType(DervStdd[nd0][nd1][i]);
724  }
725  }
726  }
727  }
728  }
729  }
730 
731  Vmath::Zero(nElmtCoef2Paded*nVar2,MatData,1);
732  DataType one = 1.0;
733  for(int ndir =0;ndir<m_spacedim;ndir++)
734  {
735  for(int i=0;i<nElmtPnt;i++)
736  {
737  Blas::Ger (nElmtCoef2Paded,nVar2,one,
738  &StdMatDataDBB[ne][ndir][i][0],1,
739  &PntJacConsStd[ndir][i][0],1,
740  &MatData[0],nElmtCoef2Paded);
741  }
742  }
743 
744  if(m_viscousJacFlag)
745  {
746  for(int nd0 =0;nd0<m_spacedim;nd0++)
747  {
748  for(int nd1 =0;nd1<m_spacedim;nd1++)
749  {
750  for(int i=0;i<nElmtPnt;i++)
751  {
752  Blas::Ger (nElmtCoef2Paded,nVar2,one,
753  &StdMatDataDBDB[ne][nd0][nd1][i][0],1,
754  &PntJacDervStd[nd0][nd1][i][0],1,
755  &MatData[0],nElmtCoef2Paded);
756  }
757  }
758  }
759  }
760 
761 
763 
764  for(int n=0; n<nvariable;n++)
765  {
766  for(int m=0; m<nvariable;m++)
767  {
768  int nVarOffset = m+n*nvariable;
769  GmatxData = gmtxarray[m][n]->GetBlock(ne,ne)->GetPtr();
770  Vmath::Vcopy(nElmtCoef2,
771  tmpA = MatData + nVarOffset*nElmtCoef2Paded,1,
772  GmatxData,1);
773  }
774  }
775  }
776  }
777 
778  template<typename DataType>
780  TensorOfArray4D<DataType> &StdMatDataDBB,
781  TensorOfArray5D<DataType> &StdMatDataDBDB)
782  {
783  std::shared_ptr<LocalRegions::ExpansionVector> expvect =
784  m_fields[0]->GetExp();
785  int nTotElmt = (*expvect).size();
786 
787  StdMatDataDBB = TensorOfArray4D<DataType> (nTotElmt);
788  StdMatDataDBDB = TensorOfArray5D<DataType> (nTotElmt);
789 
790  vector<DNekMatSharedPtr> VectStdDerivBase0;
791  vector< TensorOfArray3D<DataType> > VectStdDerivBase_Base;
792  vector< TensorOfArray4D<DataType> > VectStdDervBase_DervBase;
793  DNekMatSharedPtr MatStdDerivBase0;
796  for (int ne = 0; ne < nTotElmt; ne++)
797  {
799  stdExp = (*expvect)[ne]->GetStdExp();
801  stdExp->DetShapeType(), *stdExp);
802  MatStdDerivBase0 = stdExp->GetStdMatrix(matkey);
803 
804  int nTotStdExp = VectStdDerivBase0.size();
805  int nFoundStdExp = -1;
806  for (int i = 0; i < nTotStdExp; i++)
807  {
808  if ((*VectStdDerivBase0[i])==(*MatStdDerivBase0))
809  {
810  nFoundStdExp = i;
811  }
812  }
813  if (nFoundStdExp >= 0)
814  {
815  StdMatDataDBB[ne] = VectStdDerivBase_Base[nFoundStdExp];
816  StdMatDataDBDB[ne] = VectStdDervBase_DervBase[nFoundStdExp];
817  }
818  else
819  {
820  int nElmtCoef = (*expvect)[ne]->GetNcoeffs();
821  int nElmtCoef2 = nElmtCoef*nElmtCoef;
822  int nElmtPnt = (*expvect)[ne]->GetTotPoints();
823 
824  int nQuot = nElmtCoef2/m_nPadding;
825  int nRemd = nElmtCoef2- nQuot*m_nPadding;
826  int nQuotPlus=nQuot;
827  if(nRemd>0)
828  {
829  nQuotPlus++;
830  }
831  int nPaded = nQuotPlus*m_nPadding;
832 
833  ArrayStdMat[0] = MatStdDerivBase0;
834  if(m_spacedim>1)
835  {
837  stdExp->DetShapeType(), *stdExp);
838  ArrayStdMat[1] = stdExp->GetStdMatrix(matkey);
839 
840  if(m_spacedim>2)
841  {
844  stdExp->DetShapeType(), *stdExp);
845  ArrayStdMat[2] = stdExp->GetStdMatrix(matkey);
846  }
847  }
848  for(int nd0=0;nd0<m_spacedim;nd0++)
849  {
850  ArrayStdMatData[nd0] = ArrayStdMat[nd0]->GetPtr();
851  }
852 
854  stdExp->DetShapeType(), *stdExp);
855  DNekMatSharedPtr BwdMat = stdExp->GetStdMatrix(matkey);
856  Array<OneD, NekDouble> BwdMatData = BwdMat->GetPtr();
857 
860 
861  for(int nd0=0;nd0<m_spacedim;nd0++)
862  {
863  tmpStdDBB[nd0] = Array<OneD, Array<OneD, DataType>> (nElmtPnt);
864  for(int i=0;i<nElmtPnt;i++)
865  {
866  tmpStdDBB[nd0][i] = Array<OneD, DataType> (nPaded,0.0);
867  for(int nc1=0;nc1<nElmtCoef;nc1++)
868  {
869  int noffset = nc1*nElmtCoef;
870  for(int nc0=0;nc0<nElmtCoef;nc0++)
871  {
872  tmpStdDBB[nd0][i][nc0+noffset] =
873  DataType (ArrayStdMatData[nd0]
874  [i*nElmtCoef+nc0]*
875  BwdMatData[i*nElmtCoef+nc1]);
876  }
877  }
878  }
879 
880  tmpStdDBDB[nd0] = TensorOfArray3D<DataType> (m_spacedim);
881  for(int nd1=0;nd1<m_spacedim;nd1++)
882  {
883  tmpStdDBDB[nd0][nd1] =
885  for(int i=0;i<nElmtPnt;i++)
886  {
887  tmpStdDBDB[nd0][nd1][i] =
888  Array<OneD, DataType> (nPaded,0.0);
889  for(int nc1=0;nc1<nElmtCoef;nc1++)
890  {
891  int noffset = nc1*nElmtCoef;
892  for(int nc0=0;nc0<nElmtCoef;nc0++)
893  {
894  tmpStdDBDB[nd0][nd1][i][nc0+noffset] =
895  DataType(ArrayStdMatData[nd0]
896  [i*nElmtCoef+nc0]*
897  ArrayStdMatData[nd1]
898  [i*nElmtCoef+nc1]);
899  }
900  }
901  }
902  }
903  }
904  VectStdDerivBase0.push_back(MatStdDerivBase0);
905  VectStdDerivBase_Base.push_back(tmpStdDBB);
906  VectStdDervBase_DervBase.push_back(tmpStdDBDB);
907 
908  StdMatDataDBB[ne] = tmpStdDBB;
909  StdMatDataDBDB[ne] = tmpStdDBDB;
910  }
911  }
912  }
913 
914 
915  template<typename DataType, typename TypeNekBlkMatSharedPtr>
917  const Array<OneD, const Array<OneD, NekDouble>> &inarray,
922  Array<OneD, Array<OneD, DataType>> &TraceJacDerivSign,
923  TensorOfArray5D<DataType> &TraceIPSymJacArray)
924  {
925  int nvariables = inarray.size();
926  GetTraceJac(inarray,qfield,TraceJac,TraceJacDeriv,TraceJacDerivSign,
927  TraceIPSymJacArray);
928 
931 
932  m_advObject->AddTraceJacToMat(nvariables,m_spacedim,m_fields,
933  TraceJac,gmtxarray,tmpJac,tmpSign);
934  }
935 
936 
937  template<typename DataType, typename TypeNekBlkMatSharedPtr>
940  TypeNekBlkMatSharedPtr &gmtVar,
941  const DataType &tmpDataType)
942  {
943  boost::ignore_unused(tmpDataType);
944 
945  int n1d = gmtxarray.size();
946  int n2d = gmtxarray[0].size();
947  int nConvectiveFields = n1d;
948 
949  ASSERTL0(n1d==n2d,"ElmtVarInvMtrx requires n1d==n2d");
950 
951  Array<OneD, unsigned int> rowSizes;
952  Array<OneD, unsigned int> colSizes;
953 
954  gmtxarray[0][0]->GetBlockSizes(rowSizes,colSizes);
955  int nTotElmt = rowSizes.size();
956  int nElmtCoef = rowSizes[0]-1;
957  int nElmtCoef0 = -1;
958  int blocksize = -1;
959 
960  Array<OneD, unsigned int> tmprow(1);
961  TypeNekBlkMatSharedPtr tmpGmtx;
962 
963  Array<OneD, DataType> GMatData,ElmtMatData;
964  Array<OneD, DataType> tmpArray1,tmpArray2;
965 
966  for(int nelmt = 0; nelmt < nTotElmt; nelmt++)
967  {
968  int nrows = gmtxarray[0][0]->GetBlock(nelmt,nelmt)->GetRows();
969  int ncols = gmtxarray[0][0]->GetBlock(nelmt,nelmt)->GetColumns();
970  ASSERTL0(nrows==ncols,"ElmtVarInvMtrx requires nrows==ncols");
971 
972  nElmtCoef = nrows;
973 
974  if (nElmtCoef0!=nElmtCoef)
975  {
976  nElmtCoef0 = nElmtCoef;
977  int nElmtCoefVar = nElmtCoef0*nConvectiveFields;
978  blocksize = nElmtCoefVar*nElmtCoefVar;
979  tmprow[0] = nElmtCoefVar;
980  AllocateNekBlkMatDig(tmpGmtx,tmprow,tmprow);
981  GMatData = tmpGmtx->GetBlock(0,0)->GetPtr();
982  }
983 
984  for(int n = 0; n < nConvectiveFields; n++)
985  {
986  for(int m = 0; m < nConvectiveFields; m++)
987  {
988  ElmtMatData = gmtxarray[m][n]->
989  GetBlock(nelmt,nelmt)->GetPtr();
990 
991  for(int ncl = 0; ncl < nElmtCoef; ncl++)
992  {
993  int Goffset = (n*nElmtCoef+ncl)*nConvectiveFields*
994  nElmtCoef+m*nElmtCoef;
995  int Eoffset = ncl*nElmtCoef;
996 
997  Vmath::Vcopy(nElmtCoef,
998  tmpArray1 = ElmtMatData+Eoffset,1,
999  tmpArray2 = GMatData+Goffset,1);
1000  }
1001  }
1002  }
1003 
1004  tmpGmtx->GetBlock(0,0)->Invert();
1005 
1006  for(int m = 0; m < nConvectiveFields; m++)
1007  {
1008  for(int n = 0; n < nConvectiveFields; n++)
1009  {
1010  ElmtMatData =
1011  gmtxarray[m][n]->GetBlock(nelmt,nelmt)->GetPtr();
1012 
1013  for(int ncl = 0; ncl < nElmtCoef; ncl++)
1014  {
1015  int Goffset = (n*nElmtCoef+ncl)*nConvectiveFields*
1016  nElmtCoef+m*nElmtCoef;
1017  int Eoffset = ncl*nElmtCoef;
1018 
1019  Vmath::Vcopy(nElmtCoef,
1020  tmpArray1 = GMatData+Goffset,1,
1021  tmpArray2 = ElmtMatData+Eoffset,1);
1022  }
1023  }
1024  }
1025  ElmtMatData = gmtVar->GetBlock(nelmt,nelmt)->GetPtr();
1026  Vmath::Vcopy(blocksize, GMatData,1,ElmtMatData,1);
1027  }
1028  return;
1029  }
1030 
1031 
1032 
1033  template<typename DataType, typename TypeNekBlkMatSharedPtr>
1035  const Array<OneD, const Array<OneD, NekDouble>> &inarray,
1038  Array<OneD, TypeNekBlkMatSharedPtr > &TraceJacDeriv,
1039  Array<OneD, Array<OneD, DataType>> &TraceJacDerivSign,
1040  TensorOfArray5D<DataType> &TraceIPSymJacArray)
1041  {
1042  boost::ignore_unused(TraceJacDeriv, TraceJacDerivSign);
1043 
1044  int nvariables = inarray.size();
1045  int nTracePts = GetTraceTotPoints();
1046 
1047  // Store forwards/backwards space along trace space
1048  Array<OneD, Array<OneD, NekDouble>> Fwd (nvariables);
1049  Array<OneD, Array<OneD, NekDouble>> Bwd (nvariables);
1050 
1051  TypeNekBlkMatSharedPtr FJac,BJac;
1052  Array<OneD, unsigned int> n_blks1(nTracePts, nvariables);
1053 
1054  if(TraceJac.size()>0)
1055  {
1056  FJac = TraceJac[0];
1057  BJac = TraceJac[1];
1058  }
1059  else
1060  {
1062 
1063  AllocateNekBlkMatDig(FJac,n_blks1, n_blks1);
1064  AllocateNekBlkMatDig(BJac,n_blks1, n_blks1);
1065  }
1066 
1068  {
1071  }
1072  else
1073  {
1074  for(int i = 0; i < nvariables; ++i)
1075  {
1076  Fwd[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1077  Bwd[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1078  m_fields[i]->GetFwdBwdTracePhys(inarray[i], Fwd[i], Bwd[i]);
1079  }
1080  }
1081 
1083 
1084  NumCalcRiemFluxJac(nvariables, m_fields, AdvVel, inarray,qfield,
1085  m_bndEvaluateTime, Fwd, Bwd, FJac, BJac,TraceIPSymJacArray);
1086 
1087  TraceJac[0] = FJac;
1088  TraceJac[1] = BJac;
1089  }
1090 
1091  template<typename DataType, typename TypeNekBlkMatSharedPtr>
1093  const int nConvectiveFields,
1095  const Array<OneD, const Array<OneD, NekDouble>> &AdvVel,
1096  const Array<OneD, const Array<OneD, NekDouble>> &inarray,
1098  const NekDouble &time,
1099  const Array<OneD, const Array<OneD, NekDouble>> &Fwd,
1100  const Array<OneD, const Array<OneD, NekDouble>> &Bwd,
1101  TypeNekBlkMatSharedPtr &FJac,
1102  TypeNekBlkMatSharedPtr &BJac,
1103  TensorOfArray5D<DataType> &TraceIPSymJacArray)
1104  {
1105  boost::ignore_unused(TraceIPSymJacArray);
1106 
1107  const NekDouble PenaltyFactor2 = 0.0;
1108  int nvariables = nConvectiveFields;
1109  int npoints = GetNpoints();
1110  // int nPts = npoints;
1111  int nTracePts = GetTraceTotPoints();
1112  int nDim = m_spacedim;
1113 
1114  Array<OneD, int > nonZeroIndex;
1115 
1116  Array<OneD, Array<OneD, NekDouble>> tmpinarry(nvariables);
1117  for(int i = 0; i < nvariables; i++)
1118  {
1119  tmpinarry[i] = Array<OneD, NekDouble>(npoints,0.0);
1120  Vmath::Vcopy(npoints, inarray[i],1,tmpinarry[i],1);
1121  }
1122 
1123  // DmuDT of artificial diffusion is neglected
1124  // TODO: to consider the Jacobian of AV seperately
1127  if (m_shockCaptureType != "Off" && m_shockCaptureType != "Physical")
1128  {
1129  MuVarTrace = Array<OneD, NekDouble>(nTracePts, 0.0);
1130  muvar = Array<OneD, NekDouble>(npoints, 0.0);
1131  m_diffusion->GetAVmu(fields,inarray,muvar,MuVarTrace);
1132  muvar = NullNekDouble1DArray;
1133  }
1134 
1135  Array<OneD, Array<OneD, NekDouble>> numflux(nvariables);
1136  for(int i = 0; i < nvariables; ++i)
1137  {
1138  numflux[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1139  }
1140 
1141  const MultiRegions::AssemblyMapDGSharedPtr TraceMap =
1142  fields[0]->GetTraceMap();
1143  TensorOfArray3D<NekDouble> qBwd(nDim);
1144  TensorOfArray3D<NekDouble> qFwd(nDim);
1145  if(m_viscousJacFlag)
1146  {
1147  for (int nd = 0; nd < nDim; ++nd)
1148  {
1149  qBwd[nd] = Array<OneD, Array<OneD, NekDouble>> (nConvectiveFields);
1150  qFwd[nd] = Array<OneD, Array<OneD, NekDouble>> (nConvectiveFields);
1151  for (int i = 0; i < nConvectiveFields; ++i)
1152  {
1153  qBwd[nd][i] = Array<OneD, NekDouble>(nTracePts,0.0);
1154  qFwd[nd][i] = Array<OneD, NekDouble>(nTracePts,0.0);
1155 
1156  fields[i]->GetFwdBwdTracePhys(qfield[nd][i], qFwd[nd][i],
1157  qBwd[nd][i], true, true, false);
1158  TraceMap->GetAssemblyCommDG()->PerformExchange(qFwd[nd][i],
1159  qBwd[nd][i]);
1160  }
1161  }
1162  }
1163 
1164  CalcTraceNumericalFlux(nConvectiveFields,nDim,npoints,nTracePts,
1165  PenaltyFactor2, fields,AdvVel,inarray,time,qfield,Fwd,Bwd,
1166  qFwd,qBwd,MuVarTrace,nonZeroIndex,numflux);
1167 
1168  int nFields = nvariables;
1169  Array<OneD, Array<OneD, NekDouble>> plusFwd(nFields),plusBwd(nFields);
1170  Array<OneD, Array<OneD, NekDouble>> Jacvect(nFields);
1171  Array<OneD, Array<OneD, NekDouble>> FwdBnd(nFields);
1172  Array<OneD, Array<OneD, NekDouble>> plusflux(nFields);
1173  for(int i = 0; i < nFields; i++)
1174  {
1175  Jacvect[i] = Array<OneD, NekDouble>(nTracePts,0.0);
1176  plusFwd[i] = Array<OneD, NekDouble>(nTracePts,0.0);
1177  plusBwd[i] = Array<OneD, NekDouble>(nTracePts,0.0);
1178  plusflux[i] = Array<OneD, NekDouble>(nTracePts,0.0);
1179  FwdBnd[i] = Array<OneD, NekDouble>(nTracePts,0.0);
1180  }
1181 
1182 
1183  for(int i = 0; i < nFields; i++)
1184  {
1185  Vmath::Vcopy(nTracePts, Fwd[i],1,plusFwd[i],1);
1186  Vmath::Vcopy(nTracePts, Bwd[i],1,plusBwd[i],1);
1187  }
1188 
1189  NekDouble eps = 1.0E-6;
1190 
1191  Array<OneD, DataType> tmpMatData;
1192  // Fwd Jacobian
1193  for(int i = 0; i < nFields; i++)
1194  {
1195  NekDouble epsvar = eps*m_magnitdEstimat[i];
1196  NekDouble oepsvar = 1.0/epsvar;
1197  Vmath::Sadd(nTracePts,epsvar,Fwd[i],1,plusFwd[i],1);
1198 
1199  if (m_bndConds.size())
1200  {
1201  for(int i = 0; i < nFields; i++)
1202  {
1203  Vmath::Vcopy(nTracePts, plusFwd[i],1,FwdBnd[i],1);
1204  }
1205  // Loop over user-defined boundary conditions
1206  for (auto &x : m_bndConds)
1207  {
1208  x->Apply(FwdBnd, tmpinarry, time);
1209  }
1210  }
1211 
1212  for(int j = 0; j < nFields; j++)
1213  {
1214  m_fields[j]->FillBwdWithBoundCond(plusFwd[j], plusBwd[j]);
1215  }
1216 
1217  CalcTraceNumericalFlux(nConvectiveFields,nDim,npoints,nTracePts,
1218  PenaltyFactor2,fields,AdvVel,inarray,time,qfield,
1219  plusFwd,plusBwd,qFwd,qBwd,MuVarTrace,nonZeroIndex,plusflux);
1220 
1221  for (int n = 0; n < nFields; n++)
1222  {
1223  Vmath::Vsub(nTracePts,plusflux[n],1,numflux[n],1,Jacvect[n],1);
1224  Vmath::Smul(nTracePts, oepsvar ,Jacvect[n],1,Jacvect[n],1);
1225  }
1226  for(int j = 0; j < nTracePts; j++)
1227  {
1228  tmpMatData = FJac->GetBlock(j,j)->GetPtr();
1229  for (int n = 0; n < nFields; n++)
1230  {
1231  tmpMatData[n+i*nFields] = DataType(Jacvect[n][j]);
1232  }
1233  }
1234 
1235  Vmath::Vcopy(nTracePts, Fwd[i],1,plusFwd[i],1);
1236  }
1237 
1238  // Reset the boundary conditions
1239  if (m_bndConds.size())
1240  {
1241  for(int i = 0; i < nFields; i++)
1242  {
1243  Vmath::Vcopy(nTracePts, Fwd[i],1,FwdBnd[i],1);
1244  }
1245  // Loop over user-defined boundary conditions
1246  for (auto &x : m_bndConds)
1247  {
1248  x->Apply(FwdBnd, tmpinarry, time);
1249  }
1250  }
1251 
1252  for(int i = 0; i < nFields; i++)
1253  {
1254  Vmath::Vcopy(nTracePts, Bwd[i],1,plusBwd[i],1);
1255  }
1256 
1257  for(int i = 0; i < nFields; i++)
1258  {
1259  NekDouble epsvar = eps*m_magnitdEstimat[i];
1260  NekDouble oepsvar = 1.0/epsvar;
1261 
1262  Vmath::Sadd(nTracePts,epsvar,Bwd[i],1,plusBwd[i],1);
1263 
1264  for(int j = 0; j < nFields; j++)
1265  {
1266  m_fields[j]->FillBwdWithBoundCond(Fwd[j], plusBwd[j]);
1267  }
1268 
1269  CalcTraceNumericalFlux(nConvectiveFields,nDim,npoints,nTracePts,
1270  PenaltyFactor2,fields,AdvVel,inarray,time,qfield,Fwd,
1271  plusBwd,qFwd,qBwd,MuVarTrace,nonZeroIndex,plusflux);
1272 
1273  for (int n = 0; n < nFields; n++)
1274  {
1275  Vmath::Vsub(nTracePts,plusflux[n],1,numflux[n],1,Jacvect[n],1);
1276  Vmath::Smul(nTracePts, oepsvar,Jacvect[n],1,Jacvect[n],1);
1277  }
1278  for(int j = 0; j < nTracePts; j++)
1279  {
1280  tmpMatData = BJac->GetBlock(j,j)->GetPtr();
1281  for (int n = 0; n < nFields; n++)
1282  {
1283  tmpMatData[n+i*nFields] = DataType(Jacvect[n][j]);
1284  }
1285  }
1286 
1287  Vmath::Vcopy(nTracePts, Bwd[i],1,plusBwd[i],1);
1288  }
1289  }
1290 
1292  const int nConvectiveFields,
1293  const int nDim,
1294  const int nPts,
1295  const int nTracePts,
1296  const NekDouble PenaltyFactor2,
1298  const Array<OneD, const Array<OneD, NekDouble>> &AdvVel,
1299  const Array<OneD, const Array<OneD, NekDouble>> &inarray,
1300  const NekDouble time,
1302  const Array<OneD, const Array<OneD, NekDouble>> &vFwd,
1303  const Array<OneD, const Array<OneD, NekDouble>> &vBwd,
1304  const Array<OneD, const TensorOfArray2D<NekDouble>> &qFwd,
1305  const Array<OneD, const TensorOfArray2D<NekDouble>> &qBwd,
1306  const Array<OneD, NekDouble > &MuVarTrace,
1307  Array<OneD, int > &nonZeroIndex,
1308  Array<OneD, Array<OneD, NekDouble>> &traceflux)
1309  {
1310  boost::ignore_unused(nDim, nPts, PenaltyFactor2, time, qFwd, qBwd,
1311  MuVarTrace);
1312 
1313  if (m_advectionJacFlag)
1314  {
1315  m_advObject->AdvectTraceFlux(nConvectiveFields, m_fields, AdvVel,
1316  inarray, traceflux, m_bndEvaluateTime,vFwd, vBwd);
1317  }
1318  else
1319  {
1320  for (int i = 0; i < nConvectiveFields; i++)
1321  {
1322  traceflux[i] = Array<OneD, NekDouble>(nTracePts, 0.0);
1323  }
1324  }
1325 
1326  if(m_viscousJacFlag)
1327  {
1328  Array<OneD, Array<OneD, NekDouble > > visflux(nConvectiveFields);
1329  for(int i = 0; i < nConvectiveFields; i++)
1330  {
1331  visflux[i] = Array<OneD, NekDouble>(nTracePts,0.0);
1332  }
1333 
1334  m_diffusion->DiffuseTraceFlux(fields, inarray, qfield,
1335  NullNekDoubleTensorOfArray3D, visflux, vFwd, vBwd, nonZeroIndex);
1336  for(int i = 0; i < nConvectiveFields; i++)
1337  {
1338  Vmath::Vsub(nTracePts,traceflux[i],1,visflux[i],1,
1339  traceflux[i],1);
1340  }
1341  }
1342  }
1343 
1345  const Array<OneD, const Array<OneD, NekDouble>> &inarray,
1347  SNekBlkMatSharedPtr &gmtVar,
1349  Array<OneD, SNekBlkMatSharedPtr> &TraceJacDeriv,
1350  Array<OneD, Array<OneD, NekSingle>> &TraceJacDerivSign,
1351  TensorOfArray4D<NekSingle> &TraceJacArray,
1352  TensorOfArray4D<NekSingle> &TraceJacDerivArray,
1353  TensorOfArray5D<NekSingle> &TraceIPSymJacArray)
1354  {
1356 
1357  if(m_viscousJacFlag)
1358  {
1359  CalcPhysDeriv(inarray,qfield);
1360  }
1361 
1362  NekSingle zero =0.0;
1363  Fill2DArrayOfBlkDiagonalMat(gmtxarray,zero);
1364 
1365  AddMatNSBlkDiagVol(inarray,qfield,gmtxarray,m_stdSMatDataDBB,
1367 
1368  AddMatNSBlkDiagBnd(inarray,qfield,gmtxarray,TraceJac,
1369  TraceJacDeriv,TraceJacDerivSign,TraceIPSymJacArray);
1370 
1372 
1373  ElmtVarInvMtrx(gmtxarray,gmtVar,zero);
1374 
1375  TransTraceJacMatToArray(TraceJac,TraceJacDeriv,TraceJacArray,
1376  TraceJacDerivArray);
1377  }
1378 
1380  const int nConvectiveFields,
1381  const int nElmtPnt,
1382  const Array<OneD, const Array<OneD, NekDouble>> &locVars,
1383  const TensorOfArray3D<NekDouble> &locDerv,
1384  const Array<OneD, NekDouble> &locmu,
1385  const Array<OneD, NekDouble> &locDmuDT,
1386  const Array<OneD, NekDouble> &normals,
1387  DNekMatSharedPtr &wspMat,
1388  Array<OneD, Array<OneD, NekDouble>> &PntJacArray)
1389  {
1390  boost::ignore_unused(nConvectiveFields, nElmtPnt, locVars, locDerv,
1391  locmu, locDmuDT, normals, wspMat, PntJacArray);
1392  // Do nothing by default
1393  }
1394 
1395  template<typename DataType, typename TypeNekBlkMatSharedPtr>
1398  const NekDouble dtlamda,
1399  const DataType tmpDataType)
1400  {
1401  boost::ignore_unused(tmpDataType);
1402 
1404  std::shared_ptr<LocalRegions::ExpansionVector> pexp = explist->GetExp();
1405  int nTotElmt = (*pexp).size();
1406  int nConvectiveFields = m_fields.size();
1407 
1408  NekDouble Negdtlamda = -dtlamda;
1409 
1410  Array<OneD, NekDouble> pseudotimefactor(nTotElmt,0.0);
1411  Vmath::Fill(nTotElmt,Negdtlamda,pseudotimefactor,1);
1412 
1413  Array<OneD, DataType> GMatData;
1414  for(int m = 0; m < nConvectiveFields; m++)
1415  {
1416  for(int n = 0; n < nConvectiveFields; n++)
1417  {
1418  for(int nelmt = 0; nelmt < nTotElmt; nelmt++)
1419  {
1420  GMatData = gmtxarray[m][n]->GetBlock(nelmt,nelmt)->GetPtr();
1421  DataType factor = DataType(pseudotimefactor[nelmt]);
1422 
1423  Vmath::Smul(GMatData.size(),factor,GMatData,1,GMatData,1);
1424  }
1425  }
1426  }
1427 
1428  DNekMatSharedPtr MassMat;
1429  Array<OneD,NekDouble> BwdMatData,MassMatData,tmp;
1430  Array<OneD,NekDouble> tmp2;
1431  Array<OneD,DataType> MassMatDataDataType;
1433 
1434  for(int nelmt = 0; nelmt < nTotElmt; nelmt++)
1435  {
1436  int nelmtcoef = GetNcoeffs(nelmt);
1437  int nelmtpnts = GetTotPoints(nelmt);
1438  LibUtilities::ShapeType ElmtTypeNow =
1439  explist->GetExp(nelmt)->DetShapeType();
1440 
1441  if (tmp.size()!=nelmtcoef||(ElmtTypeNow!=ElmtTypePrevious))
1442  {
1444  stdExp = explist->GetExp(nelmt)->GetStdExp();
1446  stdExp->DetShapeType(), *stdExp);
1447 
1448  DNekMatSharedPtr BwdMat = stdExp->GetStdMatrix(matkey);
1449  BwdMatData = BwdMat->GetPtr();
1450 
1451  if(nelmtcoef!=tmp.size())
1452  {
1453  tmp = Array<OneD,NekDouble> (nelmtcoef,0.0);
1454  MassMat = MemoryManager<DNekMat>
1455  ::AllocateSharedPtr(nelmtcoef, nelmtcoef, 0.0);
1456  MassMatData = MassMat->GetPtr();
1457  MassMatDataDataType =
1458  Array<OneD, DataType> (nelmtcoef*nelmtcoef);
1459  }
1460 
1461  ElmtTypePrevious = ElmtTypeNow;
1462  }
1463 
1464  for(int np=0; np<nelmtcoef;np++)
1465  {
1466  explist->GetExp(nelmt)->IProductWRTBase(
1467  BwdMatData+np*nelmtpnts,tmp);
1468  Vmath::Vcopy(nelmtcoef,tmp,1,tmp2 = MassMatData+np*nelmtcoef,1);
1469  }
1470  for(int i=0;i<MassMatData.size();i++)
1471  {
1472  MassMatDataDataType[i] = DataType(MassMatData[i]);
1473  }
1474 
1475  for(int m = 0; m < nConvectiveFields; m++)
1476  {
1477  GMatData = gmtxarray[m][m]->GetBlock(nelmt,nelmt)->GetPtr();
1478  Vmath::Vadd(MassMatData.size(),MassMatDataDataType,1,
1479  GMatData,1,GMatData,1);
1480  }
1481  }
1482  return;
1483  }
1484 
1485  template<typename DataType, typename TypeNekBlkMatSharedPtr>
1487  const Array<OneD, TypeNekBlkMatSharedPtr> &TraceJac,
1488  const Array<OneD, TypeNekBlkMatSharedPtr> &TraceJacDeriv,
1489  TensorOfArray4D<DataType> &TraceJacArray,
1490  TensorOfArray4D<DataType> &TraceJacDerivArray)
1491  {
1492  boost::ignore_unused(TraceJacArray, TraceJacDeriv, TraceJacDerivArray);
1493 
1494  int nFwdBwd,nDiagBlks,nvar0Jac,nvar1Jac;
1495 
1496  Array<OneD, unsigned int> rowSizes;
1497  Array<OneD, unsigned int> colSizes;
1498  nFwdBwd = TraceJac.size();
1499  TraceJac[0]->GetBlockSizes(rowSizes,colSizes);
1500  nDiagBlks = rowSizes.size();
1501  nvar0Jac = rowSizes[1] - rowSizes[0];
1502  nvar1Jac = colSizes[1] - colSizes[0];
1503 
1504  if(0==TraceJacArray.size())
1505  {
1506  TraceJacArray = TensorOfArray4D<DataType> (nFwdBwd);
1507  for(int nlr=0;nlr<nFwdBwd;nlr++)
1508  {
1509  TraceJacArray[nlr] = TensorOfArray3D<DataType> (nvar0Jac);
1510  for(int m=0;m<nvar0Jac;m++)
1511  {
1512  TraceJacArray[nlr][m] = Array<OneD, Array<OneD, DataType>>(nvar1Jac);
1513  for(int n=0;n<nvar1Jac;n++)
1514  {
1515  TraceJacArray[nlr][m][n] =
1516  Array<OneD,DataType >(nDiagBlks);
1517  }
1518  }
1519  }
1520  }
1521 
1522  for(int nlr=0;nlr<nFwdBwd;nlr++)
1523  {
1524  const TypeNekBlkMatSharedPtr tmpMat = TraceJac[nlr];
1525  TensorOfArray3D<DataType> tmpaa = TraceJacArray[nlr];
1526  TranSamesizeBlkDiagMatIntoArray(tmpMat,tmpaa);
1527  }
1528 
1529  return;
1530  }
1531 
1533  const MultiRegions::ExpListSharedPtr &explist,
1534  const Array<OneD, const Array<OneD, NekDouble>> &normals,
1535  const int nDervDir,
1536  const Array<OneD, const Array<OneD, NekDouble>> &inarray,
1537  TensorOfArray5D<NekDouble> &ElmtJacArray,
1538  const int nFluxDir)
1539  {
1540  boost::ignore_unused(explist, normals, nDervDir, inarray, ElmtJacArray,
1541  nFluxDir);
1542  NEKERROR(ErrorUtil::efatal, "v_GetFluxDerivJacDirctn not coded");
1543  }
1544 
1546  const int nConvectiveFields,
1547  const int nElmtPnt,
1548  const int nDervDir,
1549  const Array<OneD, const Array<OneD, NekDouble>> &locVars,
1550  const Array<OneD, NekDouble> &locmu,
1551  const Array<OneD, const Array<OneD, NekDouble>> &locnormal,
1552  DNekMatSharedPtr &wspMat,
1553  Array<OneD, Array<OneD, NekDouble>> &PntJacArray)
1554  {
1555  boost::ignore_unused(nConvectiveFields, nElmtPnt, nDervDir, locVars,
1556  locmu, locnormal, wspMat, PntJacArray);
1557  NEKERROR(ErrorUtil::efatal, "v_GetFluxDerivJacDirctn not coded");
1558  }
1559 
1561  const MultiRegions::ExpListSharedPtr &explist,
1562  const Array<OneD, const Array<OneD, NekDouble>> &normals,
1563  const int nDervDir,
1564  const Array<OneD, const Array<OneD, NekDouble>> &inarray,
1566  {
1567  boost::ignore_unused(explist, normals, nDervDir, inarray, ElmtJac);
1568  }
1569 
1571  const int nConvectiveFields,
1572  const int nElmtPnt,
1573  const Array<OneD, const Array<OneD, NekDouble>> &locVars,
1574  const Array<OneD, NekDouble> &normals,
1575  DNekMatSharedPtr &wspMat,
1576  Array<OneD, Array<OneD, NekDouble>> &PntJacArray)
1577  {
1578  Array<OneD, NekDouble> wspMatData = wspMat->GetPtr();
1579 
1580  int matsize = nConvectiveFields*nConvectiveFields;
1581 
1582  Array<OneD, NekDouble> pointVar(nConvectiveFields);
1583 
1584  for(int npnt = 0; npnt < nElmtPnt; npnt++)
1585  {
1586  for(int j = 0; j < nConvectiveFields; j++)
1587  {
1588  pointVar[j] = locVars[j][npnt];
1589  }
1590 
1591  GetFluxVectorJacPoint(nConvectiveFields,pointVar,normals,wspMat);
1592 
1593  Vmath::Vcopy(matsize, wspMatData,1,PntJacArray[npnt],1);
1594  }
1595  return ;
1596  }
1597 
1599  const int nConvectiveFields,
1600  const Array<OneD, NekDouble> &conservVar,
1601  const Array<OneD, NekDouble> &normals,
1602  DNekMatSharedPtr &fluxJac)
1603  {
1604  int nvariables = conservVar.size();
1605  const int nvariables3D = 5;
1606  int expDim = m_spacedim;
1607 
1608  NekDouble fsw,efix_StegerWarming;
1609  efix_StegerWarming = 0.0;
1610  fsw = 0.0; // exact flux Jacobian if fsw=0.0
1611  if (nvariables > expDim+2)
1612  {
1613  NEKERROR(ErrorUtil::efatal,"nvariables > expDim+2 case not coded")
1614  }
1615 
1616  Array<OneD, NekDouble> fluxJacData;
1617  ;
1618  fluxJacData = fluxJac->GetPtr();
1619 
1620  if(nConvectiveFields==nvariables3D)
1621  {
1622  PointFluxJacobianPoint(conservVar,normals,fluxJac,
1623  efix_StegerWarming,fsw);
1624  }
1625  else
1626  {
1628  ::AllocateSharedPtr(nvariables3D, nvariables3D,0.0);
1629 
1630  Array<OneD, NekDouble> PointFJac3DData;
1631  PointFJac3DData = PointFJac3D->GetPtr();
1632 
1633  Array<OneD, NekDouble> PointFwd(nvariables3D,0.0);
1634 
1635  Array<OneD, unsigned int> index(nvariables);
1636 
1637  index[nvariables-1] = 4;
1638  for(int i=0;i<nvariables-1;i++)
1639  {
1640  index[i] = i;
1641  }
1642 
1643  int nj=0;
1644  int nk=0;
1645  for(int j=0; j< nvariables; j++)
1646  {
1647  nj = index[j];
1648  PointFwd[nj] = conservVar[j];
1649  }
1650 
1651  PointFluxJacobianPoint(PointFwd,normals,PointFJac3D,
1652  efix_StegerWarming,fsw);
1653 
1654  for(int j=0; j< nvariables; j++)
1655  {
1656  nj = index[j];
1657  for(int k=0; k< nvariables; k++)
1658  {
1659  nk = index[k];
1660  fluxJacData[j+k*nConvectiveFields] =
1661  PointFJac3DData[nj+nk*nvariables3D];
1662  }
1663  }
1664  }
1665  }
1666 
1667 
1668 
1669  /**
1670  * @brief Add the diffusions terms to the right-hand side
1671  * Similar to DoDiffusion() but with outarray in coefficient space
1672  */
1674  const Array<OneD, const Array<OneD, NekDouble>> &inarray,
1675  Array<OneD, Array<OneD, NekDouble>> &outarray,
1676  const Array<OneD, const Array<OneD, NekDouble>> &pFwd,
1677  const Array<OneD, const Array<OneD, NekDouble>> &pBwd)
1678  {
1679  v_DoDiffusionCoeff(inarray, outarray, pFwd, pBwd);
1680  }
1681 
1682 
1683 
1685  const Array<OneD, const NekDouble> &inarray,
1687  const bool &flag)
1688  {
1689  boost::ignore_unused(flag);
1690  const Array<OneD, const NekDouble> refsol =
1691  m_nonlinsol->GetRefSolution();
1692  const Array<OneD, const NekDouble> refres =
1693  m_nonlinsol->GetRefResidual();
1694  const Array<OneD, const NekDouble> refsource =
1695  m_nonlinsol->GetRefSourceVec();
1696 
1697  NekDouble eps = m_jacobiFreeEps;
1698  unsigned int nTotalGlobal = inarray.size();
1699  NekDouble magninarray = Vmath::Dot(nTotalGlobal,inarray,inarray);
1700  m_comm->AllReduce(magninarray, Nektar::LibUtilities::ReduceSum);
1701  eps *= sqrt( (sqrt(m_inArrayNorm) + 1.0)/magninarray);
1702 
1703  NekDouble oeps = 1.0 / eps;
1704  unsigned int ntotal = inarray.size();
1705  Array<OneD, NekDouble> solplus{ntotal, 0.0};
1706  Array<OneD, NekDouble> resplus{ntotal, 0.0};
1707 
1708  Vmath::Svtvp(ntotal, eps, inarray, 1, refsol, 1, solplus, 1);
1709 
1710  NonlinSysEvaluatorCoeff(solplus, resplus, flag, refsource);
1711 
1712  Vmath::Vsub(ntotal, resplus, 1, refres, 1, out,1);
1713  Vmath::Smul(ntotal, oeps, out, 1, out, 1);
1714 
1715  return;
1716  }
1717 
1718  template<typename DataType, typename TypeNekBlkMatSharedPtr>
1720  const TypeNekBlkMatSharedPtr &BlkMat,
1721  TensorOfArray3D<DataType> &MatArray)
1722  {
1723  Array<OneD, unsigned int> rowSizes;
1724  Array<OneD, unsigned int> colSizes;
1725  BlkMat->GetBlockSizes(rowSizes,colSizes);
1726  int nDiagBlks = rowSizes.size();
1727  int nvar0 = rowSizes[1] - rowSizes[0];
1728  int nvar1 = colSizes[1] - colSizes[0];
1729 
1730  Array<OneD, DataType> ElmtMatData;
1731 
1732  for(int i=0;i<nDiagBlks;i++)
1733  {
1734  ElmtMatData = BlkMat->GetBlock(i,i)->GetPtr();
1735  for(int n=0;n<nvar1;n++)
1736  {
1737  int noffset = n*nvar0;
1738  for(int m=0;m<nvar0;m++)
1739  {
1740  MatArray[m][n][i] = ElmtMatData[m+noffset];
1741  }
1742  }
1743  }
1744  }
1745 
1746  template<typename DataType, typename TypeNekBlkMatSharedPtr>
1749  const DataType valu)
1750  {
1751 
1752  int n1d = gmtxarray.size();
1753 
1754  for(int n1 = 0; n1 < n1d; ++n1)
1755  {
1756  Fill1DArrayOfBlkDiagonalMat(gmtxarray[n1],valu);
1757  }
1758  }
1759 
1760 
1761  template<typename DataType, typename TypeNekBlkMatSharedPtr>
1764  const DataType valu)
1765  {
1766  int n1d = gmtxarray.size();
1767 
1768  Array<OneD, unsigned int> rowSizes;
1769  Array<OneD, unsigned int> colSizes;
1770 
1771  Array<OneD, DataType > loc_mat_arr;
1772 
1773 
1774  for(int n1 = 0; n1 < n1d; ++n1)
1775  {
1776  gmtxarray[n1]->GetBlockSizes(rowSizes,colSizes);
1777  int nelmts = rowSizes.size();
1778 
1779  for(int i = 0; i < nelmts; ++i)
1780  {
1781  loc_mat_arr = gmtxarray[n1]->GetBlock(i,i)->GetPtr();
1782 
1783  int nrows = gmtxarray[n1]->GetBlock(i,i)->GetRows();
1784  int ncols = gmtxarray[n1]->GetBlock(i,i)->GetColumns();
1785 
1786  Vmath::Fill(nrows*ncols,valu,loc_mat_arr,1);
1787  }
1788  }
1789 
1790  }
1791 
1792 
1793  // Currently duplacate in compressibleFlowSys
1794  // if fsw=+-1 calculate the steger-Warming flux vector splitting flux Jacobian
1795  // if fsw=0 calculate the Jacobian of the exact flux
1796  // efix is the numerical flux entropy fix parameter
1798  const Array<OneD, NekDouble> &Fwd,
1799  const Array<OneD, NekDouble> &normals,
1800  DNekMatSharedPtr &FJac,
1801  const NekDouble efix, const NekDouble fsw)
1802  {
1803  Array<OneD, NekDouble> FJacData = FJac->GetPtr();
1804  const int nvariables3D = 5;
1805 
1806  NekDouble ro,vx,vy,vz,ps,gama,ae ;
1807  NekDouble a,a2,h,h0,v2,vn,eps,eps2;
1808  NekDouble nx,ny,nz;
1809  NekDouble sn,osn,nxa,nya,nza,vna;
1810  NekDouble l1,l4,l5,al1,al4,al5,x1,x2,x3,y1;
1811  NekDouble c1,d1,c2,d2,c3,d3,c4,d4,c5,d5;
1812  NekDouble sml_ssf= 1.0E-12;
1813 
1814  NekDouble fExactorSplt = 2.0-abs(fsw); // if fsw=+-1 calculate
1815 
1816  NekDouble rhoL = Fwd[0];
1817  NekDouble rhouL = Fwd[1];
1818  NekDouble rhovL = Fwd[2];
1819  NekDouble rhowL = Fwd[3];
1820  NekDouble EL = Fwd[4];
1821 
1822  ro = rhoL;
1823  vx = rhouL / rhoL;
1824  vy = rhovL / rhoL;
1825  vz = rhowL / rhoL;
1826 
1827  // Internal energy (per unit mass)
1828  NekDouble eL =
1829  (EL - 0.5 * (rhouL * vx + rhovL * vy + rhowL * vz)) / rhoL;
1830 
1831  ps = m_varConv->Geteos()->GetPressure(rhoL, eL);
1832  gama = m_gamma;
1833 
1834  ae = gama - 1.0;
1835  v2 = vx*vx + vy*vy + vz*vz;
1836  a2 = gama*ps/ro;
1837  h = a2/ae;
1838 
1839  h0 = h + 0.5*v2;
1840  a = sqrt(a2);
1841 
1842  nx = normals[0];
1843  ny = normals[1];
1844  nz = normals[2];
1845  vn = nx*vx + ny*vy + nz*vz;
1846  sn = std::max(sqrt(nx*nx + ny*ny + nz*nz),sml_ssf);
1847  osn = 1.0/sn;
1848 
1849  nxa = nx * osn;
1850  nya = ny * osn;
1851  nza = nz * osn;
1852  vna = vn * osn;
1853  l1 = vn;
1854  l4 = vn + sn*a;
1855  l5 = vn - sn*a;
1856 
1857  eps = efix*sn;
1858  eps2 = eps*eps;
1859 
1860  al1 = sqrt(l1*l1 + eps2);
1861  al4 = sqrt(l4*l4 + eps2);
1862  al5 = sqrt(l5*l5 + eps2);
1863 
1864  l1 = 0.5*(fExactorSplt*l1 + fsw*al1);
1865  l4 = 0.5*(fExactorSplt*l4 + fsw*al4);
1866  l5 = 0.5*(fExactorSplt*l5 + fsw*al5);
1867 
1868  x1 = 0.5*(l4 + l5);
1869  x2 = 0.5*(l4 - l5);
1870  x3 = x1 - l1;
1871  y1 = 0.5*v2;
1872  c1 = ae*x3/a2;
1873  d1 = x2/a;
1874 
1875  int nVar0 = 0;
1876  int nVar1 = nvariables3D;
1877  int nVar2 = 2*nvariables3D;
1878  int nVar3 = 3*nvariables3D;
1879  int nVar4 = 4*nvariables3D;
1880  FJacData[ nVar0] = c1*y1 - d1*vna + l1;
1881  FJacData[ nVar1] = -c1*vx + d1*nxa;
1882  FJacData[ nVar2] = -c1*vy + d1*nya;
1883  FJacData[ nVar3] = -c1*vz + d1*nza;
1884  FJacData[ nVar4] = c1;
1885  c2 = c1*vx + d1*nxa*ae;
1886  d2 = x3*nxa + d1*vx;
1887  FJacData[ 1 + nVar0] = c2*y1 - d2*vna;
1888  FJacData[ 1 + nVar1] = -c2*vx + d2*nxa + l1;
1889  FJacData[ 1 + nVar2] = -c2*vy + d2*nya;
1890  FJacData[ 1 + nVar3] = -c2*vz + d2*nza;
1891  FJacData[ 1 + nVar4] = c2;
1892  c3 = c1*vy + d1*nya*ae;
1893  d3 = x3*nya + d1*vy;
1894  FJacData[ 2 + nVar0] = c3*y1 - d3*vna;
1895  FJacData[ 2 + nVar1] = -c3*vx + d3*nxa;
1896  FJacData[ 2 + nVar2] = -c3*vy + d3*nya + l1;
1897  FJacData[ 2 + nVar3] = -c3*vz + d3*nza;
1898  FJacData[ 2 + nVar4] = c3;
1899  c4 = c1*vz + d1*nza*ae;
1900  d4 = x3*nza + d1*vz;
1901  FJacData[ 3 + nVar0] = c4*y1 - d4*vna;
1902  FJacData[ 3 + nVar1] = -c4*vx + d4*nxa;
1903  FJacData[ 3 + nVar2] = -c4*vy + d4*nya;
1904  FJacData[ 3 + nVar3] = -c4*vz + d4*nza + l1;
1905  FJacData[ 3 + nVar4] = c4;
1906  c5 = c1*h0 + d1*vna*ae;
1907  d5 = x3*vna + d1*h0;
1908  FJacData[ 4 + nVar0] = c5*y1 - d5*vna;
1909  FJacData[ 4 + nVar1] = -c5*vx + d5*nxa;
1910  FJacData[ 4 + nVar2] = -c5*vy + d5*nya;
1911  FJacData[ 4 + nVar3] = -c5*vz + d5*nza;
1912  FJacData[ 4 + nVar4] = c5 + l1;
1913  }
1914 
1916  {
1917  bool flag = (m_time + m_timestep > m_fintime && m_fintime > 0.0) ||
1919  m_checktime);
1920  if (m_explicitAdvection)
1921  {
1922  flag = true;
1923  }
1924  else
1925  {
1926  flag = flag || m_preconCfs->UpdatePreconMatCheck(NullNekDouble1DArray,
1928  }
1929  return flag;
1930  }
1931 
1932 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
Definition: ErrorUtil.hpp:209
size_type size() const
Returns the array's size.
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 CalcVolJacStdMat(TensorOfArray4D< DataType > &StdMatDataDBB, TensorOfArray5D< DataType > &StdMatDataDBDB)
void ElmtVarInvMtrx(Array< OneD, Array< OneD, TypeNekBlkMatSharedPtr >> &gmtxarray, TypeNekBlkMatSharedPtr &gmtVar, const DataType &tmpDatatype)
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.
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)
LibUtilities::NekNonlinSysSharedPtr m_nonlinsol
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 PointFluxJacobianPoint(const Array< OneD, NekDouble > &Fwd, const Array< OneD, NekDouble > &normals, DNekMatSharedPtr &FJac, const NekDouble efix, const NekDouble fsw)
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, const DataType tmpDataType)
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_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 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 Fill2DArrayOfBlkDiagonalMat(Array< OneD, Array< OneD, TypeNekBlkMatSharedPtr >> &gmtxarray, const DataType valu)
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 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)
Array< OneD, Array< OneD, NekDouble > > m_solutionPhys
void AllocateNekBlkMatDig(SNekBlkMatSharedPtr &mat, const Array< OneD, unsigned int > nrow, const Array< OneD, unsigned int > ncol)
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)
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)
virtual ~CFSImplicit()
Destructor for CFSImplicit class.
void DoOdeRhsCoeff(const Array< OneD, const Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, const NekDouble time)
Compute the right-hand side.
virtual void v_InitObject()
Initialization object for CFSImplicit class.
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 GetFluxVectorJacPoint(const int nConvectiveFields, const Array< OneD, NekDouble > &conservVar, const Array< OneD, NekDouble > &normals, DNekMatSharedPtr &fluxJac)
TensorOfArray5D< NekSingle > m_stdSMatDataDBDB
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 MatrixMultiplyMatrixFreeCoeff(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &out, const bool &flag=false)
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 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)
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 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 DoImplicitSolve(const Array< OneD, const Array< OneD, NekDouble >> &inpnts, Array< OneD, Array< OneD, NekDouble >> &outpnt, const NekDouble time, const NekDouble lambda)
void Fill1DArrayOfBlkDiagonalMat(Array< OneD, TypeNekBlkMatSharedPtr > &gmtxarray, const DataType valu)
void CalcMuDmuDT(const Array< OneD, const Array< OneD, NekDouble >> &inarray, Array< OneD, NekDouble > &mu, Array< OneD, NekDouble > &DmuDT)
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)
SolverUtils::DiffusionSharedPtr m_diffusion
std::vector< CFSBndCondSharedPtr > m_bndConds
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...
VariableConverterSharedPtr m_varConv
virtual void v_InitObject()
Initialization object for CompressibleFlowSystem class.
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:145
NekDouble m_NonlinIterTolRelativeL2
Definition: NekSys.h:203
NekDouble m_LinSysRelativeTolInNonlin
Definition: NekSys.h:204
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 DefineImplicitSolve(FuncPointerT func, ObjectPointerT obj)
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:102
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.
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.
NekDouble m_TimeIntegLambda
coefff of spacial derivatives(rhs or m_F in GLM) in calculating the residual of the whole equation(us...
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.
Array< OneD, NekDouble > m_magnitdEstimat
estimate the magnitude of each conserved varibles
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:226
NekNonlinSysFactory & GetNekNonlinSysFactory()
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< AssemblyMapDG > AssemblyMapDGSharedPtr
Definition: AssemblyMapDG.h:47
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
std::shared_ptr< LocTraceToTraceMap > LocTraceToTraceMapSharedPtr
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:174
std::shared_ptr< StdExpansion > StdExpansionSharedPtr
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:1
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:69
double NekDouble
PreconCfsOpFactory & GetPreconCfsOpFactory()
Declaration of the boundary condition factory singleton.
Definition: PreconCfsOp.cpp:42
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:565
void Neg(int n, T *x, const int incx)
Negate x = -x.
Definition: Vmath.cpp:461
T Dot(int n, const T *w, const T *x)
vvtvp (vector times vector times vector): z = w*x*y
Definition: Vmath.cpp:1038
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:322
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:225
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:436
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
Definition: Vmath.cpp:45
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.cpp:341
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1199
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:372
scalarT< T > abs(scalarT< T > in)
Definition: scalar.hpp:272
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:267