Skip to content

Commit 8278d00

Browse files
committed
restarted FGMRES
1 parent ecee3af commit 8278d00

3 files changed

Lines changed: 31 additions & 18 deletions

File tree

Common/include/option_structure.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ static const MapType<string, ENUM_MAIN_SOLVER> Solver_Map = {
237237
};
238238

239239
/*!
240-
* \brief different solver types for the multizone environment component
240+
* \brief Different solver types for multizone problems
241241
*/
242242
enum ENUM_MULTIZONE {
243243
MZ_BLOCK_GAUSS_SEIDEL = 0, /*!< \brief Definition of a Block-Gauss-Seidel multizone solver. */

SU2_CFD/include/drivers/CDiscAdjMultizoneDriver.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,12 @@ class CDiscAdjMultizoneDriver : public CMultizoneDriver {
106106
for jZone, we need to store all terms to have BGS-type updates with relaxation. */
107107
vector<vector<vector<su2passivematrix> > > Cross_Terms;
108108

109-
vector<CQuasiNewtonInvLeastSquares<passivedouble> > fixPtCorrector;
109+
/*!< \brief Fixed-Point corrector that can be applied to inner iterations. */
110+
vector<CQuasiNewtonInvLeastSquares<passivedouble> > FixPtCorrector;
110111

111-
static constexpr unsigned long KrylovMinIters = 5;
112+
/*!< \brief Members to use GMRES to drive inner iterations (alternative to quasi-Newton). */
113+
static constexpr unsigned long KrylovMinIters = 3;
114+
const Scalar KrylovTol = 0.01;
112115
vector<CSysSolve<Scalar> > LinSolver;
113116
vector<CSysVector<Scalar> > AdjRHS, AdjSol;
114117

SU2_CFD/src/drivers/CDiscAdjMultizoneDriver.cpp

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ CDiscAdjMultizoneDriver::CDiscAdjMultizoneDriver(char* confFile,
4646

4747
Has_Deformation.resize(nZone) = false;
4848

49-
fixPtCorrector.resize(nZone);
49+
50+
FixPtCorrector.resize(nZone);
5051
LinSolver.resize(nZone);
5152
AdjRHS.resize(nZone);
5253
AdjSol.resize(nZone);
@@ -179,10 +180,10 @@ bool CDiscAdjMultizoneDriver::Iterate(unsigned short iZone, unsigned long iInner
179180

180181
/*--- Use QN driver to improve the solution. ---*/
181182

182-
if (fixPtCorrector[iZone].size()) {
183-
GetAllSolutions(iZone, true, fixPtCorrector[iZone].FPresult());
184-
fixPtCorrector[iZone].compute();
185-
if(iInnerIter) SetAllSolutions(iZone, true, fixPtCorrector[iZone]);
183+
if (FixPtCorrector[iZone].size()) {
184+
GetAllSolutions(iZone, true, FixPtCorrector[iZone].FPresult());
185+
FixPtCorrector[iZone].compute();
186+
if(iInnerIter) SetAllSolutions(iZone, true, FixPtCorrector[iZone]);
186187
}
187188

188189
/*--- Residuals during GMRES iterations have no meaning ---*/
@@ -225,14 +226,15 @@ void CDiscAdjMultizoneDriver::Run() {
225226
const auto nPointDomain = geometry_container[iZone][INST_0][MESH_0]->GetnPointDomain();
226227
const auto nVar = GetTotalNumberOfVariables(iZone, true);
227228

228-
if (config_container[iZone]->GetNewtonKrylov() && nInnerIter[iZone] >= KrylovMinIters) {
229+
if (config_container[iZone]->GetNewtonKrylov() &&
230+
config_container[iZone]->GetnQuasiNewtonSamples() >= KrylovMinIters) {
229231
AdjRHS[iZone].Initialize(nPoint, nPointDomain, nVar, nullptr);
230232
AdjSol[iZone].Initialize(nPoint, nPointDomain, nVar, nullptr);
231233
LinSolver[iZone].SetRecomputeResidual(false);
232234
LinSolver[iZone].SetMonitoringFrequency(config_container[iZone]->GetScreen_Wrt_Freq(2));
233235
}
234236
else if (config_container[iZone]->GetnQuasiNewtonSamples() > 1) {
235-
fixPtCorrector[iZone].resize(config_container[iZone]->GetnQuasiNewtonSamples(), nPoint, nVar, nPointDomain);
237+
FixPtCorrector[iZone].resize(config_container[iZone]->GetnQuasiNewtonSamples(), nPoint, nVar, nPointDomain);
236238
}
237239
}
238240

@@ -326,12 +328,12 @@ void CDiscAdjMultizoneDriver::Run() {
326328

327329
/*--- Reset QN driver for new inner iterations. ---*/
328330

329-
if (fixPtCorrector[iZone].size()) {
330-
fixPtCorrector[iZone].reset();
331-
if(restart && (iOuterIter==1)) GetAllSolutions(iZone, true, fixPtCorrector[iZone]);
331+
if (FixPtCorrector[iZone].size()) {
332+
FixPtCorrector[iZone].reset();
333+
if(restart && (iOuterIter==1)) GetAllSolutions(iZone, true, FixPtCorrector[iZone]);
332334
}
333335

334-
if (!config_container[iZone]->GetNewtonKrylov() || !no_restart || nInnerIter[iZone]<KrylovMinIters) {
336+
if (!config_container[iZone]->GetNewtonKrylov() || !no_restart || nInnerIter[iZone] < KrylovMinIters) {
335337

336338
/*--- Regular fixed-point, possibly with quasi-Newton method. ---*/
337339

@@ -367,10 +369,18 @@ void CDiscAdjMultizoneDriver::Run() {
367369
GetAllSolutions(iZone, true, AdjSol[iZone]);
368370

369371
const bool monitor = config_container[iZone]->GetWrt_ZoneConv();
370-
371-
Scalar eps = 0.0;
372-
LinSolver[iZone].FGMRES_LinSolver(AdjRHS[iZone], AdjSol[iZone], AdjointProduct(this,iZone), Identity(),
373-
Scalar(1e-9), nInnerIter[iZone]-2, eps, monitor, config_container[iZone]);
372+
const auto product = AdjointProduct(this, iZone);
373+
374+
Scalar eps = 1.0;
375+
for (auto totalIter = nInnerIter[iZone]; totalIter >= KrylovMinIters && eps > KrylovTol;) {
376+
Scalar eps_l = 0.0;
377+
Scalar tol_l = KrylovTol / eps;
378+
auto iter = min(totalIter-1ul, config_container[iZone]->GetnQuasiNewtonSamples()-1ul);
379+
iter = LinSolver[iZone].FGMRES_LinSolver(AdjRHS[iZone], AdjSol[iZone], product, Identity(),
380+
tol_l, iter, eps_l, monitor, config_container[iZone]);
381+
totalIter -= iter+1;
382+
eps *= eps_l;
383+
}
374384

375385
SetAllSolutions(iZone, true, AdjSol[iZone]);
376386

0 commit comments

Comments
 (0)