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...
 
SOLVER_UTILS_EXPORT ~DriverSteadyState () override=default
 Destructor. More...
 
SOLVER_UTILS_EXPORT void v_InitObject (std::ostream &out=std::cout) override
 Initialises EquationSystem class members. More...
 
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...
 
 ~DriverModifiedArnoldi () override=default
 Destructor. More...
 
void v_InitObject (std::ostream &out=std::cout) override
 Virtual function for initialisation implementation. More...
 
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...
 
 ~DriverArnoldi () override=default
 Destructor. More...
 
void v_InitObject (std::ostream &out=std::cout) override
 Virtual function for initialisation implementation. More...
 
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 ()=default
 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 44 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 54 of file DriverSteadyState.cpp.

57 : DriverModifiedArnoldi(pSession, pGraph)
58{
59}
DriverModifiedArnoldi(const LibUtilities::SessionReaderSharedPtr pSession, const SpatialDomains::MeshGraphSharedPtr pGraph)
Constructor.

◆ ~DriverSteadyState()

SOLVER_UTILS_EXPORT Nektar::SolverUtils::DriverSteadyState::~DriverSteadyState ( )
overrideprotecteddefault

Destructor.

Member Function Documentation

◆ ComputeOptimization()

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

Definition at line 367 of file DriverSteadyState.cpp.

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

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

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 std::cout << "SFD - Step: " << std::left << m_stepCounter + 1
627 << ";\tTime: " << std::left << m_equ[m_nequ - 1]->GetTime()
628 << ";\tCPU time = " << std::left << cpuTime << " s"
629 << ";\tTot time = " << std::left << totalTime << " s"
630 << ";\tX = " << std::left << m_X << ";\tDelta = " << std::left
631 << m_Delta << ";\t|q-qBar|inf = " << std::left
632 << MaxNormDiff_q_qBar << std::endl;
633 std::ofstream m_file("ConvergenceHistory.txt", std::ios_base::app);
634 m_file << m_stepCounter + 1 << "\t" << m_equ[m_nequ - 1]->GetTime()
635 << "\t" << totalTime << "\t" << MaxNormDiff_q_qBar << "\t"
636 << MaxNormDiff_q1_q0 << std::endl;
637 m_file.close();
638 }
639
640 cpuTime = 0.0;
641 timer.Start();
642}
NekDouble TimePerTest(unsigned int n)
Returns amount of seconds per iteration in a test with n iterations.
Definition: Timer.cpp:65
LibUtilities::CommSharedPtr m_comm
Communication object.
Definition: Driver.h:80

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

53 {
55 pSession, pGraph);
56 p->InitObject();
57 return p;
58 }
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:52

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

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

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

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

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

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

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

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

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

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

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

65{
67}
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 111 of file DriverSteadyState.h.

Referenced by PrintSummarySFD(), and v_Execute().

◆ AdaptiveTOL

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

Definition at line 110 of file DriverSteadyState.h.

Referenced by PrintSummarySFD(), and v_Execute().

◆ className

std::string Nektar::SolverUtils::DriverSteadyState::className
static
Initial value:
=
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
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 61 of file DriverSteadyState.h.

◆ cpuTime

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

Definition at line 89 of file DriverSteadyState.h.

Referenced by ConvergenceHistory(), and v_Execute().

◆ Diff_q1_q0

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

Definition at line 106 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ Diff_q_qBar

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

Definition at line 105 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ driverLookupId

std::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 144 of file DriverSteadyState.h.

◆ elapsed

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

Definition at line 91 of file DriverSteadyState.h.

Referenced by ConvergenceHistory(), and v_Execute().

◆ FlowPartiallyConverged

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

For adaptive SFD method.

Definition at line 109 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ FrequencyEV

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

Definition at line 114 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ GrowthRateEV

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

Definition at line 113 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ M11

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

Definition of the SFD operator.

Definition at line 100 of file DriverSteadyState.h.

Referenced by ComputeSFD(), and SetSFDOperator().

◆ M12

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

Definition at line 101 of file DriverSteadyState.h.

Referenced by ComputeSFD(), and SetSFDOperator().

◆ M21

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

Definition at line 102 of file DriverSteadyState.h.

Referenced by ComputeSFD(), and SetSFDOperator().

◆ M22

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

Definition at line 103 of file DriverSteadyState.h.

Referenced by ComputeSFD(), and SetSFDOperator().

◆ m_Check

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

Definition at line 81 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ m_Check_BaseFlow

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

Definition at line 82 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ m_checksteps

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

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

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

◆ m_dt

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

Definition at line 97 of file DriverSteadyState.h.

Referenced by SetSFDOperator(), and v_Execute().

◆ m_file

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

Definition at line 92 of file DriverSteadyState.h.

Referenced by ConvergenceHistory(), and v_Execute().

◆ m_infosteps

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

Definition at line 84 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ m_NonConvergingStepsCounter

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

Definition at line 112 of file DriverSteadyState.h.

Referenced by v_Execute().

◆ m_stepCounter

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

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

Referenced by ConvergenceHistory(), and v_Execute().

◆ timer

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

Definition at line 88 of file DriverSteadyState.h.

Referenced by ConvergenceHistory(), and v_Execute().

◆ TOL

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

Definition at line 83 of file DriverSteadyState.h.

Referenced by PrintSummarySFD(), and v_Execute().

◆ totalTime

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

Definition at line 90 of file DriverSteadyState.h.

Referenced by ConvergenceHistory(), and v_Execute().