49 "Driver",
"SteadyState",0);
110 if (
m_comm->GetRank() == 0)
122 if (
m_session->GetSolverInfo(
"EqType") ==
"EulerCFE" ||
123 m_session->GetSolverInfo(
"EqType") ==
"NavierStokesCFE")
128 if(
m_session->DefinesSolverInfo(
"HOMOGENEOUS"))
130 if (
m_session->GetSolverInfo(
"HOMOGENEOUS") ==
"1D")
142 cout <<
"Besed on the dominant EV given in the xml file,"
143 <<
"a 1D model is used to evaluate the optumum parameters"
144 <<
"of the SFD method:" << endl;
157 ofstream
m_file(
"ConvergenceHistory.txt", ios::out | ios::trunc);
218 if (
m_comm->GetRank() == 0)
220 cout <<
"\n\t The SFD method is converging: we compute "
221 <<
"stability analysis using the 'partially "
222 <<
"converged' steady state as base flow:\n" << endl;
228 A->GetAdvObject()->SetBaseFlow(q0);
231 if (
m_comm->GetRank() == 0)
254 if (
m_comm->GetRank() == 0)
256 cout <<
"\n\t We compute stability analysis using"
257 <<
" the current flow field as base flow:\n"
264 A->GetAdvObject()->SetBaseFlow(q0);
267 if (
m_comm->GetRank() == 0)
303 for(
int j = 0; j <
m_equ[
m_nequ - 1]->GetNvariables(); ++j)
307 if (
m_comm->GetRank() == 0)
309 out <<
"L 2 error (variable " <<
m_equ[
m_nequ - 1]->GetVariable(j)
310 <<
") : " << vL2Error << endl;
311 out <<
"L inf error (variable " <<
m_equ[
m_nequ - 1]->GetVariable(j)
312 <<
") : " << vLinfError << endl;
329 M11 = coeff*(1.0 + X*Delta*exp(-(X + 1.0/Delta)));
330 M12 = coeff*(X*Delta*(1.0 - exp(-(X + 1.0/Delta))));
331 M21 = coeff*(1.0 - exp(-(X + 1.0/Delta)));
332 M22 = coeff*(X*Delta + exp(-(X + 1.0/Delta)));
346 Vmath::Svtvp(q1[i].num_elements(),
M11, q0[i], 1, q1[i], 1, q1[i], 1 );
347 Vmath::Svtvp(q1[i].num_elements(),
M12, qBar0[i], 1, q1[i], 1, q1[i], 1 );
365 cout <<
"\n\tgrowthEV = " << growthEV << endl;
366 cout <<
"\tfrequencyEV = " << frequencyEV << endl;
368 complex<NekDouble> ApproxEV = polar(exp(growthEV), frequencyEV);
387 const complex<NekDouble> &alpha,
391 cout <<
"\n\tWe enter the Gradient Descent Method [...]" << endl;
392 bool OptParmFound =
false;
393 bool Descending =
true;
411 while (OptParmFound ==
false)
419 s = abs(0.000001/dirx);
420 X_output = X_input + s*dirx;
421 Delta_output = Delta_input + s*diry;
424 while (Descending ==
true)
428 Delta_input = Delta_output;
438 X_output = X_input + s*dirx;
439 Delta_output = Delta_input + s*diry;
442 if(stepCounter > 9999999)
448 Delta_init = Delta_init + Delta_init*0.1;
449 Delta_input = Delta_init;
457 cout <<
"\tThe Gradient Descent Method has converged!" << endl;
459 cout <<
"\n\tThe updated parameters are: X_tilde = " << X_output
460 <<
" and Delta_tilde = " << Delta_output << endl;
475 const complex<NekDouble> &alpha,
478 NekDouble A11 = ( 1.0 + X_input * Delta_input *
479 exp(-(X_input + 1.0/Delta_input)) )/(1.0 + X_input*Delta_input);
480 NekDouble A12 = ( X_input*Delta_input - X_input * Delta_input *
481 exp(-(X_input + 1.0/Delta_input)) )/(1.0 + X_input*Delta_input);
483 exp(-(X_input + 1.0/Delta_input)) )/(1 + X_input*Delta_input);
484 NekDouble A22 = ( X_input*Delta_input + 1.0 *
485 exp(-(X_input + 1.0/Delta_input)) )/(1.0 + X_input*Delta_input);
487 complex<NekDouble> B11 = alpha;
492 complex<NekDouble> a = A11*B11 + A12*B21;
494 complex<NekDouble> c = A21*B11 + A22*B21;
497 complex<NekDouble> delt = sqrt((a-d)*(a-d) + 4.0*b*c);
498 complex<NekDouble> lambda_1 = 0.5*(a+d + delt);
499 complex<NekDouble> lambda_2 = 0.5*(a+d - delt);
504 MaxEV = max(NORM_1, NORM_2);
509 int &KrylovSubspaceDim,
516 int NumLinesInFile = 0;
517 std::string EVfileName =
m_session->GetSessionName() +
".evl";
518 std::ifstream EVfile(EVfileName.c_str());
519 ASSERTL0(EVfile.good(),
"Cannot open .evl file.");
525 while(getline(EVfile, line))
533 if(NumLinesInFile < KrylovSubspaceDim*2.0
534 + KrylovSubspaceDim*(KrylovSubspaceDim+1.0)/2.0)
536 for(
int i = 1; i <= KrylovSubspaceDim; ++i)
538 if(NumLinesInFile == i*2.0 + i*(i+1.0)/2.0)
540 KrylovSubspaceDim = i;
547 EVfile.seekg(0, ios::beg);
551 for(
int i = 0; i < (NumLinesInFile - KrylovSubspaceDim); ++i)
553 std::getline(EVfile, line);
554 cout <<
"Discard line: " << line << endl;
557 std::vector<std::string> tokens;
558 std::getline(EVfile, line);
559 boost::algorithm::split(tokens, line,
560 boost::is_any_of(
"\t "),boost::token_compress_on);
563 "Unexpected formatting of .evl file while reading line:\n"
565 growthEV = boost::lexical_cast<
NekDouble>(tokens[4]);
566 frequencyEV = boost::lexical_cast<
NekDouble>(tokens[5]);
570 cout <<
"An error occurred when opening the .evl file" << endl;
588 MaxNormDiff_q_qBar=0.0;
589 MaxNormDiff_q1_q0=0.0;
593 NormDiff_q_qBar[i] =
m_equ[
m_nequ - 1]->LinfError(i, qBar1[i]);
594 NormDiff_q1_q0[i] =
m_equ[
m_nequ - 1]->LinfError(i, q0[i]);
596 if (MaxNormDiff_q_qBar < NormDiff_q_qBar[i])
598 MaxNormDiff_q_qBar = NormDiff_q_qBar[i];
600 if (MaxNormDiff_q1_q0 < NormDiff_q1_q0[i])
602 MaxNormDiff_q1_q0 = NormDiff_q1_q0[i];
611 if (
m_comm->GetRank() == 0)
614 <<
";\tTime: " << left <<
m_equ[
m_nequ - 1]->GetFinalTime()
615 <<
";\tCPU time = " << left <<
cpuTime <<
" s"
616 <<
";\tTot time = " << left <<
totalTime <<
" s"
617 <<
";\tX = " << left <<
m_X
618 <<
";\tDelta = " << left <<
m_Delta
619 <<
";\t|q-qBar|inf = " << left << MaxNormDiff_q_qBar << endl;
620 std::ofstream
m_file(
"ConvergenceHistory.txt", std::ios_base::app);
624 << MaxNormDiff_q_qBar <<
"\t"
625 << MaxNormDiff_q1_q0 << endl;
636 cout <<
"\n====================================="
637 "=================================="
639 cout <<
"Parameters for the SFD method:" << endl;
640 cout <<
"\tControl Coefficient: X = " <<
m_X << endl;
641 cout <<
"\tFilter Width: Delta = " <<
m_Delta << endl;
642 cout <<
"The simulation is stopped when |q-qBar|inf < " <<
TOL << endl;
645 cout <<
"\nWe use the adaptive SFD method:" << endl;
646 cout <<
" The parameters are updated every " <<
AdaptiveTime
647 <<
" time units;" << endl;
648 cout <<
" until |q-qBar|inf becomes smaller than " <<
AdaptiveTOL
651 cout <<
"====================================="
652 "==================================\n" << endl;
virtual void v_InitObject(ostream &out=cout)
Virtual function for initialisation implementation.
#define ASSERTL0(condition, msg)
void EvalEV_ScalarSFD(const NekDouble &X_input, const NekDouble &Delta_input, const complex< NekDouble > &alpha, NekDouble &MaxEV)
static std::string RegisterEnumValue(std::string pEnum, std::string pString, int pEnumValue)
Registers an enumeration value.
boost::shared_ptr< AdvectionSystem > AdvectionSystemSharedPtr
Shared pointer to an AdvectionSystem class.
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 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
boost::shared_ptr< SessionReader > SessionReaderSharedPtr
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)
virtual void v_Execute(ostream &out=cout)
Virtual function for solve implementation.
SOLVER_UTILS_EXPORT DriverSteadyState(const LibUtilities::SessionReaderSharedPtr pSession)
Constructor.
int m_NonConvergingStepsCounter
void ReadEVfile(int &KrylovSubspaceDim, NekDouble &growthEV, NekDouble &frequencyEV)
enum EvolutionOperatorType m_EvolutionOperator
Evolution Operator.
static std::string className
Name of the class.
void ComputeOptimization()
static DriverSharedPtr create(const LibUtilities::SessionReaderSharedPtr &pSession)
Creates an instance of this class.
virtual SOLVER_UTILS_EXPORT ~DriverSteadyState()
Destructor.
void GradientDescentMethod(const complex< NekDouble > &alpha, NekDouble &X_output, NekDouble &Delta_output)
virtual SOLVER_UTILS_EXPORT void v_InitObject(ostream &out=cout)
Second-stage initialisation.
virtual SOLVER_UTILS_EXPORT void v_Execute(ostream &out=cout)
Virtual function for solve implementation.
void SetSFDOperator(const NekDouble X_input, const NekDouble Delta_input)
Array< OneD, EquationSystemSharedPtr > m_equ
Equation system to solve.
static std::string driverLookupId
NekDouble M11
Definition of the SFD operator.
DriverFactory & GetDriverFactory()
LibUtilities::CommSharedPtr m_comm
Communication object.
NekDouble m_Delta
Definition of the SFD parameters:
A base class for PDEs which include an advection component.
NekDouble TimePerTest(unsigned int n)
Returns amount of seconds per iteration in a test with n iterations.
LibUtilities::SessionReaderSharedPtr m_session
Session reader object.
int m_nequ
number of equations
bool FlowPartiallyConverged
For adaptive SFD method.
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, tDescription pDesc="")
Register a class with the factory.