Nektar++
MMFAdvection.cpp
Go to the documentation of this file.
1 /////////////////////////////////////////////////////////////////////////////
2 //
3 // File: MMFAdvection.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: MMF solve routines
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
35 #include <iomanip>
36 #include <iostream>
37 
38 #include <boost/algorithm/string.hpp>
39 #include <boost/core/ignore_unused.hpp>
40 
44 
45 namespace Nektar
46 {
47 std::string MMFAdvection::className =
49  "MMFAdvection", MMFAdvection::create, "MMFAdvection equation.");
50 
53  : UnsteadySystem(pSession, pGraph), MMFSystem(pSession, pGraph),
54  AdvectionSystem(pSession, pGraph)
55 {
56  m_planeNumber = 0;
57 }
58 
59 /**
60  * @brief Initialisation object for the unsteady linear advection equation.
61  */
62 void MMFAdvection::v_InitObject(bool DeclareFields)
63 {
64  // Call to the initialisation object
65  UnsteadySystem::v_InitObject(DeclareFields);
66 
67  int nq = m_fields[0]->GetNpoints();
68  int shapedim = m_fields[0]->GetShapeDimension();
69  Array<OneD, Array<OneD, NekDouble>> Anisotropy(shapedim);
70  for (int j = 0; j < shapedim; ++j)
71  {
72  Anisotropy[j] = Array<OneD, NekDouble>(nq, 1.0);
73  }
74 
75  MMFSystem::MMFInitObject(Anisotropy);
76 
77  // Define TestType
78  ASSERTL0(m_session->DefinesSolverInfo("TESTTYPE"),
79  "No TESTTYPE defined in session.");
80  std::string TestTypeStr = m_session->GetSolverInfo("TESTTYPE");
81  for (int i = 0; i < (int)SIZE_TestType; ++i)
82  {
83  if (boost::iequals(TestTypeMap[i], TestTypeStr))
84  {
85  m_TestType = (TestType)i;
86  break;
87  }
88  }
89 
90  m_session->LoadParameter("Angular Frequency", m_waveFreq, m_pi);
91  m_session->LoadParameter("Rotational Angle", m_RotAngle, 0.0);
92  m_session->LoadParameter("Velocity Projection", m_VelProjection, 0);
93 
94  // Read the advection velocities from session file
95  m_session->LoadParameter("advx", m_advx, 1.0);
96  m_session->LoadParameter("advy", m_advy, 1.0);
97  m_session->LoadParameter("advz", m_advz, 1.0);
98 
99  std::vector<std::string> vel;
100  vel.push_back("Vx");
101  vel.push_back("Vy");
102  vel.push_back("Vz");
103 
104  // Resize the advection velocities vector to dimension of the problem
105  vel.resize(m_spacedim);
106 
107  // Store in the global variable m_velocity the advection velocities
108 
110  for (int k = 0; k < m_spacedim; ++k)
111  {
113  }
114 
115  switch (m_surfaceType)
116  {
121  {
122  // true = project velocity onto the tangent plane
124  }
125  break;
126 
127  case SolverUtils::ePlane:
128  case SolverUtils::eCube:
129  {
130  GetFunction("AdvectionVelocity")->Evaluate(vel, m_velocity);
131  }
132  break;
133 
134  default:
135  break;
136  }
137 
138  std::cout << "|Velocity vector| = ( " << RootMeanSquare(m_velocity[0])
139  << " , " << RootMeanSquare(m_velocity[1]) << " , "
140  << RootMeanSquare(m_velocity[2]) << " ) " << std::endl;
141 
142  // Define the normal velocity fields
143  if (m_fields[0]->GetTrace())
144  {
146  }
147 
148  std::string advName;
149  std::string riemName;
150  m_session->LoadSolverInfo("AdvectionType", advName, "WeakDG");
151  m_advObject =
153  m_advObject->SetFluxVector(&MMFAdvection::GetFluxVector, this);
154  m_session->LoadSolverInfo("UpwindType", riemName, "Upwind");
156  riemName, m_session);
157  m_riemannSolver->SetScalar("Vn", &MMFAdvection::GetNormalVelocity, this);
158 
159  m_advObject->SetRiemannSolver(m_riemannSolver);
160  m_advObject->InitObject(m_session, m_fields);
161 
162  // Compute m_traceVn = n \cdot v
164 
165  // Compute m_vellc = nabal a^j \cdot m_vel
167  std::cout << "m_vellc is generated with mag = " << AvgInt(m_vellc)
168  << std::endl;
169 
170  // Compute vel \cdot MF
172 
173  // Modify e^i as v^i e^i
174  for (int j = 0; j < m_shapedim; j++)
175  {
176  for (int k = 0; k < m_spacedim; k++)
177  {
178  Vmath::Vmul(nq, &m_veldotMF[j][0], 1, &m_movingframes[j][k * nq], 1,
179  &m_movingframes[j][k * nq], 1);
180  }
181  }
182 
183  // Reflect it into m_ncdotMFFwd and Bwd
184  ComputencdotMF();
185 
186  // If explicit it computes RHS and PROJECTION for the time integration
188  {
191  }
192  // Otherwise it gives an error (no implicit integration)
193  else
194  {
195  ASSERTL0(false, "Implicit unsteady Advection not set up.");
196  }
197 }
198 
199 /**
200  * @brief Unsteady linear advection equation destructor.
201  */
203 {
204 }
205 
207 {
208  ASSERTL0(m_intScheme != 0, "No time integration scheme.");
209 
210  int i, nchk = 1;
211  int nvariables = 0;
212  int nfields = m_fields.size();
213  int nq = m_fields[0]->GetNpoints();
214 
215  if (m_intVariables.empty())
216  {
217  for (i = 0; i < nfields; ++i)
218  {
219  m_intVariables.push_back(i);
220  }
221  nvariables = nfields;
222  }
223  else
224  {
225  nvariables = m_intVariables.size();
226  }
227 
228  // Set up wrapper to fields data storage.
229  Array<OneD, Array<OneD, NekDouble>> fields(nvariables);
230  Array<OneD, Array<OneD, NekDouble>> tmp(nvariables);
231 
232  // Order storage to list time-integrated fields first.
233  for (i = 0; i < nvariables; ++i)
234  {
235  fields[i] = m_fields[m_intVariables[i]]->GetPhys();
236  m_fields[m_intVariables[i]]->SetPhysState(false);
237  }
238 
239  // Initialise time integration scheme
240  m_intScheme->InitializeScheme(m_timestep, fields, m_time, m_ode);
241 
242  // Check uniqueness of checkpoint output
243  ASSERTL0((m_checktime == 0.0 && m_checksteps == 0) ||
244  (m_checktime > 0.0 && m_checksteps == 0) ||
245  (m_checktime == 0.0 && m_checksteps > 0),
246  "Only one of IO_CheckTime and IO_CheckSteps "
247  "should be set!");
248 
249  LibUtilities::Timer timer;
250  bool doCheckTime = false;
251  int step = 0;
252  NekDouble intTime = 0.0;
253  NekDouble cpuTime = 0.0;
254  NekDouble elapsed = 0.0;
255 
256  int Ntot, indx;
257  // Perform integration in time.
258  Ntot = m_checksteps ? m_steps / m_checksteps + 1 : 0;
259 
260  Array<OneD, NekDouble> dMass(Ntot ? Ntot : 1);
261 
262  Array<OneD, NekDouble> zeta(nq);
263  Array<OneD, Array<OneD, NekDouble>> fieldsprimitive(nvariables);
264  for (int i = 0; i < nvariables; ++i)
265  {
266  fieldsprimitive[i] = Array<OneD, NekDouble>(nq);
267  }
268 
269  while (step < m_steps || m_time < m_fintime - NekConstants::kNekZeroTol)
270  {
271  timer.Start();
272  fields = m_intScheme->TimeIntegrate(step, m_timestep, m_ode);
273  timer.Stop();
274 
275  m_time += m_timestep;
276  elapsed = timer.TimePerTest(1);
277  intTime += elapsed;
278  cpuTime += elapsed;
279 
280  // Write out status information
281  if (m_infosteps && !((step + 1) % m_infosteps) &&
282  m_session->GetComm()->GetRank() == 0)
283  {
284  std::cout << "Steps: " << std::setw(8) << std::left << step + 1
285  << " "
286  << "Time: " << std::setw(12) << std::left << m_time;
287 
288  std::stringstream ss;
289  ss << cpuTime << "s";
290  std::cout << " CPU Time: " << std::setw(8) << std::left << ss.str()
291  << std::endl;
292 
293  // Masss = h^*
294  indx = m_checksteps ? (step + 1) / m_checksteps : 0;
295  dMass[indx] =
296  (m_fields[0]->Integral(fields[0]) - m_Mass0) / m_Mass0;
297 
298  std::cout << "dMass = " << std::setw(8) << std::left << dMass[indx]
299  << std::endl;
300 
301  cpuTime = 0.0;
302  }
303 
304  // Transform data into coefficient space
305  for (i = 0; i < nvariables; ++i)
306  {
307  m_fields[m_intVariables[i]]->SetPhys(fields[i]);
308  m_fields[m_intVariables[i]]->FwdTransLocalElmt(
309  fields[i], m_fields[m_intVariables[i]]->UpdateCoeffs());
310  m_fields[m_intVariables[i]]->SetPhysState(false);
311  }
312 
313  // Write out checkpoint files
314  if ((m_checksteps && step && !((step + 1) % m_checksteps)) ||
315  doCheckTime)
316  {
317  Checkpoint_Output(nchk++);
318  doCheckTime = false;
319  }
320 
321  // Step advance
322  ++step;
323  }
324 
325  std::cout << "dMass = ";
326  for (i = 0; i < Ntot; ++i)
327  {
328  std::cout << dMass[i] << " , ";
329  }
330  std::cout << std::endl << std::endl;
331 
332  // Print out summary statistics
333  if (m_session->GetComm()->GetRank() == 0)
334  {
335  if (m_cflSafetyFactor > 0.0)
336  {
337  std::cout << "CFL safety factor : " << m_cflSafetyFactor
338  << std::endl
339  << "CFL time-step : " << m_timestep << std::endl;
340  }
341 
342  if (m_session->GetSolverInfo("Driver") != "SteadyState")
343  {
344  std::cout << "Time-integration : " << intTime << "s" << std::endl;
345  }
346  }
347 
348  for (i = 0; i < nvariables; ++i)
349  {
350  m_fields[m_intVariables[i]]->SetPhys(fields[i]);
351  m_fields[m_intVariables[i]]->SetPhysState(true);
352  }
353 
354  for (i = 0; i < nvariables; ++i)
355  {
356  m_fields[i]->FwdTrans(m_fields[i]->GetPhys(),
357  m_fields[i]->UpdateCoeffs());
358  }
359 }
360 
361 /**
362  * @brief Get the normal velocity for the linear advection equation.
363  */
365 {
366  // Number of trace (interface) points
367  int i;
368  int nTracePts = GetTraceNpoints();
369 
370  // Auxiliary variable to compute the normal velocity
371  Array<OneD, NekDouble> tmp(nTracePts);
372 
373  // Reset the normal velocity
374  Vmath::Zero(nTracePts, m_traceVn, 1);
375 
376  for (i = 0; i < m_velocity.size(); ++i)
377  {
378  m_fields[0]->ExtractTracePhys(m_velocity[i], tmp);
379 
380  Vmath::Vvtvp(nTracePts, m_traceNormals[i], 1, tmp, 1, m_traceVn, 1,
381  m_traceVn, 1);
382  }
383 
384  return m_traceVn;
385 }
386 
387 /**
388  * @brief Compute the right-hand side for the linear advection equation.
389  *
390  * @param inarray Given fields.
391  * @param outarray Calculated solution.
392  * @param time Time.
393  */
395  const Array<OneD, const Array<OneD, NekDouble>> &inarray,
396  Array<OneD, Array<OneD, NekDouble>> &outarray, const NekDouble time)
397 {
398  boost::ignore_unused(time);
399 
400  int i;
401  int nvariables = inarray.size();
402  int npoints = GetNpoints();
403 
404  switch (m_projectionType)
405  {
407  {
408  int ncoeffs = inarray[0].size();
409 
410  if (m_spacedim == 3)
411  {
412  Array<OneD, Array<OneD, NekDouble>> WeakAdv(nvariables);
413 
414  WeakAdv[0] = Array<OneD, NekDouble>(ncoeffs * nvariables);
415  for (i = 1; i < nvariables; ++i)
416  {
417  WeakAdv[i] = WeakAdv[i - 1] + ncoeffs;
418  }
419 
420  // Compute \nabla \cdot \vel u according to MMF scheme
421  WeakDGDirectionalAdvection(inarray, WeakAdv);
422 
423  for (i = 0; i < nvariables; ++i)
424  {
425  m_fields[i]->MultiplyByElmtInvMass(WeakAdv[i], WeakAdv[i]);
426  m_fields[i]->BwdTrans(WeakAdv[i], outarray[i]);
427 
428  // Add m_vellc * inarray[i] = \nabla v^m \cdot e^m to
429  // outarray[i]
430  // Vmath::Vvtvp(npoints, &m_vellc[0], 1, &inarray[i][0], 1,
431  // &outarray[i][0], 1, &outarray[i][0], 1);
432  Vmath::Neg(npoints, outarray[i], 1);
433  }
434  }
435  else
436  {
437  m_advObject->Advect(2, m_fields, m_velocity, inarray, outarray,
438  0.0);
439 
440  for (i = 0; i < nvariables; ++i)
441  {
442  Vmath::Neg(npoints, outarray[i], 1);
443  }
444  }
445  }
446  break;
447 
448  default:
449  {
450  ASSERTL0(false, "Unknown projection scheme");
451  }
452  break;
453  }
454 }
455 /**
456  * @brief Compute the projection for the linear advection equation.
457  *
458  * @param inarray Given fields.
459  * @param outarray Calculated solution.
460  * @param time Time.
461  */
463  const Array<OneD, const Array<OneD, NekDouble>> &inarray,
464  Array<OneD, Array<OneD, NekDouble>> &outarray, const NekDouble time)
465 {
466  // Counter variable
467  int i;
468 
469  // Number of fields (variables of the problem)
470  int nVariables = inarray.size();
471 
472  // Set the boundary conditions
473  SetBoundaryConditions(time);
474 
475  // Switch on the projection type (Discontinuous or Continuous)
476  switch (m_projectionType)
477  {
478  // Discontinuous projection
480  {
481  // Number of quadrature points
482  int nQuadraturePts = GetNpoints();
483 
484  // Just copy over array
485  for (i = 0; i < nVariables; ++i)
486  {
487  Vmath::Vcopy(nQuadraturePts, inarray[i], 1, outarray[i], 1);
488  }
489  break;
490  }
491 
492  // Continuous projection
495  {
496  Array<OneD, NekDouble> coeffs(m_fields[0]->GetNcoeffs(), 0.0);
497  for (i = 0; i < nVariables; ++i)
498  {
499  m_fields[i]->FwdTrans(inarray[i], coeffs);
500  m_fields[i]->BwdTrans(coeffs, outarray[i]);
501  }
502  break;
503  }
504 
505  default:
506  ASSERTL0(false, "Unknown projection scheme");
507  break;
508  }
509 }
510 
511 /**
512  * @brief Return the flux vector for the linear advection equation.
513  *
514  * @param i Component of the flux vector to calculate.
515  * @param physfield Fields.
516  * @param flux Resulting flux.
517  */
519  const Array<OneD, Array<OneD, NekDouble>> &physfield,
521 {
522  ASSERTL1(flux[0].size() == m_velocity.size(),
523  "Dimension of flux array and velocity array do not match");
524 
525  int i, j;
526  int nq = physfield[0].size();
527 
528  for (i = 0; i < flux.size(); ++i)
529  {
530  for (j = 0; j < flux[0].size(); ++j)
531  {
532  Vmath::Vmul(nq, physfield[i], 1, m_velocity[j], 1, flux[i][j], 1);
533  }
534  }
535 }
536 
538  const Array<OneD, Array<OneD, NekDouble>> &InField,
539  Array<OneD, Array<OneD, NekDouble>> &OutField)
540 {
541  int i, j;
542  int ncoeffs = GetNcoeffs();
543  int nTracePointsTot = GetTraceNpoints();
544  int nvariables = m_fields.size();
545 
546  Array<OneD, Array<OneD, NekDouble>> physfield(nvariables);
547 
548  // Get the variables in physical space
549  // already in physical space
550  for (i = 0; i < nvariables; ++i)
551  {
552  physfield[i] = InField[i];
553  }
554 
556  for (i = 0; i < nvariables; ++i)
557  {
558  for (j = 0; j < m_shapedim; ++j)
559  {
560  WeakDeriv[j] = Array<OneD, NekDouble>(ncoeffs, 0.0);
561 
562  // Directional derivation with respect to the j'th moving frame
563  // tmp[j] = \nabla \physfield[i] \cdot \mathbf{e}^j
564  // Implemented at TriExp::v_IProductWRTDirectionalDerivBase_SumFa
565  m_fields[0]->IProductWRTDirectionalDerivBase(
566  m_movingframes[j], physfield[i], WeakDeriv[j]);
567  }
568 
569  // Get the numerical flux and add to the modal coeffs
570  // if the NumericalFluxs function already includes the
571  // normal in the output
572 
573  Array<OneD, NekDouble> Fwd(nTracePointsTot);
574  Array<OneD, NekDouble> Bwd(nTracePointsTot);
575 
576  Array<OneD, NekDouble> flux(nTracePointsTot, 0.0);
577  Array<OneD, NekDouble> fluxFwd(nTracePointsTot);
578  Array<OneD, NekDouble> fluxBwd(nTracePointsTot);
579 
580  // Evaluate numerical flux in physical space which may in
581  // general couple all component of vectors
582  m_fields[i]->GetFwdBwdTracePhys(physfield[i], Fwd, Bwd);
583 
584  // evaulate upwinded m_fields[i]
585  m_fields[i]->GetTrace()->Upwind(m_traceVn, Fwd, Bwd, flux);
586 
587  OutField[i] = Array<OneD, NekDouble>(ncoeffs, 0.0);
588  for (j = 0; j < m_shapedim; ++j)
589  {
590  // calculate numflux = (n \cdot MF)*flux
591  Vmath::Vmul(nTracePointsTot, &flux[0], 1, &m_ncdotMFFwd[j][0], 1,
592  &fluxFwd[0], 1);
593  Vmath::Vmul(nTracePointsTot, &flux[0], 1, &m_ncdotMFBwd[j][0], 1,
594  &fluxBwd[0], 1);
595  Vmath::Neg(ncoeffs, WeakDeriv[j], 1);
596 
597  // FwdBwdtegral because generallize (N \cdot MF)_{FWD} \neq -(N
598  // \cdot MF)_{BWD}
599  m_fields[i]->AddFwdBwdTraceIntegral(fluxFwd, fluxBwd, WeakDeriv[j]);
600  m_fields[i]->SetPhysState(false);
601 
602  Vmath::Vadd(ncoeffs, &WeakDeriv[j][0], 1, &OutField[i][0], 1,
603  &OutField[i][0], 1);
604  }
605  }
606 }
607 
609  Array<OneD, Array<OneD, NekDouble>> &velocity)
610 {
611  int nq = m_fields[0]->GetNpoints();
612 
613  NekDouble vel_phi, vel_theta, sin_varphi, cos_varphi, sin_theta, cos_theta;
614  NekDouble x0j, x1j, x2j;
615 
616  Array<OneD, NekDouble> x0(nq);
617  Array<OneD, NekDouble> x1(nq);
618  Array<OneD, NekDouble> x2(nq);
619 
620  m_fields[0]->GetCoords(x0, x1, x2);
621 
622  // theta = a*sin(z/r), phi = a*tan(y/x);
623  for (int j = 0; j < nq; j++)
624  {
625  x0j = x0[j];
626  x1j = x1[j];
627  x2j = x2[j];
628 
629  CartesianToSpherical(x0j, x1j, x2j, sin_varphi, cos_varphi, sin_theta,
630  cos_theta);
631 
632  vel_phi = m_waveFreq * (cos_theta * cos(m_RotAngle) +
633  sin_theta * cos_varphi * sin(m_RotAngle));
634  vel_theta = -1.0 * m_waveFreq * sin_theta * sin(m_RotAngle);
635 
636  velocity[0][j] =
637  -1.0 * vel_phi * sin_varphi - vel_theta * sin_theta * cos_varphi;
638  velocity[1][j] =
639  vel_phi * cos_varphi - vel_theta * sin_theta * sin_varphi;
640  velocity[2][j] = vel_theta * cos_theta;
641  }
642 
643  // Project the veloicty on the tangent plane
644 
645  if (m_VelProjection)
646  {
647  // Check MovingFrames \cdot SurfaceNormals = 0
649 
653 
654  for (int k = 0; k < m_spacedim; ++k)
655  {
656  newvelocity[k] = Array<OneD, NekDouble>(nq);
657  MF1[k] = Array<OneD, NekDouble>(nq);
658  MF2[k] = Array<OneD, NekDouble>(nq);
659  SN[k] = Array<OneD, NekDouble>(nq);
660 
661  Vmath::Vcopy(nq, &m_movingframes[0][k * nq], 1, &MF1[k][0], 1);
662  Vmath::Vcopy(nq, &m_movingframes[1][k * nq], 1, &MF2[k][0], 1);
663  }
664 
665  VectorCrossProd(MF1, MF2, SN);
666  GramSchumitz(SN, m_velocity, newvelocity, true);
667 
668  Array<OneD, NekDouble> tmp(nq, 0.0);
670 
671  for (int k = 0; k < m_spacedim; ++k)
672  {
673  Vmath::Vsub(nq, &m_velocity[0][0], 1, &newvelocity[0][0], 1,
674  &tmp[0], 1);
675  Vmath::Vmul(nq, &tmp[0], 1, &tmp[0], 1, &tmp[0], 1);
676  Vmath::Vadd(nq, tmp, 1, Projection, 1, Projection, 1);
677  }
678 
679  std::cout
680  << "Velocity vector is projected onto the tangent plane: Diff = "
681  << RootMeanSquare(Projection) << std::endl;
682 
683  for (int k = 0; k < m_spacedim; ++k)
684  {
685  Vmath::Vcopy(nq, &newvelocity[k][0], 1, &m_velocity[k][0], 1);
686  }
687  }
688 }
689 
690 /*
691 void MMFAdvection::EvaluateAdvectionVelocity(Array<OneD, Array<OneD, NekDouble>
692 > &velocity)
693  {
694  int nq = m_fields[0]->GetNpoints();
695 
696  NekDouble vel_phi, sin_phi, cos_phi;
697  NekDouble vel_theta, sin_theta, cos_theta;
698  NekDouble radius, xyrad, Tol = 0.00001;
699 
700  Array<OneD,NekDouble> x0(nq);
701  Array<OneD,NekDouble> x1(nq);
702  Array<OneD,NekDouble> x2(nq);
703 
704  m_fields[0]->GetCoords(x0,x1,x2);
705 
706  // theta = a*sin(z/r), phi = a*tan(y/x);
707  for (int j = 0; j < nq; j++)
708  {
709  switch(m_surfaceType)
710  {
711  case SolverUtils::eSphere:
712  case SolverUtils::eTRSphere:
713  {
714  radius = sqrt( x0[j]*x0[j] + x1[j]*x1[j] + x2[j]*x2[j] );
715  }
716  break;
717 
718  case SolverUtils::eIrregular:
719  {
720  radius = sqrt( 2.0*x0[j]*x0[j] + x1[j]*x1[j]*x1[j]*x1[j] +
721 x1[j]*x1[j]
722  + x2[j]*x2[j]*x2[j]*x2[j] + x2[j]*x2[j] );
723  }
724  break;
725 
726  // 2 x^2 + 2(y^4 - y ) + z^4 + z^2 = 2.0
727  case SolverUtils::eNonconvex:
728  {
729  radius = sqrt( 2.0*x0[j]*x0[j] + 2.0*( x1[j]*x1[j]*x1[j]*x1[j] -
730 x1[j]*x1[j] )
731  + x2[j]*x2[j]*x2[j]*x2[j] + x2[j]*x2[j] );
732  }
733  break;
734 
735  default:
736  break;
737  }
738 
739  // At North and South poles, (ax,ay,ax) = (0, Omega_f*sin(alpha),0)
740  if( fabs(fabs(x2[j]) - radius) < Tol )
741  {
742  sin_theta = x2[j]/radius;
743 
744  velocity[0][j] = 0.0;
745  velocity[1][j] = 0.0;
746  velocity[2][j] = 0.0;
747  }
748  else
749  {
750  // Compute the arc length of the trajectory
751  NekDouble zp, velmag0, velmag, length0, zcutoff=0.0, zmax;
752 
753  zp = fabs(x2[j]);
754 
755  zmax = Vmath::Vmax(nq, x2, 1);
756  velmag = ComputeCirculatingArclength(x2[j], radius*radius);
757 
758  switch(m_surfaceType)
759  {
760 
761  case SolverUtils::eSphere:
762  case SolverUtils::eTRSphere:
763  {
764  zcutoff = 0.7;
765  velmag0 = velmag;
766  }
767  break;
768 
769  case SolverUtils::eIrregular:
770  {
771  zcutoff = 0.7;
772  length0 = 0.88;
773  // velmag0 = length0*( 1.0 - (zp -
774 zcutoff)/(1.0-zcutoff) );
775  velmag0 = (length0/(zcutoff*zcutoff-zmax*zmax))*( zp*zp -
776 zmax*zmax);
777  }
778  break;
779 
780  case SolverUtils::eNonconvex:
781  {
782  zcutoff = 0.7;
783  length0 = 1.21;
784  // velmag0 = length0*( 1.0 - (zp -
785 zcutoff)/(1.0-zcutoff) );
786  velmag0 = (length0/(zcutoff*zcutoff - 1.0))*( zp*zp -
787 1.0);
788  }
789  break;
790 
791  default:
792  break;
793  }
794 
795  if( zp > zcutoff )
796  {
797  velmag = velmag0;
798  }
799 
800  vel_phi = m_waveFreq*velmag;
801  vel_theta = 0.0;
802 
803  xyrad = sqrt( x0[j]*x0[j] + x1[j]*x1[j] );
804  if(xyrad<Tol)
805  {
806  sin_phi = 0.0;
807  cos_phi = 0.0;
808  }
809 
810  else
811  {
812  sin_phi = x1[j]/xyrad;
813  cos_phi = x0[j]/xyrad;
814  }
815 
816  // sin_theta = x2[j]/radius;
817  cos_theta = sqrt( x0[j]*x0[j] + x1[j]*x1[j] )/radius;
818 
819  if(fabs(velmag) < 0.001)
820  {
821  velocity[0][j] = 0.0 ;
822  velocity[1][j] = 0.0 ;
823  velocity[2][j] = 0.0;
824  }
825 
826  else
827  {
828  velocity[0][j] = -1.0*vel_phi*sin_phi ;
829  velocity[1][j] = vel_phi*cos_phi ;
830  velocity[2][j] = 0.0;
831  }
832 
833  } // else-loop
834  }
835 
836  // Project the veloicty on the tangent plane
837  int nq = m_fields[0]->GetNpoints();
838 
839  // Check MovingFrames \cdot SurfaceNormals = 0
840  Array<OneD, NekDouble> temp0(nq,0.0);
841  Array<OneD, NekDouble> temp1(nq,0.0);
842  Array<OneD, Array<OneD, NekDouble> > newvelocity(m_spacedim);
843 
844  for(int k=0; k<m_spacedim; ++k)
845  {
846  newvelocity[k] = Array<OneD, NekDouble>(nq);
847  }
848 
849  std::cout <<"=====================================================" <<
850 std::endl;
851  std::cout << "Velocity vector is projected onto the tangent plane " <<
852 std::endl;
853  std::cout <<"=====================================================" <<
854 std::endl;
855  GramSchumitz(m_surfaceNormal, m_velocity, newvelocity);
856 
857  for(int k=0; k<m_spacedim; ++k)
858  {
859  Vmath::Vcopy(nq, &newvelocity[k][0], 1, &m_velocity[k][0], 1);
860  }
861  }
862 
863 */
864 
866  const NekDouble Rhs)
867 {
868 
869  NekDouble Tol = 0.0001, Maxiter = 1000, N = 100;
870  NekDouble newy, F = 0.0, dF = 1.0, y0, tmp;
871 
872  Array<OneD, NekDouble> xp(N + 1);
873  Array<OneD, NekDouble> yp(N + 1);
874 
875  NekDouble intval = 0.0;
876  switch (m_surfaceType)
877  {
880  {
881  intval = sqrt(Rhs - zlevel * zlevel);
882  }
883  break;
884 
886  {
887  intval = sqrt(0.5 * (Rhs - zlevel * zlevel * zlevel * zlevel -
888  zlevel * zlevel));
889  }
890  break;
891 
893  {
894  tmp = 0.5 *
895  (Rhs - zlevel * zlevel * zlevel * zlevel - zlevel * zlevel);
896  intval = sqrt(0.5 * (1.0 + sqrt(1.0 + 4.0 * tmp)));
897  }
898  break;
899 
900  default:
901  break;
902  }
903 
904  switch (m_surfaceType)
905  {
906  // Find the half of all the xp and yp on zlevel ....
910  {
911  for (int j = 0; j < N + 1; ++j)
912  {
913  xp[j] = j * 2.0 * intval / N - intval;
914 
915  y0 = 1.0;
916  for (int i = 0; i < Maxiter; ++i)
917  {
918  switch (m_surfaceType)
919  {
920  // Find the half of all the xp and yp on zlevel ....
923  {
924  F = xp[j] * xp[j] + y0 * y0 + zlevel * zlevel - Rhs;
925  dF = 2.0 * y0;
926  }
927  break;
928 
930  {
931  F = 2.0 * xp[j] * xp[j] + y0 * y0 * y0 * y0 +
932  y0 * y0 + zlevel * zlevel * zlevel * zlevel +
933  zlevel * zlevel - Rhs;
934  dF = 4.0 * y0 * y0 * y0 + 2.0 * y0;
935  }
936  break;
937 
938  default:
939  break;
940  }
941 
942  newy = y0 - F / dF;
943 
944  if (fabs(F / dF) < Tol)
945  {
946  yp[j] = newy;
947  break;
948  }
949 
950  else
951  {
952  y0 = newy;
953  }
954 
955  ASSERTL0(i < Maxiter,
956  "Advection Velocity convergence fails");
957 
958  } // i-loop
959  }
960  }
961  break;
962 
964  {
965  for (int j = 0; j < N + 1; ++j)
966  {
967  xp[j] = j * 2.0 * intval / N - intval;
968  tmp = 0.5 * Rhs -
969  0.5 * (zlevel * zlevel * zlevel * zlevel +
970  zlevel * zlevel) -
971  (xp[j] * xp[j] * xp[j] * xp[j] - xp[j] * xp[j]);
972  if (tmp < 0)
973  {
974  tmp = -1.0 * tmp;
975  }
976  yp[j] = sqrt(tmp);
977  } // j-loop
978  }
979  break;
980 
981  default:
982  break;
983 
984  } // switch-loop
985 
986  NekDouble pi = 3.14159265358979323846;
987  NekDouble arclength = 0.0;
988  for (int j = 0; j < N; ++j)
989  {
990  arclength =
991  arclength + sqrt((yp[j + 1] - yp[j]) * (yp[j + 1] - yp[j]) +
992  (xp[j + 1] - xp[j]) * (xp[j + 1] - xp[j])) /
993  pi;
994  }
995 
996  return arclength;
997 }
998 
1000  bool dumpInitialConditions,
1001  const int domain)
1002 {
1003  boost::ignore_unused(domain);
1004 
1005  int nq = m_fields[0]->GetNpoints();
1006 
1007  Array<OneD, NekDouble> u(nq);
1008 
1009  switch (m_TestType)
1010  {
1011  case eAdvectionBell:
1012  {
1014  m_fields[0]->SetPhys(u);
1015 
1016  m_Mass0 = m_fields[0]->Integral(u);
1017 
1018  // forward transform to fill the modal coeffs
1019  for (int i = 0; i < m_fields.size(); ++i)
1020  {
1021  m_fields[i]->SetPhysState(true);
1022  m_fields[i]->FwdTrans(m_fields[i]->GetPhys(),
1023  m_fields[i]->UpdateCoeffs());
1024  }
1025  }
1026  break;
1027 
1028  case eTestPlane:
1029  {
1030  Test2Dproblem(initialtime, u);
1031  m_fields[0]->SetPhys(u);
1032 
1033  m_Mass0 = m_fields[0]->Integral(u);
1034 
1035  // forward transform to fill the modal coeffs
1036  for (int i = 0; i < m_fields.size(); ++i)
1037  {
1038  m_fields[i]->SetPhysState(true);
1039  m_fields[i]->FwdTrans(m_fields[i]->GetPhys(),
1040  m_fields[i]->UpdateCoeffs());
1041  }
1042  }
1043  break;
1044 
1045  case eTestPlaneMassConsv:
1046  {
1047  AdvectionBellPlane(u);
1048  m_fields[0]->SetPhys(u);
1049 
1050  m_Mass0 = m_fields[0]->Integral(u);
1051  std::cout << "m_Mass0 = " << m_Mass0 << std::endl;
1052 
1053  // forward transform to fill the modal coeffs
1054  for (int i = 0; i < m_fields.size(); ++i)
1055  {
1056  m_fields[i]->SetPhysState(true);
1057  m_fields[i]->FwdTrans(m_fields[i]->GetPhys(),
1058  m_fields[i]->UpdateCoeffs());
1059  }
1060  }
1061  break;
1062 
1063  case eTestCube:
1064  {
1065  Test3Dproblem(initialtime, u);
1066  m_fields[0]->SetPhys(u);
1067 
1068  // forward transform to fill the modal coeffs
1069  for (int i = 0; i < m_fields.size(); ++i)
1070  {
1071  m_fields[i]->SetPhysState(true);
1072  m_fields[i]->FwdTrans(m_fields[i]->GetPhys(),
1073  m_fields[i]->UpdateCoeffs());
1074  }
1075  }
1076  break;
1077 
1078  default:
1079  break;
1080  }
1081 
1082  if (dumpInitialConditions)
1083  {
1084  // dump initial conditions to file
1085  std::string outname = m_sessionName + "_initial.chk";
1086  WriteFld(outname);
1087  }
1088 }
1089 
1091 {
1092  int nq = m_fields[0]->GetNpoints();
1093 
1094  NekDouble dist, m_radius_limit;
1095 
1096  Array<OneD, NekDouble> x(nq);
1097  Array<OneD, NekDouble> y(nq);
1098  Array<OneD, NekDouble> z(nq);
1099 
1100  m_fields[0]->GetCoords(x, y, z);
1101 
1102  // Sets of parameters
1103  m_radius_limit = 0.5;
1104 
1105  NekDouble x0j, x1j;
1106  outfield = Array<OneD, NekDouble>(nq, 0.0);
1107  for (int j = 0; j < nq; ++j)
1108  {
1109  x0j = x[j];
1110  x1j = y[j];
1111 
1112  dist = sqrt(x0j * x0j + x1j * x1j);
1113 
1114  if (dist < m_radius_limit)
1115  {
1116  outfield[j] = 0.5 * (1.0 + cos(m_pi * dist / m_radius_limit));
1117  }
1118  else
1119  {
1120  outfield[j] = 0.0;
1121  }
1122  }
1123 }
1124 
1126 {
1127  int nq = m_fields[0]->GetNpoints();
1128 
1129  NekDouble dist, radius, cosdiff, sin_theta, cos_theta, sin_varphi,
1130  cos_varphi;
1131  NekDouble m_theta_c, m_varphi_c, m_radius_limit, m_c0;
1132 
1133  Array<OneD, NekDouble> x(nq);
1134  Array<OneD, NekDouble> y(nq);
1135  Array<OneD, NekDouble> z(nq);
1136 
1137  m_fields[0]->GetCoords(x, y, z);
1138 
1139  // Sets of parameters
1140  m_theta_c = 0.0;
1141  m_varphi_c = 3.0 * m_pi / 2.0;
1142  m_radius_limit = 7.0 * m_pi / 64.0;
1143  m_c0 = 0.0;
1144 
1145  NekDouble x0j, x1j, x2j;
1146  outfield = Array<OneD, NekDouble>(nq, 0.0);
1147  for (int j = 0; j < nq; ++j)
1148  {
1149  x0j = x[j];
1150  x1j = y[j];
1151  x2j = z[j];
1152 
1153  radius = sqrt(x0j * x0j + x1j * x1j + x2j * x2j);
1154 
1155  sin_varphi = x1j / sqrt(x0j * x0j + x1j * x1j);
1156  cos_varphi = x0j / sqrt(x0j * x0j + x1j * x1j);
1157 
1158  sin_theta = x2j / radius;
1159  cos_theta = sqrt(x0j * x0j + x1j * x1j) / radius;
1160 
1161  cosdiff = cos_varphi * cos(m_varphi_c) + sin_varphi * sin(m_varphi_c);
1162  dist = radius * acos(sin(m_theta_c) * sin_theta +
1163  cos(m_theta_c) * cos_theta * cosdiff);
1164 
1165  if (dist < m_radius_limit)
1166  {
1167  outfield[j] =
1168  0.5 * (1.0 + cos(m_pi * dist / m_radius_limit)) + m_c0;
1169  }
1170  else
1171  {
1172  outfield[j] = m_c0;
1173  }
1174  }
1175 }
1176 
1178  Array<OneD, NekDouble> &outfield)
1179 {
1180  int nq = m_fields[0]->GetNpoints();
1181 
1182  Array<OneD, NekDouble> x0(nq);
1183  Array<OneD, NekDouble> x1(nq);
1184  Array<OneD, NekDouble> x2(nq);
1185 
1186  m_fields[0]->GetCoords(x0, x1, x2);
1187 
1188  Array<OneD, NekDouble> u(nq);
1189 
1190  for (int i = 0; i < nq; ++i)
1191  {
1192  u[i] = cos(m_pi * (x0[i] - m_advx * time)) *
1193  cos(m_pi * (x1[i] - m_advy * time));
1194  }
1195 
1196  outfield = u;
1197 }
1198 
1200  Array<OneD, NekDouble> &outfield)
1201 {
1202  int nq = m_fields[0]->GetNpoints();
1203 
1204  Array<OneD, NekDouble> x0(nq);
1205  Array<OneD, NekDouble> x1(nq);
1206  Array<OneD, NekDouble> x2(nq);
1207 
1208  m_fields[0]->GetCoords(x0, x1, x2);
1209 
1210  Array<OneD, NekDouble> u(nq);
1211 
1212  for (int i = 0; i < nq; ++i)
1213  {
1214  u[i] = cos(m_pi * (x0[i] - m_advx * time)) *
1215  cos(m_pi * (x1[i] - m_advy * time)) *
1216  cos(m_pi * (x2[i] - m_advz * time));
1217  }
1218 
1219  outfield = u;
1220 }
1221 
1223 {
1224  int nq = m_fields[0]->GetNpoints();
1225 
1226  Array<OneD, NekDouble> velcoeff(nq, 0.0);
1227 
1228  Array<OneD, NekDouble> Dtmp0(nq);
1229  Array<OneD, NekDouble> Dtmp1(nq);
1230  Array<OneD, NekDouble> Dtmp2(nq);
1231  Array<OneD, NekDouble> Drv(nq);
1232 
1233  vellc = Array<OneD, NekDouble>(nq, 0.0);
1234 
1235  // m_vellc = \nabla m_vel \cdot tan_i
1236  Array<OneD, NekDouble> tmp(nq);
1237  Array<OneD, NekDouble> vessel(nq);
1238 
1239  for (int j = 0; j < m_shapedim; ++j)
1240  {
1241  Vmath::Zero(nq, velcoeff, 1);
1242  for (int k = 0; k < m_spacedim; ++k)
1243  {
1244  // a_j = tan_j cdot m_vel
1245  Vmath::Vvtvp(nq, &m_movingframes[j][k * nq], 1, &m_velocity[k][0],
1246  1, &velcoeff[0], 1, &velcoeff[0], 1);
1247  }
1248 
1249  // d a_j / d x^k
1250  m_fields[0]->PhysDeriv(velcoeff, Dtmp0, Dtmp1, Dtmp2);
1251 
1252  for (int k = 0; k < m_spacedim; ++k)
1253  {
1254  // tan_j^k ( d a_j / d x^k )
1255  switch (k)
1256  {
1257  case (0):
1258  {
1259  Vmath::Vvtvp(nq, &Dtmp0[0], 1, &m_movingframes[j][k * nq],
1260  1, &vellc[0], 1, &vellc[0], 1);
1261  }
1262  break;
1263 
1264  case (1):
1265  {
1266  Vmath::Vvtvp(nq, &Dtmp1[0], 1, &m_movingframes[j][k * nq],
1267  1, &vellc[0], 1, &vellc[0], 1);
1268  }
1269  break;
1270 
1271  case (2):
1272  {
1273  Vmath::Vvtvp(nq, &Dtmp2[0], 1, &m_movingframes[j][k * nq],
1274  1, &vellc[0], 1, &vellc[0], 1);
1275  }
1276  break;
1277  }
1278  }
1279  }
1280 }
1281 
1283  Array<OneD, Array<OneD, NekDouble>> &veldotMF)
1284 {
1285  int nq = m_fields[0]->GetNpoints();
1286 
1288 
1289  Array<OneD, NekDouble> magMF(nq);
1290  for (int j = 0; j < m_shapedim; ++j)
1291  {
1292  veldotMF[j] = Array<OneD, NekDouble>(nq, 0.0);
1293 
1294  for (int k = 0; k < m_spacedim; ++k)
1295  {
1296  Vmath::Vvtvp(nq, &m_movingframes[j][k * nq], 1, &m_velocity[k][0],
1297  1, &veldotMF[j][0], 1, &veldotMF[j][0], 1);
1298  }
1299  }
1300 }
1301 
1303  Array<OneD, NekDouble> &outfield,
1304  const NekDouble time)
1305 {
1306  boost::ignore_unused(field);
1307 
1308  switch (m_TestType)
1309  {
1310  case eAdvectionBell:
1311  {
1312  AdvectionBellSphere(outfield);
1313  }
1314  break;
1315 
1316  case eTestPlane:
1317  {
1318  Test2Dproblem(time, outfield);
1319  }
1320  break;
1321 
1322  case eTestPlaneMassConsv:
1323  {
1324  AdvectionBellPlane(outfield);
1325  }
1326  break;
1327 
1328  case eTestCube:
1329  {
1330  Test3Dproblem(time, outfield);
1331  }
1332  break;
1333 
1334  default:
1335  break;
1336  }
1337 }
1338 
1340 {
1343  SolverUtils::AddSummaryItem(s, "Rotation Angle", m_RotAngle);
1344 }
1345 } // namespace Nektar
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:249
@ eTestPlaneMassConsv
Definition: MMFAdvection.h:46
@ eAdvectionBell
Definition: MMFAdvection.h:48
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:198
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:144
void DefineProjection(FuncPointerT func, ObjectPointerT obj)
void DefineOdeRhs(FuncPointerT func, ObjectPointerT obj)
NekDouble TimePerTest(unsigned int n)
Returns amount of seconds per iteration in a test with n iterations.
Definition: Timer.cpp:68
void Test2Dproblem(const NekDouble time, Array< OneD, NekDouble > &outfield)
virtual ~MMFAdvection()
Destructor.
Array< OneD, Array< OneD, NekDouble > > m_veldotMF
Definition: MMFAdvection.h:98
void Test3Dproblem(const NekDouble time, Array< OneD, NekDouble > &outfield)
void AdvectionBellSphere(Array< OneD, NekDouble > &outfield)
NekDouble ComputeCirculatingArclength(const NekDouble zlevel, const NekDouble Rhs)
MMFAdvection(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
Session reader.
void ComputeNablaCdotVelocity(Array< OneD, NekDouble > &vellc)
void EvaluateAdvectionVelocity(Array< OneD, Array< OneD, NekDouble >> &velocity)
void DoOdeRhs(const Array< OneD, const Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, const NekDouble time)
Compute the RHS.
void DoOdeProjection(const Array< OneD, const Array< OneD, NekDouble >> &inarray, Array< OneD, Array< OneD, NekDouble >> &outarray, const NekDouble time)
Compute the projection.
void WeakDGDirectionalAdvection(const Array< OneD, Array< OneD, NekDouble >> &InField, Array< OneD, Array< OneD, NekDouble >> &OutField)
void GetFluxVector(const Array< OneD, Array< OneD, NekDouble >> &physfield, Array< OneD, Array< OneD, Array< OneD, NekDouble >>> &flux)
Evaluate the flux at each solution point.
virtual void v_SetInitialConditions(const NekDouble initialtime, bool dumpInitialConditions, const int domain) override
void ComputeveldotMF(Array< OneD, Array< OneD, NekDouble >> &veldotMF)
static SolverUtils::EquationSystemSharedPtr create(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
Creates an instance of this class.
Definition: MMFAdvection.h:68
virtual void v_GenerateSummary(SolverUtils::SummaryList &s) override
Print Summary.
virtual void v_InitObject(bool DeclareFields=true) override
Initialise the object.
SolverUtils::RiemannSolverSharedPtr m_riemannSolver
Definition: MMFAdvection.h:86
virtual void v_EvaluateExactSolution(unsigned int field, Array< OneD, NekDouble > &outfield, const NekDouble time) override
Array< OneD, Array< OneD, NekDouble > > m_velocity
Advection velocity.
Definition: MMFAdvection.h:95
Array< OneD, NekDouble > & GetNormalVelocity()
Get the normal velocity.
virtual void v_DoSolve() override
Solves an unsteady problem.
static std::string className
Name of class.
Definition: MMFAdvection.h:78
Array< OneD, NekDouble > m_vellc
Definition: MMFAdvection.h:99
void AdvectionBellPlane(Array< OneD, NekDouble > &outfield)
Array< OneD, NekDouble > m_traceVn
Definition: MMFAdvection.h:96
A base class for PDEs which include an advection component.
SolverUtils::AdvectionSharedPtr m_advObject
Advection term.
int m_spacedim
Spatial dimension (>= expansion dim).
SOLVER_UTILS_EXPORT int GetTraceNpoints()
NekDouble m_timestep
Time step size.
int m_infosteps
Number of time steps between outputting status information.
NekDouble m_time
Current time of simulation.
Array< OneD, MultiRegions::ExpListSharedPtr > m_fields
Array holding all dependent variables.
NekDouble m_fintime
Finish time of the simulation.
SOLVER_UTILS_EXPORT void Checkpoint_Output(const int n)
Write checkpoint file of m_fields.
NekDouble m_checktime
Time between checkpoints.
SOLVER_UTILS_EXPORT void WriteFld(const std::string &outname)
Write field data to the given filename.
std::string m_sessionName
Name of the session.
LibUtilities::SessionReaderSharedPtr m_session
The session reader.
Array< OneD, Array< OneD, NekDouble > > m_traceNormals
Array holding trace normals for DG simulations in the forwards direction.
SOLVER_UTILS_EXPORT int GetNpoints()
SOLVER_UTILS_EXPORT int GetNcoeffs()
enum MultiRegions::ProjectionType m_projectionType
Type of projection; e.g continuous or discontinuous.
int m_steps
Number of steps to take.
SOLVER_UTILS_EXPORT void SetBoundaryConditions(NekDouble time)
Evaluates the boundary conditions at the given time.
int m_checksteps
Number of steps between checkpoints.
SOLVER_UTILS_EXPORT SessionFunctionSharedPtr GetFunction(std::string name, const MultiRegions::ExpListSharedPtr &field=MultiRegions::NullExpListSharedPtr, bool cache=false)
Get a SessionFunction by name.
A base class for PDEs which include an advection component.
Definition: MMFSystem.h:147
SOLVER_UTILS_EXPORT void GramSchumitz(const Array< OneD, const Array< OneD, NekDouble >> &v1, const Array< OneD, const Array< OneD, NekDouble >> &v2, Array< OneD, Array< OneD, NekDouble >> &outarray, bool KeepTheMagnitude=true)
Definition: MMFSystem.cpp:2405
SOLVER_UTILS_EXPORT void VectorCrossProd(const Array< OneD, const Array< OneD, NekDouble >> &v1, const Array< OneD, const Array< OneD, NekDouble >> &v2, Array< OneD, Array< OneD, NekDouble >> &v3)
Definition: MMFSystem.cpp:699
virtual SOLVER_UTILS_EXPORT void v_GenerateSummary(SummaryList &s) override
Print a summary of time stepping parameters.
Definition: MMFSystem.cpp:2469
SOLVER_UTILS_EXPORT NekDouble AvgInt(const Array< OneD, const NekDouble > &inarray)
Definition: MMFSystem.cpp:2298
Array< OneD, Array< OneD, NekDouble > > m_movingframes
Definition: MMFSystem.h:186
SOLVER_UTILS_EXPORT void MMFInitObject(const Array< OneD, const Array< OneD, NekDouble >> &Anisotropy, const int TangentXelem=-1)
Definition: MMFSystem.cpp:53
Array< OneD, Array< OneD, NekDouble > > m_ncdotMFBwd
Definition: MMFSystem.h:190
SOLVER_UTILS_EXPORT void ComputencdotMF()
Definition: MMFSystem.cpp:320
SOLVER_UTILS_EXPORT void CartesianToSpherical(const NekDouble x0j, const NekDouble x1j, const NekDouble x2j, NekDouble &sin_varphi, NekDouble &cos_varphi, NekDouble &sin_theta, NekDouble &cos_theta)
Definition: MMFSystem.cpp:795
SOLVER_UTILS_EXPORT NekDouble RootMeanSquare(const Array< OneD, const NekDouble > &inarray)
Definition: MMFSystem.cpp:2344
Array< OneD, Array< OneD, NekDouble > > m_ncdotMFFwd
Definition: MMFSystem.h:189
Base class for unsteady solvers.
LibUtilities::TimeIntegrationSchemeOperators m_ode
The time integration scheme operators to use.
NekDouble m_cflSafetyFactor
CFL safety factor (comprise between 0 to 1).
LibUtilities::TimeIntegrationSchemeSharedPtr m_intScheme
Wrapper to the time integration scheme.
bool m_explicitAdvection
Indicates if explicit or implicit treatment of advection is used.
virtual SOLVER_UTILS_EXPORT void v_InitObject(bool DeclareField=true) override
Init object for UnsteadySystem class.
std::shared_ptr< SessionReader > SessionReaderSharedPtr
static const NekDouble kNekZeroTol
AdvectionFactory & GetAdvectionFactory()
Gets the factory for initialising advection objects.
Definition: Advection.cpp:47
std::vector< std::pair< std::string, std::string > > SummaryList
Definition: Misc.h:48
EquationSystemFactory & GetEquationSystemFactory()
void AddSummaryItem(SummaryList &l, const std::string &name, const std::string &value)
Adds a summary item to the summary info list.
Definition: Misc.cpp:49
RiemannSolverFactory & GetRiemannSolverFactory()
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:172
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
@ eTestPlane
Definition: MMFDiffusion.h:48
@ eTestCube
Definition: MMFDiffusion.h:49
@ SIZE_TestType
Length of enum list.
Definition: MMFDiffusion.h:55
const char *const TestTypeMap[]
Definition: MMFDiffusion.h:58
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:209
void Neg(int n, T *x, const int incx)
Negate x = -x.
Definition: Vmath.cpp:518
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:574
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:359
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:492
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1255
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:419
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294