Commit 62a4cdbf authored by PIACIBELLO Cyrille's avatar PIACIBELLO Cyrille

New version for each arnoldi procedure is functionnal, to use with testBGMRes

parent 8ef263f3
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "Block.hpp" #include "Block.hpp"
#include "HessStandard.hpp" #include "HessStandard.hpp"
#include "Utils.hpp" #include "Utils.hpp"
#include "Logger.hpp"
/** /**
* @brief : Arnoldi iterations * @brief : Arnoldi iterations
...@@ -13,7 +14,10 @@ ...@@ -13,7 +14,10 @@
* @param X0 : Needed for computing real solution if convergence * @param X0 : Needed for computing real solution if convergence
* @param B : Needed for computing real residual if convergence * @param B : Needed for computing real residual if convergence
* @param max_ite : number of iteration to do (at max) * @param max_ite : number of iteration to do (at max)
* @param MaxKSize : Maximum size of Krylov Search space.
* @param epsilon : tolerance for Residual * @param epsilon : tolerance for Residual
* @param log : logger
*
* @return Number of iterations done * @return Number of iterations done
* *
* Solution will be stored inside X0 at the end of computation. * Solution will be stored inside X0 at the end of computation.
...@@ -22,18 +26,23 @@ ...@@ -22,18 +26,23 @@
*/ */
template<class Matrix,class Scalar,class Primary=Scalar> template<class Matrix,class Scalar,class Primary=Scalar>
struct Arnoldi{ struct Arnoldi{
static int Exec_Procedure(Matrix& A,Block<Scalar,Primary>& X0, static ArnReturn Exec_Procedure(Matrix& A,Block<Scalar,Primary>& X0,
Block<Scalar,Primary>& B, Block<Scalar,Primary>& B,
int max_iter,Primary epsilon){ int max_iter,int MaxKSize,Primary epsilon,
Logger<Primary>& log){
std::cout<<"################# Arnoldi standard ##################\n"; std::cout<<"################# Arnoldi standard ##################\n";
std::cout<<"################# Iterations scheduled "<<max_iter<<"\n";
//Initial Size of block //Initial Size of block
int SizeBlock = B.getSizeBlock(); int SizeBlock = B.getSizeBlock();
//Size of matrix //Size of matrix
int dim = A.size(); int dim = A.size();
//Return struct
ArnReturn returned_struct;
//Storage needed for computating //Storage needed for computating
Base<Scalar,Primary> base(SizeBlock,max_iter+1,dim); Base<Scalar,Primary> base(SizeBlock,MaxKSize,dim);
HessStandard<Scalar> Hess(max_iter,SizeBlock); HessStandard<Scalar> Hess(MaxKSize,SizeBlock);
Block<Scalar,Primary> Yj(SizeBlock,dim+SizeBlock); Block<Scalar,Primary> Yj(SizeBlock,dim+SizeBlock);
Block<Scalar,Primary> R0(SizeBlock,dim); Block<Scalar,Primary> R0(SizeBlock,dim);
...@@ -54,13 +63,20 @@ struct Arnoldi{ ...@@ -54,13 +63,20 @@ struct Arnoldi{
//Fisrt block of base added //Fisrt block of base added
base.addBlockDatas(V1); base.addBlockDatas(V1);
bool convergence = false;
int j; int j = 0;
for(j=0 ; j<max_iter ; ++j){ while(j<max_iter){
double timestamp = Logger<Primary>::GetTime();
std::cout<<"\t\tStart of Iteration\n"; std::cout<<"\t\tStart of Iteration\n";
//Compute block Wj //Compute block Wj
Block<Scalar,Primary> Wj(SizeBlock,dim); Block<Scalar,Primary> Wj(SizeBlock,dim);
//Where to write in hess
Scalar * toWrite = Hess.getNewCol(Wj.getSizeBlock());
if(nullptr == toWrite){
break;
}
if(A.useRightPreCond()){//Wj = A*preCond*V[j] if preCond if(A.useRightPreCond()){//Wj = A*preCond*V[j] if preCond
Block<Scalar,Primary> temp(SizeBlock,dim); Block<Scalar,Primary> temp(SizeBlock,dim);
A.preCondBaseProduct(base.getPtr(base.getCurrentBlock()-1),temp); A.preCondBaseProduct(base.getPtr(base.getCurrentBlock()-1),temp);
...@@ -70,10 +86,7 @@ struct Arnoldi{ ...@@ -70,10 +86,7 @@ struct Arnoldi{
Wj.getSizeBlock(),Wj.getPtr()); Wj.getSizeBlock(),Wj.getPtr());
} }
//Where to write in hess
Scalar * toWrite = Hess.getPtr(j);
base.ComputeMGSOrtho(Wj,toWrite,Hess.getLeadingDim()); base.ComputeMGSOrtho(Wj,toWrite,Hess.getLeadingDim());
std::cout<<"Ortho done"<<std::endl; std::cout<<"Ortho done"<<std::endl;
//QR facto of orthogonalized Wj //QR facto of orthogonalized Wj
...@@ -87,13 +100,16 @@ struct Arnoldi{ ...@@ -87,13 +100,16 @@ struct Arnoldi{
//Tests over criterion //Tests over criterion
Hess.ComputeBlockResidual(R1,Yj); Hess.ComputeBlockResidual(R1,Yj);
std::cout<<"["<<j<<"]\t"<<"Residual computed"<<std::endl; std::cout<<"["<<j<<"]\t"<<"Residual computed"<<std::endl;
std::pair<Primary,Primary> MinMax;
{//Display residual to see convergence {//Display residual to see convergence
std::pair<Primary,Primary> MinMax MinMax = Hess.template displayBlockResidual<Primary>(Yj,R1);
= Hess.template displayBlockResidual<Primary>(Yj,R1);
std::cout<<"["<<j<<"]\t"<<"Min "<<MinMax.first std::cout<<"["<<j<<"]\t"<<"Min "<<MinMax.first
<<"\tMax "<<MinMax.second<<"\n"; <<"\tMax "<<MinMax.second<<"\n";
if(MinMax.second <= epsilon){ if(MinMax.second <= epsilon){
if(CheckCurrentSolution(A,B,X0,base,Yj,epsilon)){ if(CheckCurrentSolution(A,B,X0,base,Yj,epsilon)){
//Adding last ite
log.add_ite(j,SizeBlock,MinMax.first,MinMax.second,timestamp);
convergence = true;
break; break;
}else{ }else{
std::cout<<"Residual is small enough, but not the real's one \n"; std::cout<<"Residual is small enough, but not the real's one \n";
...@@ -103,8 +119,10 @@ struct Arnoldi{ ...@@ -103,8 +119,10 @@ struct Arnoldi{
//Base augmentation //Base augmentation
base.addBlockDatas(Q); base.addBlockDatas(Q);
std::cout<<"Base has been augmented\n"; std::cout<<"Base has been augmented\n";
log.add_ite(j,SizeBlock,MinMax.first,MinMax.second,timestamp);
j++;
} }
if(j==max_iter){ //No convergence, we need to write current sol into X0 if(!convergence){ //No convergence, we need to write current sol into X0
Block<Scalar,Primary> Sol{SizeBlock,dim}; Block<Scalar,Primary> Sol{SizeBlock,dim};
if(A.useRightPreCond()){ if(A.useRightPreCond()){
Block<Scalar,Primary> temp(SizeBlock,dim); Block<Scalar,Primary> temp(SizeBlock,dim);
...@@ -119,7 +137,10 @@ struct Arnoldi{ ...@@ -119,7 +137,10 @@ struct Arnoldi{
} }
} }
} }
return j; std::cout<<"################# Iterations done ... "<<j<<"\n";
returned_struct.nbIteDone = j;
returned_struct.hasConverged = convergence;
return returned_struct;
} }
}; };
#endif //ARNOLDI_HP #endif //ARNOLDI_HP
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "BlockWP.hpp" #include "BlockWP.hpp"
#include "HessExtended.hpp" #include "HessExtended.hpp"
#include "Utils.hpp" #include "Utils.hpp"
#include "Logger.hpp"
/** /**
* @brief : Arnoldi iterations with inexact breakdowns * @brief : Arnoldi iterations with inexact breakdowns
...@@ -14,6 +15,8 @@ ...@@ -14,6 +15,8 @@
* @param B : Needed for computing real residual if convergence * @param B : Needed for computing real residual if convergence
* @param max_ite : number of iteration to do (at max) * @param max_ite : number of iteration to do (at max)
* @param epsilon : tolerance for Residual * @param epsilon : tolerance for Residual
* @param log : logger
*
* @return Number of iterations done * @return Number of iterations done
* *
* Solution will be stored inside X0 at the end of computation. * Solution will be stored inside X0 at the end of computation.
...@@ -22,22 +25,34 @@ ...@@ -22,22 +25,34 @@
*/ */
template<class Matrix,class Scalar,class Primary=Scalar> template<class Matrix,class Scalar,class Primary=Scalar>
struct Arnoldi_IB{ struct Arnoldi_IB{
static int Exec_Procedure(Matrix& A,Block<Scalar,Primary>& X0, static ArnReturn Exec_Procedure(Matrix& A,Block<Scalar,Primary>& X0,
Block<Scalar,Primary>& B, Block<Scalar,Primary>& B,
int max_iter,Primary epsilon){ int max_iter,int MaxKSize, Primary epsilon,
Logger<Primary>& log){
std::cout<<"########### Arnoldi with Inexact Breakdown ############\n"; std::cout<<"########### Arnoldi with Inexact Breakdown ############\n";
//Initial Size of block //Initial Size of block
int SizeBlock = B.getSizeBlock(); int SizeBlock = B.getSizeBlock();
//Size of matrix //Size of matrix
int dim = A.size(); int dim = A.size();
//Return struct
ArnReturn returned_struct;
//We store the size of each block -- Could be delegated to a class ? //We store the size of each block -- Could be delegated to a class ?
std::vector<int> sizeOfEachBlock; // std::vector<int> sizeOfEachBlock;
sizeOfEachBlock.reserve(max_iter); // sizeOfEachBlock.reserve(max_iter);
sizeOfEachBlock.push_back(SizeBlock); // sizeOfEachBlock.push_back(SizeBlock);
std::vector<int> sumOfSizeOfEachBlock; std::vector<int> sumOfSizeOfEachBlock;
sumOfSizeOfEachBlock.push_back(SizeBlock); sumOfSizeOfEachBlock.push_back(SizeBlock);
//Counter
int j; //Set the hessenberg
HessExtended<Scalar> L(MaxKSize,SizeBlock);
Base<Scalar,Primary> base(SizeBlock,MaxKSize,dim);
//Create Block to Store W and P (if IB happens)
BlockWP<Scalar,Primary> WP(SizeBlock,dim);
//Create Block to Store Y
Block<Scalar,Primary> Y(SizeBlock,dim+SizeBlock);
//Compute first block residual (step 1) //Compute first block residual (step 1)
Block<Scalar,Primary> R0(SizeBlock,dim); Block<Scalar,Primary> R0(SizeBlock,dim);
//Fill matrix R0 with each vector r0_i = B[i] - A * X0[i] //Fill matrix R0 with each vector r0_i = B[i] - A * X0[i]
...@@ -51,22 +66,24 @@ struct Arnoldi_IB{ ...@@ -51,22 +66,24 @@ struct Arnoldi_IB{
Block<Scalar,Primary> R1(SizeBlock,SizeBlock); Block<Scalar,Primary> R1(SizeBlock,SizeBlock);
//Q-R Decomposition of (R0) //Q-R Decomposition of (R0)
R0.ComputeQRFacto(V1,R1); R0.ComputeQRFacto(V1,R1);
//First block of base added
//Set the base
Base<Scalar,Primary> base(SizeBlock,max_iter+1,dim);
base.addBlockDatas(V1); base.addBlockDatas(V1);
//Set the hessenberg
HessExtended<Scalar> L(SizeBlock,max_iter);
//Create Block to Store W and P (if IB happens)
BlockWP<Scalar,Primary> WP(SizeBlock,dim);
//Create Block to Store Y
Block<Scalar,Primary> Y(SizeBlock,dim+SizeBlock);
//Nb directions discarded //Nb directions discarded
int nbDeflDir = 0; int nbDeflDir = 0;
//Main Loop bool convergence = false;
for(j=0 ; j<max_iter ; ++j){ //Counter
int j=0;
while(j<max_iter){ //Main Loop
double timestamp = Logger<Primary>::GetTime();
std::cout<<"\t\tStart of Iteration\n"; std::cout<<"\t\tStart of Iteration\n";
//Get new starting point, and test if restart is triggered
Scalar * toWrite = L.getNewStartingCol(WP.getSizeW()); //Where to write
if(nullptr == toWrite){ //No more room for this iteration
break;
}
if(A.useRightPreCond()){//Wj = A*preCond*V[j] if preCond if(A.useRightPreCond()){//Wj = A*preCond*V[j] if preCond
Block<Scalar,Primary> temp(SizeBlock-nbDeflDir,dim); Block<Scalar,Primary> temp(SizeBlock-nbDeflDir,dim);
A.preCondBaseProduct(base.getPtr(base.getCurrentBlock()-1),temp); A.preCondBaseProduct(base.getPtr(base.getCurrentBlock()-1),temp);
...@@ -76,8 +93,6 @@ struct Arnoldi_IB{ ...@@ -76,8 +93,6 @@ struct Arnoldi_IB{
WP.getW()); WP.getW());
} }
//Ortho against V and store coeff inside new block column of Hess L //Ortho against V and store coeff inside new block column of Hess L
//L.displayHessExtended("Hess Before ortho");
Scalar * toWrite = L.getNewStartingCol(WP.getSizeW()); //Where to write
base.ComputeMGSOrtho(WP,toWrite,L.getLeadingDim(),WP.getSizeP()); base.ComputeMGSOrtho(WP,toWrite,L.getLeadingDim(),WP.getSizeP());
std::cout<<"Ortho against V and P"<<std::endl; std::cout<<"Ortho against V and P"<<std::endl;
...@@ -101,6 +116,9 @@ struct Arnoldi_IB{ ...@@ -101,6 +116,9 @@ struct Arnoldi_IB{
if(MinMax.second < epsilon){ if(MinMax.second < epsilon){
//here, add a test on the real residual //here, add a test on the real residual
if(CheckCurrentSolution(A,B,X0,base,Y,epsilon)){ if(CheckCurrentSolution(A,B,X0,base,Y,epsilon)){
//Adding last ite
log.add_ite(j,WP.getSizeW(),MinMax.first,MinMax.second,timestamp);
convergence = true;
break; break;
} }
} }
...@@ -129,9 +147,14 @@ struct Arnoldi_IB{ ...@@ -129,9 +147,14 @@ struct Arnoldi_IB{
//Update //Update
//V_{j+1} = [P_{j-1},~Wj] * Directions_1 //V_{j+1} = [P_{j-1},~Wj] * Directions_1
WP.ComputeProduct(Directions,U.getSizeBlock(), Scalar * baseToWrite = base.getLastColPtr(U.getSizeBlock());
base.getLastColPtr(U.getSizeBlock()), if(baseToWrite){
base.getLeadingDim()); WP.ComputeProduct(Directions,U.getSizeBlock(),
baseToWrite,
base.getLeadingDim());
}else{
break;
}
//Pj = [P_{j-1},~Wj] * Directions_2 //Pj = [P_{j-1},~Wj] * Directions_2
WP.ComputeProduct(Directions,U.getSizeBlock()); WP.ComputeProduct(Directions,U.getSizeBlock());
//L.displayHessExtended("hess before update bottom line"); //L.displayHessExtended("hess before update bottom line");
...@@ -139,12 +162,14 @@ struct Arnoldi_IB{ ...@@ -139,12 +162,14 @@ struct Arnoldi_IB{
//Gj = | Directions_2^{H} | //Gj = | Directions_2^{H} |
L.UpdateBottomLine(Directions); L.UpdateBottomLine(Directions);
} }
sizeOfEachBlock.push_back(U.getSizeBlock()); //sizeOfEachBlock.push_back(U.getSizeBlock());
sumOfSizeOfEachBlock.push_back(U.getSizeBlock()+sumOfSizeOfEachBlock.back()); sumOfSizeOfEachBlock.push_back(U.getSizeBlock()+sumOfSizeOfEachBlock.back());
std::cout<<"################## End of Iteration ##################\n\n"; std::cout<<"################## End of Iteration ##################\n\n";
log.add_ite(j,WP.getSizeW(),MinMax.first,MinMax.second,timestamp);
++j;
} }
if(j==max_iter){ //No convergence, we need to write current sol into X0 if(!convergence){ //No convergence, we need to write current sol into X0
Block<Scalar,Primary> Sol{SizeBlock,dim}; Block<Scalar,Primary> Sol{SizeBlock,dim};
if(A.useRightPreCond()){ if(A.useRightPreCond()){
Block<Scalar,Primary> temp(SizeBlock,dim); Block<Scalar,Primary> temp(SizeBlock,dim);
...@@ -159,7 +184,10 @@ struct Arnoldi_IB{ ...@@ -159,7 +184,10 @@ struct Arnoldi_IB{
} }
} }
} }
return j; std::cout<<"################# Iterations done ... "<<j<<"\n";
returned_struct.nbIteDone = j;
returned_struct.hasConverged = convergence;
return returned_struct;
} }
}; };
......
...@@ -13,7 +13,10 @@ ...@@ -13,7 +13,10 @@
* @param X0 : Needed for computing real solution if convergence * @param X0 : Needed for computing real solution if convergence
* @param B : Needed for computing real residual if convergence * @param B : Needed for computing real residual if convergence
* @param max_ite : number of iteration to do (at max) * @param max_ite : number of iteration to do (at max)
* @param MaxKSize : Maximum size of Krylov Search space.
* @param epsilon : tolerance for Residual * @param epsilon : tolerance for Residual
* @param log : logger
*
* @return Number of iterations done * @return Number of iterations done
* *
* Solution will be stored inside X0 at the end of computation. * Solution will be stored inside X0 at the end of computation.
...@@ -22,9 +25,10 @@ ...@@ -22,9 +25,10 @@
*/ */
template<class Matrix,class Scalar,class Primary=Scalar> template<class Matrix,class Scalar,class Primary=Scalar>
struct Arnoldi_QRInc{ struct Arnoldi_QRInc{
static int Exec_Procedure(Matrix& A,Block<Scalar,Primary>& X0, static ArnReturn Exec_Procedure(Matrix& A,Block<Scalar,Primary>& X0,
Block<Scalar,Primary>& B, Block<Scalar,Primary>& B,
int max_iter,Primary epsilon){ int max_iter,int MaxKSize, Primary epsilon,
Logger<Primary>& log){
std::cout<<"################# Arnoldi with QR Inc ################\n"; std::cout<<"################# Arnoldi with QR Inc ################\n";
//Initial Size of block //Initial Size of block
...@@ -32,9 +36,12 @@ struct Arnoldi_QRInc{ ...@@ -32,9 +36,12 @@ struct Arnoldi_QRInc{
//Size of matrix //Size of matrix
int dim = A.size(); int dim = A.size();
//Return struct
ArnReturn returned_struct;
//Storage needed for computating //Storage needed for computating
Base<Scalar,Primary> base(SizeBlock,max_iter+1,dim); Base<Scalar,Primary> base(SizeBlock,MaxKSize,dim);
HessQR<Scalar,Primary> Hess(max_iter+1,SizeBlock); HessQR<Scalar,Primary> Hess(MaxKSize,SizeBlock);
Block<Scalar,Primary> Yj(SizeBlock,dim+SizeBlock); Block<Scalar,Primary> Yj(SizeBlock,dim+SizeBlock);
Block<Scalar,Primary> R0(SizeBlock,dim); Block<Scalar,Primary> R0(SizeBlock,dim);
...@@ -52,19 +59,27 @@ struct Arnoldi_QRInc{ ...@@ -52,19 +59,27 @@ struct Arnoldi_QRInc{
Block<Scalar,Primary> R1(SizeBlock,SizeBlock); Block<Scalar,Primary> R1(SizeBlock,SizeBlock);
//Q-R Decomposition of (R0) //Q-R Decomposition of (R0)
R0.ComputeQRFacto(V1,R1); R0.ComputeQRFacto(V1,R1);
//First block of base added
//Fisrt block of base added
base.addBlockDatas(V1); base.addBlockDatas(V1);
//Give to Hessenberg the Gamma, that will be used as RHS in //Give to Hessenberg the Gamma, that will be used as RHS in
//leastsquare calls. //leastsquare calls.
Hess.initRHS(R1); Hess.initRHS(R1);
int j; bool convergence = false;
for(j=0 ; j<max_iter ; ++j){ int j = 0;
while(j<max_iter){
double timestamp = Logger<Primary>::GetTime();
std::cout<<"\t\tStart of Iteration\n"; std::cout<<"\t\tStart of Iteration\n";
//Compute block Wj //Compute block Wj
Block<Scalar,Primary> Wj(SizeBlock,dim); Block<Scalar,Primary> Wj(SizeBlock,dim);
//Where to write in hess
Scalar * toWrite = Hess.getNewCol(Wj.getSizeBlock());
if(nullptr == toWrite){ //No more room for this iteration
break;
}
if(A.useRightPreCond()){//Wj = A*preCond*V[j] if preCond if(A.useRightPreCond()){//Wj = A*preCond*V[j] if preCond
Block<Scalar,Primary> temp(SizeBlock,dim); Block<Scalar,Primary> temp(SizeBlock,dim);
A.preCondBaseProduct(base.getPtr(base.getCurrentBlock()-1),temp); A.preCondBaseProduct(base.getPtr(base.getCurrentBlock()-1),temp);
...@@ -74,8 +89,6 @@ struct Arnoldi_QRInc{ ...@@ -74,8 +89,6 @@ struct Arnoldi_QRInc{
Wj.getSizeBlock(),Wj.getPtr()); Wj.getSizeBlock(),Wj.getPtr());
} }
//Where to write in hess
Scalar * toWrite = Hess.getNewCol();
base.ComputeMGSOrtho(Wj,toWrite,Hess.getLeadingDim()); base.ComputeMGSOrtho(Wj,toWrite,Hess.getLeadingDim());
std::cout<<"Ortho done"<<std::endl; std::cout<<"Ortho done"<<std::endl;
...@@ -83,7 +96,6 @@ struct Arnoldi_QRInc{ ...@@ -83,7 +96,6 @@ struct Arnoldi_QRInc{
Block<Scalar,Primary> Q(SizeBlock,dim); Block<Scalar,Primary> Q(SizeBlock,dim);
Block<Scalar,Primary> R(SizeBlock,SizeBlock); Block<Scalar,Primary> R(SizeBlock,SizeBlock);
Wj.ComputeQRFacto(Q,R); Wj.ComputeQRFacto(Q,R);
//Copy Block R inside Hess //Copy Block R inside Hess
Hess.addRPartToHess(R); Hess.addRPartToHess(R);
std::cout<<"QR done"<<std::endl; std::cout<<"QR done"<<std::endl;
...@@ -91,12 +103,14 @@ struct Arnoldi_QRInc{ ...@@ -91,12 +103,14 @@ struct Arnoldi_QRInc{
//Tests over criterion //Tests over criterion
std::pair<Primary,Primary> MinMax = Hess.LeastSquare(Yj,epsilon); std::pair<Primary,Primary> MinMax = Hess.LeastSquare(Yj,epsilon);
std::cout<<"["<<j<<"]\t"<<"Residual computed\n" std::cout<<"["<<j<<"]\t"<<"Residual computed\n"
<<"\t\tMin\t"<<MinMax.first<<"\tMax"<<MinMax.second <<"\t\tMin\t"<<MinMax.first<<"\tMax\t"<<MinMax.second
<<std::endl; <<std::endl;
if(MinMax.second <= epsilon){ if(MinMax.second <= epsilon){
if(CheckCurrentSolution(A,B,X0,base,Yj,epsilon)){ if(CheckCurrentSolution(A,B,X0,base,Yj,epsilon)){
std::cout<<"There\n"; //Adding last ite
log.add_ite(j,SizeBlock,MinMax.first,MinMax.second,timestamp);
convergence = true;
break; break;
}else{ }else{
std::cout<<"Residual is small enough, but not the real's one \n"; std::cout<<"Residual is small enough, but not the real's one \n";
...@@ -105,8 +119,12 @@ struct Arnoldi_QRInc{ ...@@ -105,8 +119,12 @@ struct Arnoldi_QRInc{
//Base augmentation //Base augmentation
base.addBlockDatas(Q); base.addBlockDatas(Q);
std::cout<<"Base has been augmented\n"; std::cout<<"Base has been augmented\n";
log.add_ite(j,SizeBlock,MinMax.first,MinMax.second,timestamp);
++j;
} }
if(j==max_iter){ //No convergence, we need to write current sol into X0 if(!convergence){ //No convergence, we need to write current sol into X0
//First, call the triangular solver to get the solution
Hess.ComputeCurrentSol(Yj);
Block<Scalar,Primary> Sol{SizeBlock,dim}; Block<Scalar,Primary> Sol{SizeBlock,dim};
if(A.useRightPreCond()){ if(A.useRightPreCond()){
Block<Scalar,Primary> temp(SizeBlock,dim); Block<Scalar,Primary> temp(SizeBlock,dim);
...@@ -121,7 +139,10 @@ struct Arnoldi_QRInc{ ...@@ -121,7 +139,10 @@ struct Arnoldi_QRInc{
} }
} }
} }
return j; std::cout<<"################# Iterations done ... "<<j<<"\n";
returned_struct.nbIteDone = j;
returned_struct.hasConverged = convergence;
return returned_struct;
} }
}; };
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <algorithm> #include <algorithm>
#include "Block.hpp" #include "Block.hpp"
#include "Utils.hpp"
/** /**
* @brief : GMRes with Inexact Breakdowns, restart and preconditionner * @brief : GMRes with Inexact Breakdowns, restart and preconditionner
...@@ -13,7 +14,7 @@ ...@@ -13,7 +14,7 @@
* @param B : Block containing Right Hand Side * @param B : Block containing Right Hand Side
* @param X0 : Initial guess * @param X0 : Initial guess
* @param max_iter : Total iteration * @param max_iter : Total iteration
* @param restart : max number of iteration before restarting * @param MaxKSize : maximum size of Krylov space
* @param Sol : Block to store the solution * @param Sol : Block to store the solution
* @param epsilon : Target accuracy * @param epsilon : Target accuracy
* *
...@@ -21,8 +22,9 @@ ...@@ -21,8 +22,9 @@
*/ */
template<typename Arn,class Matrix,class Scalar,class Primary> template<typename Arn,class Matrix,class Scalar,class Primary>
int BGMRes(Matrix& A,Block<Scalar,Primary>& B, Block<Scalar,Primary>& X0, int BGMRes(Matrix& A,Block<Scalar,Primary>& B, Block<Scalar,Primary>& X0,
int max_iter, int restart, int max_iter, int MaxKSize,
Block<Scalar,Primary>& Sol,Primary epsilon = 0.0000001){ Block<Scalar,Primary>& Sol,Logger<Primary>& log,
Primary epsilon = 0.0000001){
//Cste Size //Cste Size
int SizeBlock = B.getSizeBlock(); int SizeBlock = B.getSizeBlock();
...@@ -34,7 +36,7 @@ int BGMRes(Matrix& A,Block<Scalar,Primary>& B, Block<Scalar,Primary>& X0, ...@@ -34,7 +36,7 @@ int BGMRes(Matrix& A,Block<Scalar,Primary>& B, Block<Scalar,Primary>& X0,
std::cout<<"Dimension of Problem :\t"<<dim<<"\n"; std::cout<<"Dimension of Problem :\t"<<dim<<"\n";
std::cout<<"Number of Right Hand Side :\t"<<SizeBlock<<"\n"; std::cout<<"Number of Right Hand Side :\t"<<SizeBlock<<"\n";
std::cout<<"Maximum nb of Iterations:\t"<<max_iter<<"\n"; std::cout<<"Maximum nb of Iterations:\t"<<max_iter<<"\n";
std::cout<<"Restart IBGMRes each:\t"<<restart<<" iterations.\n"; std::cout<<"Max Size Krylov space before restart :\t"<<MaxKSize<<"\n";
std::cout<<"#######################################################\n"; std::cout<<"#######################################################\n";
if(A.useRightPreCond()){ if(A.useRightPreCond()){
...@@ -56,28 +58,35 @@ int BGMRes(Matrix& A,Block<Scalar,Primary>& B, Block<Scalar,Primary>& X0, ...@@ -56,28 +58,35 @@ int BGMRes(Matrix& A,Block<Scalar,Primary>& B, Block<Scalar,Primary>& X0,
// Global step is total number of iteration (thus is <max_iter) // Global step is total number of iteration (thus is <max_iter)
int k=0,nb_restart=0; int k=0,nb_restart=0;
int nbIteDone = 0;
while(k<max_iter){ while(k<max_iter){
//Compute nb_iter to give to Arnoldi procedure //Compute nb_iter to give to Arnoldi procedure
int arnoldi_ite = std::min(restart,max_iter-k); int arnoldi_ite = max_iter - nbIteDone;
std::cout<<"\n################## Restart number "<<nb_restart std::cout<<"\n################## Restart number "<<nb_restart
<<" #################\n"; <<" #################\n";