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