Added method Linfnorm for system matrices (returns the largest abs-max row sum of the matrix)
git-svn-id: http://svn.sintef.no/trondheim/IFEM/trunk@865 e10b68d5-8a6e-419e-a041-bce267b0401d
This commit is contained in:
@@ -138,6 +138,9 @@ public:
|
||||
bool solveEig(DenseMatrix& B, RealArray& eigVal, Matrix& eigVec, int nev,
|
||||
real shift = 0.0);
|
||||
|
||||
//! \brief Returns the L-infinity norm of the matrix.
|
||||
virtual real Linfnorm() const { return myMat.normInf(); }
|
||||
|
||||
protected:
|
||||
//! \brief Augments a dense matrix symmetrically to the current matrix.
|
||||
//! \param[in] B The matrix to be augmented
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
#ifdef HAS_PETSC
|
||||
#include "SAM.h"
|
||||
#include "petscmg.h"
|
||||
#ifdef HAS_SLEPC
|
||||
#include "slepceps.h"
|
||||
#endif
|
||||
|
||||
|
||||
PETScVector::PETScVector()
|
||||
@@ -151,20 +154,17 @@ real PETScVector::Linfnorm() const
|
||||
|
||||
PETScMatrix::PETScMatrix(const LinSolParams& spar) : solParams(spar)
|
||||
{
|
||||
// Create matrix object. By default the matrix type is AIJ
|
||||
// Create matrix object, by default the matrix type is AIJ
|
||||
MatCreate(PETSC_COMM_WORLD,&A);
|
||||
|
||||
// Create linear solver object.
|
||||
KSPCreate(PETSC_COMM_WORLD,&ksp);
|
||||
// Create linear solver object
|
||||
KSPCreate(PETSC_COMM_WORLD,&ksp);
|
||||
|
||||
// Create null space if any
|
||||
if (solParams.getNullSpace() == CONSTANT) {
|
||||
MatNullSpaceCreate(PETSC_COMM_WORLD,PETSC_TRUE,0,0,&nsp);
|
||||
KSPSetNullSpace(ksp,nsp);
|
||||
}
|
||||
|
||||
// Create eigenvalue solver object.
|
||||
//EPSCreate(PETSC_COMM_WORLD,&eps);
|
||||
}
|
||||
|
||||
|
||||
@@ -182,17 +182,11 @@ PETScMatrix::PETScMatrix (const PETScMatrix& B) : solParams(B.solParams)
|
||||
MatNullSpaceCreate(PETSC_COMM_WORLD,PETSC_TRUE,0,0,&nsp);
|
||||
KSPSetNullSpace(ksp,nsp);
|
||||
}
|
||||
|
||||
// Create eigenvalue solver object.
|
||||
//EPSCreate(PETSC_COMM_WORLD,&eps);
|
||||
}
|
||||
|
||||
|
||||
PETScMatrix::~PETScMatrix ()
|
||||
{
|
||||
// Deallocation of eigenvalue solver object.
|
||||
//EPSDestroy(eps);
|
||||
|
||||
// Deallocation of null space
|
||||
if (solParams.getNullSpace() == CONSTANT)
|
||||
MatNullSpaceDestroy(nsp);
|
||||
@@ -205,20 +199,21 @@ PETScMatrix::~PETScMatrix ()
|
||||
}
|
||||
|
||||
|
||||
static void assemPETScPara(const Matrix& eM, Mat SM, PETScVector& SV,
|
||||
const std::vector<int>& meen, const int* meqn,
|
||||
const int* mpmceq, const int* mmceq, const real* ttcc)
|
||||
static void assemPETScPara (const Matrix& eM, Mat SM, PETScVector& SV,
|
||||
const std::vector<int>& meen, const int* meqn,
|
||||
const int* mpmceq, const int* mmceq,
|
||||
const real* ttcc)
|
||||
{
|
||||
real c0;
|
||||
int i, j, jp, jceq;
|
||||
real c0;
|
||||
size_t i, j;
|
||||
int jp, jceq;
|
||||
|
||||
// Number of degrees of freedom for element
|
||||
const int nedof = meen.size();
|
||||
size_t nedof = meen.size();
|
||||
|
||||
// Convert meen to C array. Start column numbering at 0.
|
||||
int *l2g;
|
||||
l2g = new int[nedof];
|
||||
for (i = 0;i < nedof;i++)
|
||||
// Convert meen to 0-based C array
|
||||
int* l2g = new int[nedof];
|
||||
for (i = 0; i < nedof; i++)
|
||||
l2g[i] = meqn[meen[i]-1]-1;
|
||||
|
||||
// Cast to non-constant Matrix to modify for Dirichlet BCs
|
||||
@@ -270,24 +265,24 @@ static void assemPETScPara(const Matrix& eM, Mat SM, PETScVector& SV,
|
||||
}
|
||||
|
||||
|
||||
static void assemPETSc(const Matrix& eM, Mat SM, PETScVector& SV,
|
||||
const std::vector<int>& meen, const int* meqn,
|
||||
const int* mpmceq, const int* mmceq, const real* ttcc)
|
||||
static void assemPETSc (const Matrix& eM, Mat SM, PETScVector& SV,
|
||||
const std::vector<int>& meen, const int* meqn,
|
||||
const int* mpmceq, const int* mmceq, const real* ttcc)
|
||||
{
|
||||
real c0;
|
||||
int i, j, ieq, jeq, ip, jp, iceq, jceq;
|
||||
real c0;
|
||||
size_t i, j;
|
||||
int ieq, jeq, ip, jp, iceq, jceq;
|
||||
|
||||
// Get C array
|
||||
PetscScalar* svec;
|
||||
VecGetArray(SV.getVector(),&svec);
|
||||
|
||||
// Number of degrees of freedom for element
|
||||
const int nedof = meen.size();
|
||||
size_t nedof = meen.size();
|
||||
|
||||
// Convert meen to C array. Start column numbering at 0.
|
||||
int *l2g;
|
||||
l2g = new int[nedof];
|
||||
for (i = 0;i < nedof; i++)
|
||||
// Convert meen to 0-based C array
|
||||
int* l2g = new int[nedof];
|
||||
for (i = 0; i < nedof; i++)
|
||||
l2g[i] = meen[i]-1;
|
||||
|
||||
// Cast to non-constant Matrix
|
||||
@@ -358,20 +353,20 @@ static void assemPETSc(const Matrix& eM, Mat SM, PETScVector& SV,
|
||||
}
|
||||
|
||||
|
||||
static void assemPETSc(const Matrix& eM, Mat SM, const std::vector<int>& meen,
|
||||
const int* meqn, const int* mpmceq, const int* mmceq,
|
||||
const real* ttcc)
|
||||
static void assemPETSc (const Matrix& eM, Mat SM, const std::vector<int>& meen,
|
||||
const int* meqn, const int* mpmceq, const int* mmceq,
|
||||
const real* ttcc)
|
||||
{
|
||||
real c0;
|
||||
int i, j, ieq, jeq, ip, jp, iceq, jceq;
|
||||
real c0;
|
||||
size_t i, j;
|
||||
int ieq, jeq, ip, jp, iceq, jceq;
|
||||
|
||||
// Number of degrees of freedom for element
|
||||
const int nedof = meen.size();
|
||||
size_t nedof = meen.size();
|
||||
|
||||
// Convert meen to C array. Start column numbering at 0.
|
||||
int *l2g;
|
||||
l2g = new int[nedof];
|
||||
for (i = 0;i < nedof; i++)
|
||||
// Convert meen to 0-based C array
|
||||
int* l2g = new int[nedof];
|
||||
for (i = 0; i < nedof; i++)
|
||||
l2g[i] = meen[i]-1;
|
||||
|
||||
// Cast to non-constant Matrix
|
||||
@@ -559,12 +554,10 @@ bool PETScMatrix::solve (SystemVector& B, bool newLHS)
|
||||
}
|
||||
|
||||
|
||||
bool PETScMatrix::solveEig(PETScMatrix& B, RealArray& val,
|
||||
Matrix& vec, int nv, real shift, int iop)
|
||||
bool PETScMatrix::solveEig (PETScMatrix& B, RealArray& val,
|
||||
Matrix& vec, int nv, real shift, int iop)
|
||||
{
|
||||
#ifdef HAS_SLEPC
|
||||
return false;
|
||||
int i;
|
||||
ST st;
|
||||
PetscInt m, n, nconv;
|
||||
PetscScalar kr, ki;
|
||||
@@ -600,7 +593,7 @@ bool PETScMatrix::solveEig(PETScMatrix& B, RealArray& val,
|
||||
|
||||
val.resize(nv);
|
||||
vec.resize(n,nv);
|
||||
for ( i = 0; i < nv; i++) {
|
||||
for (int i = 0; i < nv; i++) {
|
||||
EPSGetEigenpair(eps,i,&kr,&ki,xr,xi);
|
||||
VecGetArray(xr,&xrarr);
|
||||
|
||||
@@ -620,4 +613,12 @@ bool PETScMatrix::solveEig(PETScMatrix& B, RealArray& val,
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
real PETScMatrix::Linfnorm () const
|
||||
{
|
||||
PetscReal norm;
|
||||
MatNorm(A,NORM_INFINITY,&norm);
|
||||
return norm;
|
||||
}
|
||||
|
||||
#endif // HAS_PETSC
|
||||
|
||||
@@ -97,7 +97,6 @@ private:
|
||||
Vec x; //!< The actual PETSc vector.
|
||||
|
||||
#else // dummy implementation when PETSc is not included
|
||||
PETScVector() {}
|
||||
virtual SystemVector* copy() const { return 0; }
|
||||
virtual size_t dim() const { return 0; }
|
||||
virtual void redim(size_t) {}
|
||||
@@ -203,6 +202,9 @@ public:
|
||||
bool solveEig(PETScMatrix& B, RealArray& eigVal, Matrix& eigVec, int nev,
|
||||
real shift = real(0), int iop = 1);
|
||||
|
||||
//! \brief Returns the L-infinity norm of the matrix.
|
||||
virtual real Linfnorm() const;
|
||||
|
||||
private:
|
||||
Mat A; //!< Linear system matrix
|
||||
KSP ksp; //!< Linear solver
|
||||
|
||||
@@ -403,3 +403,10 @@ bool SPRMatrix::solveEig (SPRMatrix& B, RealArray& val, Matrix& vec, int nv,
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
real SPRMatrix::Linfnorm () const
|
||||
{
|
||||
std::cerr <<"SPRMatrix::Linfnorm not yet implemented"<< std::endl;
|
||||
return real(0);
|
||||
}
|
||||
|
||||
@@ -106,6 +106,9 @@ public:
|
||||
bool solveEig (SPRMatrix& B, RealArray& eigVal, Matrix& eigVec, int nev,
|
||||
real shift = 0.0, int iop = 1);
|
||||
|
||||
//! \brief Returns the L-infinity norm of the matrix.
|
||||
virtual real Linfnorm() const;
|
||||
|
||||
private:
|
||||
int mpar[NS]; //!< Matrix of sparse PARameters
|
||||
int* msica; //!< Matrix of Storage Information for CA
|
||||
|
||||
@@ -199,7 +199,7 @@ real& SparseMatrix::operator () (size_t r, size_t c)
|
||||
<< nrow <<"x"<< ncol << std::endl;
|
||||
else if (editable) {
|
||||
IJPair index(r,c);
|
||||
if (elem.find(index) == elem.end()) elem[index] = 0.0;
|
||||
if (elem.find(index) == elem.end()) elem[index] = real(0);
|
||||
return elem[index];
|
||||
}
|
||||
|
||||
@@ -988,3 +988,25 @@ bool SparseMatrix::solveSAMG (bool isFirstRHS, Vector& B)
|
||||
#endif
|
||||
return ierr <= 0;
|
||||
}
|
||||
|
||||
|
||||
real SparseMatrix::Linfnorm () const
|
||||
{
|
||||
RealArray sums(nrow,real(0));
|
||||
|
||||
if (editable)
|
||||
for (ValueIter it = elem.begin(); it != elem.end(); ++it)
|
||||
sums[it->first.first-1] += fabs(it->second);
|
||||
else if (solver == SUPERLU)
|
||||
// Column-oriented format with 0-based row-indices
|
||||
for (size_t j = 1; j <= ncol; j++)
|
||||
for (int i = IA[j-1]; i < IA[j]; i++)
|
||||
sums[JA[i]] += fabs(A[i]);
|
||||
else
|
||||
// Row-oriented format with 1-based row-indices
|
||||
for (size_t i = 1; i <= nrow; i++)
|
||||
for (int j = IA[i-1]; j < IA[i]; j++)
|
||||
sums[i-1] += fabs(A[j-1]);
|
||||
|
||||
return *std::max_element(sums.begin(),sums.end());
|
||||
}
|
||||
|
||||
@@ -196,6 +196,9 @@ protected:
|
||||
//! \brief Writes the system matrix to the given output stream.
|
||||
virtual std::ostream& write(std::ostream& os) const;
|
||||
|
||||
//! \brief Returns the L-infinity norm of the matrix.
|
||||
virtual real Linfnorm() const;
|
||||
|
||||
public:
|
||||
static bool printSLUstat; //!< Print solution statistics for SuperLU?
|
||||
|
||||
|
||||
@@ -265,6 +265,9 @@ public:
|
||||
//! \param newLHS \e true if the left-hand-side matrix has been updated
|
||||
virtual bool solve(SystemVector&, bool newLHS = true) { return false; }
|
||||
|
||||
//! \brief Returns the L-infinity norm of the matrix.
|
||||
virtual real Linfnorm() const = 0;
|
||||
|
||||
protected:
|
||||
//! \brief Writes the system matrix to the given output stream.
|
||||
virtual std::ostream& write(std::ostream& os) const { return os; }
|
||||
|
||||
@@ -505,6 +505,18 @@ namespace utl //! General utility classes and functions.
|
||||
return true;
|
||||
}
|
||||
|
||||
//! \brief Return the infinite norm of the matrix.
|
||||
T normInf() const
|
||||
{
|
||||
if (nrow == 0) return T(0);
|
||||
|
||||
// Compute row sums
|
||||
vector<T> sums(nrow);
|
||||
for (size_t i = 0; i < nrow; i++)
|
||||
sums[i] = elem.asum(i,ncol);
|
||||
return *std::max_element(sums.begin(),sums.end());
|
||||
}
|
||||
|
||||
private:
|
||||
//! \brief Check dimension compatibility for matrix-vector multiplication.
|
||||
bool compatible(const std::vector<T>& X, const std::vector<T>& Y,
|
||||
|
||||
Reference in New Issue
Block a user