Nektar++
DiffusionIP.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: DiffusionIP.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 // License for the specific language governing rights and limitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 //
32 // Description: IP diffusion class.
33 //
34 ///////////////////////////////////////////////////////////////////////////////
35 
37 #include <iomanip>
38 #include <iostream>
39 
41 
42 namespace Nektar
43 {
44 namespace SolverUtils
45 {
47  "InteriorPenalty", DiffusionIP::create);
48 
50 {
51 }
52 
56 {
57  m_session = pSession;
58 
59  m_session->LoadSolverInfo("ShockCaptureType", m_shockCaptureType, "Off");
60 
61  m_session->LoadParameter("IPSymmFluxCoeff", m_IPSymmFluxCoeff, 0.0); // 0.5
62 
63  m_session->LoadParameter("IP2ndDervCoeff", m_IP2ndDervCoeff,
64  0.0); // 1.0/12.0
65 
66  m_session->LoadParameter("IPPenaltyCoeff", m_IPPenaltyCoeff,
67  4.0); // 1.0/12.0
68 
69  // Setting up the normals
70  size_t nDim = pFields[0]->GetCoordim(0);
71  size_t nVariable = pFields.size();
72  size_t nTracePts = pFields[0]->GetTrace()->GetTotPoints();
73 
75  for (int i = 0; i < nDim; ++i)
76  {
77  m_traceNormals[i] = Array<OneD, NekDouble>{nTracePts, 0.0};
78  }
81  for (int i = 0; i < nVariable; ++i)
82  {
83  m_traceAver[i] = Array<OneD, NekDouble>{nTracePts, 0.0};
84  m_traceJump[i] = Array<OneD, NekDouble>{nTracePts, 0.0};
85  }
86 
87  pFields[0]->GetTrace()->GetNormals(m_traceNormals);
88  Array<OneD, NekDouble> lengthFwd{nTracePts, 0.0};
89  Array<OneD, NekDouble> lengthBwd{nTracePts, 0.0};
90  pFields[0]->GetTrace()->GetElmtNormalLength(lengthFwd, lengthBwd);
91  pFields[0]->PeriodicBwdCopy(lengthFwd, lengthBwd);
92 
94  pFields[0]->GetTraceMap();
95  TraceMap->GetAssemblyCommDG()->PerformExchange(lengthFwd, lengthBwd);
96 
97  Vmath::Vadd(nTracePts, lengthBwd, 1, lengthFwd, 1, lengthFwd, 1);
98  m_traceNormDirctnElmtLength = lengthFwd;
100  Vmath::Sdiv(nTracePts, 1.0, m_traceNormDirctnElmtLength, 1,
102 
105  pFields[0]->GetBwdWeight(m_tracBwdWeightAver, m_tracBwdWeightJump);
106  Array<OneD, NekDouble> tmpBwdWeight{nTracePts, 0.0};
107  Array<OneD, NekDouble> tmpBwdWeightJump{nTracePts, 0.0};
108  for (int i = 1; i < nVariable; ++i)
109  {
110  pFields[i]->GetBwdWeight(tmpBwdWeight, tmpBwdWeightJump);
111  Vmath::Vsub(nTracePts, tmpBwdWeight, 1, m_tracBwdWeightAver, 1,
112  tmpBwdWeight, 1);
113  Vmath::Vabs(nTracePts, tmpBwdWeight, 1, tmpBwdWeight, 1);
114  NekDouble norm = 0.0;
115  for (int j = 0; j < nTracePts; ++j)
116  {
117  norm += tmpBwdWeight[j];
118  }
119  ASSERTL0(norm < 1.0E-11,
120  "different BWD for different variable not coded yet");
121  }
122 
125  {
126  m_MuVarTrace = Array<OneD, NekDouble>{nTracePts, 0.0};
127  }
128 
129  // workspace for v_diffuse
130  size_t nCoeffs = pFields[0]->GetNcoeffs();
132  for (int i = 0; i < nVariable; ++i)
133  {
134  m_wspDiff[i] = Array<OneD, NekDouble>{nCoeffs, 0.0};
135  }
136 
137  // workspace for callnumtraceflux
140  for (int nd = 0; nd < nDim; ++nd)
141  {
142  m_wspNumDerivBwd[nd] =
144  m_wspNumDerivFwd[nd] =
146  for (int i = 0; i < nVariable; ++i)
147  {
148  m_wspNumDerivBwd[nd][i] = Array<OneD, NekDouble>{nTracePts, 0.0};
149  m_wspNumDerivFwd[nd][i] = Array<OneD, NekDouble>{nTracePts, 0.0};
150  }
151  }
152 }
153 
155  const size_t nConvectiveFields,
157  const Array<OneD, Array<OneD, NekDouble>> &inarray,
158  Array<OneD, Array<OneD, NekDouble>> &outarray,
159  const Array<OneD, Array<OneD, NekDouble>> &pFwd,
160  const Array<OneD, Array<OneD, NekDouble>> &pBwd)
161 {
162 
163  LibUtilities::Timer timer;
164  timer.Start();
165  DiffusionIP::v_DiffuseCoeffs(nConvectiveFields, fields, inarray, m_wspDiff,
166  pFwd, pBwd);
167  for (int i = 0; i < nConvectiveFields; ++i)
168  {
169  fields[i]->BwdTrans(m_wspDiff[i], outarray[i]);
170  }
171  timer.Stop();
172  timer.AccumulateRegion("Diffusion IP");
173 }
174 
176  const size_t nConvectiveFields,
178  const Array<OneD, Array<OneD, NekDouble>> &inarray,
179  Array<OneD, Array<OneD, NekDouble>> &outarray,
180  const Array<OneD, Array<OneD, NekDouble>> &pFwd,
181  const Array<OneD, Array<OneD, NekDouble>> &pBwd)
182 {
183  LibUtilities::Timer timer;
184  timer.Start();
185 
186  size_t nDim = fields[0]->GetCoordim(0);
187  size_t nPts = fields[0]->GetTotPoints();
188  size_t nCoeffs = fields[0]->GetNcoeffs();
189  size_t nTracePts = fields[0]->GetTrace()->GetTotPoints();
190 
191  // pre-allocate this?
192  Array<OneD, NekDouble> Fwd{nTracePts, 0.0};
193  Array<OneD, NekDouble> Bwd{nTracePts, 0.0};
194  TensorOfArray3D<NekDouble> elmtFlux{nDim};
195  TensorOfArray3D<NekDouble> qfield{nDim};
196 
197  for (int j = 0; j < nDim; ++j)
198  {
199  qfield[j] = Array<OneD, Array<OneD, NekDouble>>{nConvectiveFields};
200  elmtFlux[j] = Array<OneD, Array<OneD, NekDouble>>{nConvectiveFields};
201  for (int i = 0; i < nConvectiveFields; ++i)
202  {
203  qfield[j][i] = Array<OneD, NekDouble>{nPts, 0.0};
204  }
205  for (int i = 0; i < nConvectiveFields; ++i)
206  {
207  elmtFlux[j][i] = Array<OneD, NekDouble>{nPts, 0.0};
208  }
209  }
210 
211  // pre-allocate this?
212  Array<OneD, Array<OneD, NekDouble>> vFwd{nConvectiveFields};
213  Array<OneD, Array<OneD, NekDouble>> vBwd{nConvectiveFields};
214  // when does this happen?
216  {
217  for (int i = 0; i < nConvectiveFields; ++i)
218  {
219  vFwd[i] = Array<OneD, NekDouble>{nTracePts, 0.0};
220  vBwd[i] = Array<OneD, NekDouble>{nTracePts, 0.0};
221  }
222  for (int i = 0; i < nConvectiveFields; ++i)
223  {
224  fields[i]->GetFwdBwdTracePhys(inarray[i], vFwd[i], vBwd[i]);
225  }
226  }
227  else
228  {
229  for (int i = 0; i < nConvectiveFields; ++i)
230  {
231  vFwd[i] = pFwd[i];
232  vBwd[i] = pBwd[i];
233  }
234  }
235 
236  DiffuseCalcDerivative(fields, inarray, qfield, vFwd, vBwd);
237  Array<OneD, int> nonZeroIndex;
238  DiffuseVolumeFlux(fields, inarray, qfield, elmtFlux, nonZeroIndex);
239  timer.Stop();
240  timer.AccumulateRegion("Diffusion:Volumeflux");
241 
242  // pre-allocate this?
243  Array<OneD, Array<OneD, NekDouble>> tmpFluxIprdct{nDim};
244  // volume intergration: the nonZeroIndex indicates which flux is nonzero
245  for (int i = 0; i < nonZeroIndex.size(); ++i)
246  {
247  int j = nonZeroIndex[i];
248  for (int k = 0; k < nDim; ++k)
249  {
250  tmpFluxIprdct[k] = elmtFlux[k][j];
251  }
252  fields[j]->IProductWRTDerivBase(tmpFluxIprdct, outarray[j]);
253  Vmath::Neg(nCoeffs, outarray[j], 1);
254  }
255  timer.Stop();
256  timer.AccumulateRegion("Diffusion:IPWRTDB");
257 
258 
259  // release qfield, elmtFlux and muvar;
260  timer.Start();
261  for (int j = 0; j < nDim; ++j)
262  {
263  elmtFlux[j] = NullNekDoubleArrayOfArray;
264  }
265 
266  // pre-allocate this?
267  Array<OneD, Array<OneD, NekDouble>> Traceflux{nConvectiveFields};
268  for (int j = 0; j < nConvectiveFields; ++j)
269  {
270  Traceflux[j] = Array<OneD, NekDouble>{nTracePts, 0.0};
271  }
272 
273  DiffuseTraceFlux(fields, inarray, qfield, elmtFlux, Traceflux, vFwd, vBwd,
274  nonZeroIndex);
275  timer.Stop();
276  timer.AccumulateRegion("Diffusion:TraceFlux");
277 
278  for (int i = 0; i < nonZeroIndex.size(); ++i)
279  {
280  int j = nonZeroIndex[i];
281 
282  fields[j]->AddTraceIntegral(Traceflux[j], outarray[j]);
283  fields[j]->SetPhysState(false);
284  }
285 
286  AddDiffusionSymmFluxToCoeff(nConvectiveFields, fields, inarray, qfield,
287  elmtFlux, outarray, vFwd, vBwd);
288 
289  timer.Start();
290  for (int i = 0; i < nonZeroIndex.size(); ++i)
291  {
292  int j = nonZeroIndex[i];
293 
294  fields[j]->MultiplyByElmtInvMass(outarray[j], outarray[j]);
295  }
296  timer.Stop();
297  timer.AccumulateRegion("DiffIP:Diffusion Coeff:");
298 }
299 
301  const std::size_t nConvectiveFields,
303  const Array<OneD, Array<OneD, NekDouble>> &inarray,
304  Array<OneD, Array<OneD, NekDouble>> &outarray,
305  const Array<OneD, Array<OneD, NekDouble>> &vFwd,
306  const Array<OneD, Array<OneD, NekDouble>> &vBwd,
308  Array< OneD, int > &nonZeroIndex)
309 {
310  int i, j;
311  int nDim = fields[0]->GetCoordim(0);
312  int nPts = fields[0]->GetTotPoints();
313  int nCoeffs = fields[0]->GetNcoeffs();
314  int nTracePts = fields[0]->GetTrace()->GetTotPoints();
315 
316  TensorOfArray3D<NekDouble> elmtFlux(nDim);
317  for (j = 0; j < nDim; ++j)
318  {
319  elmtFlux[j] = Array<OneD, Array<OneD, NekDouble>>(nConvectiveFields);
320  for (i = 0; i < nConvectiveFields; ++i)
321  {
322  elmtFlux[j][i] = Array<OneD, NekDouble>(nPts, 0.0);
323  }
324  }
325 
326  DiffuseVolumeFlux(fields,inarray,qfield,elmtFlux,nonZeroIndex);
327 
328  Array<OneD, Array<OneD, NekDouble>> tmpFluxIprdct(nDim);
329  // volume intergration: the nonZeroIndex indicates which flux is nonzero
330  for(i = 0; i < nonZeroIndex.size(); ++i)
331  {
332  int j = nonZeroIndex[i];
333  for (int k = 0; k < nDim; ++k)
334  {
335  tmpFluxIprdct[k] = elmtFlux[k][j];
336  }
337  fields[j]->IProductWRTDerivBase(tmpFluxIprdct,outarray[j]);
338  Vmath::Neg (nCoeffs, outarray[j], 1);
339  }
340 
341  Array<OneD, Array<OneD, NekDouble > > Traceflux(nConvectiveFields);
342  for (int j = 0; j < nConvectiveFields; ++j)
343  {
344  Traceflux[j] = Array<OneD, NekDouble>(nTracePts, 0.0);
345  }
346 
347  DiffuseTraceFlux(fields,inarray,qfield,elmtFlux,
348  Traceflux,vFwd,vBwd,nonZeroIndex);
349 
350  // release qfield, elmtFlux and muvar;
351  for (j = 0; j < nDim; ++j)
352  {
353  elmtFlux[j] = NullNekDoubleArrayOfArray;
354  }
355 
356  for(i = 0; i < nonZeroIndex.size(); ++i)
357  {
358  int j = nonZeroIndex[i];
359 
360  fields[j]->AddTraceIntegral (Traceflux[j], outarray[j]);
361  fields[j]->SetPhysState (false);
362  }
363 
364  AddDiffusionSymmFluxToCoeff(nConvectiveFields, fields, inarray,qfield,
365  elmtFlux, outarray, vFwd, vBwd);
366 }
367 
370  const Array<OneD, Array<OneD, NekDouble>> &inarray,
372  const Array<OneD, Array<OneD, NekDouble>> &pFwd,
373  const Array<OneD, Array<OneD, NekDouble>> &pBwd)
374 {
375  size_t nConvectiveFields = fields.size();
376  boost::ignore_unused(pFwd, pBwd);
377 
378  size_t nDim = fields[0]->GetCoordim(0);
379 
381  for (int nd = 0; nd < 3; ++nd)
382  {
383  qtmp[nd] = NullNekDouble1DArray;
384  }
385  for (int i = 0; i < nConvectiveFields; ++i)
386  {
387  for (int nd = 0; nd < nDim; ++nd)
388  {
389  qtmp[nd] = qfield[nd][i];
390  }
391  fields[i]->PhysDeriv(inarray[i], qtmp[0], qtmp[1], qtmp[2]);
392  }
393 }
394 
397  const Array<OneD, Array<OneD, NekDouble>> &inarray,
399  Array<OneD, int> &nonZeroIndex)
400 {
401  size_t nDim = fields[0]->GetCoordim(0);
402  size_t nPts = fields[0]->GetTotPoints();
403 
406  {
407  muvar = Array<OneD, NekDouble>{nPts, 0.0};
408  GetAVmu(fields, inarray, muvar, m_MuVarTrace);
409  }
410 
412 
413  LibUtilities::Timer timer;
414  timer.Start();
415  m_FunctorDiffusionfluxCons(nDim, inarray, qfield, VolumeFlux, nonZeroIndex,
416  tmparray2D, muvar);
417  timer.Stop();
418  timer.AccumulateRegion("DiffIP:_FunctorDiffFluxCons",1);
419 }
420 
423  const Array<OneD, Array<OneD, NekDouble>> &inarray,
425  Array<OneD, Array<OneD, NekDouble>> &TraceFlux,
426  const Array<OneD, Array<OneD, NekDouble>> &pFwd,
427  const Array<OneD, Array<OneD, NekDouble>> &pBwd,
428  Array<OneD, int> &nonZeroIndex)
429 {
430  boost::ignore_unused(VolumeFlux);
431 
432  TensorOfArray3D<NekDouble> traceflux3D(1);
433  traceflux3D[0] = TraceFlux;
434 
435  size_t nConvectiveFields = fields.size();
436 
437  LibUtilities::Timer timer;
438  timer.Start();
440  fields, inarray, qfield, pFwd, pBwd, m_MuVarTrace,
441  nonZeroIndex, traceflux3D, m_traceAver, m_traceJump);
442  timer.Stop();
443  timer.AccumulateRegion("DiffIP:_CalcTraceNumFlux",1);
444 
445  ApplyFluxBndConds(nConvectiveFields, fields, TraceFlux);
446 }
447 
449  const std::size_t nConvectiveFields,
451  const Array<OneD, Array<OneD, NekDouble>> &inarray,
453  Array<OneD, Array<OneD, NekDouble>> &outarray,
454  const Array<OneD, Array<OneD, NekDouble>> &pFwd,
455  const Array<OneD, Array<OneD, NekDouble>> &pBwd)
456 {
457  if (fabs(m_IPSymmFluxCoeff) > 1.0E-12)
458  {
459  size_t nDim = fields[0]->GetCoordim(0);
460  size_t nPts = fields[0]->GetTotPoints();
461  size_t nTracePts = fields[0]->GetTrace()->GetTotPoints();
462  TensorOfArray3D<NekDouble> traceSymflux{nDim};
463  for (int nd = 0; nd < nDim; ++nd)
464  {
465  traceSymflux[nd] =
466  Array<OneD, Array<OneD, NekDouble>>{nConvectiveFields};
467  for (int j = 0; j < nConvectiveFields; ++j)
468  {
469  traceSymflux[nd][j] = Array<OneD, NekDouble>{nTracePts, 0.0};
470  }
471  }
472  Array<OneD, int> nonZeroIndex;
473  DiffuseTraceSymmFlux(nConvectiveFields, fields, inarray, qfield,
474  VolumeFlux, traceSymflux, pFwd, pBwd,
475  nonZeroIndex);
476 
477  AddSymmFluxIntegralToCoeff(nConvectiveFields, nDim, nPts, nTracePts,
478  fields, nonZeroIndex, traceSymflux,
479  outarray);
480  }
481 }
482 
484  const std::size_t nConvectiveFields,
486  const Array<OneD, Array<OneD, NekDouble>> &inarray,
488  TensorOfArray3D<NekDouble> &VolumeFlux,
489  Array<OneD, Array<OneD, NekDouble>> &outarray,
490  const Array<OneD, Array<OneD, NekDouble>> &pFwd,
491  const Array<OneD, Array<OneD, NekDouble>> &pBwd)
492 {
493  if (fabs(m_IPSymmFluxCoeff) > 1.0E-12)
494  {
495  size_t nDim = fields[0]->GetCoordim(0);
496  size_t nPts = fields[0]->GetTotPoints();
497  size_t nTracePts = fields[0]->GetTrace()->GetTotPoints();
498  TensorOfArray3D<NekDouble> traceSymflux{nDim};
499  for (int nd = 0; nd < nDim; ++nd)
500  {
501  traceSymflux[nd] =
502  Array<OneD, Array<OneD, NekDouble>>{nConvectiveFields};
503  for (int j = 0; j < nConvectiveFields; ++j)
504  {
505  traceSymflux[nd][j] = Array<OneD, NekDouble>{nTracePts, 0.0};
506  }
507  }
508  Array<OneD, int> nonZeroIndex;
509  DiffuseTraceSymmFlux(nConvectiveFields, fields, inarray, qfield,
510  VolumeFlux, traceSymflux, pFwd, pBwd,
511  nonZeroIndex);
512 
513  AddSymmFluxIntegralToPhys(nConvectiveFields, nDim, nPts, nTracePts,
514  fields, nonZeroIndex, traceSymflux, outarray);
515  }
516 }
517 
519  const std::size_t nConvectiveFields,
521  const Array<OneD, Array<OneD, NekDouble>> &inarray,
523  TensorOfArray3D<NekDouble> &SymmFlux,
524  const Array<OneD, Array<OneD, NekDouble>> &pFwd,
525  const Array<OneD, Array<OneD, NekDouble>> &pBwd,
526  Array<OneD, int> &nonZeroIndex)
527 {
528  boost::ignore_unused(inarray, qfield, VolumeFlux, pFwd, pBwd);
529  size_t nDim = fields[0]->GetCoordim(0);
530 
531  CalcTraceSymFlux(nConvectiveFields, nDim, fields, m_traceAver, m_traceJump,
532  nonZeroIndex, SymmFlux);
533 }
534 
536  const std::size_t nConvectiveFields, const size_t nDim,
538  const Array<OneD, Array<OneD, NekDouble>> &solution_Aver,
539  Array<OneD, Array<OneD, NekDouble>> &solution_jump,
540  Array<OneD, int> &nonZeroIndexsymm,
541  TensorOfArray3D<NekDouble> &traceSymflux)
542 {
543  size_t nTracePts = solution_jump[nConvectiveFields - 1].size();
544 
545  for (int i = 0; i < nConvectiveFields; ++i)
546  {
547  Vmath::Smul(nTracePts, m_IPSymmFluxCoeff, solution_jump[i], 1,
548  solution_jump[i], 1);
549  }
550 
551  m_FunctorSymmetricfluxCons(nDim, solution_Aver, solution_jump, traceSymflux,
552  nonZeroIndexsymm, m_traceNormals);
553 
554  for (int i = 0; i < nConvectiveFields; ++i)
555  {
556  MultiRegions::ExpListSharedPtr tracelist = fields[i]->GetTrace();
557  for (int nd = 0; nd < nDim; ++nd)
558  {
559  tracelist->MultiplyByQuadratureMetric(traceSymflux[nd][i],
560  traceSymflux[nd][i]);
561  }
562  }
563 }
564 
566  const std::size_t nConvectiveFields, const size_t nDim, const size_t nPts,
567  const size_t nTracePts,
569  const Array<OneD, const int> &nonZeroIndex,
570  TensorOfArray3D<NekDouble> &tracflux,
571  Array<OneD, Array<OneD, NekDouble>> &outarray)
572 {
573  boost::ignore_unused(nTracePts);
574 
575  size_t nCoeffs = outarray[nConvectiveFields - 1].size();
576  Array<OneD, NekDouble> tmpCoeff{nCoeffs, 0.0};
577  Array<OneD, Array<OneD, NekDouble>> tmpfield(nDim);
578  for (int i = 0; i < nDim; ++i)
579  {
580  tmpfield[i] = Array<OneD, NekDouble>{nPts, 0.0};
581  }
582  int nv = 0;
583  for (int j = 0; j < nonZeroIndex.size(); ++j)
584  {
585  nv = nonZeroIndex[j];
586  for (int nd = 0; nd < nDim; ++nd)
587  {
588  Vmath::Zero(nPts, tmpfield[nd], 1);
589 
590  fields[nv]->AddTraceQuadPhysToField(tracflux[nd][nv],
591  tracflux[nd][nv], tmpfield[nd]);
592  fields[nv]->DivideByQuadratureMetric(tmpfield[nd], tmpfield[nd]);
593  }
594  fields[nv]->IProductWRTDerivBase(tmpfield, tmpCoeff);
595  Vmath::Vadd(nCoeffs, tmpCoeff, 1, outarray[nv], 1, outarray[nv], 1);
596  }
597 }
598 
600  const std::size_t nConvectiveFields, const size_t nDim, const size_t nPts,
601  const size_t nTracePts,
603  const Array<OneD, const int> &nonZeroIndex,
604  TensorOfArray3D<NekDouble> &tracflux,
605  Array<OneD, Array<OneD, NekDouble>> &outarray)
606 {
607  boost::ignore_unused(nTracePts);
608 
609  size_t nCoeffs = outarray[nConvectiveFields - 1].size();
610  Array<OneD, NekDouble> tmpCoeff{nCoeffs, 0.0};
611  Array<OneD, NekDouble> tmpPhysi{nPts, 0.0};
612  Array<OneD, Array<OneD, NekDouble>> tmpfield{nDim};
613  for (int i = 0; i < nDim; ++i)
614  {
615  tmpfield[i] = Array<OneD, NekDouble>{nPts, 0.0};
616  }
617  for (int j = 0; j < nonZeroIndex.size(); ++j)
618  {
619  int nv = nonZeroIndex[j];
620  for (int nd = 0; nd < nDim; ++nd)
621  {
622  Vmath::Zero(nPts, tmpfield[nd], 1);
623 
624  fields[nv]->AddTraceQuadPhysToField(tracflux[nd][nv],
625  tracflux[nd][nv], tmpfield[nd]);
626  fields[nv]->DivideByQuadratureMetric(tmpfield[nd], tmpfield[nd]);
627  }
628  fields[nv]->IProductWRTDerivBase(tmpfield, tmpCoeff);
629  fields[nv]->BwdTrans(tmpCoeff, tmpPhysi);
630  Vmath::Vadd(nPts, tmpPhysi, 1, outarray[nv], 1, outarray[nv], 1);
631  }
632 }
633 
636  Array<OneD, NekDouble> &factor)
637 {
638  MultiRegions::ExpListSharedPtr tracelist = fields[0]->GetTrace();
639  std::shared_ptr<LocalRegions::ExpansionVector> traceExp =
640  tracelist->GetExp();
641  size_t ntotTrac = (*traceExp).size();
642  int nTracPnt, noffset;
643 
644  const MultiRegions::LocTraceToTraceMapSharedPtr locTraceToTraceMap =
645  fields[0]->GetLocTraceToTraceMap();
646 
647  const Array<OneD, const Array<OneD, int>> LRAdjExpid =
648  locTraceToTraceMap->GetLeftRightAdjacentExpId();
649  const Array<OneD, const Array<OneD, bool>> LRAdjflag =
650  locTraceToTraceMap->GetLeftRightAdjacentExpFlag();
651 
652  std::shared_ptr<LocalRegions::ExpansionVector> fieldExp =
653  fields[0]->GetExp();
654 
655  Array<OneD, NekDouble> factorFwdBwd{2, 0.0};
656 
657  NekDouble spaceDim = NekDouble(fields[0]->GetCoordim(0));
658 
659  for (int ntrace = 0; ntrace < ntotTrac; ++ntrace)
660  {
661  noffset = tracelist->GetPhys_Offset(ntrace);
662  nTracPnt = tracelist->GetTotPoints(ntrace);
663 
664  factorFwdBwd[0] = 0.0;
665  factorFwdBwd[1] = 0.0;
666 
667  for (int nlr = 0; nlr < 2; ++nlr)
668  {
669  if (LRAdjflag[nlr][ntrace])
670  {
671  int numModes = fields[0]->GetNcoeffs(LRAdjExpid[nlr][ntrace]);
672  NekDouble numModesdir =
673  pow(NekDouble(numModes), (1.0 / spaceDim));
674  factorFwdBwd[nlr] = 1.0 * numModesdir * (numModesdir + 1.0);
675  }
676  }
677 
678  for (int np = 0; np < nTracPnt; ++np)
679  {
680  factor[noffset + np] = std::max(factorFwdBwd[0], factorFwdBwd[1]);
681  }
682  }
683 }
684 
687  Array<OneD, NekDouble> &factor)
688 {
689  boost::ignore_unused(fields);
690  Vmath::Fill(factor.size(), m_IPPenaltyCoeff, factor, 1);
691 }
692 
694  const std::size_t nConvectiveFields, const size_t nPts,
695  const Array<OneD, const Array<OneD, NekDouble>> &vFwd,
696  const Array<OneD, const Array<OneD, NekDouble>> &vBwd,
699 {
700  // ConsVarAve(nConvectiveFields, nPts, vFwd, vBwd, aver);
701 
702  std::vector<NekDouble> vFwdTmp(nConvectiveFields),
703  vBwdTmp(nConvectiveFields), averTmp(nConvectiveFields) ;
704  for (size_t p = 0; p < nPts; ++p)
705  {
706  // re-arrange data
707  for (size_t f = 0; f < nConvectiveFields; ++f)
708  {
709  vFwdTmp[f] = vFwd[f][p];
710  vBwdTmp[f] = vBwd[f][p];
711  }
712 
713  ConsVarAve(nConvectiveFields, m_tracBwdWeightAver[p], vFwdTmp, vBwdTmp,
714  averTmp);
715 
716  // store
717  for (size_t f = 0; f < nConvectiveFields; ++f)
718  {
719  aver[f][p] = averTmp[f];
720  }
721  }
722 
723  // if this can be make function of points, the nPts loop can be lifted more
724  m_SpecialBndTreat(aver);
725 
726  // note: here the jump is 2.0*(aver-vFwd)
727  // because Viscous wall use a symmetry value as the Bwd,
728  // not the target one
729 
730  for (size_t f = 0; f < nConvectiveFields; ++f)
731  {
732  for (size_t p = 0; p < nPts; ++p)
733  {
734  NekDouble Bweight = m_tracBwdWeightJump[p];
735  NekDouble Fweight = 2.0 - Bweight;
736 
737  NekDouble tmpF = aver[f][p] - vFwd[f][p];
738  NekDouble tmpB = vBwd[f][p] - aver[f][p];
739  jump[f][p] = tmpF * Fweight + tmpB * Bweight;
740  }
741  }
742 }
743 
745  const NekDouble PenaltyFactor2,
747  const Array<OneD, Array<OneD, NekDouble>> &inarray,
748  const TensorOfArray3D<NekDouble> &qfield,
749  const Array<OneD, Array<OneD, NekDouble>> &vFwd,
750  const Array<OneD, Array<OneD, NekDouble>> &vBwd,
751  const Array<OneD, NekDouble> &MuVarTrace,
752  Array<OneD, int> &nonZeroIndexflux, TensorOfArray3D<NekDouble> &traceflux,
753  Array<OneD, Array<OneD, NekDouble>> &solution_Aver,
754  Array<OneD, Array<OneD, NekDouble>> &solution_jump)
755 {
756  size_t nDim = fields[0]->GetCoordim(0);
757  size_t nPts = fields[0]->GetTotPoints();
758  size_t nTracePts = fields[0]->GetTrace()->GetTotPoints();
759  size_t nConvectiveFields = fields.size();
760 
761  boost::ignore_unused(inarray);
762  const MultiRegions::AssemblyMapDGSharedPtr TraceMap =
763  fields[0]->GetTraceMap();
764 
765 
766  LibUtilities::Timer timer;
767  timer.Start();
768  // with further restructuring this iniziatilization could be eliminated
769  for (int nd = 0; nd < nDim; ++nd)
770  {
771  for (int i = 0; i < nConvectiveFields; ++i)
772  {
773  Vmath::Zero(nTracePts, m_wspNumDerivBwd[nd][i], 1);
774  Vmath::Zero(nTracePts, m_wspNumDerivFwd[nd][i], 1);
775  }
776  }
777 
778  // could this be pre-allocated?
779  Array<OneD, NekDouble> Fwd{nTracePts, 0.0};
780  Array<OneD, NekDouble> Bwd{nTracePts, 0.0};
781 
782  timer.Stop();
783  timer.AccumulateRegion("DiffIP:_CalcTraceNumFlux_alloc",1);
784 
785 
786  timer.Start();
787  if (fabs(PenaltyFactor2) > 1.0E-12)
788  {
789  AddSecondDerivToTrace(nConvectiveFields, nDim, nPts, nTracePts,
790  PenaltyFactor2, fields, qfield, m_wspNumDerivFwd,
792  }
793 
794  timer.Stop();
795  timer.AccumulateRegion("DiffIP:_AddSecondDerivToTrace",1);
796 
797  for (int nd = 0; nd < nDim; ++nd)
798  {
799  for (int i = 0; i < nConvectiveFields; ++i)
800  {
801  // this sequence of operations is really exepensive,
802  // it should be done collectively for all fields together instead of
803  // one by one
804  timer.Start();
805  fields[i]->GetFwdBwdTracePhys(qfield[nd][i], Fwd, Bwd, true, true,
806  false);
807  timer.Stop();
808  timer.AccumulateRegion("DiffIP:_GetFwdBwdTracePhys",1);
809 
810  for (size_t p = 0; p < nTracePts; ++p)
811  {
812  m_wspNumDerivBwd[nd][i][p] += 0.5 * Bwd[p];
813  m_wspNumDerivFwd[nd][i][p] += 0.5 * Fwd[p];
814  }
815 
816  timer.Start();
817  TraceMap->GetAssemblyCommDG()->PerformExchange(m_wspNumDerivFwd[nd][i],
818  m_wspNumDerivBwd[nd][i]);
819  timer.Stop();
820  timer.AccumulateRegion("DiffIP:_PerformExchange",1);
821 
822  Vmath::Vadd(nTracePts, m_wspNumDerivFwd[nd][i], 1, m_wspNumDerivBwd[nd][i], 1,
823  m_wspNumDerivFwd[nd][i], 1);
824  }
825  }
826 
827  timer.Start();
828  ConsVarAveJump(nConvectiveFields, nTracePts, vFwd, vBwd, solution_Aver,
829  solution_jump);
830  timer.Stop();
831  timer.AccumulateRegion("DiffIP:_ConsVarAveJump",1);
832 
833  for (size_t p = 0; p < nTracePts; ++p)
834  {
835  NekDouble PenaltyFactor = m_IPPenaltyCoeff * m_traceNormDirctnElmtLengthRecip[p]; // load 1x
836 
837  for (size_t f = 0; f < nConvectiveFields; ++f)
838  {
839  NekDouble jumpTmp = solution_jump[f][p] * PenaltyFactor; // load 1x
840  for (size_t d = 0; d < nDim; ++d)
841  {
842  NekDouble tmp = m_traceNormals[d][p] * jumpTmp + m_wspNumDerivFwd[d][f][p]; // load 2x
843  m_wspNumDerivFwd[d][f][p] = tmp; // store 1x
844  }
845  }
846  }
847 
848  timer.Start();
849  // Calculate normal viscous flux
850  m_FunctorDiffusionfluxConsTrace(nDim, solution_Aver, m_wspNumDerivFwd, traceflux,
851  nonZeroIndexflux, m_traceNormals, MuVarTrace);
852  timer.Stop();
853  timer.AccumulateRegion("DiffIP:_FunctorDiffFluxConsTrace",1);
854 }
855 
857  const std::size_t nConvectiveFields, const size_t nDim, const size_t nPts,
858  const size_t nTracePts, const NekDouble PenaltyFactor2,
860  const TensorOfArray3D<NekDouble> &qfield,
861  TensorOfArray3D<NekDouble> &numDerivFwd,
862  TensorOfArray3D<NekDouble> &numDerivBwd)
863 {
864  Array<OneD, NekDouble> Fwd{nTracePts, 0.0};
865  Array<OneD, NekDouble> Bwd{nTracePts, 0.0};
866  Array<OneD, NekDouble> tmp{nTracePts, 0.0};
867 
868  Array<OneD, Array<OneD, NekDouble>> elmt2ndDerv{nDim};
869  for (int nd1 = 0; nd1 < nDim; ++nd1)
870  {
871  elmt2ndDerv[nd1] = Array<OneD, NekDouble>{nPts, 0.0};
872  }
873 
875  for (int nd = 0; nd < 3; ++nd)
876  {
877  qtmp[nd] = NullNekDouble1DArray;
878  }
879  for (int nd2 = 0; nd2 < nDim; ++nd2)
880  {
881  qtmp[nd2] = elmt2ndDerv[nd2];
882  }
883 
884  Vmath::Smul(nTracePts, PenaltyFactor2, m_traceNormDirctnElmtLength, 1, tmp,
885  1);
886  // the derivatives are assumed to be exchangable
887  for (int nd1 = 0; nd1 < nDim; ++nd1)
888  {
889  for (int i = 0; i < nConvectiveFields; ++i)
890  {
891  fields[i]->PhysDeriv(qfield[nd1][i], qtmp[0], qtmp[1], qtmp[2]);
892 
893  for (int nd2 = nd1; nd2 < nDim; ++nd2)
894  {
895  Vmath::Zero(nTracePts, Bwd, 1);
896  fields[i]->GetFwdBwdTracePhys(elmt2ndDerv[nd2], Fwd, Bwd,
897  true, true, false);
898  Vmath::Vmul(nTracePts, tmp, 1, Bwd, 1, Bwd, 1);
899  Vmath::Vvtvp(nTracePts, m_traceNormals[nd2], 1, Bwd, 1,
900  numDerivBwd[nd1][i], 1, numDerivBwd[nd1][i], 1);
901  Vmath::Vmul(nTracePts, tmp, 1, Fwd, 1, Fwd, 1);
902  Vmath::Vvtvm(nTracePts, m_traceNormals[nd2], 1, Fwd, 1,
903  numDerivFwd[nd1][i], 1, numDerivFwd[nd1][i], 1);
904  Vmath::Neg(nTracePts, numDerivFwd[nd1][i], 1);
905 
906  if (nd2 != nd1)
907  {
908  Vmath::Vvtvp(nTracePts, m_traceNormals[nd1], 1, Bwd, 1,
909  numDerivBwd[nd2][i], 1, numDerivBwd[nd2][i],
910  1);
911  Vmath::Vvtvm(nTracePts, m_traceNormals[nd1], 1, Fwd, 1,
912  numDerivFwd[nd2][i], 1, numDerivFwd[nd2][i],
913  1);
914  Vmath::Neg(nTracePts, numDerivFwd[nd2][i], 1);
915  }
916  }
917  }
918  }
919 }
920 
921 
922 /**
923  * @brief aplly Neuman boundary conditions on flux
924  * Currently only consider WallAdiabatic
925  *
926  **/
928  const int nConvectiveFields,
931 {
932  int nengy = nConvectiveFields-1;
933  int cnt;
934  // Compute boundary conditions for Energy
935  cnt = 0;
936  size_t nBndRegions = fields[nengy]->
937  GetBndCondExpansions().size();
938  for (size_t j = 0; j < nBndRegions; ++j)
939  {
940  if (fields[nengy]->GetBndConditions()[j]->
941  GetBoundaryConditionType() ==
943  {
944  continue;
945  }
946 
947  size_t nBndEdges = fields[nengy]->
948  GetBndCondExpansions()[j]->GetExpSize();
949  for (size_t e = 0; e < nBndEdges; ++e)
950  {
951  size_t nBndEdgePts = fields[nengy]->
952  GetBndCondExpansions()[j]->GetExp(e)->GetTotPoints();
953 
954  std::size_t id2 = fields[0]->GetTrace()->
955  GetPhys_Offset(fields[0]->GetTraceMap()->
956  GetBndCondIDToGlobalTraceID(cnt++));
957 
958  if (fields[0]->GetBndConditions()[j]->
959  GetUserDefined() =="WallAdiabatic")
960  {
961  Vmath::Zero(nBndEdgePts, &flux[nengy][id2], 1);
962  }
963  }
964  }
965 }
966 
967 } // namespace SolverUtils
968 } // namespace Nektar
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:200
void AccumulateRegion(std::string, int iolevel=0)
Accumulate elapsed time for a region.
Definition: Timer.cpp:67
SOLVER_UTILS_EXPORT void DiffuseTraceFlux(const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble >> &inarray, TensorOfArray3D< NekDouble > &qfields, TensorOfArray3D< NekDouble > &VolumeFlux, Array< OneD, Array< OneD, NekDouble > > &TraceFlux, const Array< OneD, Array< OneD, NekDouble >> &pFwd=NullNekDoubleArrayOfArray, const Array< OneD, Array< OneD, NekDouble >> &pBwd=NullNekDoubleArrayOfArray, Array< OneD, int > &nonZeroIndex=NullInt1DArray)
Diffusion term Trace Flux.
Definition: Diffusion.h:249
SOLVER_UTILS_EXPORT void GetAVmu(const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble > > &inarray, Array< OneD, NekDouble > &muvar, Array< OneD, NekDouble > &MuVarTrace)
Get the mu of artifical viscosity(AV)
Definition: Diffusion.cpp:115
SOLVER_UTILS_EXPORT void DiffuseVolumeFlux(const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble >> &inarray, TensorOfArray3D< NekDouble > &qfields, TensorOfArray3D< NekDouble > &VolumeFlux, Array< OneD, int > &nonZeroIndex=NullInt1DArray)
Diffusion Volume FLux.
Definition: Diffusion.h:236
DiffusionFluxCons m_FunctorDiffusionfluxConsTrace
Definition: Diffusion.h:471
DiffusionArtificialDiffusion m_ArtificialDiffusionVector
Definition: Diffusion.h:469
SOLVER_UTILS_EXPORT void DiffuseCalcDerivative(const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble >> &inarray, TensorOfArray3D< NekDouble > &qfields, const Array< OneD, Array< OneD, NekDouble >> &pFwd=NullNekDoubleArrayOfArray, const Array< OneD, Array< OneD, NekDouble >> &pBwd=NullNekDoubleArrayOfArray)
Definition: Diffusion.cpp:224
SOLVER_UTILS_EXPORT void AddDiffusionSymmFluxToCoeff(const std::size_t nConvectiveFields, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble > > &inarray, TensorOfArray3D< NekDouble > &qfield, TensorOfArray3D< NekDouble > &VolumeFlux, Array< OneD, Array< OneD, NekDouble > > &outarray, const Array< OneD, Array< OneD, NekDouble > > &pFwd, const Array< OneD, Array< OneD, NekDouble > > &pBwd)
Add symmetric flux to field in coeff space.
Definition: Diffusion.h:285
DiffusionFluxCons m_FunctorDiffusionfluxCons
Definition: Diffusion.h:470
SpecialBndTreat m_SpecialBndTreat
Definition: Diffusion.h:472
DiffusionSymmFluxCons m_FunctorSymmetricfluxCons
Definition: Diffusion.h:474
SOLVER_UTILS_EXPORT void ConsVarAveJump(const std::size_t nConvectiveFields, const size_t npnts, const Array< OneD, const Array< OneD, NekDouble > > &vFwd, const Array< OneD, const Array< OneD, NekDouble > > &vBwd, Array< OneD, Array< OneD, NekDouble > > &aver, Array< OneD, Array< OneD, NekDouble > > &jump)
Get the average and jump value of conservative variables on trace.
Definition: Diffusion.h:446
Array< OneD, NekDouble > m_traceNormDirctnElmtLengthRecip
Definition: DiffusionIP.h:121
static DiffusionSharedPtr create(std::string diffType)
Definition: DiffusionIP.h:48
virtual void v_Diffuse(const std::size_t nConvectiveFields, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, const Array< OneD, Array< OneD, NekDouble >> &pFwd, const Array< OneD, Array< OneD, NekDouble >> &pBwd)
Array< OneD, NekDouble > m_tracBwdWeightAver
Definition: DiffusionIP.h:118
Array< OneD, NekDouble > m_traceNormDirctnElmtLength
Definition: DiffusionIP.h:120
void ApplyFluxBndConds(const int nConvectiveFields, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, Array< OneD, Array< OneD, NekDouble > > &flux)
aplly Neuman boundary conditions on flux Currently only consider WallAdiabatic
void GetPenaltyFactor(const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, Array< OneD, NekDouble > &factor)
Get IP penalty factor based on order.
void ConsVarAve(const size_t nConvectiveFields, const T &Bweight, const std::vector< T > &vFwd, const std::vector< T > &vBwd, std::vector< T > &aver)
Calculate the average of conservative variables on traces.
Definition: DiffusionIP.h:63
virtual void v_DiffuseVolumeFlux(const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble >> &inarray, TensorOfArray3D< NekDouble > &qfields, TensorOfArray3D< NekDouble > &VolumeFlux, Array< OneD, int > &nonZeroIndex)
Diffusion Volume Flux.
void GetPenaltyFactorConst(const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, Array< OneD, NekDouble > &factor)
Get a constant IP penalty factor.
void AddSecondDerivToTrace(const std::size_t nConvectiveFields, const size_t nDim, const size_t nPts, const size_t nTracePts, const NekDouble PenaltyFactor2, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const TensorOfArray3D< NekDouble > &qfield, TensorOfArray3D< NekDouble > &numDerivFwd, TensorOfArray3D< NekDouble > &numDerivBwd)
Add second derivative term to trace jump (for DDG scheme)
Array< OneD, NekDouble > m_MuVarTrace
Definition: DiffusionIP.h:108
virtual void v_InitObject(LibUtilities::SessionReaderSharedPtr pSession, Array< OneD, MultiRegions::ExpListSharedPtr > pFields)
Definition: DiffusionIP.cpp:53
void AddSymmFluxIntegralToCoeff(const std::size_t nConvectiveFields, const size_t nDim, const size_t nPts, const size_t nTracePts, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, const int > &nonZeroIndex, TensorOfArray3D< NekDouble > &tracflux, Array< OneD, Array< OneD, NekDouble >> &outarray)
Add symmetric flux integration to field (in coefficient space)
Array< OneD, Array< OneD, NekDouble > > m_traceJump
Definition: DiffusionIP.h:111
virtual void v_ConsVarAveJump(const std::size_t nConvectiveFields, const size_t npnts, const Array< OneD, const Array< OneD, NekDouble >> &vFwd, const Array< OneD, const Array< OneD, NekDouble >> &vBwd, Array< OneD, Array< OneD, NekDouble >> &aver, Array< OneD, Array< OneD, NekDouble >> &jump)
TensorOfArray3D< NekDouble > m_wspNumDerivBwd
Workspace for CallTraceNumFlux.
Definition: DiffusionIP.h:115
virtual void v_AddDiffusionSymmFluxToPhys(const std::size_t nConvectiveFields, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble >> &inarray, TensorOfArray3D< NekDouble > &qfield, TensorOfArray3D< NekDouble > &VolumeFlux, Array< OneD, Array< OneD, NekDouble >> &outarray, const Array< OneD, Array< OneD, NekDouble >> &pFwd, const Array< OneD, Array< OneD, NekDouble >> &pBwd)
void DiffuseTraceSymmFlux(const std::size_t nConvectiveFields, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble >> &inarray, TensorOfArray3D< NekDouble > &qfield, TensorOfArray3D< NekDouble > &VolumeFlux, TensorOfArray3D< NekDouble > &SymmFlux, const Array< OneD, Array< OneD, NekDouble >> &pFwd, const Array< OneD, Array< OneD, NekDouble >> &pBwd, Array< OneD, int > &nonZeroIndex)
Calculate symmetric flux on traces interface.
TensorOfArray3D< NekDouble > m_wspNumDerivFwd
Definition: DiffusionIP.h:116
LibUtilities::SessionReaderSharedPtr m_session
Definition: DiffusionIP.h:122
void CalcTraceSymFlux(const std::size_t nConvectiveFields, const size_t nDim, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble >> &solution_Aver, Array< OneD, Array< OneD, NekDouble >> &solution_jump, Array< OneD, int > &nonZeroIndexsymm, Array< OneD, Array< OneD, Array< OneD, NekDouble >>> &traceSymflux)
Calculate symmetric flux on traces.
Array< OneD, Array< OneD, NekDouble > > m_traceAver
Definition: DiffusionIP.h:110
Array< OneD, NekDouble > m_tracBwdWeightJump
Definition: DiffusionIP.h:119
virtual void v_AddDiffusionSymmFluxToCoeff(const std::size_t nConvectiveFields, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble >> &inarray, TensorOfArray3D< NekDouble > &qfield, TensorOfArray3D< NekDouble > &VolumeFlux, Array< OneD, Array< OneD, NekDouble >> &outarray, const Array< OneD, Array< OneD, NekDouble >> &pFwd, const Array< OneD, Array< OneD, NekDouble >> &pBwd)
virtual void v_DiffuseCalcDerivative(const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble >> &inarray, TensorOfArray3D< NekDouble > &qfield, const Array< OneD, Array< OneD, NekDouble >> &pFwd, const Array< OneD, Array< OneD, NekDouble >> &pBwd)
virtual void v_DiffuseCoeffs(const std::size_t nConvectiveFields, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, const Array< OneD, Array< OneD, NekDouble >> &pFwd, const Array< OneD, Array< OneD, NekDouble >> &pBwd)
void CalcTraceNumFlux(const NekDouble PenaltyFactor2, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble >> &inarray, const TensorOfArray3D< NekDouble > &qfield, const Array< OneD, Array< OneD, NekDouble >> &vFwd, const Array< OneD, Array< OneD, NekDouble >> &vBwd, const Array< OneD, NekDouble > &MuVarTrace, Array< OneD, int > &nonZeroIndexflux, TensorOfArray3D< NekDouble > &traceflux, Array< OneD, Array< OneD, NekDouble >> &solution_Aver, Array< OneD, Array< OneD, NekDouble >> &solution_jump)
Calculate numerical flux on traces.
void AddSymmFluxIntegralToPhys(const std::size_t nConvectiveFields, const size_t nDim, const size_t nPts, const size_t nTracePts, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, const int > &nonZeroIndex, TensorOfArray3D< NekDouble > &tracflux, Array< OneD, Array< OneD, NekDouble >> &outarray)
Add symmetric flux integration to field (in physical space)
virtual void v_DiffuseTraceFlux(const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble >> &inarray, TensorOfArray3D< NekDouble > &qfields, TensorOfArray3D< NekDouble > &VolumeFlux, Array< OneD, Array< OneD, NekDouble >> &TraceFlux, const Array< OneD, Array< OneD, NekDouble >> &pFwd, const Array< OneD, Array< OneD, NekDouble >> &pBwd, Array< OneD, int > &nonZeroIndex)
Array< OneD, Array< OneD, NekDouble > > m_wspDiff
Workspace for v_Diffusion.
Definition: DiffusionIP.h:113
Array< OneD, Array< OneD, NekDouble > > m_traceNormals
Definition: DiffusionIP.h:109
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
DiffusionFactory & GetDiffusionFactory()
Definition: Diffusion.cpp:41
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:1
static Array< OneD, Array< OneD, NekDouble > > NullNekDoubleArrayOfArray
static Array< OneD, NekDouble > NullNekDouble1DArray
double NekDouble
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.
Definition: Vmath.cpp:192
void Vabs(int n, const T *x, const int incx, T *y, const int incy)
vabs: y = |x|
Definition: Vmath.cpp:493
void Neg(int n, T *x, const int incx)
Negate x = -x.
Definition: Vmath.cpp:461
void Vvtvp(int n, const T *w, const int incw, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
vvtvp (vector times vector plus vector): z = w*x + y
Definition: Vmath.cpp:513
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 Vvtvm(int n, const T *w, const int incw, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
vvtvm (vector times vector plus vector): z = w*x - y
Definition: Vmath.cpp:541
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 Sdiv(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha/y.
Definition: Vmath.cpp:291
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 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