Nektar++
Public Member Functions | Static Public Member Functions | Static Public Attributes | Protected Member Functions | Static Protected Attributes | Private Attributes | Friends | List of all members
Nektar::SolverUtils::DriverSteadyState Class Reference

#include <DriverSteadyState.h>

Inheritance diagram for Nektar::SolverUtils::DriverSteadyState:
[legend]

Public Member Functions

void PrintSummarySFD ()
 
void ConvergenceHistory (const Array< OneD, const Array< OneD, NekDouble >> &qBar1, const Array< OneD, const Array< OneD, NekDouble >> &q0, NekDouble &MaxNormDiff_q_qBar, NekDouble &MaxNormDiff_q1_q0)
 
void ComputeSFD (const int i, const Array< OneD, const Array< OneD, NekDouble >> &q0, const Array< OneD, const Array< OneD, NekDouble >> &qBar0, Array< OneD, Array< OneD, NekDouble >> &q1, Array< OneD, Array< OneD, NekDouble >> &qBar1)
 
void EvalEV_ScalarSFD (const NekDouble &X_input, const NekDouble &Delta_input, const std::complex< NekDouble > &alpha, NekDouble &MaxEV)
 
void GradientDescentMethod (const std::complex< NekDouble > &alpha, NekDouble &X_output, NekDouble &Delta_output)
 
void ReadEVfile (int &KrylovSubspaceDim, NekDouble &growthEV, NekDouble &frequencyEV)
 
void ComputeOptimization ()
 
void SetSFDOperator (const NekDouble X_input, const NekDouble Delta_input)
 
- Public Member Functions inherited from Nektar::SolverUtils::DriverArnoldi
SOLVER_UTILS_EXPORT void ArnoldiSummary (std::ostream &out)
 
SOLVER_UTILS_EXPORT const Array< OneD, const NekDouble > & GetMaskCoeff () const
 
SOLVER_UTILS_EXPORT const Array< OneD, const NekDouble > & GetMaskPhys () const
 
- Public Member Functions inherited from Nektar::SolverUtils::Driver
virtual ~Driver ()
 Destructor. More...
 
SOLVER_UTILS_EXPORT void InitObject (std::ostream &out=std::cout)
 Initialise Object. More...
 
SOLVER_UTILS_EXPORT void Execute (std::ostream &out=std::cout)
 Execute driver. More...
 
SOLVER_UTILS_EXPORT Array< OneD, EquationSystemSharedPtrGetEqu ()
 
SOLVER_UTILS_EXPORT Array< OneD, NekDoubleGetRealEvl (void)
 
SOLVER_UTILS_EXPORT Array< OneD, NekDoubleGetImagEvl (void)
 

Static Public Member Functions

static DriverSharedPtr create (const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
 Creates an instance of this class. More...
 
- Static Public Member Functions inherited from Nektar::SolverUtils::DriverModifiedArnoldi
static DriverSharedPtr create (const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
 Creates an instance of this class. More...
 

Static Public Attributes

static std::string className
 Name of the class. More...
 
- Static Public Attributes inherited from Nektar::SolverUtils::DriverModifiedArnoldi
static std::string className
 Name of the class. More...
 

Protected Member Functions

SOLVER_UTILS_EXPORT DriverSteadyState (const LibUtilities::SessionReaderSharedPtr pSession, const SpatialDomains::MeshGraphSharedPtr pGraph)
 Constructor. More...
 
virtual SOLVER_UTILS_EXPORT ~DriverSteadyState ()
 Destructor. More...
 
virtual SOLVER_UTILS_EXPORT void v_InitObject (std::ostream &out=std::cout) override
 Second-stage initialisation. More...
 
virtual SOLVER_UTILS_EXPORT void v_Execute (std::ostream &out=std::cout) override
 Virtual function for solve implementation. More...
 
- Protected Member Functions inherited from Nektar::SolverUtils::DriverModifiedArnoldi
 DriverModifiedArnoldi (const LibUtilities::SessionReaderSharedPtr pSession, const SpatialDomains::MeshGraphSharedPtr pGraph)
 Constructor. More...
 
virtual ~DriverModifiedArnoldi ()
 Destructor. More...
 
- Protected Member Functions inherited from Nektar::SolverUtils::DriverArnoldi
 DriverArnoldi (const LibUtilities::SessionReaderSharedPtr pSession, const SpatialDomains::MeshGraphSharedPtr pGraph)
 Constructor. More...
 
virtual ~DriverArnoldi ()
 Destructor. More...
 
void CopyArnoldiArrayToField (Array< OneD, NekDouble > &array)
 Copy Arnoldi storage to fields. More...
 
void CopyFieldToArnoldiArray (Array< OneD, NekDouble > &array)
 Copy fields to Arnoldi storage. More...
 
void CopyFwdToAdj ()
 Copy the forward field to the adjoint system in transient growth calculations. More...
 
void WriteFld (std::string file, std::vector< Array< OneD, NekDouble >> coeffs)
 Write coefficients to file. More...
 
void WriteFld (std::string file, Array< OneD, NekDouble > coeffs)
 
void WriteEvs (std::ostream &evlout, const int k, const NekDouble real, const NekDouble imag, NekDouble resid=NekConstants::kNekUnsetDouble, bool DumpInverse=true)
 
void MaskInit ()
 init mask More...
 
void GetUnmaskFunction (std::vector< std::vector< LibUtilities::EquationSharedPtr >> &unmaskfun)
 
virtual Array< OneD, NekDoublev_GetRealEvl (void) override
 
virtual Array< OneD, NekDoublev_GetImagEvl (void) override
 
- Protected Member Functions inherited from Nektar::SolverUtils::Driver
 Driver (const LibUtilities::SessionReaderSharedPtr pSession, const SpatialDomains::MeshGraphSharedPtr pGraph)
 Initialises EquationSystem class members. More...
 

Static Protected Attributes

static std::string driverLookupId
 
- Static Protected Attributes inherited from Nektar::SolverUtils::Driver
static std::string evolutionOperatorLookupIds []
 
static std::string evolutionOperatorDef
 
static std::string driverDefault
 

Private Attributes

int m_stepCounter
 
int m_Check
 
int m_Check_BaseFlow
 
NekDouble TOL
 
int m_infosteps
 
int m_checksteps
 
int NumVar_SFD
 
LibUtilities::Timer timer
 
NekDouble cpuTime
 
NekDouble totalTime
 
NekDouble elapsed
 
std::ofstream m_file
 
NekDouble m_Delta
 Definition of the SFD parameters: More...
 
NekDouble m_X
 
NekDouble m_dt
 
NekDouble M11
 Definition of the SFD operator. More...
 
NekDouble M12
 
NekDouble M21
 
NekDouble M22
 
NekDouble Diff_q_qBar
 
NekDouble Diff_q1_q0
 
bool FlowPartiallyConverged
 For adaptive SFD method. More...
 
NekDouble AdaptiveTOL
 
NekDouble AdaptiveTime
 
int m_NonConvergingStepsCounter
 
NekDouble GrowthRateEV
 
NekDouble FrequencyEV
 

Friends

class MemoryManager< DriverSteadyState >
 

Additional Inherited Members

- Protected Attributes inherited from Nektar::SolverUtils::DriverArnoldi
int m_kdim
 
int m_nvec
 Dimension of Krylov subspace. More...
 
int m_nits
 Number of vectors to test. More...
 
NekDouble m_evtol
 Maxmum number of iterations. More...
 
NekDouble m_period
 Tolerance of iteratiosn. More...
 
bool m_timeSteppingAlgorithm
 Period of time stepping algorithm. More...
 
int m_infosteps
 underlying operator is time stepping More...
 
int m_nfields
 interval to dump information if required. More...
 
NekDouble m_realShift
 
NekDouble m_imagShift
 
int m_negatedOp
 
Array< OneD, NekDoublem_real_evl
 Operator in solve call is negated. More...
 
Array< OneD, NekDoublem_imag_evl
 
bool m_useMask
 
Array< OneD, NekDoublem_maskCoeffs
 
Array< OneD, NekDoublem_maskPhys
 
- Protected Attributes inherited from Nektar::SolverUtils::Driver
LibUtilities::CommSharedPtr m_comm
 Communication object. More...
 
LibUtilities::SessionReaderSharedPtr m_session
 Session reader object. More...
 
LibUtilities::SessionReaderSharedPtr session_LinNS
 I the Coupling between SFD and arnoldi. More...
 
SpatialDomains::MeshGraphSharedPtr m_graph
 MeshGraph object. More...
 
Array< OneD, EquationSystemSharedPtrm_equ
 Equation system to solve. More...
 
int m_nequ
 number of equations More...
 
enum EvolutionOperatorType m_EvolutionOperator
 Evolution Operator. More...
 

Detailed Description

Definition at line 48 of file DriverSteadyState.h.

Constructor & Destructor Documentation

◆ DriverSteadyState()

Nektar::SolverUtils::DriverSteadyState::DriverSteadyState ( const LibUtilities::SessionReaderSharedPtr  pSession,
const SpatialDomains::MeshGraphSharedPtr  pGraph 
)
protected

Constructor.

Definition at line 58 of file DriverSteadyState.cpp.

61  : DriverModifiedArnoldi(pSession, pGraph)
62 {
63 }
DriverModifiedArnoldi(const LibUtilities::SessionReaderSharedPtr pSession, const SpatialDomains::MeshGraphSharedPtr pGraph)
Constructor.

◆ ~DriverSteadyState()

Nektar::SolverUtils::DriverSteadyState::~DriverSteadyState ( )
protectedvirtual

Destructor.

Definition at line 68 of file DriverSteadyState.cpp.

69 {
70 }

Member Function Documentation

◆ ComputeOptimization()

void Nektar::SolverUtils::DriverSteadyState::ComputeOptimization ( )

Definition at line 368 of file DriverSteadyState.cpp.

369 {
370  NekDouble growthEV(0.0);
371  NekDouble frequencyEV(0.0);
372 
373  // m_kdim is the dimension of Krylov subspace (defined in the xml file and
374  // used in DriverArnoldi.cpp)
375  ReadEVfile(m_kdim, growthEV, frequencyEV);
376 
377  cout << "\n\tgrowthEV = " << growthEV << endl;
378  cout << "\tfrequencyEV = " << frequencyEV << endl;
379 
380  complex<NekDouble> ApproxEV = polar(exp(growthEV), frequencyEV);
381 
382  NekDouble X_new = m_X;
383  NekDouble Delta_new = m_Delta;
384 
385  GradientDescentMethod(ApproxEV, X_new, Delta_new);
386 
387  m_X = X_new;
388  m_Delta = Delta_new;
389 
391 }
NekDouble m_Delta
Definition of the SFD parameters:
void SetSFDOperator(const NekDouble X_input, const NekDouble Delta_input)
void GradientDescentMethod(const std::complex< NekDouble > &alpha, NekDouble &X_output, NekDouble &Delta_output)
void ReadEVfile(int &KrylovSubspaceDim, NekDouble &growthEV, NekDouble &frequencyEV)
double NekDouble

References GradientDescentMethod(), m_Delta, Nektar::SolverUtils::DriverArnoldi::m_kdim, m_X, ReadEVfile(), and SetSFDOperator().

Referenced by v_Execute().

◆ ComputeSFD()

void Nektar::SolverUtils::DriverSteadyState::ComputeSFD ( const int  i,
const Array< OneD, const Array< OneD, NekDouble >> &  q0,
const Array< OneD, const Array< OneD, NekDouble >> &  qBar0,
Array< OneD, Array< OneD, NekDouble >> &  q1,
Array< OneD, Array< OneD, NekDouble >> &  qBar1 
)

Encapsulated SFD method

Definition at line 351 of file DriverSteadyState.cpp.

356 {
357  q1[i] = Array<OneD, NekDouble>(m_equ[m_nequ - 1]->GetTotPoints(), 0.0);
358  qBar1[i] = Array<OneD, NekDouble>(m_equ[m_nequ - 1]->GetTotPoints(), 0.0);
359 
360  /// Encapsulated SFD method
361  Vmath::Svtvp(q1[i].size(), M11, q0[i], 1, q1[i], 1, q1[i], 1);
362  Vmath::Svtvp(q1[i].size(), M12, qBar0[i], 1, q1[i], 1, q1[i], 1);
363 
364  Vmath::Svtvp(qBar1[i].size(), M21, q0[i], 1, qBar1[i], 1, qBar1[i], 1);
365  Vmath::Svtvp(qBar1[i].size(), M22, qBar0[i], 1, qBar1[i], 1, qBar1[i], 1);
366 }
Array< OneD, EquationSystemSharedPtr > m_equ
Equation system to solve.
Definition: Driver.h:97
int m_nequ
number of equations
Definition: Driver.h:100
NekDouble M11
Definition of the SFD operator.
void Svtvp(int n, const T alpha, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
svtvp (scalar times vector plus vector): z = alpha*x + y
Definition: Vmath.cpp:622

References M11, M12, M21, M22, Nektar::SolverUtils::Driver::m_equ, Nektar::SolverUtils::Driver::m_nequ, and Vmath::Svtvp().

Referenced by v_Execute().

◆ ConvergenceHistory()

void Nektar::SolverUtils::DriverSteadyState::ConvergenceHistory ( const Array< OneD, const Array< OneD, NekDouble >> &  qBar1,
const Array< OneD, const Array< OneD, NekDouble >> &  q0,
NekDouble MaxNormDiff_q_qBar,
NekDouble MaxNormDiff_q1_q0 
)

This routine evaluates |q-qBar|_inf (and |q1-q0|_inf) and writes the values in "ConvergenceHistory.txt"

Definition at line 589 of file DriverSteadyState.cpp.

593 {
594  Array<OneD, NekDouble> NormDiff_q_qBar(NumVar_SFD, 1.0);
595  Array<OneD, NekDouble> NormDiff_q1_q0(NumVar_SFD, 1.0);
596  MaxNormDiff_q_qBar = 0.0;
597  MaxNormDiff_q1_q0 = 0.0;
598 
599  for (int i = 0; i < NumVar_SFD; ++i)
600  {
601  NormDiff_q_qBar[i] = m_equ[m_nequ - 1]->LinfError(i, qBar1[i]);
602  NormDiff_q1_q0[i] = m_equ[m_nequ - 1]->LinfError(i, q0[i]);
603 
604  if (MaxNormDiff_q_qBar < NormDiff_q_qBar[i])
605  {
606  MaxNormDiff_q_qBar = NormDiff_q_qBar[i];
607  }
608  if (MaxNormDiff_q1_q0 < NormDiff_q1_q0[i])
609  {
610  MaxNormDiff_q1_q0 = NormDiff_q1_q0[i];
611  }
612  }
613 
614  timer.Stop();
616  cpuTime += elapsed;
617  totalTime += elapsed;
618 
619  if (m_comm->GetRank() == 0)
620  {
621  cout << "SFD - Step: " << left << m_stepCounter + 1
622  << ";\tTime: " << left << m_equ[m_nequ - 1]->GetFinalTime()
623  << ";\tCPU time = " << left << cpuTime << " s"
624  << ";\tTot time = " << left << totalTime << " s"
625  << ";\tX = " << left << m_X << ";\tDelta = " << left << m_Delta
626  << ";\t|q-qBar|inf = " << left << MaxNormDiff_q_qBar << endl;
627  std::ofstream m_file("ConvergenceHistory.txt", std::ios_base::app);
628  m_file << m_stepCounter + 1 << "\t" << m_equ[m_nequ - 1]->GetFinalTime()
629  << "\t" << totalTime << "\t" << MaxNormDiff_q_qBar << "\t"
630  << MaxNormDiff_q1_q0 << endl;
631  m_file.close();
632  }
633 
634  cpuTime = 0.0;
635  timer.Start();
636 }
NekDouble TimePerTest(unsigned int n)
Returns amount of seconds per iteration in a test with n iterations.
Definition: Timer.cpp:68
LibUtilities::CommSharedPtr m_comm
Communication object.
Definition: Driver.h:85

References cpuTime, elapsed, Nektar::SolverUtils::Driver::m_comm, m_Delta, Nektar::SolverUtils::Driver::m_equ, m_file, Nektar::SolverUtils::Driver::m_nequ, m_stepCounter, m_X, NumVar_SFD, Nektar::LibUtilities::Timer::Start(), Nektar::LibUtilities::Timer::Stop(), Nektar::LibUtilities::Timer::TimePerTest(), timer, and totalTime.

Referenced by v_Execute().

◆ create()

static DriverSharedPtr Nektar::SolverUtils::DriverSteadyState::create ( const LibUtilities::SessionReaderSharedPtr pSession,
const SpatialDomains::MeshGraphSharedPtr pGraph 
)
inlinestatic

Creates an instance of this class.

Definition at line 54 of file DriverSteadyState.h.

57  {
59  pSession, pGraph);
60  p->InitObject();
61  return p;
62  }
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
std::shared_ptr< Driver > DriverSharedPtr
A shared pointer to a Driver object.
Definition: Driver.h:51

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), and CellMLToNektar.cellml_metadata::p.

◆ EvalEV_ScalarSFD()

void Nektar::SolverUtils::DriverSteadyState::EvalEV_ScalarSFD ( const NekDouble X_input,
const NekDouble Delta_input,
const std::complex< NekDouble > &  alpha,
NekDouble MaxEV 
)

This routine evaluates the maximum eigenvalue of the SFD system when applied to the 1D model u(n+1) = alpha*u(n)

Definition at line 481 of file DriverSteadyState.cpp.

485 {
486  NekDouble A11 =
487  (1.0 + X_input * Delta_input * exp(-(X_input + 1.0 / Delta_input))) /
488  (1.0 + X_input * Delta_input);
489  NekDouble A12 =
490  (X_input * Delta_input -
491  X_input * Delta_input * exp(-(X_input + 1.0 / Delta_input))) /
492  (1.0 + X_input * Delta_input);
493  NekDouble A21 = (1.0 - 1.0 * exp(-(X_input + 1.0 / Delta_input))) /
494  (1 + X_input * Delta_input);
495  NekDouble A22 =
496  (X_input * Delta_input + 1.0 * exp(-(X_input + 1.0 / Delta_input))) /
497  (1.0 + X_input * Delta_input);
498 
499  complex<NekDouble> B11 = alpha;
500  NekDouble B12 = 0.0;
501  NekDouble B21 = 0.0;
502  NekDouble B22 = 1.0;
503 
504  complex<NekDouble> a = A11 * B11 + A12 * B21;
505  NekDouble b = A11 * B12 + A12 * B22;
506  complex<NekDouble> c = A21 * B11 + A22 * B21;
507  NekDouble d = A21 * B12 + A22 * B22;
508 
509  complex<NekDouble> delt = sqrt((a - d) * (a - d) + 4.0 * b * c);
510  complex<NekDouble> lambda_1 = 0.5 * (a + d + delt);
511  complex<NekDouble> lambda_2 = 0.5 * (a + d - delt);
512 
513  NekDouble NORM_1 = abs(lambda_1);
514  NekDouble NORM_2 = abs(lambda_2);
515 
516  MaxEV = max(NORM_1, NORM_2);
517 }
scalarT< T > abs(scalarT< T > in)
Definition: scalar.hpp:298
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294

References tinysimd::abs(), and tinysimd::sqrt().

Referenced by GradientDescentMethod().

◆ GradientDescentMethod()

void Nektar::SolverUtils::DriverSteadyState::GradientDescentMethod ( const std::complex< NekDouble > &  alpha,
NekDouble X_output,
NekDouble Delta_output 
)

This routine implements a gradient descent method to find the parameters X end Delta which give the minimum eigenlavue of the SFD problem applied to the scalar case u(n+1) = \alpha*u(n).

Definition at line 398 of file DriverSteadyState.cpp.

401 {
402  cout << "\n\tWe enter the Gradient Descent Method [...]" << endl;
403  bool OptParmFound = false;
404  bool Descending = true;
405  NekDouble X_input = X_output;
406  NekDouble Delta_input = Delta_output;
407 
408  NekDouble X_init = X_output;
409  NekDouble Delta_init = Delta_output;
410  int stepCounter(0);
411 
412  NekDouble F0(0.0);
413  NekDouble F0x(0.0);
414  NekDouble F0y(0.0);
415  NekDouble F1(0.0);
416  NekDouble dx = 0.00000001;
417  NekDouble dirx(0.0);
418  NekDouble diry(0.0);
419  NekDouble s(0.0);
420  NekDouble CurrentMin = 1.0;
421 
422  while (OptParmFound == false)
423  {
424  Descending = true;
425  EvalEV_ScalarSFD(X_input, Delta_input, alpha, F0);
426  EvalEV_ScalarSFD(X_input + dx, Delta_input, alpha, F0x);
427  EvalEV_ScalarSFD(X_input, Delta_input + dx, alpha, F0y);
428  dirx = (F0 - F0x);
429  diry = (F0 - F0y);
430  s = abs(0.000001 / dirx);
431  X_output = X_input + s * dirx;
432  Delta_output = Delta_input + s * diry;
433  F1 = F0;
434 
435  while (Descending == true)
436  {
437  CurrentMin = F1;
438  X_input = X_output;
439  Delta_input = Delta_output;
440  EvalEV_ScalarSFD(X_output, Delta_output, alpha, F1);
441 
442  if (F1 > CurrentMin)
443  {
444  Descending = false;
445  }
446  else
447  {
448  s = s + s * 0.01;
449  X_output = X_input + s * dirx;
450  Delta_output = Delta_input + s * diry;
451  }
452 
453  if (stepCounter > 9999999)
454  {
455  // We are stuck in this loop..
456  // Then we restart it with different initail conditions
457  Descending = false;
458  X_input = X_init;
459  Delta_init = Delta_init + Delta_init * 0.1;
460  Delta_input = Delta_init;
461  stepCounter = 0;
462  }
463  stepCounter++;
464  }
465 
466  if (abs(F0 - F1) < dx)
467  {
468  cout << "\tThe Gradient Descent Method has converged!" << endl;
469  EvalEV_ScalarSFD(X_output, Delta_output, alpha, F1);
470  cout << "\n\tThe updated parameters are: X_tilde = " << X_output
471  << " and Delta_tilde = " << Delta_output << endl;
472  OptParmFound = true;
473  }
474  }
475 }
void EvalEV_ScalarSFD(const NekDouble &X_input, const NekDouble &Delta_input, const std::complex< NekDouble > &alpha, NekDouble &MaxEV)

References tinysimd::abs(), and EvalEV_ScalarSFD().

Referenced by ComputeOptimization(), and v_Execute().

◆ PrintSummarySFD()

void Nektar::SolverUtils::DriverSteadyState::PrintSummarySFD ( )

Definition at line 638 of file DriverSteadyState.cpp.

639 {
640  cout << "\n====================================="
641  "=================================="
642  << endl;
643  cout << "Parameters for the SFD method:" << endl;
644  cout << "\tControl Coefficient: X = " << m_X << endl;
645  cout << "\tFilter Width: Delta = " << m_Delta << endl;
646  cout << "The simulation is stopped when |q-qBar|inf < " << TOL << endl;
648  {
649  cout << "\nWe use the adaptive SFD method:" << endl;
650  cout << " The parameters are updated every " << AdaptiveTime
651  << " time units;" << endl;
652  cout << " until |q-qBar|inf becomes smaller than " << AdaptiveTOL
653  << endl;
654  }
655  cout << "====================================="
656  "==================================\n"
657  << endl;
658 }
enum EvolutionOperatorType m_EvolutionOperator
Evolution Operator.
Definition: Driver.h:103

References AdaptiveTime, AdaptiveTOL, Nektar::SolverUtils::eAdaptiveSFD, m_Delta, Nektar::SolverUtils::Driver::m_EvolutionOperator, m_X, and TOL.

Referenced by v_Execute().

◆ ReadEVfile()

void Nektar::SolverUtils::DriverSteadyState::ReadEVfile ( int &  KrylovSubspaceDim,
NekDouble growthEV,
NekDouble frequencyEV 
)

Definition at line 519 of file DriverSteadyState.cpp.

521 {
522  // This routine reads the .evl file written by the Arnoldi algorithm
523  // (written in September 2014)
524  std::string line;
525  int NumLinesInFile = 0;
526  std::string EVfileName = m_session->GetSessionName() + ".evl";
527  std::ifstream EVfile(EVfileName.c_str());
528  ASSERTL0(EVfile.good(), "Cannot open .evl file.");
529 
530  if (EVfile)
531  {
532  // This block counts the total number of lines of the .evl file
533  // We keep going util we reach the end of the file
534  while (getline(EVfile, line))
535  {
536  ++NumLinesInFile;
537  }
538 
539  // It may happen that the Stability method that have produced the .elv
540  // file converges in less than m_kdim iterations. In this case,
541  // KrylovSubspaceDim has to be changed here
542  if (NumLinesInFile <
543  KrylovSubspaceDim * 2.0 +
544  KrylovSubspaceDim * (KrylovSubspaceDim + 1.0) / 2.0)
545  {
546  for (int i = 1; i <= KrylovSubspaceDim; ++i)
547  {
548  if (NumLinesInFile == i * 2.0 + i * (i + 1.0) / 2.0)
549  {
550  KrylovSubspaceDim = i;
551  }
552  }
553  }
554 
555  // go back to the beginning of the file
556  EVfile.clear();
557  EVfile.seekg(0, ios::beg);
558 
559  // We now want to go to the line where the most unstable eigenlavue was
560  // written
561  for (int i = 0; i < (NumLinesInFile - KrylovSubspaceDim); ++i)
562  {
563  std::getline(EVfile, line);
564  cout << "Discard line: " << line << endl;
565  }
566 
567  std::vector<std::string> tokens;
568  std::getline(EVfile, line);
569  boost::algorithm::split(tokens, line, boost::is_any_of("\t "),
570  boost::token_compress_on);
571 
572  ASSERTL0(tokens.size() >= 5,
573  "Unexpected formatting of .evl file while reading line:\n" +
574  line);
575  growthEV = boost::lexical_cast<NekDouble>(tokens[4]);
576  frequencyEV = boost::lexical_cast<NekDouble>(tokens[5]);
577  }
578  else
579  {
580  cout << "An error occurred when opening the .evl file" << endl;
581  }
582  EVfile.close();
583 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
LibUtilities::SessionReaderSharedPtr m_session
Session reader object.
Definition: Driver.h:88

References ASSERTL0, and Nektar::SolverUtils::Driver::m_session.

Referenced by ComputeOptimization().

◆ SetSFDOperator()

void Nektar::SolverUtils::DriverSteadyState::SetSFDOperator ( const NekDouble  X_input,
const NekDouble  Delta_input 
)

This routine defines the encapsulated SFD operator with first-order splitting and exact resolution of the second subproblem. (See http://scitation.aip.org/content/aip/journal/pof2/26/3/10.1063/1.4867482 for details)

Definition at line 339 of file DriverSteadyState.cpp.

341 {
342  NekDouble X = X_input * m_dt;
343  NekDouble Delta = Delta_input / m_dt;
344  NekDouble coeff = 1.0 / (1.0 + X * Delta);
345  M11 = coeff * (1.0 + X * Delta * exp(-(X + 1.0 / Delta)));
346  M12 = coeff * (X * Delta * (1.0 - exp(-(X + 1.0 / Delta))));
347  M21 = coeff * (1.0 - exp(-(X + 1.0 / Delta)));
348  M22 = coeff * (X * Delta + exp(-(X + 1.0 / Delta)));
349 }

References M11, M12, M21, M22, and m_dt.

Referenced by ComputeOptimization(), and v_Execute().

◆ v_Execute()

void Nektar::SolverUtils::DriverSteadyState::v_Execute ( std::ostream &  out = std::cout)
overrideprotectedvirtual

Virtual function for solve implementation.

Definition of variables used in this algorithm

Call the Navier-Stokes solver for one time step

Copy the current flow field into q0

Apply the linear operator to the outcome of the solver

Update qBar

Copy the output of the SFD method into the current flow field

Loop for the adaptive SFD method

We save the final solution into a .fld file

Reimplemented from Nektar::SolverUtils::DriverModifiedArnoldi.

Definition at line 80 of file DriverSteadyState.cpp.

82 {
83  // With a loop over "DoSolve", this Driver implements the
84  // "encapsulated" Selective Frequency Damping method(SFD)
85  // to find the steady state of a flow above the critical Reynolds
86  // number.
87  m_equ[m_nequ - 1]->PrintSummary(out);
88 
89  m_session->LoadParameter("IO_InfoSteps", m_infosteps, 1000);
90  m_session->LoadParameter("IO_CheckSteps", m_checksteps, 100000);
91  m_session->LoadParameter("ControlCoeff", m_X, 1);
92  m_session->LoadParameter("FilterWidth", m_Delta, 2);
93 
94  // To evaluate optimum SFD parameters if growth rate provided in the
95  // xml file
96  m_session->LoadParameter("GrowthRateEV", GrowthRateEV, 0.0);
97 
98  // To evaluate optimum SFD parameters if frequency provided in the xml
99  // file
100  m_session->LoadParameter("FrequencyEV", FrequencyEV, 0.0);
101 
102  // Determine when SFD method is converged
103  m_session->LoadParameter("TOL", TOL, 1.0e-08);
104 
105  // Used only for the Adaptive SFD method
106  m_session->LoadParameter("AdaptiveTOL", AdaptiveTOL, 1.0e-02);
107 
108  // Used only for the Adaptive SFD method
109  m_session->LoadParameter("AdaptiveTime", AdaptiveTime, 50.0 * m_Delta);
110 
111  if (m_comm->GetRank() == 0)
112  {
113  PrintSummarySFD();
114  }
115 
116  timer.Start();
117 
118  // Definition of shared pointer (used only for the Adaptive SFD method)
119  AdvectionSystemSharedPtr A = m_equ[0]->as<AdvectionSystem>();
120 
121  NumVar_SFD = m_equ[m_nequ - 1]->UpdateFields()[0]->GetCoordim(0);
122  // SFD to run for incompressible case with scalar field
123  if (m_session->GetSolverInfo("EqType") == "UnsteadyNavierStokes" ||
124  m_session->GetSolverInfo("EqType") == "SteadyNavierStokes")
125  {
126  int nConvectiveFields = m_session->GetVariables().size();
127  if (boost::iequals(m_session->GetVariable(nConvectiveFields - 1), "p"))
128  {
129  nConvectiveFields -= 1;
130  }
131  NumVar_SFD = nConvectiveFields;
132  }
133  // Condition necessary to run SFD for the compressible case
134  if (m_session->GetSolverInfo("EqType") == "EulerCFE" ||
135  m_session->GetSolverInfo("EqType") == "NavierStokesCFE" ||
136  m_session->GetSolverInfo("EqType") == "NavierStokesImplicitCFE")
137  {
138  // Number of variables for the compressible equations
139  NumVar_SFD += 2;
140  }
141  if (m_session->DefinesSolverInfo("HOMOGENEOUS"))
142  {
143  if (m_session->GetSolverInfo("HOMOGENEOUS") == "1D")
144  {
145  NumVar_SFD += 1;
146  }
147  }
148 
149  // We store the time step
150  m_dt = m_equ[m_nequ - 1]->GetTimeStep();
151 
152  // Evaluate optimum SFD parameters if dominent EV given by xml file
153  if (GrowthRateEV != 0.0 && FrequencyEV != 0.0)
154  {
155  cout << "Besed on the dominant EV given in the xml file,"
156  << "a 1D model is used to evaluate the optumum parameters"
157  << "of the SFD method:" << endl;
158  complex<NekDouble> EV = polar(exp(GrowthRateEV), FrequencyEV);
160  }
161 
162  // We set up the elements of the operator of the encapsulated
163  // formulation of the selective frequencive damping method
165 
166  // m_steps is set to 1. Then "m_equ[m_nequ - 1]->DoSolve()" will run
167  // for only one time step
168  m_equ[m_nequ - 1]->SetSteps(1);
169  ofstream m_file("ConvergenceHistory.txt", ios::out | ios::trunc);
170 
171  Array<OneD, Array<OneD, NekDouble>> q0(NumVar_SFD);
172  Array<OneD, Array<OneD, NekDouble>> q1(NumVar_SFD);
173  Array<OneD, Array<OneD, NekDouble>> qBar0(NumVar_SFD);
174  Array<OneD, Array<OneD, NekDouble>> qBar1(NumVar_SFD);
175 
176  for (int i = 0; i < NumVar_SFD; ++i)
177  {
178  q0[i] = Array<OneD, NekDouble>(m_equ[m_nequ - 1]->GetTotPoints(),
179  0.0); // q0 is initialised
180  qBar0[i] =
181  Array<OneD, NekDouble>(m_equ[m_nequ - 1]->GetTotPoints(), 0.0);
182  m_equ[m_nequ - 1]->CopyFromPhysField(i, qBar0[i]);
183  }
184 
185  /// Definition of variables used in this algorithm
186  m_stepCounter = 0;
187  m_Check = 0;
188  m_Check_BaseFlow = 1;
190  Diff_q_qBar = 1.0;
191  Diff_q1_q0 = 1.0;
192  cpuTime = 0.0;
193  elapsed = 0.0;
194  totalTime = 0.0;
195  FlowPartiallyConverged = false;
196 
197  while (max(Diff_q_qBar, Diff_q1_q0) > TOL)
198  {
199  /// Call the Navier-Stokes solver for one time step
200  m_equ[m_nequ - 1]->DoSolve();
201 
202  for (int i = 0; i < NumVar_SFD; ++i)
203  {
204  /// Copy the current flow field into q0
205  m_equ[m_nequ - 1]->CopyFromPhysField(i, q0[i]);
206 
207  /// Apply the linear operator to the outcome of the solver
208  ComputeSFD(i, q0, qBar0, q1, qBar1);
209 
210  /// Update qBar
211  qBar0[i] = qBar1[i];
212 
213  /// Copy the output of the SFD method into the current flow field
214  m_equ[m_nequ - 1]->CopyToPhysField(i, q1[i]);
215  }
216 
217  if (m_infosteps && !((m_stepCounter + 1) % m_infosteps))
218  {
220 
221  /// Loop for the adaptive SFD method
223  FlowPartiallyConverged == false)
224  {
225 
227 
228  if (Diff_q_qBar < AdaptiveTOL)
229  {
230  if (m_comm->GetRank() == 0)
231  {
232  cout << "\n\t The SFD method is converging: we compute "
233  << "stability analysis using the 'partially "
234  << "converged' steady state as base flow:\n"
235  << endl;
236  }
237 
238  m_equ[m_nequ - 1]->Checkpoint_BaseFlow(m_Check_BaseFlow);
240 
241  A->GetAdvObject()->SetBaseFlow(q0,
242  m_equ[0]->UpdateFields());
244 
245  if (m_comm->GetRank() == 0)
246  {
247  // Compute the update of the SFD parameters only on
248  // one processor
250  }
251  else
252  {
253  // On all the other processors, the parameters are set
254  // to 0
255  m_X = 0;
256  m_Delta = 0;
257  }
258  // The we give to all the processors the value of X and
259  // Delta of the first processor
262 
263  FlowPartiallyConverged = true;
264  }
266  AdaptiveTime)
267  {
268  if (m_comm->GetRank() == 0)
269  {
270  cout << "\n\t We compute stability analysis using"
271  << " the current flow field as base flow:\n"
272  << endl;
273  }
274 
275  m_equ[m_nequ - 1]->Checkpoint_BaseFlow(m_Check_BaseFlow);
277 
278  A->GetAdvObject()->SetBaseFlow(q0,
279  m_equ[0]->UpdateFields());
281 
282  if (m_comm->GetRank() == 0)
283  {
284  // Compute the update of the SFD parameters only on
285  // one processor
287  }
288  else
289  {
290  // On all the other processors, the parameters are set
291  // to 0
292  m_X = 0;
293  m_Delta = 0;
294  }
295  // The we give to all the processors the value of X and
296  // Delta of the first processor
299 
301  }
302  }
303  }
304 
305  if (m_checksteps && m_stepCounter &&
306  (!((m_stepCounter + 1) % m_checksteps)))
307  {
308  m_Check++;
309  m_equ[m_nequ - 1]->Checkpoint_Output(m_Check);
310  }
311  m_stepCounter++;
312  }
313 
314  m_file.close();
315 
316  /// We save the final solution into a .fld file
317  m_equ[m_nequ - 1]->Output();
318 
319  for (int j = 0; j < m_equ[m_nequ - 1]->GetNvariables(); ++j)
320  {
321  NekDouble vL2Error = m_equ[m_nequ - 1]->L2Error(j, false);
322  NekDouble vLinfError = m_equ[m_nequ - 1]->LinfError(j);
323  if (m_comm->GetRank() == 0)
324  {
325  out << "L 2 error (variable " << m_equ[m_nequ - 1]->GetVariable(j)
326  << ") : " << vL2Error << endl;
327  out << "L inf error (variable " << m_equ[m_nequ - 1]->GetVariable(j)
328  << ") : " << vLinfError << endl;
329  }
330  }
331 }
virtual void v_Execute(std::ostream &out=std::cout) override
Virtual function for solve implementation.
void ComputeSFD(const int i, const Array< OneD, const Array< OneD, NekDouble >> &q0, const Array< OneD, const Array< OneD, NekDouble >> &qBar0, Array< OneD, Array< OneD, NekDouble >> &q1, Array< OneD, Array< OneD, NekDouble >> &qBar1)
void ConvergenceHistory(const Array< OneD, const Array< OneD, NekDouble >> &qBar1, const Array< OneD, const Array< OneD, NekDouble >> &q0, NekDouble &MaxNormDiff_q_qBar, NekDouble &MaxNormDiff_q1_q0)
bool FlowPartiallyConverged
For adaptive SFD method.
std::shared_ptr< AdvectionSystem > AdvectionSystemSharedPtr
Shared pointer to an AdvectionSystem class.

References AdaptiveTime, AdaptiveTOL, ComputeOptimization(), ComputeSFD(), ConvergenceHistory(), cpuTime, Diff_q1_q0, Diff_q_qBar, Nektar::SolverUtils::eAdaptiveSFD, elapsed, FlowPartiallyConverged, FrequencyEV, GradientDescentMethod(), GrowthRateEV, m_Check, m_Check_BaseFlow, m_checksteps, Nektar::SolverUtils::Driver::m_comm, m_Delta, m_dt, Nektar::SolverUtils::Driver::m_equ, Nektar::SolverUtils::Driver::m_EvolutionOperator, m_file, m_infosteps, Nektar::SolverUtils::Driver::m_nequ, m_NonConvergingStepsCounter, Nektar::SolverUtils::Driver::m_session, m_stepCounter, m_X, NumVar_SFD, PrintSummarySFD(), Nektar::LibUtilities::ReduceSum, SetSFDOperator(), Nektar::LibUtilities::Timer::Start(), timer, TOL, totalTime, and Nektar::SolverUtils::DriverModifiedArnoldi::v_Execute().

◆ v_InitObject()

void Nektar::SolverUtils::DriverSteadyState::v_InitObject ( std::ostream &  out = std::cout)
overrideprotectedvirtual

Second-stage initialisation.

Reimplemented from Nektar::SolverUtils::DriverModifiedArnoldi.

Definition at line 75 of file DriverSteadyState.cpp.

76 {
78 }
virtual void v_InitObject(std::ostream &out=std::cout) override
Virtual function for initialisation implementation.

References Nektar::SolverUtils::DriverModifiedArnoldi::v_InitObject().

Friends And Related Function Documentation

◆ MemoryManager< DriverSteadyState >

friend class MemoryManager< DriverSteadyState >
friend

Definition at line 1 of file DriverSteadyState.h.

Member Data Documentation

◆ AdaptiveTime

NekDouble Nektar::SolverUtils::DriverSteadyState::AdaptiveTime
private

Definition at line 146 of file DriverSteadyState.h.

Referenced by PrintSummarySFD(), and v_Execute().

◆ AdaptiveTOL

NekDouble Nektar::SolverUtils::DriverSteadyState::AdaptiveTOL
private

Definition at line 145 of file DriverSteadyState.h.

Referenced by PrintSummarySFD(), and v_Execute().

◆ className

string Nektar::SolverUtils::DriverSteadyState::className
static
Initial value:
=
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:198
static DriverSharedPtr create(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
Creates an instance of this class.
DriverFactory & GetDriverFactory()
Definition: Driver.cpp:64

Name of the class.

Definition at line 65 of file DriverSteadyState.h.

◆ cpuTime

NekDouble Nektar::SolverUtils::DriverSteadyState::cpuTime
private

Definition at line 124 of file DriverSteadyState.h.

Referenced by ConvergenceHistory(), and v_Execute().

◆ Diff_q1_q0

NekDouble Nektar::SolverUtils::DriverSteadyState::Diff_q1_q0
private

Definition at line 141 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ Diff_q_qBar

NekDouble Nektar::SolverUtils::DriverSteadyState::Diff_q_qBar
private

Definition at line 140 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ driverLookupId

string Nektar::SolverUtils::DriverSteadyState::driverLookupId
staticprotected
Initial value:
=
static std::string RegisterEnumValue(std::string pEnum, std::string pString, int pEnumValue)
Registers an enumeration value.

Definition at line 112 of file DriverSteadyState.h.

◆ elapsed

NekDouble Nektar::SolverUtils::DriverSteadyState::elapsed
private

Definition at line 126 of file DriverSteadyState.h.

Referenced by ConvergenceHistory(), and v_Execute().

◆ FlowPartiallyConverged

bool Nektar::SolverUtils::DriverSteadyState::FlowPartiallyConverged
private

For adaptive SFD method.

Definition at line 144 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ FrequencyEV

NekDouble Nektar::SolverUtils::DriverSteadyState::FrequencyEV
private

Definition at line 149 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ GrowthRateEV

NekDouble Nektar::SolverUtils::DriverSteadyState::GrowthRateEV
private

Definition at line 148 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ M11

NekDouble Nektar::SolverUtils::DriverSteadyState::M11
private

Definition of the SFD operator.

Definition at line 135 of file DriverSteadyState.h.

Referenced by ComputeSFD(), and SetSFDOperator().

◆ M12

NekDouble Nektar::SolverUtils::DriverSteadyState::M12
private

Definition at line 136 of file DriverSteadyState.h.

Referenced by ComputeSFD(), and SetSFDOperator().

◆ M21

NekDouble Nektar::SolverUtils::DriverSteadyState::M21
private

Definition at line 137 of file DriverSteadyState.h.

Referenced by ComputeSFD(), and SetSFDOperator().

◆ M22

NekDouble Nektar::SolverUtils::DriverSteadyState::M22
private

Definition at line 138 of file DriverSteadyState.h.

Referenced by ComputeSFD(), and SetSFDOperator().

◆ m_Check

int Nektar::SolverUtils::DriverSteadyState::m_Check
private

Definition at line 116 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ m_Check_BaseFlow

int Nektar::SolverUtils::DriverSteadyState::m_Check_BaseFlow
private

Definition at line 117 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ m_checksteps

int Nektar::SolverUtils::DriverSteadyState::m_checksteps
private

Definition at line 120 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ m_Delta

NekDouble Nektar::SolverUtils::DriverSteadyState::m_Delta
private

Definition of the SFD parameters:

Definition at line 130 of file DriverSteadyState.h.

Referenced by ComputeOptimization(), ConvergenceHistory(), PrintSummarySFD(), and v_Execute().

◆ m_dt

NekDouble Nektar::SolverUtils::DriverSteadyState::m_dt
private

Definition at line 132 of file DriverSteadyState.h.

Referenced by SetSFDOperator(), and v_Execute().

◆ m_file

std::ofstream Nektar::SolverUtils::DriverSteadyState::m_file
private

Definition at line 127 of file DriverSteadyState.h.

Referenced by ConvergenceHistory(), and v_Execute().

◆ m_infosteps

int Nektar::SolverUtils::DriverSteadyState::m_infosteps
private

Definition at line 119 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ m_NonConvergingStepsCounter

int Nektar::SolverUtils::DriverSteadyState::m_NonConvergingStepsCounter
private

Definition at line 147 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ m_stepCounter

int Nektar::SolverUtils::DriverSteadyState::m_stepCounter
private

Definition at line 115 of file DriverSteadyState.h.

Referenced by ConvergenceHistory(), and v_Execute().

◆ m_X

NekDouble Nektar::SolverUtils::DriverSteadyState::m_X
private

◆ NumVar_SFD

int Nektar::SolverUtils::DriverSteadyState::NumVar_SFD
private

Definition at line 121 of file DriverSteadyState.h.

Referenced by ConvergenceHistory(), and v_Execute().

◆ timer

LibUtilities::Timer Nektar::SolverUtils::DriverSteadyState::timer
private

Definition at line 123 of file DriverSteadyState.h.

Referenced by ConvergenceHistory(), and v_Execute().

◆ TOL

NekDouble Nektar::SolverUtils::DriverSteadyState::TOL
private

Definition at line 118 of file DriverSteadyState.h.

Referenced by PrintSummarySFD(), and v_Execute().

◆ totalTime

NekDouble Nektar::SolverUtils::DriverSteadyState::totalTime
private

Definition at line 125 of file DriverSteadyState.h.

Referenced by ConvergenceHistory(), and v_Execute().