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)
 Second-stage initialisation. More...
 
virtual SOLVER_UTILS_EXPORT void v_Execute (std::ostream &out=std::cout)
 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)
 
virtual Array< OneD, NekDoublev_GetImagEvl (void)
 
- 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 59 of file DriverSteadyState.cpp.

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

◆ ~DriverSteadyState()

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

Destructor.

Definition at line 70 of file DriverSteadyState.cpp.

71 {
72 }

Member Function Documentation

◆ ComputeOptimization()

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

Definition at line 372 of file DriverSteadyState.cpp.

373 {
374  NekDouble growthEV(0.0);
375  NekDouble frequencyEV(0.0);
376 
377  // m_kdim is the dimension of Krylov subspace (defined in the xml file and
378  // used in DriverArnoldi.cpp)
379  ReadEVfile(m_kdim, growthEV, frequencyEV);
380 
381  cout << "\n\tgrowthEV = " << growthEV << endl;
382  cout << "\tfrequencyEV = " << frequencyEV << endl;
383 
384  complex<NekDouble> ApproxEV = polar(exp(growthEV), frequencyEV);
385 
386  NekDouble X_new = m_X;
387  NekDouble Delta_new = m_Delta;
388 
389  GradientDescentMethod(ApproxEV, X_new, Delta_new);
390 
391  m_X = X_new;
392  m_Delta = Delta_new;
393 
395 }
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 352 of file DriverSteadyState.cpp.

357 {
358  q1[i] = Array<OneD, NekDouble> (m_equ[m_nequ - 1]->GetTotPoints(),0.0);
359  qBar1[i] = Array<OneD, NekDouble> (m_equ[m_nequ - 1]->GetTotPoints(),0.0);
360 
361  ///Encapsulated SFD method
362  Vmath::Svtvp(q1[i].size(), M11, q0[i], 1, q1[i], 1, q1[i], 1 );
363  Vmath::Svtvp(q1[i].size(), M12, qBar0[i], 1, q1[i], 1, q1[i], 1 );
364 
365  Vmath::Svtvp(qBar1[i].size(), M21, q0[i], 1, qBar1[i], 1,
366  qBar1[i], 1 );
367  Vmath::Svtvp(qBar1[i].size(), M22, qBar0[i], 1, qBar1[i], 1,
368  qBar1[i], 1 );
369 }
Array< OneD, EquationSystemSharedPtr > m_equ
Equation system to solve.
Definition: Driver.h:98
int m_nequ
number of equations
Definition: Driver.h:101
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:565

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 596 of file DriverSteadyState.cpp.

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

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  ::AllocateSharedPtr(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 488 of file DriverSteadyState.cpp.

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

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 402 of file DriverSteadyState.cpp.

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

651 {
652  cout << "\n====================================="
653  "=================================="
654  << endl;
655  cout << "Parameters for the SFD method:" << endl;
656  cout << "\tControl Coefficient: X = " << m_X << endl;
657  cout << "\tFilter Width: Delta = " << m_Delta << endl;
658  cout << "The simulation is stopped when |q-qBar|inf < " << TOL << endl;
660  {
661  cout << "\nWe use the adaptive SFD method:" << endl;
662  cout << " The parameters are updated every " << AdaptiveTime
663  << " time units;" << endl;
664  cout << " until |q-qBar|inf becomes smaller than " << AdaptiveTOL
665  << endl;
666  }
667  cout << "====================================="
668  "==================================\n" << endl;
669 }
enum EvolutionOperatorType m_EvolutionOperator
Evolution Operator.
Definition: Driver.h:104

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 524 of file DriverSteadyState.cpp.

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

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)
protectedvirtual

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 84 of file DriverSteadyState.cpp.

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

Second-stage initialisation.

Reimplemented from Nektar::SolverUtils::DriverModifiedArnoldi.

Definition at line 78 of file DriverSteadyState.cpp.

79 {
81 }
virtual void v_InitObject(std::ostream &out=std::cout)
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 154 of file DriverSteadyState.h.

Referenced by PrintSummarySFD(), and v_Execute().

◆ AdaptiveTOL

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

Definition at line 153 of file DriverSteadyState.h.

Referenced by PrintSummarySFD(), and v_Execute().

◆ className

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

Name of the class.

Definition at line 65 of file DriverSteadyState.h.

◆ cpuTime

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

Definition at line 132 of file DriverSteadyState.h.

Referenced by ConvergenceHistory(), and v_Execute().

◆ Diff_q1_q0

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

Definition at line 149 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ Diff_q_qBar

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

Definition at line 148 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ driverLookupId

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

Definition at line 120 of file DriverSteadyState.h.

◆ elapsed

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

Definition at line 134 of file DriverSteadyState.h.

Referenced by ConvergenceHistory(), and v_Execute().

◆ FlowPartiallyConverged

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

For adaptive SFD method.

Definition at line 152 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ FrequencyEV

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

Definition at line 157 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ GrowthRateEV

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

Definition at line 156 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ M11

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

Definition of the SFD operator.

Definition at line 143 of file DriverSteadyState.h.

Referenced by ComputeSFD(), and SetSFDOperator().

◆ M12

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

Definition at line 144 of file DriverSteadyState.h.

Referenced by ComputeSFD(), and SetSFDOperator().

◆ M21

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

Definition at line 145 of file DriverSteadyState.h.

Referenced by ComputeSFD(), and SetSFDOperator().

◆ M22

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

Definition at line 146 of file DriverSteadyState.h.

Referenced by ComputeSFD(), and SetSFDOperator().

◆ m_Check

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

Definition at line 124 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ m_Check_BaseFlow

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

Definition at line 125 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ m_checksteps

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

Definition at line 128 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 138 of file DriverSteadyState.h.

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

◆ m_dt

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

Definition at line 140 of file DriverSteadyState.h.

Referenced by SetSFDOperator(), and v_Execute().

◆ m_file

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

Definition at line 135 of file DriverSteadyState.h.

Referenced by ConvergenceHistory(), and v_Execute().

◆ m_infosteps

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

Definition at line 127 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ m_NonConvergingStepsCounter

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

Definition at line 155 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ m_stepCounter

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

Definition at line 123 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 129 of file DriverSteadyState.h.

Referenced by ConvergenceHistory(), and v_Execute().

◆ timer

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

Definition at line 131 of file DriverSteadyState.h.

Referenced by ConvergenceHistory(), and v_Execute().

◆ TOL

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

Definition at line 126 of file DriverSteadyState.h.

Referenced by PrintSummarySFD(), and v_Execute().

◆ totalTime

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

Definition at line 133 of file DriverSteadyState.h.

Referenced by ConvergenceHistory(), and v_Execute().