41 namespace MultiRegions
43 std::string GlobalLinSysIterative::IteratSolverlookupIds[2] =
45 LibUtilities::SessionReader::RegisterEnumValue(
46 "LinSysIterSolver",
"ConjugateGradient", MultiRegions::
48 LibUtilities::SessionReader::RegisterEnumValue(
52 std::string GlobalLinSysIterative::IteratSolverdef =
53 LibUtilities::SessionReader::RegisterDefaultSolverInfo(
54 "LinSysIterSolver",
"ConjugateGradient");
63 GlobalLinSysIterative::GlobalLinSysIterative(
65 const std::weak_ptr<ExpList> &pExpList,
66 const std::shared_ptr<AssemblyMap>
73 m_useProjection(false),
76 m_tolerance = pLocToGloMap->GetIterativeTolerance();
77 m_maxiter = pLocToGloMap->GetMaxIterations();
81 m_root = (vComm->GetRank())?
false :
true;
90 WARNINGL0(
false,
"To use A-conjugate projection, the matrix should be symmetric positive definite.");
111 m_expList.lock()->GetComm()->GetRowComm();
119 "' is not defined.\n");
162 const bool isAconjugate)
164 int numIterations = 0;
168 numIterations =
m_linsol->SolveSystem(nGlobal, pInput, pOutput, nDir, tol);
174 =
m_expList.lock()->GetComm()->GetRowComm();
177 int nNonDir = nGlobal - nDir;
194 cout <<
"No iterations made"
195 <<
" using tolerance of " << tol
237 alpha[0] = alphaback[latest];
247 pInput.get() + nDir, 1,
248 pb_s.get() + nDir, 1);
257 cout <<
"SuccessiveRHS: " <<
m_prevBasis.size() <<
"-bases projection reduces L2-norm of RHS from " <<
std::sqrt(rhsNorm) <<
" to ";
268 numIterations =
m_linsol->SolveSystem(nGlobal, pb_s, tmpx_s, nDir, tol);
305 const bool isAconjugate)
308 int nNonDir = nGlobal - nDir;
314 =
m_expList.lock()->GetComm()->GetRowComm();
326 newBasis = newX + nDir;
330 newBasis = tmpAx_s + nDir;
348 tmp = tmpAx_s + nDir, 1);
352 if(i == insertLocation)
continue;
353 int skip = i > insertLocation;
369 if(i == insertLocation)
continue;
370 int iskip = i > insertLocation;
373 if(j == insertLocation)
continue;
374 int jskip = j > insertLocation;
375 tilCoeffMatrix->SetValue(i-iskip, j-jskip,
m_coeffMatrix->GetValue(i, j));
385 int n, info1 = 0, info2 = 0, info3 = 0;
388 n = tilCoeffMatrix->GetRows();
390 Vmath::Vcopy(tilCoeffMatrix->GetStorageSize(), tilCoeffMatrix->GetPtr(), 1, tilCoeffMatrixFactor, 1);
391 Lapack::Dsptrf(
'U', n, tilCoeffMatrixFactor.get(), ipivot.get(), info1);
395 Lapack::Dsptrs(
'U', n, 1, tilCoeffMatrixFactor.get(), ipivot.get(), invMy_s.get(), n, info2);
401 y_s[0] = y_s[latest - (latest > insertLocation)];
408 for (
int i = 0; i <
m_prevBasis.size()-fullbuffer; i++)
410 residual -= y_s[i] * invMy_s[i];
412 if(
m_verbose &&
m_root) cout <<
"SuccessiveRHS: residual " << residual;
413 if (residual < epsilon)
415 if(
m_verbose &&
m_root) cout <<
" < " << epsilon <<
", reject" << endl;
425 newCoeffMatrix->SetValue(insertLocation, insertLocation, 1.);
428 if(i == insertLocation)
continue;
429 int iskip = i > insertLocation;
430 newCoeffMatrix->SetValue(insertLocation, i, y_s[i-iskip]);
436 newCoeffMatrix->SetValue(insertLocation, insertLocation, 1.);
439 newCoeffMatrix->SetValue(insertLocation, i, y_s[i]);
442 newCoeffMatrix->SetValue(i, j,
m_coeffMatrix->GetValue(i, j));
446 n = newCoeffMatrix->GetRows();
448 Vmath::Vcopy(newCoeffMatrix->GetStorageSize(), newCoeffMatrix->GetPtr(), 1, coeffMatrixFactor, 1);
449 Lapack::Dsptrf(
'U', n, coeffMatrixFactor.get(), ipivot.get(), info3);
452 if(
m_verbose &&
m_root) cout <<
" >= " << epsilon <<
", reject (Dsptrf fails)" << endl;
455 if(
m_verbose &&
m_root) cout <<
" >= " << epsilon <<
", accept" << endl;
472 tmp = newX + nDir, 1,
488 if (
m_map.size() > 0)
491 &pIn[0],&pIn[0],&
m_map[0]);
494 m_expList.lock()->GetComm()->GetRowComm()->AllReduce(
501 NekDouble new_rhs_mag = (vExchange[0] > 1e-6)? vExchange[0] : 1.0;
#define ASSERTL0(condition, msg)
#define WARNINGL0(condition, msg)
void DefineNekSysLhsEval(FuncPointerT func, ObjectPointerT obj)
void DefineNekSysPrecon(FuncPointerT func, ObjectPointerT obj)
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
const std::weak_ptr< ExpList > m_expList
Local Matrix System.
PreconditionerSharedPtr CreatePrecon(AssemblyMapSharedPtr asmMap)
Create a preconditioner object from the parameters defined in the supplied assembly map.
Array< OneD, int > m_ipivot
std::vector< Array< OneD, NekDouble > > m_prevBasis
LibUtilities::NekLinSysIterSharedPtr m_linsol
PreconditionerSharedPtr m_precon
void DoProjection(const int pNumRows, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const int pNumDir, const NekDouble tol, const bool isAconjugate)
projection technique
void UpdateKnownSolutions(const int pGlobalBndDofs, const Array< OneD, const NekDouble > &pSolution, const int pNumDirBndDofs, const bool isAconjugate)
Array< OneD, NekDouble > m_coeffMatrixFactor
int ResetKnownSolutionsToLatestOne()
std::vector< Array< OneD, NekDouble > > m_prevLinSol
Storage for solutions to previous linear problems.
void DoMatrixMultiplyFlag(const Array< OneD, NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const bool &controlFlag)
virtual ~GlobalLinSysIterative()
bool m_useProjection
Whether to apply projection technique.
NekDouble m_tolerance
Tolerance of iterative solver.
virtual void v_UniqueMap()=0
void DoPreconditionerFlag(const Array< OneD, NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const bool &controlFlag)
Array< OneD, int > m_map
Global to universal unique map.
NekDouble m_rhs_magnitude
dot product of rhs to normalise stopping criterion
DNekMatSharedPtr m_coeffMatrix
LibUtilities::NekSysOperators m_NekSysOp
virtual void v_SolveLinearSystem(const int pNumRows, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const AssemblyMapSharedPtr &locToGloMap, const int pNumDir)
Solve the matrix system.
std::string m_linSysIterSolver
Iterative solver: Conjugate Gradient, GMRES.
void Set_Rhs_Magnitude(const NekVector< NekDouble > &pIn)
int m_maxiter
maximum iterations
bool m_root
Root if parallel.
NekDouble m_rhs_mag_sm
cnt to how many times rhs_magnitude is called
Describe a linear system.
unsigned int GetDimension() const
Returns the number of dimensions for the point.
static void Dsptrs(const char &uplo, const int &n, const int &nrhs, const double *ap, const int *ipiv, double *b, const int &ldb, int &info)
Solve a real symmetric matrix problem using Bunch-Kaufman pivoting.
static void Dsptrf(const char &uplo, const int &n, double *ap, int *ipiv, int &info)
factor a real packed-symmetric matrix using Bunch-Kaufman pivoting.
std::shared_ptr< SessionReader > SessionReaderSharedPtr
NekLinSysIterFactory & GetNekLinSysIterFactory()
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
static PreconditionerSharedPtr NullPreconditionerSharedPtr
std::shared_ptr< AssemblyMap > AssemblyMapSharedPtr
static const NekDouble kNekUnsetDouble
static const NekDouble kNekSparseNonZeroTol
static const NekDouble kNekZeroTol
The above copyright notice and this permission notice shall be included.
std::shared_ptr< DNekMat > DNekMatSharedPtr
T Dot2(int n, const T *w, const T *x, const int *y)
vvtvp (vector times vector times vector): z = w*x*y
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
void Zero(int n, T *x, const int incx)
Zero vector.
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
scalarT< T > abs(scalarT< T > in)
scalarT< T > sqrt(scalarT< T > in)