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

#include <DriverSteadyState.h>

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

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 ()=default
 Destructor. More...
 
virtual SOLVER_UTILS_EXPORT void v_InitObject (std::ostream &out=std::cout) override
 Initialises EquationSystem class members. 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 ()=default
 Destructor. More...
 
virtual void v_InitObject (std::ostream &out=std::cout) override
 Virtual function for initialisation implementation. More...
 
virtual void v_Execute (std::ostream &out=std::cout) override
 Virtual function for solve implementation. More...
 
- Protected Member Functions inherited from Nektar::SolverUtils::DriverArnoldi
 DriverArnoldi (const LibUtilities::SessionReaderSharedPtr pSession, const SpatialDomains::MeshGraphSharedPtr pGraph)
 Constructor. More...
 
virtual ~DriverArnoldi ()=default
 Destructor. More...
 
virtual void v_InitObject (std::ostream &out=std::cout) override
 Virtual function for initialisation implementation. More...
 
virtual void v_Execute (std::ostream &out=std::cout) override
 Virtual function for solve implementation. 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 GetMaskInfo (std::vector< std::vector< LibUtilities::EquationSharedPtr > > &selectedDomains, std::set< int > &unselectedVariables)
 
SOLVER_UTILS_EXPORT void ArnoldiSummary (std::ostream &out)
 
- Protected Member Functions inherited from Nektar::SolverUtils::Driver
 Driver (const LibUtilities::SessionReaderSharedPtr pSession, const SpatialDomains::MeshGraphSharedPtr pGraph)
 Initialises EquationSystem class members. More...
 
virtual SOLVER_UTILS_EXPORT void v_InitObject (std::ostream &out=std::cout)
 Virtual function for initialisation implementation. More...
 
virtual SOLVER_UTILS_EXPORT void v_Execute (std::ostream &out=std::cout)=0
 Virtual function for solve implementation. More...
 

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

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
 

Static Private Attributes

static std::string driverLookupId
 

Friends

class MemoryManager< DriverSteadyState >
 

Additional Inherited Members

- Public Member Functions inherited from Nektar::SolverUtils::DriverArnoldi
Array< OneD, NekDoubleGetRealEvl (void)
 
Array< OneD, NekDoubleGetImagEvl (void)
 
- 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 ()
 
- 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 iterations. 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
 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...
 
- Static Protected Attributes inherited from Nektar::SolverUtils::DriverModifiedArnoldi
static std::string driverLookupId
 
- Static Protected Attributes inherited from Nektar::SolverUtils::Driver
static std::string evolutionOperatorLookupIds []
 
static std::string evolutionOperatorDef
 
static std::string driverDefault
 

Detailed Description

Definition at line 46 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()

virtual SOLVER_UTILS_EXPORT Nektar::SolverUtils::DriverSteadyState::~DriverSteadyState ( )
protectedvirtualdefault

Destructor.

Member Function Documentation

◆ ComputeOptimization()

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

Definition at line 370 of file DriverSteadyState.cpp.

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

Encapsulated SFD method

Definition at line 350 of file DriverSteadyState.cpp.

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

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

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

Definition at line 594 of file DriverSteadyState.cpp.

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

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 52 of file DriverSteadyState.h.

55 {
57 pSession, pGraph);
58 p->InitObject();
59 return p;
60 }
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:54

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

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

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

References tinysimd::abs(), Nektar::UnitTests::d(), and tinysimd::sqrt().

Referenced by GradientDescentMethod().

◆ GradientDescentMethod()

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

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

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

Definition at line 646 of file DriverSteadyState.cpp.

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

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

Definition at line 524 of file DriverSteadyState.cpp.

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

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

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

337{
338 NekDouble X = X_input * m_dt;
339 NekDouble Delta = Delta_input / m_dt;
340 NekDouble coeff = 1.0 / (1.0 + X * Delta);
341 M11 = coeff * (1.0 + X * Delta * exp(-(X + 1.0 / Delta)));
342 M12 = coeff * (X * Delta * (1.0 - exp(-(X + 1.0 / Delta))));
343 M21 = coeff * (1.0 - exp(-(X + 1.0 / Delta)));
344 M22 = coeff * (X * Delta + exp(-(X + 1.0 / Delta)));
345}

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

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

Initialises EquationSystem class members.

Reimplemented from Nektar::SolverUtils::DriverModifiedArnoldi.

Definition at line 68 of file DriverSteadyState.cpp.

69{
71}
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 114 of file DriverSteadyState.h.

Referenced by PrintSummarySFD(), and v_Execute().

◆ AdaptiveTOL

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

Definition at line 113 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:67

Name of the class.

Definition at line 63 of file DriverSteadyState.h.

◆ cpuTime

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

Definition at line 92 of file DriverSteadyState.h.

Referenced by ConvergenceHistory(), and v_Execute().

◆ Diff_q1_q0

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

Definition at line 109 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ Diff_q_qBar

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

Definition at line 108 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ driverLookupId

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

Definition at line 147 of file DriverSteadyState.h.

◆ elapsed

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

Definition at line 94 of file DriverSteadyState.h.

Referenced by ConvergenceHistory(), and v_Execute().

◆ FlowPartiallyConverged

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

For adaptive SFD method.

Definition at line 112 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ FrequencyEV

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

Definition at line 117 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ GrowthRateEV

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

Definition at line 116 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ M11

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

Definition of the SFD operator.

Definition at line 103 of file DriverSteadyState.h.

Referenced by ComputeSFD(), and SetSFDOperator().

◆ M12

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

Definition at line 104 of file DriverSteadyState.h.

Referenced by ComputeSFD(), and SetSFDOperator().

◆ M21

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

Definition at line 105 of file DriverSteadyState.h.

Referenced by ComputeSFD(), and SetSFDOperator().

◆ M22

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

Definition at line 106 of file DriverSteadyState.h.

Referenced by ComputeSFD(), and SetSFDOperator().

◆ m_Check

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

Definition at line 84 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ m_Check_BaseFlow

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

Definition at line 85 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ m_checksteps

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

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

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

◆ m_dt

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

Definition at line 100 of file DriverSteadyState.h.

Referenced by SetSFDOperator(), and v_Execute().

◆ m_file

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

Definition at line 95 of file DriverSteadyState.h.

Referenced by ConvergenceHistory(), and v_Execute().

◆ m_infosteps

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

Definition at line 87 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ m_NonConvergingStepsCounter

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

Definition at line 115 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ m_stepCounter

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

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

Referenced by ConvergenceHistory(), and v_Execute().

◆ timer

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

Definition at line 91 of file DriverSteadyState.h.

Referenced by ConvergenceHistory(), and v_Execute().

◆ TOL

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

Definition at line 86 of file DriverSteadyState.h.

Referenced by PrintSummarySFD(), and v_Execute().

◆ totalTime

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

Definition at line 93 of file DriverSteadyState.h.

Referenced by ConvergenceHistory(), and v_Execute().