This is the first check in of the trilinos package
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,74 @@
|
||||
# Scroll down to see the main part.
|
||||
# (This first part is dedicated to compiling and installing LAPACK.)
|
||||
|
||||
wgetrule(
|
||||
name = "trilinos_tgz",
|
||||
type = Types.ANY,
|
||||
url = "http://www.cc.gatech.edu/~gtg739c/trilinos-8.0.4.tar.gz")
|
||||
|
||||
def gen_compile_trilinos(sysentry, files, params):
|
||||
trilinos_tgz = files["trilinos_tgz"].single(Types.ANY)
|
||||
libtrilinospack = sysentry.file("KEEP/trilinospack.a", "arch", "kernel", "compiler")
|
||||
workspace_dir = os.path.join(os.path.dirname(libtrilinospack.name), "libtrilinospack_workspace")
|
||||
compiler_info = compilers[params["compiler"]]
|
||||
compiler = compiler_info.compiler_program("f")
|
||||
# Make sure we won't rm -rf anything bad
|
||||
assert "libtrilinospack_workspace" in workspace_dir
|
||||
sysentry.command("echo '... Extracting Source trilinos files...'")
|
||||
sysentry.command("mkdir -p %s" % sq(workspace_dir))
|
||||
sysentry.command("cd %s && tar -xzf %s" % (sq(workspace_dir), sq(trilinos_tgz.name)))
|
||||
sysentry.command("echo '*** Compiling Trilinos 8.0.4 version.'")
|
||||
sysentry.command("echo '... We only compile Epetra, Teuchos, Anasazi:'")
|
||||
sysentry.command("echo '... At this time we do not support distributed trilinos.'")
|
||||
sysentry.command("echo '... Only serial version is built.'")
|
||||
sysentry.command("echo '... For more information see http://trilinos.sandia.gov/Trilinos8.0Tutorial.pdf'")
|
||||
sysentry.command("echo '... This may take several minutes .'")
|
||||
sysentry.command("cd %s/trilinos-8.0.4 && mkdir -p LINUX_SERIAL " % sq(workspace_dir))
|
||||
sysentry.command("echo '***Configuring Trilinos...'")
|
||||
sysentry.command("cd %s/trilinos-8.0.4/LINUX_SERIAL && \
|
||||
../configure --prefix=%s/trilinos-8.0.4/LINUX_SERIAL \
|
||||
--disable-default-packages \
|
||||
--enable-epetra \
|
||||
--enable-teuchos \
|
||||
--enable-anasazi \
|
||||
| tee configure_LINUX_SERIAL.log" % (sq(workspace_dir) ,
|
||||
sq(workspace_dir)))
|
||||
sysentry.command("echo '...Configuration Done, if you encountered errors check\
|
||||
logfile configure_LINUX_SERIAL.log'")
|
||||
sysentry.command("echo '*** Ready to compile now'");
|
||||
sysentry.command("cd %s/trilinos-8.0.4/LINUX_SERIAL && \
|
||||
make everything| tee make_LINUX_SERIAL.log" % (sq(workspace_dir)))
|
||||
sysentry.command("cd %s/trilinos-8.0.4/LINUX_SERIAL && \
|
||||
make install | tee make_install.LINUX_SERIAL.log" % (sq(workspace_dir)))
|
||||
sysentry.command("echo '*** Finished compiling, for errors check \
|
||||
logfile make_LINUX_SERIAL.log and make_install_LINUX_SERIAL.log'")
|
||||
#we have to find out how to combine all libraries into one but
|
||||
#first we have to remove any old libtrilinos.a
|
||||
sysentry.command("rm -f %s" % sq(libtrilinospack.name))
|
||||
sysentry.command("cd %s/trilinos-8.0.4/LINUX_SERIAL/lib && \
|
||||
ar -x libepetra.a && \
|
||||
ar -x libteuchos.a && \
|
||||
ar -x libanasazi.a && \
|
||||
ar -rS %s *.o" %
|
||||
(sq(workspace_dir), sq(libtrilinospack.name)))
|
||||
sysentry.command("echo '... Created archive'")
|
||||
sysentry.command("echo '... Copying the include header files to fastlib'")
|
||||
sysentry.command("cp -r %s/trilinos-8.0.4/LINUX_SERIAL/include ." % sq(workspace_dir))
|
||||
sysentry.command("echo '... Cleaning'")
|
||||
#sysentry.command("rm -rf %s" % sq(workspace_dir))
|
||||
sysentry.command("echo '*** Done with TRILINOS!'")
|
||||
return [(Types.LINKABLE, libtrilinospack)]
|
||||
|
||||
customrule(
|
||||
name = "libtrilinos",
|
||||
dependencies = {"trilinos_tgz": [find(":trilinos_tgz")]},
|
||||
doit_fn = gen_compile_trilinos)
|
||||
|
||||
#---- This is the test part of the installation
|
||||
|
||||
binrule(
|
||||
name = "test_trilinos",
|
||||
sources = ["test.cc"],
|
||||
headers = lglob("./include/*.hpp"),
|
||||
deplibs = ["base:base", "la:libblaspack", ":libtrilinos"])
|
||||
|
||||
@@ -0,0 +1,314 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
|
||||
#ifndef ANASAZI_BASIC_EIGENPROBLEM_H
|
||||
#define ANASAZI_BASIC_EIGENPROBLEM_H
|
||||
|
||||
/*! \file AnasaziBasicEigenproblem.hpp
|
||||
\brief Basic implementation of the Anasazi::Eigenproblem class
|
||||
*/
|
||||
|
||||
#include "AnasaziEigenproblem.hpp"
|
||||
#include "AnasaziMultiVecTraits.hpp"
|
||||
#include "AnasaziOperatorTraits.hpp"
|
||||
|
||||
/*! \class Anasazi::BasicEigenproblem
|
||||
\brief This provides a basic implementation for defining standard or
|
||||
generalized eigenvalue problems.
|
||||
*/
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
template<class ScalarType, class MV, class OP>
|
||||
class BasicEigenproblem : public virtual Eigenproblem<ScalarType, MV, OP> {
|
||||
|
||||
public:
|
||||
|
||||
//! @name Constructors/Destructor
|
||||
//@{
|
||||
|
||||
//! Empty constructor - allows Anasazi::BasicEigenproblem to be described at a later time through "Set Methods".
|
||||
BasicEigenproblem();
|
||||
|
||||
//! Standard Eigenvalue Problem Constructor.
|
||||
BasicEigenproblem( const Teuchos::RCP<const OP>& Op, const Teuchos::RCP<MV>& InitVec );
|
||||
|
||||
//! Generalized Eigenvalue Problem Constructor.
|
||||
BasicEigenproblem( const Teuchos::RCP<const OP>& Op, const Teuchos::RCP<const OP>& B, const Teuchos::RCP<MV>& InitVec );
|
||||
|
||||
//! Copy Constructor.
|
||||
BasicEigenproblem( const BasicEigenproblem<ScalarType, MV, OP>& Problem );
|
||||
|
||||
//! Destructor.
|
||||
virtual ~BasicEigenproblem() {};
|
||||
//@}
|
||||
|
||||
//! @name Set Methods
|
||||
//@{
|
||||
|
||||
/*! \brief Set the operator for which eigenvalues will be computed.
|
||||
|
||||
\note This may be different from the \c A if a spectral transformation is employed.
|
||||
For example, this operator may apply the operation \f$(A-\sigma I)^{-1}\f$ if you are
|
||||
looking for eigenvalues of \c A around \f$\sigma\f$.
|
||||
*/
|
||||
void setOperator( const Teuchos::RCP<const OP>& Op ) { _Op = Op; _isSet=false; };
|
||||
|
||||
/*! \brief Set the operator \c A of the eigenvalue problem \f$Ax=Mx\lambda\f$.
|
||||
*/
|
||||
void setA( const Teuchos::RCP<const OP>& A ) { _AOp = A; _isSet=false; };
|
||||
|
||||
/*! \brief Set the operator \c M of the eigenvalue problem \f$Ax = Mx\lambda\f$.
|
||||
*/
|
||||
void setM( const Teuchos::RCP<const OP>& M ) { _MOp = M; _isSet=false; };
|
||||
|
||||
/*! \brief Set the preconditioner for this eigenvalue problem \f$Ax = Mx\lambda\f$.
|
||||
*/
|
||||
void setPrec( const Teuchos::RCP<const OP>& Prec ) { _Prec = Prec; _isSet=false; };
|
||||
|
||||
/*! \brief Set the initial guess.
|
||||
|
||||
This vector is required to create all the space needed
|
||||
by Anasazi to solve the eigenvalue problem.
|
||||
|
||||
\note Even if an initial guess is not known by the user, an initial vector must be passed in.
|
||||
*/
|
||||
void setInitVec( const Teuchos::RCP<MV>& InitVec ) { _InitVec = InitVec; _isSet=false; };
|
||||
|
||||
/*! \brief Set auxiliary vectors.
|
||||
|
||||
\note This multivector can have any number of columns, and most likely will contain vectors that
|
||||
will be used by the eigensolver to orthogonalize against.
|
||||
*/
|
||||
void setAuxVecs( const Teuchos::RCP<const MV>& AuxVecs ) { _AuxVecs = AuxVecs; _isSet=false; };
|
||||
|
||||
//! Specify the number of eigenvalues (NEV) that are requested.
|
||||
void setNEV( int nev ){ _nev = nev; _isSet=false; };
|
||||
|
||||
//! Specify the symmetry of this eigenproblem.
|
||||
/*! This knowledge may allow the solver to take advantage of the eigenproblems' symmetry.
|
||||
Some computational work can be avoided by setting this properly.
|
||||
*/
|
||||
void setHermitian( bool isSym ){ _isSym = isSym; _isSet=false; };
|
||||
|
||||
/*! \brief Specify that this eigenproblem is fully defined.
|
||||
*
|
||||
* This routine serves multiple purpose:
|
||||
* - sanity check that the eigenproblem has been fully and consistently defined
|
||||
* - opportunity for the eigenproblem to allocate internal storage for eigenvalues
|
||||
* and eigenvectors (to be used by eigensolvers and solver managers)
|
||||
* </ul>
|
||||
*
|
||||
* This method reallocates internal storage, so that any previously retrieved references to
|
||||
* internal storage (eigenvectors or eigenvalues) are invalidated.
|
||||
*
|
||||
* \note The user MUST call this routine before they send the eigenproblem to any solver or solver manager.
|
||||
*
|
||||
* \returns \c true signifies success, \c false signifies error.
|
||||
*/
|
||||
bool setProblem();
|
||||
|
||||
/*! \brief Set the solution to the eigenproblem.
|
||||
*
|
||||
* This mechanism allows an Eigensolution struct to be associated with an Eigenproblem object.
|
||||
* setSolution() is usually called by a solver manager at the end of its SolverManager::solve()
|
||||
* routine.
|
||||
*/
|
||||
void setSolution(const Eigensolution<ScalarType,MV> &sol) {_sol = sol;}
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Accessor Methods
|
||||
//@{
|
||||
|
||||
//! Get a pointer to the operator for which eigenvalues will be computed.
|
||||
Teuchos::RCP<const OP> getOperator() const { return( _Op ); };
|
||||
|
||||
//! Get a pointer to the operator \c A of the eigenproblem \f$Ax=\lambda Mx\f$.
|
||||
Teuchos::RCP<const OP> getA() const { return( _AOp ); };
|
||||
|
||||
//! Get a pointer to the operator \c M of the eigenproblem \f$Ax=\lambda Mx\f$.
|
||||
Teuchos::RCP<const OP> getM() const { return( _MOp ); };
|
||||
|
||||
//! Get a pointer to the preconditioner of the eigenproblem \f$Ax=\lambda Mx\f$.
|
||||
Teuchos::RCP<const OP> getPrec() const { return( _Prec ); };
|
||||
|
||||
//! Get a pointer to the initial vector
|
||||
Teuchos::RCP<const MV> getInitVec() const { return( _InitVec ); };
|
||||
|
||||
//! Get a pointer to the auxiliary vector
|
||||
Teuchos::RCP<const MV> getAuxVecs() const { return( _AuxVecs ); };
|
||||
|
||||
//! Get the number of eigenvalues (NEV) that are required by this eigenproblem.
|
||||
int getNEV() const { return( _nev ); }
|
||||
|
||||
//! Get the symmetry information for this eigenproblem.
|
||||
bool isHermitian() const { return( _isSym ); }
|
||||
|
||||
//! If the problem has been set, this method will return true.
|
||||
bool isProblemSet() const { return( _isSet ); }
|
||||
|
||||
/*! \brief Get the solution to the eigenproblem.
|
||||
*
|
||||
* There is no computation associated with this method. It only provides a
|
||||
* mechanism for associating an Eigensolution with a Eigenproblem.
|
||||
*/
|
||||
const Eigensolution<ScalarType,MV> & getSolution() const { return(_sol); }
|
||||
|
||||
//@}
|
||||
|
||||
protected:
|
||||
|
||||
//! Reference-counted pointer for \c A of the eigenproblem \f$Ax=\lambda Mx\f$
|
||||
Teuchos::RCP<const OP> _AOp;
|
||||
|
||||
//! Reference-counted pointer for \c M of the eigenproblem \f$Ax=\lambda Mx\f$
|
||||
Teuchos::RCP<const OP> _MOp;
|
||||
|
||||
//! Reference-counted pointer for the operator of the eigenproblem \f$Ax=\lambda Mx\f$
|
||||
Teuchos::RCP<const OP> _Op;
|
||||
|
||||
//! Reference-counted pointer for the preconditioner of the eigenproblem \f$Ax=\lambda Mx\f$
|
||||
Teuchos::RCP<const OP> _Prec;
|
||||
|
||||
//! Reference-counted pointer for the initial vector of the eigenproblem \f$Ax=\lambda Mx\f$
|
||||
Teuchos::RCP<MV> _InitVec;
|
||||
|
||||
//! Reference-counted pointer for the auxiliary vector of the eigenproblem \f$Ax=\lambda Mx\f$
|
||||
Teuchos::RCP<const MV> _AuxVecs;
|
||||
|
||||
//! Number of eigenvalues requested
|
||||
int _nev;
|
||||
|
||||
//! Symmetry of the eigenvalue problem
|
||||
/*! \note A generalized eigenvalue problem \f$Ax= \lambda Mx\f$ is considered symmetric
|
||||
if the operator \c M is positive (semi) definite.
|
||||
*/
|
||||
bool _isSym;
|
||||
|
||||
//! Sanity Check Flag
|
||||
bool _isSet;
|
||||
|
||||
//! Type-definition for the MultiVecTraits class corresponding to the \c MV type
|
||||
typedef MultiVecTraits<ScalarType,MV> MVT;
|
||||
//! Type-definition for the OperatorTraits class corresponding to the \c OP type
|
||||
typedef OperatorTraits<ScalarType,MV,OP> OPT;
|
||||
|
||||
//! Solution to problem
|
||||
Eigensolution<ScalarType,MV> _sol;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// Implementations (Constructors / Destructors)
|
||||
//=============================================================================
|
||||
template <class ScalarType, class MV, class OP>
|
||||
BasicEigenproblem<ScalarType, MV, OP>::BasicEigenproblem() :
|
||||
_nev(0),
|
||||
_isSym(false),
|
||||
_isSet(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
template <class ScalarType, class MV, class OP>
|
||||
BasicEigenproblem<ScalarType, MV, OP>::BasicEigenproblem( const Teuchos::RCP<const OP>& Op, const Teuchos::RCP<MV>& InitVec ) :
|
||||
_Op(Op),
|
||||
_InitVec(InitVec),
|
||||
_nev(0),
|
||||
_isSym(false),
|
||||
_isSet(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
template <class ScalarType, class MV, class OP>
|
||||
BasicEigenproblem<ScalarType, MV, OP>::BasicEigenproblem( const Teuchos::RCP<const OP>& Op, const Teuchos::RCP<const OP>& M,
|
||||
const Teuchos::RCP<MV>& InitVec ) :
|
||||
_MOp(M),
|
||||
_Op(Op),
|
||||
_InitVec(InitVec),
|
||||
_nev(0),
|
||||
_isSym(false),
|
||||
_isSet(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
template <class ScalarType, class MV, class OP>
|
||||
BasicEigenproblem<ScalarType, MV, OP>::BasicEigenproblem( const BasicEigenproblem<ScalarType,MV,OP>& Problem ) :
|
||||
_AOp(Problem._AOp),
|
||||
_MOp(Problem._MOp),
|
||||
_Op(Problem._Op),
|
||||
_Prec(Problem._Prec),
|
||||
_InitVec(Problem._InitVec),
|
||||
_nev(Problem._nev),
|
||||
_isSym(Problem._isSym),
|
||||
_isSet(Problem._isSet),
|
||||
_sol(Problem._sol)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// SetProblem (sanity check method)
|
||||
//=============================================================================
|
||||
template <class ScalarType, class MV, class OP>
|
||||
bool BasicEigenproblem<ScalarType, MV, OP>::setProblem()
|
||||
{
|
||||
//----------------------------------------------------------------
|
||||
// Sanity Checks
|
||||
//----------------------------------------------------------------
|
||||
// If there is no operator, then we can't proceed.
|
||||
if ( !_AOp.get() && !_Op.get() ) { return false; }
|
||||
|
||||
// If there is no initial vector, then we don't have anything to clone workspace from.
|
||||
if ( !_InitVec.get() ) { return false; }
|
||||
|
||||
// If we don't need any eigenvalues, we don't need to continue.
|
||||
if (_nev == 0) { return false; }
|
||||
|
||||
// If there is an A, but no operator, we can set them equal.
|
||||
if (_AOp.get() && !_Op.get()) { _Op = _AOp; }
|
||||
|
||||
// Clear the storage from any previous call to setSolution()
|
||||
Eigensolution<ScalarType,MV> emptysol;
|
||||
_sol = emptysol;
|
||||
|
||||
// mark the problem as set and return no-error
|
||||
_isSet=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // end Anasazi namespace
|
||||
#endif
|
||||
|
||||
// end AnasaziBasicEigenproblem.hpp
|
||||
@@ -0,0 +1,893 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
|
||||
|
||||
/*! \file AnasaziBasicOrthoManager.hpp
|
||||
\brief Basic implementation of the Anasazi::OrthoManager class
|
||||
*/
|
||||
|
||||
#ifndef ANASAZI_BASIC_ORTHOMANAGER_HPP
|
||||
#define ANASAZI_BASIC_ORTHOMANAGER_HPP
|
||||
|
||||
/*! \class Anasazi::BasicOrthoManager
|
||||
\brief An implementation of the Anasazi::MatOrthoManager that performs orthogonalization
|
||||
using (potentially) multiple steps of classical Gram-Schmidt.
|
||||
|
||||
\author Chris Baker, Ulrich Hetmaniuk, Rich Lehoucq, and Heidi Thornquist
|
||||
*/
|
||||
|
||||
// #define ANASAZI_BASICORTHO_DEBUG
|
||||
|
||||
#include "AnasaziConfigDefs.hpp"
|
||||
#include "AnasaziMultiVecTraits.hpp"
|
||||
#include "AnasaziOperatorTraits.hpp"
|
||||
#include "AnasaziMatOrthoManager.hpp"
|
||||
#include "Teuchos_TimeMonitor.hpp"
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
template<class ScalarType, class MV, class OP>
|
||||
class BasicOrthoManager : public MatOrthoManager<ScalarType,MV,OP> {
|
||||
|
||||
private:
|
||||
typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
|
||||
typedef Teuchos::ScalarTraits<ScalarType> SCT;
|
||||
typedef MultiVecTraits<ScalarType,MV> MVT;
|
||||
typedef OperatorTraits<ScalarType,MV,OP> OPT;
|
||||
|
||||
public:
|
||||
|
||||
//! @name Constructor/Destructor
|
||||
//@{
|
||||
//! Constructor specifying re-orthogonalization tolerance.
|
||||
BasicOrthoManager( Teuchos::RCP<const OP> Op = Teuchos::null, typename Teuchos::ScalarTraits<ScalarType>::magnitudeType kappa = 1.5625 );
|
||||
|
||||
|
||||
//! Destructor
|
||||
~BasicOrthoManager() {}
|
||||
//@}
|
||||
|
||||
|
||||
//! @name Accessor routines
|
||||
//@{
|
||||
|
||||
//! Set parameter for re-orthogonalization threshold.
|
||||
void setKappa( typename Teuchos::ScalarTraits<ScalarType>::magnitudeType kappa ) { kappa_ = kappa; }
|
||||
|
||||
//! Return parameter for re-orthogonalization threshold.
|
||||
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType getKappa() const { return kappa_; }
|
||||
|
||||
//@}
|
||||
|
||||
|
||||
//! @name Methods implementing Anasazi::MatOrthoManager
|
||||
//@{
|
||||
|
||||
|
||||
/*! \brief Given a list of mutually orthogonal and internally orthonormal bases \c Q, this method
|
||||
* projects a multivector \c X onto the space orthogonal to the individual <tt>Q[i]</tt>,
|
||||
* optionally returning the coefficients of \c X for the individual <tt>Q[i]</tt>. All of this is done with respect
|
||||
* to the inner product innerProd().
|
||||
*
|
||||
* After calling this routine, \c X will be orthogonal to each of the <tt>Q[i]</tt>.
|
||||
*
|
||||
@param X [in/out] The multivector to be modified.<br>
|
||||
On output, the columns of \c X will be orthogonal to each <tt>Q[i]</tt>, satisfying
|
||||
\f[
|
||||
X_{out} = X_{in} - \sum_i Q[i] \langle Q[i], X_{in} \rangle
|
||||
\f]
|
||||
|
||||
@param MX [in/out] The image of \c X under the inner product operator \c Op.
|
||||
If \f$ MX != 0\f$: On input, this is expected to be consistent with \c Op \cdot X. On output, this is updated consistent with updates to \c X.
|
||||
If \f$ MX == 0\f$ or \f$ Op == 0\f$: \c MX is not referenced.
|
||||
|
||||
@param C [out] The coefficients of \c X in the bases <tt>Q[i]</tt>. If <tt>C[i]</tt> is a non-null pointer
|
||||
and <tt>C[i]</tt> matches the dimensions of \c X and <tt>Q[i]</tt>, then the coefficients computed during the orthogonalization
|
||||
routine will be stored in the matrix <tt>C[i]</tt>, similar to calling
|
||||
\code
|
||||
innerProd( Q[i], X, C[i] );
|
||||
\endcode
|
||||
If <tt>C[i]</tt> points to a Teuchos::SerialDenseMatrix with size
|
||||
inconsistent with \c X and \c <tt>Q[i]</tt>, then a std::invalid_argument
|
||||
exception will be thrown. Otherwise, if <tt>C.size() < i</tt> or
|
||||
<tt>C[i]</tt> is a null pointer, the caller will not have access to the
|
||||
computed coefficients.
|
||||
|
||||
@param Q [in] A list of multivector bases specifying the subspaces to be orthogonalized against, satisfying
|
||||
\f[
|
||||
\langle Q[i], Q[j] \rangle = I \quad\textrm{if}\quad i=j
|
||||
\f]
|
||||
and
|
||||
\f[
|
||||
\langle Q[i], Q[j] \rangle = 0 \quad\textrm{if}\quad i \neq j\ .
|
||||
\f]
|
||||
*/
|
||||
void projectMat (
|
||||
MV &X,
|
||||
Teuchos::RCP<MV> MX = Teuchos::null,
|
||||
Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C = Teuchos::tuple(Teuchos::null),
|
||||
Teuchos::Array<Teuchos::RCP<const MV> > Q = Teuchos::tuple(Teuchos::null) ) const;
|
||||
|
||||
|
||||
/*! \brief This method takes a multivector \c X and attempts to compute an orthonormal basis for \f$colspan(X)\f$, with respect to innerProd().
|
||||
*
|
||||
* The method uses classical Gram-Schmidt with selective reorthogonalization. As a result, the coefficient matrix \c B is upper triangular.
|
||||
*
|
||||
* This routine returns an integer \c rank stating the rank of the computed basis. If \c X does not have full rank and the normalize() routine does
|
||||
* not attempt to augment the subspace, then \c rank may be smaller than the number of columns in \c X. In this case, only the first \c rank columns of
|
||||
* output \c X and first \c rank rows of \c B will be valid.
|
||||
*
|
||||
* The method attempts to find a basis with dimension equal to the number of columns in \c X. It does this by augmenting linearly dependent
|
||||
* vectors in \c X with random directions. A finite number of these attempts will be made; therefore, it is possible that the dimension of the
|
||||
* computed basis is less than the number of vectors in \c X.
|
||||
*
|
||||
@param X [in/out] The multivector to be modified.<br>
|
||||
On output, the first \c rank columns of \c X satisfy
|
||||
\f[
|
||||
\langle X[i], X[j] \rangle = \delta_{ij}\ .
|
||||
\f]
|
||||
Also,
|
||||
\f[
|
||||
X_{in}(1:m,1:n) = X_{out}(1:m,1:rank) B(1:rank,1:n)
|
||||
\f]
|
||||
where \c m is the number of rows in \c X and \c n is the number of columns in \c X.
|
||||
|
||||
@param MX [in/out] The image of \c X under the inner product operator \c Op.
|
||||
If \f$ MX != 0\f$: On input, this is expected to be consistent with \c Op \cdot X. On output, this is updated consistent with updates to \c X.
|
||||
If \f$ MX == 0\f$ or \f$ Op == 0\f$: \c MX is not referenced.
|
||||
|
||||
@param B [out] The coefficients of the original \c X with respect to the computed basis. If \c B is a non-null pointer and \c B matches the dimensions of \c B, then the
|
||||
coefficients computed during the orthogonalization routine will be stored in \c B, similar to calling
|
||||
\code
|
||||
innerProd( Xout, Xin, B );
|
||||
\endcode
|
||||
If \c B points to a Teuchos::SerialDenseMatrix with size inconsistent with \c X, then a std::invalid_argument exception will be thrown. Otherwise, if \c B is null, the caller will not have
|
||||
access to the computed coefficients. This matrix is not necessarily triangular (as in a QR factorization); see the documentation of specific orthogonalization managers.<br>
|
||||
The first rows in \c B corresponding to the valid columns in \c X will be upper triangular.
|
||||
|
||||
@return Rank of the basis computed by this method, less than or equal to the number of columns in \c X. This specifies how many columns in the returned \c X and rows in the returned \c B are valid.
|
||||
*/
|
||||
int normalizeMat (
|
||||
MV &X,
|
||||
Teuchos::RCP<MV> MX = Teuchos::null,
|
||||
Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B = Teuchos::tuple(Teuchos::null) ) const;
|
||||
|
||||
|
||||
/*! \brief Given a set of bases <tt>Q[i]</tt> and a multivector \c X, this method computes an orthonormal basis for \f$colspan(X) - \sum_i colspan(Q[i])\f$.
|
||||
*
|
||||
* This routine returns an integer \c rank stating the rank of the computed basis. If the subspace \f$colspan(X) - \sum_i colspan(Q[i])\f$ does not
|
||||
* have dimension as large as the number of columns of \c X and the orthogonalization manager doe not attempt to augment the subspace, then \c rank
|
||||
* may be smaller than the number of columns of \c X. In this case, only the first \c rank columns of output \c X and first \c rank rows of \c B will
|
||||
* be valid.
|
||||
*
|
||||
* The method attempts to find a basis with dimension the same as the number of columns in \c X. It does this by augmenting linearly dependent
|
||||
* vectors with random directions. A finite number of these attempts will be made; therefore, it is possible that the dimension of the
|
||||
* computed basis is less than the number of vectors in \c X.
|
||||
*
|
||||
@param X [in/out] The multivector to be modified.<br>
|
||||
On output, the first \c rank columns of \c X satisfy
|
||||
\f[
|
||||
\langle X[i], X[j] \rangle = \delta_{ij} \quad \textrm{and} \quad \langle X, Q[i] \rangle = 0\ .
|
||||
\f]
|
||||
Also,
|
||||
\f[
|
||||
X_{in}(1:m,1:n) = X_{out}(1:m,1:rank) B(1:rank,1:n) + \sum_i Q[i] C[i]
|
||||
\f]
|
||||
where \c m is the number of rows in \c X and \c n is the number of columns in \c X.
|
||||
|
||||
@param MX [in/out] The image of \c X under the inner product operator \c Op.
|
||||
If \f$ MX != 0\f$: On input, this is expected to be consistent with \c Op \cdot X. On output, this is updated consistent with updates to \c X.
|
||||
If \f$ MX == 0\f$ or \f$ Op == 0\f$: \c MX is not referenced.
|
||||
|
||||
@param C [out] The coefficients of \c X in the <tt>Q[i]</tt>. If <tt>C[i]</tt> is a non-null pointer
|
||||
and <tt>C[i]</tt> matches the dimensions of \c X and <tt>Q[i]</tt>, then the coefficients computed during the orthogonalization
|
||||
routine will be stored in the matrix <tt>C[i]</tt>, similar to calling
|
||||
\code
|
||||
innerProd( Q[i], X, C[i] );
|
||||
\endcode
|
||||
If <tt>C[i]</tt> points to a Teuchos::SerialDenseMatrix with size
|
||||
inconsistent with \c X and \c <tt>Q[i]</tt>, then a std::invalid_argument
|
||||
exception will be thrown. Otherwise, if <tt>C.size() < i</tt> or
|
||||
<tt>C[i]</tt> is a null pointer, the caller will not have access to the
|
||||
computed coefficients.
|
||||
|
||||
@param B [out] The coefficients of the original \c X with respect to the computed basis. If \c B is a non-null pointer and \c B matches the dimensions of \c B, then the
|
||||
coefficients computed during the orthogonalization routine will be stored in \c B, similar to calling
|
||||
\code
|
||||
innerProd( Xout, Xin, B );
|
||||
\endcode
|
||||
If \c B points to a Teuchos::SerialDenseMatrix with size inconsistent with \c X, then a std::invalid_argument exception will be thrown. Otherwise, if \c B is null, the caller will not have
|
||||
access to the computed coefficients. This matrix is not necessarily triangular (as in a QR factorization); see the documentation of specific orthogonalization managers.<br>
|
||||
The first rows in \c B corresponding to the valid columns in \c X will be upper triangular.
|
||||
|
||||
@param Q [in] A list of multivector bases specifying the subspaces to be orthogonalized against, satisfying
|
||||
\f[
|
||||
\langle Q[i], Q[j] \rangle = I \quad\textrm{if}\quad i=j
|
||||
\f]
|
||||
and
|
||||
\f[
|
||||
\langle Q[i], Q[j] \rangle = 0 \quad\textrm{if}\quad i \neq j\ .
|
||||
\f]
|
||||
|
||||
@return Rank of the basis computed by this method, less than or equal to the number of columns in \c X. This specifies how many columns in the returned \c X and rows in the returned \c B are valid.
|
||||
|
||||
*/
|
||||
int projectAndNormalizeMat (
|
||||
MV &X,
|
||||
Teuchos::RCP<MV> MX = Teuchos::null,
|
||||
Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C = Teuchos::tuple(Teuchos::null),
|
||||
Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B = Teuchos::null,
|
||||
Teuchos::Array<Teuchos::RCP<const MV> > Q = Teuchos::tuple(Teuchos::null) ) const;
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Error methods
|
||||
//@{
|
||||
|
||||
/*! \brief This method computes the error in orthonormality of a multivector, measured
|
||||
* as the Frobenius norm of the difference <tt>innerProd(X,Y) - I</tt>.
|
||||
* The method has the option of exploiting a caller-provided \c MX.
|
||||
*/
|
||||
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
|
||||
orthonormErrorMat(const MV &X, Teuchos::RCP<const MV> MX = Teuchos::null) const;
|
||||
|
||||
/*! \brief This method computes the error in orthogonality of two multivectors, measured
|
||||
* as the Frobenius norm of <tt>innerProd(X,Y)</tt>.
|
||||
* The method has the option of exploiting a caller-provided \c MX.
|
||||
*/
|
||||
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
|
||||
orthogErrorMat(const MV &X1, Teuchos::RCP<const MV> MX1, const MV &X2) const;
|
||||
|
||||
//@}
|
||||
|
||||
private:
|
||||
|
||||
//! Parameter for re-orthogonalization.
|
||||
MagnitudeType kappa_;
|
||||
|
||||
// ! Routine to find an orthonormal basis for the
|
||||
int findBasis(MV &X, Teuchos::RCP<MV> MX,
|
||||
Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > C,
|
||||
bool completeBasis, int howMany = -1 ) const;
|
||||
|
||||
//
|
||||
// Internal timers
|
||||
//
|
||||
Teuchos::RCP<Teuchos::Time> timerReortho_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
template<class ScalarType, class MV, class OP>
|
||||
BasicOrthoManager<ScalarType,MV,OP>::BasicOrthoManager( Teuchos::RCP<const OP> Op,
|
||||
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType kappa ) :
|
||||
MatOrthoManager<ScalarType,MV,OP>(Op),
|
||||
kappa_(kappa),
|
||||
timerReortho_(Teuchos::TimeMonitor::getNewTimer("BasicOrthoManager::Re-orthogonalization"))
|
||||
{}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Compute the distance from orthonormality
|
||||
template<class ScalarType, class MV, class OP>
|
||||
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
|
||||
BasicOrthoManager<ScalarType,MV,OP>::orthonormErrorMat(const MV &X, Teuchos::RCP<const MV> MX) const {
|
||||
const ScalarType ONE = SCT::one();
|
||||
int rank = MVT::GetNumberVecs(X);
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> xTx(rank,rank);
|
||||
innerProdMat(X,X,MX,xTx);
|
||||
for (int i=0; i<rank; i++) {
|
||||
xTx(i,i) -= ONE;
|
||||
}
|
||||
return xTx.normFrobenius();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Compute the distance from orthogonality
|
||||
template<class ScalarType, class MV, class OP>
|
||||
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
|
||||
BasicOrthoManager<ScalarType,MV,OP>::orthogErrorMat(const MV &X1, Teuchos::RCP<const MV> MX1, const MV &X2) const {
|
||||
int r1 = MVT::GetNumberVecs(X1);
|
||||
int r2 = MVT::GetNumberVecs(X2);
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> xTx(r2,r1);
|
||||
innerProdMat(X2,X1,MX1,xTx);
|
||||
return xTx.normFrobenius();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Find an Op-orthonormal basis for span(X) - span(W)
|
||||
template<class ScalarType, class MV, class OP>
|
||||
int BasicOrthoManager<ScalarType, MV, OP>::projectAndNormalizeMat(
|
||||
MV &X, Teuchos::RCP<MV> MX,
|
||||
Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
|
||||
Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
|
||||
Teuchos::Array<Teuchos::RCP<const MV> > Q ) const {
|
||||
|
||||
int nq = Q.length();
|
||||
int xc = MVT::GetNumberVecs( X );
|
||||
int xr = MVT::GetVecLength( X );
|
||||
int rank;
|
||||
|
||||
/* if the user doesn't want to store the coefficients,
|
||||
* allocate some local memory for them
|
||||
*/
|
||||
if ( B == Teuchos::null ) {
|
||||
B = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>(xc,xc) );
|
||||
}
|
||||
|
||||
/****** DO NO MODIFY *MX IF _hasOp == false ******/
|
||||
if (this->_hasOp) {
|
||||
if (MX == Teuchos::null) {
|
||||
// we need to allocate space for MX
|
||||
MX = MVT::Clone(X,MVT::GetNumberVecs(X));
|
||||
OPT::Apply(*(this->_Op),X,*MX);
|
||||
this->_OpCounter += MVT::GetNumberVecs(X);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Op == I --> MX = X (ignore it if the user passed it in)
|
||||
MX = Teuchos::rcp( &X, false );
|
||||
}
|
||||
|
||||
int mxc = MVT::GetNumberVecs( *MX );
|
||||
int mxr = MVT::GetVecLength( *MX );
|
||||
|
||||
// short-circuit
|
||||
TEST_FOR_EXCEPTION( xc == 0 || xr == 0, std::invalid_argument, "Anasazi::BasicOrthoManager::projectAndNormalizeMat(): X must be non-empty" );
|
||||
|
||||
int numbas = 0;
|
||||
for (int i=0; i<nq; i++) {
|
||||
numbas += MVT::GetNumberVecs( *Q[i] );
|
||||
}
|
||||
|
||||
// check size of B
|
||||
TEST_FOR_EXCEPTION( B->numRows() != xc || B->numCols() != xc, std::invalid_argument,
|
||||
"Anasazi::BasicOrthoManager::projectAndNormalizeMat(): Size of X must be consistant with size of B" );
|
||||
// check size of X and MX
|
||||
TEST_FOR_EXCEPTION( xc<0 || xr<0 || mxc<0 || mxr<0, std::invalid_argument,
|
||||
"Anasazi::BasicOrthoManager::projectAndNormalizeMat(): MVT returned negative dimensions for X,MX" );
|
||||
// check size of X w.r.t. MX
|
||||
TEST_FOR_EXCEPTION( xc!=mxc || xr!=mxr, std::invalid_argument,
|
||||
"Anasazi::BasicOrthoManager::projectAndNormalizeMat(): Size of X must be consistant with size of MX" );
|
||||
// check feasibility
|
||||
TEST_FOR_EXCEPTION( numbas+xc > xr, std::invalid_argument,
|
||||
"Anasazi::BasicOrthoManager::projectAndNormalizeMat(): Orthogonality constraints not feasible" );
|
||||
|
||||
// orthogonalize all of X against Q
|
||||
projectMat(X,MX,C,Q);
|
||||
|
||||
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> oldCoeff(xc,1);
|
||||
|
||||
// start working
|
||||
rank = 0;
|
||||
int numTries = 10; // each vector in X gets 10 random chances to escape degeneracy
|
||||
int oldrank = -1;
|
||||
do {
|
||||
int curxsize = xc - rank;
|
||||
|
||||
// orthonormalize X, but quit if it is rank deficient
|
||||
// we can't let findBasis generated random vectors to complete the basis,
|
||||
// because it doesn't know about Q; we will do this ourselves below
|
||||
rank = findBasis(X,MX,B,false,curxsize);
|
||||
|
||||
if (rank < xc && numTries == 10) {
|
||||
// we quit on this vector, and for the first time;
|
||||
// save the coefficient information, because findBasis will overwrite it
|
||||
for (int i=0; i<xc; i++) {
|
||||
oldCoeff(i,0) = (*B)(i,rank);
|
||||
}
|
||||
}
|
||||
|
||||
if (oldrank != -1 && rank != oldrank) {
|
||||
// we moved on; restore the previous coefficients
|
||||
for (int i=0; i<xc; i++) {
|
||||
(*B)(i,oldrank) = oldCoeff(i,0);
|
||||
}
|
||||
}
|
||||
|
||||
if (rank == xc) {
|
||||
// we are done
|
||||
break;
|
||||
}
|
||||
else {
|
||||
TEST_FOR_EXCEPTION( rank < oldrank, OrthoError,
|
||||
"Anasazi::BasicOrthoManager::projectAndNormalizeMat(): basis lost rank; this shouldn't happen");
|
||||
|
||||
if (rank != oldrank) {
|
||||
// we added a basis vector from random info; reset the chance counter
|
||||
numTries = 10;
|
||||
}
|
||||
|
||||
// store old rank
|
||||
oldrank = rank;
|
||||
|
||||
// has this vector run out of chances to escape degeneracy?
|
||||
if (numTries <= 0) {
|
||||
break;
|
||||
}
|
||||
// use one of this vector's chances
|
||||
numTries--;
|
||||
|
||||
// randomize troubled direction
|
||||
#ifdef ANASAZI_BASICORTHO_DEBUG
|
||||
cout << "Random for column " << rank << endl;
|
||||
#endif
|
||||
Teuchos::RCP<MV> curX, curMX;
|
||||
std::vector<int> ind(1);
|
||||
ind[0] = rank;
|
||||
curX = MVT::CloneView(X,ind);
|
||||
MVT::MvRandom(*curX);
|
||||
if (this->_hasOp) {
|
||||
curMX = MVT::CloneView(*MX,ind);
|
||||
OPT::Apply( *(this->_Op), *curX, *curMX );
|
||||
this->_OpCounter += MVT::GetNumberVecs(*curX);
|
||||
}
|
||||
|
||||
// orthogonalize against Q
|
||||
// if !this->_hasOp, the curMX will be ignored.
|
||||
// we don't care about these coefficients; in fact, we need to preserve the previous coeffs
|
||||
projectMat(*curX,curMX,Teuchos::null,Q);
|
||||
}
|
||||
} while (1);
|
||||
|
||||
// this should never raise an exception; but our post-conditions oblige us to check
|
||||
TEST_FOR_EXCEPTION( rank > xc || rank < 0, std::logic_error,
|
||||
"Anasazi::BasicOrthoManager::projectAndNormalizeMat(): Debug error in rank variable." );
|
||||
return rank;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Find an Op-orthonormal basis for span(X), with rank numvectors(X)
|
||||
template<class ScalarType, class MV, class OP>
|
||||
int BasicOrthoManager<ScalarType, MV, OP>::normalizeMat(
|
||||
MV &X, Teuchos::RCP<MV> MX,
|
||||
Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B ) const {
|
||||
// call findBasis, with the instruction to try to generate a basis of rank numvecs(X)
|
||||
return findBasis(X, MX, B, true );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<class ScalarType, class MV, class OP>
|
||||
void BasicOrthoManager<ScalarType, MV, OP>::projectMat(
|
||||
MV &X, Teuchos::RCP<MV> MX,
|
||||
Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
|
||||
Teuchos::Array<Teuchos::RCP<const MV> > Q) const {
|
||||
// For the inner product defined by the operator Op or the identity (Op == 0)
|
||||
// -> Orthogonalize X against each Q[i]
|
||||
// Modify MX accordingly
|
||||
//
|
||||
// Note that when Op is 0, MX is not referenced
|
||||
//
|
||||
// Parameter variables
|
||||
//
|
||||
// X : Vectors to be transformed
|
||||
//
|
||||
// MX : Image of the block vector X by the mass matrix
|
||||
//
|
||||
// Q : Bases to orthogonalize against. These are assumed orthonormal, mutually and independently.
|
||||
//
|
||||
|
||||
ScalarType ONE = SCT::one();
|
||||
|
||||
int xc = MVT::GetNumberVecs( X );
|
||||
int xr = MVT::GetVecLength( X );
|
||||
int nq = Q.length();
|
||||
std::vector<int> qcs(nq);
|
||||
// short-circuit
|
||||
if (nq == 0 || xc == 0 || xr == 0) {
|
||||
return;
|
||||
}
|
||||
int qr = MVT::GetVecLength ( *Q[0] );
|
||||
// if we don't have enough C, expand it with null references
|
||||
// if we have too many, resize to throw away the latter ones
|
||||
// if we have exactly as many as we have Q, this call has no effect
|
||||
C.resize(nq);
|
||||
|
||||
|
||||
/****** DO NO MODIFY *MX IF _hasOp == false ******/
|
||||
if (this->_hasOp) {
|
||||
if (MX == Teuchos::null) {
|
||||
// we need to allocate space for MX
|
||||
MX = MVT::Clone(X,MVT::GetNumberVecs(X));
|
||||
OPT::Apply(*(this->_Op),X,*MX);
|
||||
this->_OpCounter += MVT::GetNumberVecs(X);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Op == I --> MX = X (ignore it if the user passed it in)
|
||||
MX = Teuchos::rcp( &X, false );
|
||||
}
|
||||
int mxc = MVT::GetNumberVecs( *MX );
|
||||
int mxr = MVT::GetVecLength( *MX );
|
||||
|
||||
// check size of X and Q w.r.t. common sense
|
||||
TEST_FOR_EXCEPTION( xc<0 || xr<0 || mxc<0 || mxr<0, std::invalid_argument,
|
||||
"Anasazi::BasicOrthoManager::projectMat(): MVT returned negative dimensions for X,MX" );
|
||||
// check size of X w.r.t. MX and Q
|
||||
TEST_FOR_EXCEPTION( xc!=mxc || xr!=mxr || xr!=qr, std::invalid_argument,
|
||||
"Anasazi::BasicOrthoManager::projectMat(): Size of X not consistant with MX,Q" );
|
||||
|
||||
// tally up size of all Q and check/allocate C
|
||||
int baslen = 0;
|
||||
for (int i=0; i<nq; i++) {
|
||||
TEST_FOR_EXCEPTION( MVT::GetVecLength( *Q[i] ) != qr, std::invalid_argument,
|
||||
"Anasazi::BasicOrthoManager::projectMat(): Q lengths not mutually consistant" );
|
||||
qcs[i] = MVT::GetNumberVecs( *Q[i] );
|
||||
TEST_FOR_EXCEPTION( qr < qcs[i], std::invalid_argument,
|
||||
"Anasazi::BasicOrthoManager::projectMat(): Q has less rows than columns" );
|
||||
baslen += qcs[i];
|
||||
|
||||
// check size of C[i]
|
||||
if ( C[i] == Teuchos::null ) {
|
||||
C[i] = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>(qcs[i],xc) );
|
||||
}
|
||||
else {
|
||||
TEST_FOR_EXCEPTION( C[i]->numRows() != qcs[i] || C[i]->numCols() != xc , std::invalid_argument,
|
||||
"Anasazi::BasicOrthoManager::projectMat(): Size of Q not consistant with size of C" );
|
||||
}
|
||||
}
|
||||
|
||||
// Perform the Gram-Schmidt transformation for a block of vectors
|
||||
|
||||
// Compute the initial Op-norms
|
||||
std::vector<ScalarType> oldDot( xc );
|
||||
MVT::MvDot( X, *MX, &oldDot );
|
||||
|
||||
Teuchos::Array<Teuchos::RCP<MV> > MQ(nq);
|
||||
// Define the product Q^T * (Op*X)
|
||||
for (int i=0; i<nq; i++) {
|
||||
// Multiply Q' with MX
|
||||
innerProdMat(*Q[i],X,MX,*C[i]);
|
||||
// Multiply by Q and subtract the result in X
|
||||
MVT::MvTimesMatAddMv( -ONE, *Q[i], *C[i], ONE, X );
|
||||
|
||||
// Update MX, with the least number of applications of Op as possible
|
||||
if (this->_hasOp) {
|
||||
if (xc <= qcs[i]) {
|
||||
OPT::Apply( *(this->_Op), X, *MX);
|
||||
this->_OpCounter += MVT::GetNumberVecs(X);
|
||||
}
|
||||
else {
|
||||
// this will possibly be used again below; don't delete it
|
||||
MQ[i] = MVT::Clone( *Q[i], qcs[i] );
|
||||
OPT::Apply( *(this->_Op), *Q[i], *MQ[i] );
|
||||
this->_OpCounter += MVT::GetNumberVecs(*Q[i]);
|
||||
MVT::MvTimesMatAddMv( -ONE, *MQ[i], *C[i], ONE, *MX );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Compute new Op-norms
|
||||
std::vector<ScalarType> newDot(xc);
|
||||
MVT::MvDot( X, *MX, &newDot );
|
||||
|
||||
// determine (individually) whether to do another step of classical Gram-Schmidt
|
||||
for (int j = 0; j < xc; ++j) {
|
||||
|
||||
if ( SCT::magnitude(kappa_*newDot[j]) < SCT::magnitude(oldDot[j]) ) {
|
||||
Teuchos::TimeMonitor lcltimer( *timerReortho_ );
|
||||
for (int i=0; i<nq; i++) {
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> C2(*C[i]);
|
||||
|
||||
// Apply another step of classical Gram-Schmidt
|
||||
innerProdMat(*Q[i],X,MX,C2);
|
||||
*C[i] += C2;
|
||||
MVT::MvTimesMatAddMv( -ONE, *Q[i], C2, ONE, X );
|
||||
|
||||
// Update MX, with the least number of applications of Op as possible
|
||||
if (this->_hasOp) {
|
||||
if (MQ[i].get()) {
|
||||
// MQ was allocated and computed above; use it
|
||||
MVT::MvTimesMatAddMv( -ONE, *MQ[i], C2, ONE, *MX );
|
||||
}
|
||||
else if (xc <= qcs[i]) {
|
||||
// MQ was not allocated and computed above; it was cheaper to use X before and it still is
|
||||
OPT::Apply( *(this->_Op), X, *MX);
|
||||
this->_OpCounter += MVT::GetNumberVecs(X);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
} // if (kappa_*newDot[j] < oldDot[j])
|
||||
} // for (int j = 0; j < xc; ++j)
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Find an Op-orthonormal basis for span(X), with the option of extending the subspace so that
|
||||
// the rank is numvectors(X)
|
||||
template<class ScalarType, class MV, class OP>
|
||||
int BasicOrthoManager<ScalarType, MV, OP>::findBasis(
|
||||
MV &X, Teuchos::RCP<MV> MX,
|
||||
Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
|
||||
bool completeBasis, int howMany ) const {
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
// For the inner product defined by the operator Op or the identity (Op == 0)
|
||||
// -> Orthonormalize X
|
||||
// Modify MX accordingly
|
||||
//
|
||||
// Note that when Op is 0, MX is not referenced
|
||||
//
|
||||
// Parameter variables
|
||||
//
|
||||
// X : Vectors to be orthonormalized
|
||||
//
|
||||
// MX : Image of the multivector X under the operator Op
|
||||
//
|
||||
// Op : Pointer to the operator for the inner product
|
||||
//
|
||||
// TODO: add reference
|
||||
// kappa= Coefficient determining when to perform a second Gram-Schmidt step
|
||||
// Default value = 1.5625 = (1.25)^2 (as suggested in Parlett's book)
|
||||
//
|
||||
|
||||
const ScalarType ONE = SCT::one();
|
||||
const MagnitudeType ZERO = SCT::magnitude(SCT::zero());
|
||||
const ScalarType EPS = SCT::eps();
|
||||
|
||||
int xc = MVT::GetNumberVecs( X );
|
||||
int xr = MVT::GetVecLength( X );
|
||||
|
||||
if (howMany == -1) {
|
||||
howMany = xc;
|
||||
}
|
||||
|
||||
/*******************************************************
|
||||
* If _hasOp == false, we will not reference MX below *
|
||||
*******************************************************/
|
||||
|
||||
// if Op==null, MX == X (via pointer)
|
||||
// Otherwise, either the user passed in MX or we will allocated and compute it
|
||||
if (this->_hasOp) {
|
||||
if (MX == Teuchos::null) {
|
||||
// we need to allocate space for MX
|
||||
MX = MVT::Clone(X,xc);
|
||||
OPT::Apply(*(this->_Op),X,*MX);
|
||||
this->_OpCounter += MVT::GetNumberVecs(X);
|
||||
}
|
||||
}
|
||||
|
||||
/* if the user doesn't want to store the coefficients,
|
||||
* allocate some local memory for them
|
||||
*/
|
||||
if ( B == Teuchos::null ) {
|
||||
B = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>(xc,xc) );
|
||||
}
|
||||
|
||||
int mxc = (this->_hasOp) ? MVT::GetNumberVecs( *MX ) : xc;
|
||||
int mxr = (this->_hasOp) ? MVT::GetVecLength( *MX ) : xr;
|
||||
|
||||
// check size of C, B
|
||||
TEST_FOR_EXCEPTION( xc == 0 || xr == 0, std::invalid_argument,
|
||||
"Anasazi::BasicOrthoManager::findBasis(): X must be non-empty" );
|
||||
TEST_FOR_EXCEPTION( B->numRows() != xc || B->numCols() != xc, std::invalid_argument,
|
||||
"Anasazi::BasicOrthoManager::findBasis(): Size of X not consistant with size of B" );
|
||||
TEST_FOR_EXCEPTION( xc != mxc || xr != mxr, std::invalid_argument,
|
||||
"Anasazi::BasicOrthoManager::findBasis(): Size of X not consistant with size of MX" );
|
||||
TEST_FOR_EXCEPTION( xc > xr, std::invalid_argument,
|
||||
"Anasazi::BasicOrthoManager::findBasis(): Size of X not feasible for normalization" );
|
||||
TEST_FOR_EXCEPTION( howMany < 0 || howMany > xc, std::invalid_argument,
|
||||
"Anasazi::BasicOrthoManager::findBasis(): Invalid howMany parameter" );
|
||||
|
||||
/* xstart is which column we are starting the process with, based on howMany
|
||||
* columns before xstart are assumed to be Op-orthonormal already
|
||||
*/
|
||||
int xstart = xc - howMany;
|
||||
|
||||
for (int j = xstart; j < xc; j++) {
|
||||
|
||||
// numX represents the number of currently orthonormal columns of X
|
||||
int numX = j;
|
||||
// j represents the index of the current column of X
|
||||
// these are different interpretations of the same value
|
||||
|
||||
//
|
||||
// set the lower triangular part of R to zero
|
||||
for (int i=j+1; i<xc; ++i) {
|
||||
(*B)(i,j) = ZERO;
|
||||
}
|
||||
|
||||
// Get a view of the vector currently being worked on.
|
||||
std::vector<int> index(1);
|
||||
index[0] = j;
|
||||
Teuchos::RCP<MV> Xj = MVT::CloneView( X, index );
|
||||
Teuchos::RCP<MV> MXj;
|
||||
if ((this->_hasOp)) {
|
||||
// MXj is a view of the current vector in MX
|
||||
MXj = MVT::CloneView( *MX, index );
|
||||
}
|
||||
else {
|
||||
// MXj is a pointer to Xj, and MUST NOT be modified
|
||||
MXj = Xj;
|
||||
}
|
||||
|
||||
// Get a view of the previous vectors.
|
||||
std::vector<int> prev_idx( numX );
|
||||
Teuchos::RCP<const MV> prevX, prevMX;
|
||||
|
||||
if (numX > 0) {
|
||||
for (int i=0; i<numX; ++i) prev_idx[i] = i;
|
||||
prevX = MVT::CloneView( X, prev_idx );
|
||||
if (this->_hasOp) {
|
||||
prevMX = MVT::CloneView( *MX, prev_idx );
|
||||
}
|
||||
}
|
||||
|
||||
bool rankDef = true;
|
||||
/* numTrials>0 will denote that the current vector was randomized for the purpose
|
||||
* of finding a basis vector, and that the coefficients of that vector should
|
||||
* not be stored in B
|
||||
*/
|
||||
for (int numTrials = 0; numTrials < 10; numTrials++) {
|
||||
|
||||
// Make storage for these Gram-Schmidt iterations.
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> product(numX, 1);
|
||||
std::vector<ScalarType> oldDot( 1 ), newDot( 1 );
|
||||
|
||||
//
|
||||
// Save old MXj vector and compute Op-norm
|
||||
//
|
||||
Teuchos::RCP<MV> oldMXj = MVT::CloneCopy( *MXj );
|
||||
MVT::MvDot( *Xj, *MXj, &oldDot );
|
||||
// Xj^H Op Xj should be real and positive, by the Hermitian positive definiteness of Op
|
||||
TEST_FOR_EXCEPTION( SCT::real(oldDot[0]) < ZERO, OrthoError,
|
||||
"Anasazi::BasicOrthoManager::findBasis(): Negative definiteness discovered in inner product" );
|
||||
|
||||
if (numX > 0) {
|
||||
// Apply the first step of Gram-Schmidt
|
||||
|
||||
// product <- prevX^T MXj
|
||||
innerProdMat(*prevX,*Xj,MXj,product);
|
||||
|
||||
// Xj <- Xj - prevX prevX^T MXj
|
||||
// = Xj - prevX product
|
||||
MVT::MvTimesMatAddMv( -ONE, *prevX, product, ONE, *Xj );
|
||||
|
||||
// Update MXj
|
||||
if (this->_hasOp) {
|
||||
// MXj <- Op*Xj_new
|
||||
// = Op*(Xj_old - prevX prevX^T MXj)
|
||||
// = MXj - prevMX product
|
||||
MVT::MvTimesMatAddMv( -ONE, *prevMX, product, ONE, *MXj );
|
||||
}
|
||||
|
||||
// Compute new Op-norm
|
||||
MVT::MvDot( *Xj, *MXj, &newDot );
|
||||
|
||||
// Check if a correction is needed.
|
||||
if ( SCT::magnitude(kappa_*newDot[0]) < SCT::magnitude(oldDot[0]) ) {
|
||||
// Apply the second step of Gram-Schmidt
|
||||
// This is the same as above
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> P2(numX,1);
|
||||
|
||||
innerProdMat(*prevX,*Xj,MXj,P2);
|
||||
product += P2;
|
||||
MVT::MvTimesMatAddMv( -ONE, *prevX, P2, ONE, *Xj );
|
||||
if ((this->_hasOp)) {
|
||||
MVT::MvTimesMatAddMv( -ONE, *prevMX, P2, ONE, *MXj );
|
||||
}
|
||||
} // if (kappa_*newDot[0] < oldDot[0])
|
||||
|
||||
} // if (numX > 0)
|
||||
|
||||
// Compute Op-norm with old MXj
|
||||
MVT::MvDot( *Xj, *oldMXj, &newDot );
|
||||
|
||||
// save the coefficients, if we are working on the original vector and not a randomly generated one
|
||||
if (numTrials == 0) {
|
||||
for (int i=0; i<numX; i++) {
|
||||
(*B)(i,j) = product(i,0);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if Xj has any directional information left after the orthogonalization.
|
||||
#ifdef ANASAZI_BASICORTHO_DEBUG
|
||||
cout << "olddot: " << SCT::magnitude(oldDot[0]) << " newdot: " << SCT::magnitude(newDot[0]);
|
||||
#endif
|
||||
if ( SCT::magnitude(newDot[0]) > SCT::magnitude(oldDot[0]*EPS*EPS) && SCT::real(newDot[0]) > ZERO ) {
|
||||
#ifdef ANASAZI_BASICORTHO_DEBUG
|
||||
cout << " ACCEPTED" << endl;
|
||||
#endif
|
||||
// Normalize Xj.
|
||||
// Xj <- Xj / sqrt(newDot)
|
||||
ScalarType diag = SCT::squareroot(SCT::magnitude(newDot[0]));
|
||||
|
||||
MVT::MvAddMv( ONE/diag, *Xj, ZERO, *Xj, *Xj );
|
||||
if (this->_hasOp) {
|
||||
// Update MXj.
|
||||
MVT::MvAddMv( ONE/diag, *MXj, ZERO, *MXj, *MXj );
|
||||
}
|
||||
|
||||
// save it, if it corresponds to the original vector and not a randomly generated one
|
||||
if (numTrials == 0) {
|
||||
(*B)(j,j) = diag;
|
||||
}
|
||||
|
||||
// We are not rank deficient in this vector. Move on to the next vector in X.
|
||||
rankDef = false;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
#ifdef ANASAZI_BASICORTHO_DEBUG
|
||||
cout << " REJECTED" << endl;
|
||||
#endif
|
||||
// There was nothing left in Xj after orthogonalizing against previous columns in X.
|
||||
// X is rank deficient.
|
||||
// reflect this in the coefficients
|
||||
(*B)(j,j) = ZERO;
|
||||
|
||||
if (completeBasis) {
|
||||
// Fill it with random information and keep going.
|
||||
#ifdef ANASAZI_BASICORTHO_DEBUG
|
||||
cout << "Random for column " << j << endl;
|
||||
#endif
|
||||
MVT::MvRandom( *Xj );
|
||||
if (this->_hasOp) {
|
||||
OPT::Apply( *(this->_Op), *Xj, *MXj );
|
||||
this->_OpCounter += MVT::GetNumberVecs(*Xj);
|
||||
}
|
||||
}
|
||||
else {
|
||||
rankDef = true;
|
||||
break;
|
||||
}
|
||||
|
||||
} // if (norm > oldDot*EPS*EPS)
|
||||
|
||||
} // for (numTrials = 0; numTrials < 10; ++numTrials)
|
||||
|
||||
// if rankDef == true, then quit and notify user of rank obtained
|
||||
if (rankDef == true) {
|
||||
MVT::MvInit( *Xj, ZERO );
|
||||
if (this->_hasOp) {
|
||||
MVT::MvInit( *MXj, ZERO );
|
||||
}
|
||||
TEST_FOR_EXCEPTION( completeBasis, OrthoError,
|
||||
"Anasazi::BasicOrthoManager::findBasis(): Unable to complete basis" );
|
||||
return j;
|
||||
}
|
||||
|
||||
} // for (j = 0; j < xc; ++j)
|
||||
|
||||
return xc;
|
||||
}
|
||||
|
||||
} // namespace Anasazi
|
||||
|
||||
#endif // ANASAZI_BASIC_ORTHOMANAGER_HPP
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
|
||||
#ifndef ANASAZI_BASIC_OUTPUT_MANAGER_HPP
|
||||
#define ANASAZI_BASIC_OUTPUT_MANAGER_HPP
|
||||
|
||||
/*! \file AnasaziBasicOutputManager.hpp
|
||||
\brief Basic output manager for sending information of select verbosity levels to the appropriate output stream
|
||||
*/
|
||||
|
||||
#include "AnasaziConfigDefs.hpp"
|
||||
#include "AnasaziOutputManager.hpp"
|
||||
#include "Teuchos_oblackholestream.hpp"
|
||||
|
||||
#ifdef HAVE_MPI
|
||||
#include <mpi.h>
|
||||
#endif
|
||||
|
||||
/*! \class Anasazi::BasicOutputManager
|
||||
|
||||
\brief Anasazi's basic output manager for sending information of select verbosity levels
|
||||
to the appropriate output stream.
|
||||
|
||||
\author Chris Baker, Ulrich Hetmaniuk, Rich Lehoucq, and Heidi Thornquist
|
||||
*/
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
using std::ostream;
|
||||
|
||||
template <class ScalarType>
|
||||
class BasicOutputManager : public OutputManager<ScalarType> {
|
||||
|
||||
public:
|
||||
|
||||
//! @name Constructors/Destructor
|
||||
//@{
|
||||
|
||||
//! Default constructor
|
||||
BasicOutputManager( int vb = Anasazi::Errors, Teuchos::RCP<ostream> os = Teuchos::rcp(&std::cout,false) );
|
||||
|
||||
//! Destructor.
|
||||
virtual ~BasicOutputManager() {};
|
||||
//@}
|
||||
|
||||
//! @name Set/Get methods
|
||||
//@{
|
||||
|
||||
//! Set the output stream for this manager.
|
||||
void setOStream( Teuchos::RCP<ostream> os );
|
||||
|
||||
//! Get the output stream for this manager.
|
||||
Teuchos::RCP<ostream> getOStream();
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Output methods
|
||||
//@{
|
||||
|
||||
//! Find out whether we need to print out information for this message type.
|
||||
/*! This method is used by the solver to determine whether computations are
|
||||
necessary for this message type.
|
||||
*/
|
||||
bool isVerbosity( MsgType type ) const;
|
||||
|
||||
//! Send some output to this output stream.
|
||||
void print( MsgType type, const std::string output );
|
||||
|
||||
//! Return a stream for outputting to.
|
||||
ostream &stream( MsgType type );
|
||||
|
||||
//@}
|
||||
|
||||
private:
|
||||
|
||||
//! @name Undefined methods
|
||||
//@{
|
||||
|
||||
//! Copy constructor.
|
||||
BasicOutputManager( const OutputManager<ScalarType>& OM );
|
||||
|
||||
//! Assignment operator.
|
||||
BasicOutputManager<ScalarType>& operator=( const OutputManager<ScalarType>& OM );
|
||||
|
||||
//@}
|
||||
|
||||
Teuchos::RCP<ostream> myOS_;
|
||||
Teuchos::oblackholestream myBHS_;
|
||||
bool iPrint_;
|
||||
};
|
||||
|
||||
template<class ScalarType>
|
||||
BasicOutputManager<ScalarType>::BasicOutputManager(int vb, Teuchos::RCP<ostream> os)
|
||||
: OutputManager<ScalarType>(vb), myOS_(os) {
|
||||
int MyPID;
|
||||
#ifdef HAVE_MPI
|
||||
// Initialize MPI
|
||||
int mpiStarted = 0;
|
||||
MPI_Initialized(&mpiStarted);
|
||||
if (mpiStarted) MPI_Comm_rank(MPI_COMM_WORLD, &MyPID);
|
||||
else MyPID=0;
|
||||
#else
|
||||
MyPID = 0;
|
||||
#endif
|
||||
iPrint_ = (MyPID == 0);
|
||||
}
|
||||
|
||||
template<class ScalarType>
|
||||
void BasicOutputManager<ScalarType>::setOStream( Teuchos::RCP<ostream> os ) {
|
||||
myOS_ = os;
|
||||
}
|
||||
|
||||
template<class ScalarType>
|
||||
Teuchos::RCP<ostream> BasicOutputManager<ScalarType>::getOStream() {
|
||||
return myOS_;
|
||||
}
|
||||
|
||||
template<class ScalarType>
|
||||
bool BasicOutputManager<ScalarType>::isVerbosity( MsgType type ) const {
|
||||
if ( (type & this->vb_) == type ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class ScalarType>
|
||||
void BasicOutputManager<ScalarType>::print( MsgType type, const std::string output ) {
|
||||
if ( (type & this->vb_) == type && iPrint_ ) {
|
||||
*myOS_ << output;
|
||||
}
|
||||
}
|
||||
|
||||
template<class ScalarType>
|
||||
ostream & BasicOutputManager<ScalarType>::stream( MsgType type ) {
|
||||
if ( (type & this->vb_) == type && iPrint_ ) {
|
||||
return *myOS_;
|
||||
}
|
||||
return myBHS_;
|
||||
}
|
||||
|
||||
} // end Anasazi namespace
|
||||
|
||||
#endif
|
||||
|
||||
// end of file AnasaziOutputManager.hpp
|
||||
@@ -0,0 +1,465 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
|
||||
/*! \file AnasaziBasicSort.hpp
|
||||
\brief Basic implementation of the Anasazi::SortManager class
|
||||
*/
|
||||
|
||||
#ifndef ANASAZI_BASIC_SORT_HPP
|
||||
#define ANASAZI_BASIC_SORT_HPP
|
||||
|
||||
/*! \class Anasazi::BasicSort
|
||||
\brief An implementation of the Anasazi::SortManager that performs a collection
|
||||
of common sorting techniques.
|
||||
|
||||
\author Chris Baker, Ulrich Hetmaniuk, Rich Lehoucq, and Heidi Thornquist
|
||||
*/
|
||||
|
||||
#include "AnasaziConfigDefs.hpp"
|
||||
#include "AnasaziSortManager.hpp"
|
||||
#include "Teuchos_LAPACK.hpp"
|
||||
#include "Teuchos_ScalarTraits.hpp"
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
template<class ScalarType, class MV, class OP>
|
||||
class BasicSort : public SortManager<ScalarType,MV,OP> {
|
||||
|
||||
public:
|
||||
|
||||
//! Constructor
|
||||
/**
|
||||
@param which [in] The eigenvalues of interest for this eigenproblem.
|
||||
<ul>
|
||||
<li> "LM" - Largest Magnitude [ default ]
|
||||
<li> "SM" - Smallest Magnitude
|
||||
<li> "LR" - Largest Real
|
||||
<li> "SR" - Smallest Real
|
||||
<li> "LI" - Largest Imaginary
|
||||
<li> "SI" - Smallest Imaginary
|
||||
</ul>
|
||||
*/
|
||||
BasicSort( const std::string which = "LM" ) {
|
||||
setSortType(which);
|
||||
}
|
||||
|
||||
//! Destructor
|
||||
virtual ~BasicSort() {};
|
||||
|
||||
//! Set sort type
|
||||
/**
|
||||
@param which [in] The eigenvalues of interest for this eigenproblem.
|
||||
<ul>
|
||||
<li> "LM" - Largest Magnitude [ default ]
|
||||
<li> "SM" - Smallest Magnitude
|
||||
<li> "LR" - Largest Real
|
||||
<li> "SR" - Smallest Real
|
||||
<li> "LI" - Largest Imaginary
|
||||
<li> "SI" - Smallest Imaginary
|
||||
</ul>
|
||||
*/
|
||||
void setSortType( const std::string which ) {
|
||||
which_ = which;
|
||||
TEST_FOR_EXCEPTION(which_.compare("LM") && which_.compare("SM") &&
|
||||
which_.compare("LR") && which_.compare("SR") &&
|
||||
which_.compare("LI") && which_.compare("SI"), std::invalid_argument,
|
||||
"Anasazi::BasicSort::sort(): sorting order is not valid");
|
||||
};
|
||||
|
||||
//! Sort the vector of eigenvalues, optionally returning the permutation vector.
|
||||
/**
|
||||
@param solver [in] Eigensolver that is calling the sorting routine
|
||||
|
||||
@param n [in] Number of values in evals to be sorted.
|
||||
|
||||
@param evals [in/out] Vector of length n containing the eigenvalues to be sorted
|
||||
|
||||
@param perm [out] Vector of length n to store the permutation index (optional)
|
||||
*/
|
||||
void sort(Eigensolver<ScalarType,MV,OP>* solver, const int n, std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &evals, std::vector<int> *perm = 0) const;
|
||||
|
||||
/*! \brief Sort the vectors of eigenpairs, optionally returning the permutation vector.
|
||||
|
||||
This routine takes two vectors, one for each part of a complex
|
||||
eigenvalue. This is helpful for solving real, non-symmetric eigenvalue
|
||||
problems.
|
||||
|
||||
@param solver [in] Eigensolver that is calling the sorting routine
|
||||
|
||||
@param n [in] Number of values in r_evals,i_evals to be sorted.
|
||||
|
||||
@param r_evals [in/out] Vector of length n containing the real part of the eigenvalues to be sorted
|
||||
|
||||
@param i_evals [in/out] Vector of length n containing the imaginary part of the eigenvalues to be sorted
|
||||
|
||||
@param perm [out] Vector of length n to store the permutation index (optional)
|
||||
*/
|
||||
void sort(Eigensolver<ScalarType,MV,OP>* solver,
|
||||
const int n,
|
||||
std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &r_evals,
|
||||
std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &i_evals,
|
||||
std::vector<int> *perm = 0) const;
|
||||
|
||||
protected:
|
||||
|
||||
//! Sorting type
|
||||
/*! \note Sorting choices:
|
||||
<ul>
|
||||
<li> "LM" - Largest Magnitude [ default ]
|
||||
<li> "SM" - Smallest Magnitude
|
||||
<li> "LR" - Largest Real
|
||||
<li> "SR" - Smallest Real
|
||||
<li> "LI" - Largest Imaginary
|
||||
<li> "SI" - Smallest Imaginary
|
||||
</ul>
|
||||
*/
|
||||
std::string which_;
|
||||
|
||||
};
|
||||
|
||||
template<class ScalarType, class MV, class OP>
|
||||
void BasicSort<ScalarType,MV,OP>::sort(Eigensolver<ScalarType,MV,OP>* solver, const int n,
|
||||
std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &evals,
|
||||
std::vector<int> *perm) const
|
||||
{
|
||||
int i=0,j=0;
|
||||
|
||||
TEST_FOR_EXCEPTION(evals.size() < (unsigned int) n,
|
||||
std::invalid_argument, "Anasazi::BasicSort:sort(): eigenvalue vector size isn't consistent with n.");
|
||||
if (perm) {
|
||||
TEST_FOR_EXCEPTION(perm->size() < (unsigned int) n,
|
||||
std::invalid_argument, "Anasazi::BasicSort:sort(): permutation vector size isn't consistent with n.");
|
||||
}
|
||||
|
||||
// Temp integer for swapping the index of the permutation, used in all sorting types.
|
||||
int tempord=0;
|
||||
|
||||
typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
|
||||
typedef Teuchos::ScalarTraits<MagnitudeType> MT;
|
||||
|
||||
// Temp variable for swapping the eigenvalue used in all sorting types.
|
||||
MagnitudeType temp;
|
||||
|
||||
Teuchos::LAPACK<int,MagnitudeType> lapack;
|
||||
|
||||
//
|
||||
// Reset the permutation if it is required.
|
||||
//
|
||||
if (perm) {
|
||||
for (i=0; i < n; i++) {
|
||||
(*perm)[i] = i;
|
||||
}
|
||||
}
|
||||
//
|
||||
// These methods use an insertion sort method to circumvent recursive calls.
|
||||
//---------------------------------------------------------------
|
||||
// Sort eigenvalues in increasing order of magnitude
|
||||
//---------------------------------------------------------------
|
||||
if (!which_.compare("SM")) {
|
||||
for (j=1; j < n; j++) {
|
||||
temp = evals[j];
|
||||
if (perm) {
|
||||
tempord = (*perm)[j];
|
||||
}
|
||||
MagnitudeType temp2 = MT::magnitude(evals[j]);
|
||||
for (i=j-1; i >=0 && MT::magnitude(evals[i]) > temp2; i--) {
|
||||
evals[i+1] = evals[i];
|
||||
if (perm) {
|
||||
(*perm)[i+1]=(*perm)[i];
|
||||
}
|
||||
}
|
||||
evals[i+1] = temp;
|
||||
if (perm) {
|
||||
(*perm)[i+1] = tempord;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
// Sort eigenvalues in increasing order of real part
|
||||
//---------------------------------------------------------------
|
||||
if (!which_.compare("SR")) {
|
||||
for (j=1; j < n; j++) {
|
||||
temp = evals[j];
|
||||
if (perm) {
|
||||
tempord = (*perm)[j];
|
||||
}
|
||||
for (i=j-1; i >= 0 && evals[i] > temp; i--) {
|
||||
evals[i+1]=evals[i];
|
||||
if (perm) {
|
||||
(*perm)[i+1]=(*perm)[i];
|
||||
}
|
||||
}
|
||||
evals[i+1] = temp;
|
||||
if (perm) {
|
||||
(*perm)[i+1] = tempord;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
// Sort eigenvalues in increasing order of imaginary part
|
||||
// NOTE: There is no implementation for this since this sorting
|
||||
// method assumes only real eigenvalues.
|
||||
//---------------------------------------------------------------
|
||||
TEST_FOR_EXCEPTION(!which_.compare("SI"), SortManagerError,
|
||||
"Anasazi::BasicSort::sort() with one arg assumes real eigenvalues");
|
||||
//---------------------------------------------------------------
|
||||
// Sort eigenvalues in decreasing order of magnitude
|
||||
//---------------------------------------------------------------
|
||||
if (!which_.compare("LM")) {
|
||||
for (j=1; j < n; j++) {
|
||||
temp = evals[j];
|
||||
if (perm) {
|
||||
tempord = (*perm)[j];
|
||||
}
|
||||
MagnitudeType temp2 = MT::magnitude(evals[j]);
|
||||
for (i=j-1; i >= 0 && MT::magnitude(evals[i]) < temp2; i--) {
|
||||
evals[i+1]=evals[i];
|
||||
if (perm) {
|
||||
(*perm)[i+1]=(*perm)[i];
|
||||
}
|
||||
}
|
||||
evals[i+1] = temp;
|
||||
if (perm) {
|
||||
(*perm)[i+1] = tempord;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
// Sort eigenvalues in decreasing order of real part
|
||||
//---------------------------------------------------------------
|
||||
if (!which_.compare("LR")) {
|
||||
for (j=1; j < n; j++) {
|
||||
temp = evals[j];
|
||||
if (perm) {
|
||||
tempord = (*perm)[j];
|
||||
}
|
||||
for (i=j-1; i >= 0 && evals[i]<temp; i--) {
|
||||
evals[i+1]=evals[i];
|
||||
if (perm) {
|
||||
(*perm)[i+1]=(*perm)[i];
|
||||
}
|
||||
}
|
||||
evals[i+1] = temp;
|
||||
if (perm) {
|
||||
(*perm)[i+1] = tempord;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
// Sort eigenvalues in decreasing order of imaginary part
|
||||
// NOTE: There is no implementation for this since this templating
|
||||
// assumes only real eigenvalues.
|
||||
//---------------------------------------------------------------
|
||||
TEST_FOR_EXCEPTION(!which_.compare("LI"), SortManagerError,
|
||||
"Anasazi::BasicSort::sort() with one arg assumes real eigenvalues");
|
||||
|
||||
// The character string held by this class is not valid.
|
||||
TEST_FOR_EXCEPTION(true, std::logic_error,
|
||||
"Anasazi::BasicSort::sort(): sorting order is not valid");
|
||||
}
|
||||
|
||||
|
||||
template<class ScalarType, class MV, class OP>
|
||||
void BasicSort<ScalarType,MV,OP>::sort(Eigensolver<ScalarType,MV,OP>* solver,
|
||||
const int n,
|
||||
std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &r_evals,
|
||||
std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &i_evals,
|
||||
std::vector<int> *perm) const
|
||||
{
|
||||
typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
|
||||
typedef Teuchos::ScalarTraits<MagnitudeType> MT;
|
||||
|
||||
TEST_FOR_EXCEPTION(r_evals.size() < (unsigned int) n || i_evals.size() < (unsigned int) n,
|
||||
std::invalid_argument, "Anasazi::BasicSort:sort(): real and imaginary vector sizes aren't consistent with n.");
|
||||
if (perm) {
|
||||
TEST_FOR_EXCEPTION(perm->size() < (unsigned int) n,
|
||||
std::invalid_argument, "Anasazi::BasicSort:sort(): permutation vector size isn't consistent with n.");
|
||||
}
|
||||
int i=0,j=0;
|
||||
int tempord=0;
|
||||
|
||||
MagnitudeType temp, tempr, tempi;
|
||||
Teuchos::LAPACK<int,MagnitudeType> lapack;
|
||||
//
|
||||
// Reset the index
|
||||
//
|
||||
if (perm) {
|
||||
for (i=0; i < n; i++) {
|
||||
(*perm)[i] = i;
|
||||
}
|
||||
}
|
||||
//
|
||||
// These methods use an insertion sort method to circumvent recursive calls.
|
||||
//---------------------------------------------------------------
|
||||
// Sort eigenvalues in increasing order of magnitude
|
||||
//---------------------------------------------------------------
|
||||
if (!which_.compare("SM")) {
|
||||
for (j=1; j < n; j++) {
|
||||
tempr = r_evals[j]; tempi = i_evals[j];
|
||||
if (perm) {
|
||||
tempord = (*perm)[j];
|
||||
}
|
||||
temp=lapack.LAPY2(r_evals[j],i_evals[j]);
|
||||
for (i=j-1; i>=0 && lapack.LAPY2(r_evals[i],i_evals[i]) > temp; i--) {
|
||||
r_evals[i+1]=r_evals[i]; i_evals[i+1]=i_evals[i];
|
||||
if (perm) {
|
||||
(*perm)[i+1]=(*perm)[i];
|
||||
}
|
||||
}
|
||||
r_evals[i+1] = tempr; i_evals[i+1] = tempi;
|
||||
if (perm) {
|
||||
(*perm)[i+1] = tempord;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
// Sort eigenvalues in increasing order of real part
|
||||
//---------------------------------------------------------------
|
||||
if (!which_.compare("SR")) {
|
||||
for (j=1; j < n; j++) {
|
||||
tempr = r_evals[j]; tempi = i_evals[j];
|
||||
if (perm) {
|
||||
tempord = (*perm)[j];
|
||||
}
|
||||
for (i=j-1; i>=0 && r_evals[i]>tempr; i--) {
|
||||
r_evals[i+1]=r_evals[i]; i_evals[i+1]=i_evals[i];
|
||||
if (perm) {
|
||||
(*perm)[i+1]=(*perm)[i];
|
||||
}
|
||||
}
|
||||
r_evals[i+1] = tempr; i_evals[i+1] = tempi;
|
||||
if (perm) {
|
||||
(*perm)[i+1] = tempord;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
// Sort eigenvalues in increasing order of imaginary part
|
||||
//---------------------------------------------------------------
|
||||
if (!which_.compare("SI")) {
|
||||
for (j=1; j < n; j++) {
|
||||
tempr = r_evals[j]; tempi = i_evals[j];
|
||||
if (perm) {
|
||||
tempord = (*perm)[j];
|
||||
}
|
||||
for (i=j-1; i>=0 && i_evals[i]>tempi; i--) {
|
||||
r_evals[i+1]=r_evals[i]; i_evals[i+1]=i_evals[i];
|
||||
if (perm) {
|
||||
(*perm)[i+1]=(*perm)[i];
|
||||
}
|
||||
}
|
||||
r_evals[i+1] = tempr; i_evals[i+1] = tempi;
|
||||
if (perm) {
|
||||
(*perm)[i+1] = tempord;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
// Sort eigenvalues in decreasing order of magnitude
|
||||
//---------------------------------------------------------------
|
||||
if (!which_.compare("LM")) {
|
||||
for (j=1; j < n; j++) {
|
||||
tempr = r_evals[j]; tempi = i_evals[j];
|
||||
if (perm) {
|
||||
tempord = (*perm)[j];
|
||||
}
|
||||
temp=lapack.LAPY2(r_evals[j],i_evals[j]);
|
||||
for (i=j-1; i>=0 && lapack.LAPY2(r_evals[i],i_evals[i])<temp; i--) {
|
||||
r_evals[i+1]=r_evals[i]; i_evals[i+1]=i_evals[i];
|
||||
if (perm) {
|
||||
(*perm)[i+1]=(*perm)[i];
|
||||
}
|
||||
}
|
||||
r_evals[i+1] = tempr; i_evals[i+1] = tempi;
|
||||
if (perm) {
|
||||
(*perm)[i+1] = tempord;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
// Sort eigenvalues in decreasing order of real part
|
||||
//---------------------------------------------------------------
|
||||
if (!which_.compare("LR")) {
|
||||
for (j=1; j < n; j++) {
|
||||
tempr = r_evals[j]; tempi = i_evals[j];
|
||||
if (perm) {
|
||||
tempord = (*perm)[j];
|
||||
}
|
||||
for (i=j-1; i>=0 && r_evals[i]<tempr; i--) {
|
||||
r_evals[i+1]=r_evals[i]; i_evals[i+1]=i_evals[i];
|
||||
if (perm) {
|
||||
(*perm)[i+1]=(*perm)[i];
|
||||
}
|
||||
}
|
||||
r_evals[i+1] = tempr; i_evals[i+1] = tempi;
|
||||
if (perm) {
|
||||
(*perm)[i+1] = tempord;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
// Sort eigenvalues in decreasing order of imaginary part
|
||||
//---------------------------------------------------------------
|
||||
if (!which_.compare("LI")) {
|
||||
for (j=1; j < n; j++) {
|
||||
tempr = r_evals[j]; tempi = i_evals[j];
|
||||
if (perm) {
|
||||
tempord = (*perm)[j];
|
||||
}
|
||||
for (i=j-1; i>=0 && i_evals[i]<tempi; i--) {
|
||||
r_evals[i+1]=r_evals[i]; i_evals[i+1]=i_evals[i];
|
||||
if (perm) {
|
||||
(*perm)[i+1]=(*perm)[i];
|
||||
}
|
||||
}
|
||||
r_evals[i+1] = tempr; i_evals[i+1] = tempi;
|
||||
if (perm) {
|
||||
(*perm)[i+1] = tempord;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
TEST_FOR_EXCEPTION(true, std::logic_error,
|
||||
"Anasazi::BasicSort::sort(): sorting order is not valid");
|
||||
}
|
||||
|
||||
|
||||
} // namespace Anasazi
|
||||
|
||||
#endif // ANASAZI_BASIC_SORT_HPP
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,988 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
|
||||
#ifndef ANASAZI_BLOCKDAVIDSON_SOLMGR_HPP
|
||||
#define ANASAZI_BLOCKDAVIDSON_SOLMGR_HPP
|
||||
|
||||
/*! \file AnasaziBlockDavidsonSolMgr.hpp
|
||||
* \brief The Anasazi::BlockDavidsonSolMgr provides a solver manager for the BlockDavidson eigensolver.
|
||||
*/
|
||||
|
||||
#include "AnasaziConfigDefs.hpp"
|
||||
#include "AnasaziTypes.hpp"
|
||||
|
||||
#include "AnasaziEigenproblem.hpp"
|
||||
#include "AnasaziSolverManager.hpp"
|
||||
#include "AnasaziSolverUtils.hpp"
|
||||
|
||||
#include "AnasaziBlockDavidson.hpp"
|
||||
#include "AnasaziBasicSort.hpp"
|
||||
#include "AnasaziSVQBOrthoManager.hpp"
|
||||
#include "AnasaziStatusTestMaxIters.hpp"
|
||||
#include "AnasaziStatusTestResNorm.hpp"
|
||||
#include "AnasaziStatusTestOrderedResNorm.hpp"
|
||||
#include "AnasaziStatusTestCombo.hpp"
|
||||
#include "AnasaziStatusTestOutput.hpp"
|
||||
#include "AnasaziBasicOutputManager.hpp"
|
||||
#include "Teuchos_BLAS.hpp"
|
||||
#include "Teuchos_LAPACK.hpp"
|
||||
|
||||
|
||||
/** \example BlockDavidson/BlockDavidsonEpetraEx.cpp
|
||||
This is an example of how to use the Anasazi::BlockDavidsonSolMgr solver manager to solve a standard eigenvalue problem.
|
||||
*/
|
||||
|
||||
/** \example BlockDavidson/BlockDavidsonEpetraExGen.cpp
|
||||
This is an example of how to use the Anasazi::BlockDavidsonSolMgr solver manager to solve a generalized eigenvalue problem.
|
||||
*/
|
||||
|
||||
/*! \class Anasazi::BlockDavidsonSolMgr
|
||||
*
|
||||
* \brief The Anasazi::BlockDavidsonSolMgr provides a powerful and fully-featured solver manager over the BlockDavidson eigensolver.
|
||||
*
|
||||
* This solver manager implements a hard-locking mechanism, whereby eigenpairs designated to be locked are moved from the eigensolver and placed in
|
||||
* auxiliary storage. The eigensolver is then restarted and continues to iterate, always orthogonal to the locked eigenvectors.
|
||||
|
||||
\ingroup anasazi_solver_framework
|
||||
|
||||
\author Chris Baker, Ulrich Hetmaniuk, Rich Lehoucq, Heidi Thornquist
|
||||
*/
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
template<class ScalarType, class MV, class OP>
|
||||
class BlockDavidsonSolMgr : public SolverManager<ScalarType,MV,OP> {
|
||||
|
||||
private:
|
||||
typedef MultiVecTraits<ScalarType,MV> MVT;
|
||||
typedef OperatorTraits<ScalarType,MV,OP> OPT;
|
||||
typedef Teuchos::ScalarTraits<ScalarType> SCT;
|
||||
typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
|
||||
typedef Teuchos::ScalarTraits<MagnitudeType> MT;
|
||||
|
||||
public:
|
||||
|
||||
//! @name Constructors/Destructor
|
||||
//@{
|
||||
|
||||
/*! \brief Basic constructor for BlockDavidsonSolMgr.
|
||||
*
|
||||
* This constructor accepts the Eigenproblem to be solved in addition
|
||||
* to a parameter list of options for the solver manager. These options include the following:
|
||||
* - "Which" - a \c string specifying the desired eigenvalues: SM, LM, SR or LR. Default: "SR"
|
||||
* - "Block Size" - a \c int specifying the block size to be used by the underlying block Davidson solver. Default: problem->getNEV()
|
||||
* - "Num Blocks" - a \c int specifying the number of blocks allocated for the Krylov basis. Default: 2
|
||||
* - "Maximum Restarts" - a \c int specifying the maximum number of restarts the underlying solver is allowed to perform. Default: 20
|
||||
* - "Verbosity" - a sum of MsgType specifying the verbosity. Default: Anasazi::Errors
|
||||
* - "Convergence Tolerance" - a \c MagnitudeType specifying the level that residual norms must reach to decide convergence. Default: machine precision.
|
||||
* - "Relative Convergence Tolerance" - a \c bool specifying whether residuals norms should be scaled by their eigenvalues for the purposing of deciding convergence. Default: true
|
||||
* - "Use Locking" - a \c bool specifying whether the algorithm should employ locking of converged eigenpairs. Default: false
|
||||
* - "Max Locked" - a \c int specifying the maximum number of eigenpairs to be locked. Default: problem->getNEV()
|
||||
* - "Locking Quorum" - a \c int specifying the number of eigenpairs that must meet the locking criteria before locking actually occurs. Default: 1
|
||||
* - "Locking Tolerance" - a \c MagnitudeType specifying the level that residual norms must reach to decide locking. Default: 0.1*convergence tolerance
|
||||
* - "Relative Locking Tolerance" - a \c bool specifying whether residuals norms should be scaled by their eigenvalues for the purposing of deciding locking. Default: true
|
||||
*/
|
||||
BlockDavidsonSolMgr( const Teuchos::RCP<Eigenproblem<ScalarType,MV,OP> > &problem,
|
||||
Teuchos::ParameterList &pl );
|
||||
|
||||
//! Destructor.
|
||||
virtual ~BlockDavidsonSolMgr() {};
|
||||
//@}
|
||||
|
||||
//! @name Accessor methods
|
||||
//@{
|
||||
|
||||
const Eigenproblem<ScalarType,MV,OP>& getProblem() const {
|
||||
return *problem_;
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Solver application methods
|
||||
//@{
|
||||
|
||||
/*! \brief This method performs possibly repeated calls to the underlying eigensolver's iterate() routine
|
||||
* until the problem has been solved (as decided by the solver manager) or the solver manager decides to
|
||||
* quit.
|
||||
*
|
||||
* This method calls BlockDavidson::iterate(), which will return either because a specially constructed status test evaluates to ::Passed
|
||||
* or an exception is thrown.
|
||||
*
|
||||
* A return from BlockDavidson::iterate() signifies one of the following scenarios:
|
||||
* - the maximum number of restarts has been exceeded. In this scenario, the solver manager will place\n
|
||||
* all converged eigenpairs into the eigenproblem and return ::Unconverged.
|
||||
* - the locking conditions have been met. In this scenario, some of the current eigenpairs will be removed\n
|
||||
* from the eigensolver and placed into auxiliary storage. The eigensolver will be restarted with the remaining part of the Krylov subspace\n
|
||||
* and some random information to replace the removed subspace.
|
||||
* - global convergence has been met. In this case, the most significant NEV eigenpairs in the solver and locked storage \n
|
||||
* have met the convergence criterion. (Here, NEV refers to the number of eigenpairs requested by the Eigenproblem.) \n
|
||||
* In this scenario, the solver manager will return ::Converged.
|
||||
*
|
||||
* \returns ::ReturnType specifying:
|
||||
* - ::Converged: the eigenproblem was solved to the specification required by the solver manager.
|
||||
* - ::Unconverged: the eigenproblem was not solved to the specification desired by the solver manager.
|
||||
*/
|
||||
ReturnType solve();
|
||||
//@}
|
||||
|
||||
private:
|
||||
Teuchos::RCP<Eigenproblem<ScalarType,MV,OP> > problem_;
|
||||
|
||||
std::string whch_;
|
||||
|
||||
MagnitudeType convtol_, locktol_;
|
||||
int maxRestarts_;
|
||||
bool useLocking_;
|
||||
bool relconvtol_, rellocktol_;
|
||||
int blockSize_, numBlocks_;
|
||||
int maxLocked_;
|
||||
int verbosity_;
|
||||
int lockQuorum_;
|
||||
bool inSituRestart_;
|
||||
int numRestartBlocks_;
|
||||
};
|
||||
|
||||
|
||||
// Constructor
|
||||
template<class ScalarType, class MV, class OP>
|
||||
BlockDavidsonSolMgr<ScalarType,MV,OP>::BlockDavidsonSolMgr(
|
||||
const Teuchos::RCP<Eigenproblem<ScalarType,MV,OP> > &problem,
|
||||
Teuchos::ParameterList &pl ) :
|
||||
problem_(problem),
|
||||
whch_("SR"),
|
||||
convtol_(0),
|
||||
locktol_(0),
|
||||
maxRestarts_(20),
|
||||
useLocking_(false),
|
||||
relconvtol_(true),
|
||||
rellocktol_(true),
|
||||
blockSize_(0),
|
||||
numBlocks_(0),
|
||||
maxLocked_(0),
|
||||
verbosity_(Anasazi::Errors),
|
||||
lockQuorum_(1),
|
||||
inSituRestart_(false),
|
||||
numRestartBlocks_(1)
|
||||
{
|
||||
TEST_FOR_EXCEPTION(problem_ == Teuchos::null, std::invalid_argument, "Problem not given to solver manager.");
|
||||
TEST_FOR_EXCEPTION(!problem_->isProblemSet(), std::invalid_argument, "Problem not set.");
|
||||
TEST_FOR_EXCEPTION(!problem_->isHermitian(), std::invalid_argument, "Problem not symmetric.");
|
||||
TEST_FOR_EXCEPTION(problem_->getInitVec() == Teuchos::null, std::invalid_argument, "Problem does not contain initial vectors to clone from.");
|
||||
|
||||
// which values to solve for
|
||||
whch_ = pl.get("Which",whch_);
|
||||
TEST_FOR_EXCEPTION(whch_ != "SM" && whch_ != "LM" && whch_ != "SR" && whch_ != "LR",std::invalid_argument, "Invalid sorting string.");
|
||||
|
||||
// convergence tolerance
|
||||
convtol_ = pl.get("Convergence Tolerance",MT::prec());
|
||||
relconvtol_ = pl.get("Relative Convergence Tolerance",relconvtol_);
|
||||
|
||||
// locking tolerance
|
||||
useLocking_ = pl.get("Use Locking",useLocking_);
|
||||
rellocktol_ = pl.get("Relative Locking Tolerance",rellocktol_);
|
||||
locktol_ = pl.get("Locking Tolerance",convtol_/10.0);
|
||||
|
||||
// maximum number of restarts
|
||||
maxRestarts_ = pl.get("Maximum Restarts",maxRestarts_);
|
||||
|
||||
// block size: default is nev()
|
||||
blockSize_ = pl.get("Block Size",problem_->getNEV());
|
||||
TEST_FOR_EXCEPTION(blockSize_ <= 0, std::invalid_argument,
|
||||
"Anasazi::BlockDavidsonSolMgr: \"Block Size\" must be strictly positive.");
|
||||
numBlocks_ = pl.get("Num Blocks",2);
|
||||
TEST_FOR_EXCEPTION(numBlocks_ <= 1, std::invalid_argument,
|
||||
"Anasazi::BlockDavidsonSolMgr: \"Num Blocks\" must be >= 1.");
|
||||
|
||||
// max locked: default is nev(), must satisfy maxLocked_ + blockSize_ >= nev
|
||||
if (useLocking_) {
|
||||
maxLocked_ = pl.get("Max Locked",problem_->getNEV());
|
||||
}
|
||||
else {
|
||||
maxLocked_ = 0;
|
||||
}
|
||||
if (maxLocked_ == 0) {
|
||||
useLocking_ = false;
|
||||
}
|
||||
TEST_FOR_EXCEPTION(maxLocked_ < 0, std::invalid_argument,
|
||||
"Anasazi::BlockDavidsonSolMgr: \"Max Locked\" must be positive.");
|
||||
TEST_FOR_EXCEPTION(maxLocked_ + blockSize_ < problem_->getNEV(),
|
||||
std::invalid_argument,
|
||||
"Anasazi::BlockDavidsonSolMgr: Not enough storage space for requested number of eigenpairs.");
|
||||
TEST_FOR_EXCEPTION(numBlocks_*blockSize_ + maxLocked_ > MVT::GetVecLength(*problem_->getInitVec()),
|
||||
std::invalid_argument,
|
||||
"Anasazi::BlockDavidsonSolMgr: Potentially impossible orthogonality requests. Reduce basis size or locking size.");
|
||||
|
||||
if (useLocking_) {
|
||||
lockQuorum_ = pl.get("Locking Quorum",lockQuorum_);
|
||||
TEST_FOR_EXCEPTION(lockQuorum_ <= 0,
|
||||
std::invalid_argument,
|
||||
"Anasazi::BlockDavidsonSolMgr: \"Locking Quorum\" must be strictly positive.");
|
||||
}
|
||||
|
||||
// verbosity level
|
||||
if (pl.isParameter("Verbosity")) {
|
||||
if (Teuchos::isParameterType<int>(pl,"Verbosity")) {
|
||||
verbosity_ = pl.get("Verbosity", verbosity_);
|
||||
} else {
|
||||
verbosity_ = (int)Teuchos::getParameter<Anasazi::MsgType>(pl,"Verbosity");
|
||||
}
|
||||
}
|
||||
|
||||
// restart size
|
||||
numRestartBlocks_ = pl.get("Num Restart Blocks",numRestartBlocks_);
|
||||
TEST_FOR_EXCEPTION(numRestartBlocks_ <= 0, std::invalid_argument,
|
||||
"Anasazi::BlockDavidsonSolMgr: \"Num Restart Blocks\" must be strictly positive.");
|
||||
TEST_FOR_EXCEPTION(numRestartBlocks_ >= numBlocks_, std::invalid_argument,
|
||||
"Anasazi::BlockDavidsonSolMgr: \"Num Restart Blocks\" must be strictly less than \"Num Blocks\".");
|
||||
|
||||
// restarting technique: V*Q or applyHouse(V,H,tau)
|
||||
if (pl.isParameter("In Situ Restarting")) {
|
||||
if (Teuchos::isParameterType<bool>(pl,"In Situ Restarting")) {
|
||||
inSituRestart_ = pl.get("In Situ Restarting",inSituRestart_);
|
||||
} else {
|
||||
inSituRestart_ = (bool)Teuchos::getParameter<int>(pl,"In Situ Restarting");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// solve()
|
||||
template<class ScalarType, class MV, class OP>
|
||||
ReturnType
|
||||
BlockDavidsonSolMgr<ScalarType,MV,OP>::solve() {
|
||||
|
||||
typedef SolverUtils<ScalarType,MV,OP> msutils;
|
||||
|
||||
const int nev = problem_->getNEV();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Sort manager
|
||||
Teuchos::RCP<BasicSort<ScalarType,MV,OP> > sorter = Teuchos::rcp( new BasicSort<ScalarType,MV,OP>(whch_) );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Output manager
|
||||
Teuchos::RCP<BasicOutputManager<ScalarType> > printer = Teuchos::rcp( new BasicOutputManager<ScalarType>(verbosity_) );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Status tests
|
||||
//
|
||||
// convergence
|
||||
Teuchos::RCP<StatusTestOrderedResNorm<ScalarType,MV,OP> > convtest
|
||||
= Teuchos::rcp( new StatusTestOrderedResNorm<ScalarType,MV,OP>(sorter,convtol_,nev,StatusTestOrderedResNorm<ScalarType,MV,OP>::RES_ORTH,relconvtol_) );
|
||||
// locking
|
||||
Teuchos::RCP<StatusTestResNorm<ScalarType,MV,OP> > locktest;
|
||||
if (useLocking_) {
|
||||
locktest = Teuchos::rcp( new StatusTestResNorm<ScalarType,MV,OP>(locktol_,lockQuorum_,StatusTestResNorm<ScalarType,MV,OP>::RES_ORTH,rellocktol_) );
|
||||
}
|
||||
// combo class
|
||||
Teuchos::Array<Teuchos::RCP<StatusTest<ScalarType,MV,OP> > > alltests;
|
||||
// for an OR test, the order doesn't matter
|
||||
alltests.push_back(convtest);
|
||||
if (locktest != Teuchos::null) alltests.push_back(locktest);
|
||||
// combo: convergence || locking
|
||||
Teuchos::RCP<StatusTestCombo<ScalarType,MV,OP> > combotest
|
||||
= Teuchos::rcp( new StatusTestCombo<ScalarType,MV,OP>( StatusTestCombo<ScalarType,MV,OP>::OR, alltests) );
|
||||
// printing StatusTest
|
||||
Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputtest
|
||||
= Teuchos::rcp( new StatusTestOutput<ScalarType,MV,OP>( printer,combotest,1,Passed ) );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Orthomanager
|
||||
Teuchos::RCP<SVQBOrthoManager<ScalarType,MV,OP> > ortho
|
||||
= Teuchos::rcp( new SVQBOrthoManager<ScalarType,MV,OP>(problem_->getM()) );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Parameter list
|
||||
Teuchos::ParameterList plist;
|
||||
plist.set("Block Size",blockSize_);
|
||||
plist.set("Num Blocks",numBlocks_);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// BlockDavidson solver
|
||||
Teuchos::RCP<BlockDavidson<ScalarType,MV,OP> > bd_solver
|
||||
= Teuchos::rcp( new BlockDavidson<ScalarType,MV,OP>(problem_,sorter,printer,outputtest,ortho,plist) );
|
||||
// set any auxiliary vectors defined in the problem
|
||||
Teuchos::RCP< const MV > probauxvecs = problem_->getAuxVecs();
|
||||
if (probauxvecs != Teuchos::null) {
|
||||
bd_solver->setAuxVecs( Teuchos::tuple< Teuchos::RCP<const MV> >(probauxvecs) );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Storage
|
||||
// for locked vectors
|
||||
int curNumLocked = 0;
|
||||
Teuchos::RCP<MV> lockvecs;
|
||||
// lockvecs is used to hold the locked eigenvectors, as well as for temporary storage when locking.
|
||||
// when locking, we will lock some number of vectors numnew, where numnew <= maxlocked - curlocked
|
||||
// we will produce numnew random vectors, which will go into the space with the new basis.
|
||||
// we will also need numnew storage for the image of these random vectors under A and M;
|
||||
// columns [curlocked+1,curlocked+numnew] will be used for this storage
|
||||
if (maxLocked_ > 0) {
|
||||
lockvecs = MVT::Clone(*problem_->getInitVec(),maxLocked_);
|
||||
}
|
||||
std::vector<MagnitudeType> lockvals;
|
||||
//
|
||||
// Restarting occurs under two scenarios: when the basis is full and after locking.
|
||||
//
|
||||
// For the former, a new basis of size blockSize*numRestartBlocks is generated using the current basis
|
||||
// and the most significant primitive Ritz vectors (projected eigenvectors).
|
||||
// [S,L] = eig(KK)
|
||||
// S = [Sr St] // some for "r"estarting, some are "t"runcated
|
||||
// newV = V*Sr
|
||||
// KK_new = newV'*K*newV = Sr'*V'*K*V*Sr = Sr'*KK*Sr
|
||||
// Therefore, the only multivector operation needed is for the generation of newV.
|
||||
//
|
||||
// * If the multiplication is explicit, it requires a workspace of blockSize*numRestartBlocks vectors.
|
||||
// This space must be specifically allocated for that task, as we don't have any space of that size.
|
||||
// It (workMV) will be allocated at the beginning of solve()
|
||||
// * Optionally, the multiplication can be performed implicitly, via a Householder QR factorization of
|
||||
// Sr. This can be done in situ, using the basis multivector contained in the solver. This requires
|
||||
// that we cast away the const on the multivector returned from getState(). Workspace for this approach
|
||||
// is a single vector. the solver's internal storage must be preserved (X,MX,KX,R), requiring us to
|
||||
// allocate this vector.
|
||||
//
|
||||
// For the latter (restarting after locking), the new basis is the same size as existing basis. If numnew
|
||||
// vectors are locked, they are deflated from the current basis and replaced with randomly generated
|
||||
// vectors.
|
||||
// [S,L] = eig(KK)
|
||||
// S = [Sl Su] // partitioned: "l"ocked and "u"nlocked
|
||||
// newL = V*Sl = X(locked)
|
||||
// defV = V*Su
|
||||
// augV = rand(numnew) // orthogonal to oldL,newL,defV,auxvecs
|
||||
// newV = [defV augV]
|
||||
// Kknew = newV'*K*newV = [Su'*KK*Su defV'*K*augV]
|
||||
// [augV'*K*defV augV'*K*augV]
|
||||
// locked = [oldL newL]
|
||||
// Clearly, this operation is more complicated than the previous.
|
||||
// Here is a list of the significant computations that need to be performed:
|
||||
// - newL will be put into space in lockvecs, but will be copied from getState().X at the end
|
||||
// - defV,augV will be stored in workspace the size of the current basis.
|
||||
// - If inSituRestart==true, we compute defV in situ in bd_solver::V_ and
|
||||
// put augV at the end of bd_solver::V_
|
||||
// - If inSituRestart==false, we must have curDim vectors available for
|
||||
// defV and augV; we will allocate a multivector (workMV) at the beginning of solve()
|
||||
// for this purpose.
|
||||
// - M*augV and K*augV are needed; they will be stored in lockvecs. As a result, newL will
|
||||
// not be put into lockvecs until the end.
|
||||
//
|
||||
// Therefore, we must allocate workMV when ((maxRestarts_ > 0) || (useLocking_ == true)) && inSituRestart == false
|
||||
// It will be allocated to size (numBlocks-1)*blockSize
|
||||
//
|
||||
Teuchos::RCP<MV> workMV;
|
||||
if (inSituRestart_ == false) {
|
||||
// we need storage space to restart, either if we may lock or if may restart after a full basis
|
||||
if (useLocking_==true || maxRestarts_ > 0) {
|
||||
workMV = MVT::Clone(*problem_->getInitVec(),(numBlocks_-1)*blockSize_);
|
||||
}
|
||||
else {
|
||||
// we will never need to restart.
|
||||
workMV = Teuchos::null;
|
||||
}
|
||||
}
|
||||
else { // inSituRestart_ == true
|
||||
// we will restart in situ, if we need to restart
|
||||
// three situation remain:
|
||||
// - never restart => no space needed
|
||||
// - only restart for locking (i.e., never restart full) => no space needed
|
||||
// - restart for full basis => need one vector
|
||||
if (maxRestarts_ > 0) {
|
||||
workMV = MVT::Clone(*problem_->getInitVec(),1);
|
||||
}
|
||||
else {
|
||||
workMV = Teuchos::null;
|
||||
}
|
||||
}
|
||||
|
||||
// some consts and utils
|
||||
const ScalarType ONE = SCT::one();
|
||||
const ScalarType ZERO = SCT::zero();
|
||||
Teuchos::LAPACK<int,ScalarType> lapack;
|
||||
Teuchos::BLAS<int,ScalarType> blas;
|
||||
|
||||
// go ahead and initialize the solution to nothing in case we throw an exception
|
||||
Eigensolution<ScalarType,MV> sol;
|
||||
sol.numVecs = 0;
|
||||
problem_->setSolution(sol);
|
||||
|
||||
int numRestarts = 0;
|
||||
|
||||
// tell bd_solver to iterate
|
||||
while (1) {
|
||||
try {
|
||||
bd_solver->iterate();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// check convergence first
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
if (convtest->getStatus() == Passed ) {
|
||||
// we have convergence
|
||||
// convtest->whichVecs() tells us which vectors from lockvecs and solver state are the ones we want
|
||||
// convtest->howMany() will tell us how many
|
||||
break;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// check for restarting before locking: if we need to lock, it will happen after the restart
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
else if ( bd_solver->getCurSubspaceDim() == bd_solver->getMaxSubspaceDim() ) {
|
||||
|
||||
if ( numRestarts >= maxRestarts_ ) {
|
||||
break; // break from while(1){bd_solver->iterate()}
|
||||
}
|
||||
numRestarts++;
|
||||
|
||||
printer->stream(IterationDetails) << " Performing restart number " << numRestarts << " of " << maxRestarts_ << std::endl << std::endl;
|
||||
|
||||
BlockDavidsonState<ScalarType,MV> state = bd_solver->getState();
|
||||
int curdim = state.curDim;
|
||||
int newdim = numRestartBlocks_*blockSize_;
|
||||
|
||||
//
|
||||
// compute eigenvectors of the projected problem
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> S(curdim,curdim);
|
||||
std::vector<MagnitudeType> theta(curdim);
|
||||
int rank = curdim;
|
||||
int info = msutils::directSolver(curdim,*state.KK,Teuchos::null,S,theta,rank,10);
|
||||
TEST_FOR_EXCEPTION(info != 0 ,std::logic_error,
|
||||
"Anasazi::BlockDavidsonSolMgr::solve(): error calling SolverUtils::directSolver."); // this should never happen
|
||||
TEST_FOR_EXCEPTION(rank != curdim,std::logic_error,
|
||||
"Anasazi::BlockDavidsonSolMgr::solve(): direct solve did not compute all eigenvectors."); // this should never happen
|
||||
|
||||
//
|
||||
// sort the eigenvalues (so that we can order the eigenvectors)
|
||||
{
|
||||
std::vector<int> order(curdim);
|
||||
sorter->sort(bd_solver.get(),curdim,theta,&order);
|
||||
//
|
||||
// apply the same ordering to the primitive ritz vectors
|
||||
msutils::permuteVectors(order,S);
|
||||
}
|
||||
//
|
||||
// select the significant primitive ritz vectors
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> Sr(Teuchos::View,S,curdim,newdim);
|
||||
//
|
||||
// generate newKK = Sr'*KKold*Sr
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> newKK(newdim,newdim);
|
||||
{
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> KKtmp(curdim,newdim),
|
||||
KKold(Teuchos::View,*state.KK,curdim,curdim);
|
||||
int teuchosRet;
|
||||
// KKtmp = KKold*Sr
|
||||
teuchosRet = KKtmp.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,ONE,KKold,Sr,ZERO);
|
||||
TEST_FOR_EXCEPTION(teuchosRet != 0,std::logic_error,
|
||||
"Anasazi::BlockDavidsonSolMgr::solve(): Logic error calling SerialDenseMatrix::multiply.");
|
||||
// newKK = Sr'*KKtmp = Sr'*KKold*Sr
|
||||
teuchosRet = newKK.multiply(Teuchos::CONJ_TRANS,Teuchos::NO_TRANS,ONE,Sr,KKtmp,ZERO);
|
||||
TEST_FOR_EXCEPTION(teuchosRet != 0,std::logic_error,
|
||||
"Anasazi::BlockDavidsonSolMgr::solve(): Logic error calling SerialDenseMatrix::multiply.");
|
||||
// make it Hermitian in memory
|
||||
for (int j=0; j<newdim; ++j) {
|
||||
for (int i=j+1; i<newdim; ++i) {
|
||||
newKK(i,j) = SCT::conjugate(newKK(j,i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// prepare new state
|
||||
BlockDavidsonState<ScalarType,MV> rstate;
|
||||
rstate.curDim = newdim;
|
||||
rstate.KK = Teuchos::rcp( &newKK, false );
|
||||
//
|
||||
// we know that newX = newV*Sr(:,1:bS) = oldV*S(:1:bS) = oldX
|
||||
// the restarting preserves the Ritz vectors and residual
|
||||
// for the Ritz values, we want all of the values associated with newV.
|
||||
// these have already been placed at the beginning of theta
|
||||
rstate.X = state.X;
|
||||
rstate.KX = state.KX;
|
||||
rstate.MX = state.MX;
|
||||
rstate.R = state.R;
|
||||
rstate.T = Teuchos::rcp( new std::vector<MagnitudeType>(&theta[0],&theta[newdim]) );
|
||||
|
||||
if (inSituRestart_ == true) {
|
||||
//
|
||||
// get non-const pointer to solver's basis so we can work in situ
|
||||
Teuchos::RCP<MV> solverbasis = Teuchos::rcp_const_cast<MV>(state.V);
|
||||
//
|
||||
// perform Householder QR of Sr = Q [D;0], where D is unit diag.
|
||||
// WARNING: this will overwrite Sr; however, we do not need Sr anymore after this
|
||||
std::vector<ScalarType> tau(newdim), work(newdim);
|
||||
int info;
|
||||
lapack.GEQRF(curdim,newdim,Sr.values(),Sr.stride(),&tau[0],&work[0],work.size(),&info);
|
||||
TEST_FOR_EXCEPTION(info != 0,std::logic_error,
|
||||
"Anasazi::BlockDavidsonSolMgr::solve(): error calling GEQRF during restarting.");
|
||||
if (printer->isVerbosity(Debug)) {
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> R(Teuchos::Copy,Sr,newdim,newdim);
|
||||
for (int j=0; j<newdim; j++) {
|
||||
R(j,j) = SCT::magnitude(R(j,j)) - 1.0;
|
||||
for (int i=j+1; i<newdim; i++) {
|
||||
R(i,j) = ZERO;
|
||||
}
|
||||
}
|
||||
printer->stream(Debug) << "||Triangular factor of Sr - I||: " << R.normFrobenius() << std::endl;
|
||||
}
|
||||
//
|
||||
// perform implicit oldV*Sr
|
||||
// this actually performs oldV*[Sr Su*M] = [newV truncV], for some unitary M
|
||||
// we are actually interested in only the first newdim vectors of the result
|
||||
{
|
||||
std::vector<int> curind(curdim);
|
||||
for (int i=0; i<curdim; i++) curind[i] = i;
|
||||
Teuchos::RCP<MV> oldV = MVT::CloneView(*solverbasis,curind);
|
||||
msutils::applyHouse(newdim,*oldV,Sr,tau,workMV);
|
||||
}
|
||||
//
|
||||
// put the new basis into the state for initialize()
|
||||
// the new basis is contained in the the first newdim columns of solverbasis
|
||||
// initialize() will recognize that pointer bd_solver.V_ == pointer rstate.V, and will neglect the copy.
|
||||
rstate.V = solverbasis;
|
||||
}
|
||||
else { // inSituRestart == false)
|
||||
// newV = oldV*Sr, explicitly. workspace is in workMV
|
||||
std::vector<int> curind(curdim), newind(newdim);
|
||||
for (int i=0; i<curdim; i++) curind[i] = i;
|
||||
for (int i=0; i<newdim; i++) newind[i] = i;
|
||||
Teuchos::RCP<const MV> oldV = MVT::CloneView(*state.V,curind);
|
||||
Teuchos::RCP<MV> newV = MVT::CloneView(*workMV ,newind);
|
||||
|
||||
MVT::MvTimesMatAddMv(ONE,*oldV,Sr,ZERO,*newV);
|
||||
//
|
||||
// put the new basis into the state for initialize()
|
||||
rstate.V = newV;
|
||||
}
|
||||
|
||||
//
|
||||
// send the new state to the solver
|
||||
bd_solver->initialize(rstate);
|
||||
} // end of restarting
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// check locking if we didn't converge or restart
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
else if (locktest != Teuchos::null && locktest->getStatus() == Passed) {
|
||||
|
||||
//
|
||||
// get current state
|
||||
BlockDavidsonState<ScalarType,MV> state = bd_solver->getState();
|
||||
const int curdim = state.curDim;
|
||||
|
||||
//
|
||||
// get number,indices of vectors to be locked
|
||||
TEST_FOR_EXCEPTION(locktest->howMany() <= 0,std::logic_error,
|
||||
"Anasazi::BlockDavidsonSolMgr::solve(): status test mistake.");
|
||||
TEST_FOR_EXCEPTION(locktest->howMany() != (int)locktest->whichVecs().size(),std::logic_error,
|
||||
"Anasazi::BlockDavidsonSolMgr::solve(): status test mistake.");
|
||||
//
|
||||
// don't lock more than maxLocked_; we didn't allocate enough space.
|
||||
std::vector<int> tmp_vector_int;
|
||||
if (curNumLocked + locktest->howMany() > maxLocked_) {
|
||||
// just use the first of them
|
||||
tmp_vector_int.insert(tmp_vector_int.begin(),locktest->whichVecs().begin(),locktest->whichVecs().begin()+maxLocked_-curNumLocked);
|
||||
}
|
||||
else {
|
||||
tmp_vector_int = locktest->whichVecs();
|
||||
}
|
||||
const std::vector<int> lockind(tmp_vector_int);
|
||||
const int numNewLocked = lockind.size();
|
||||
//
|
||||
// generate indices of vectors left unlocked
|
||||
// curind = [0,...,curdim-1] = UNION( lockind, unlockind )
|
||||
const int numUnlocked = curdim-numNewLocked;
|
||||
tmp_vector_int.resize(curdim);
|
||||
for (int i=0; i<curdim; i++) tmp_vector_int[i] = i;
|
||||
const std::vector<int> curind(tmp_vector_int); // curind = [0 ... curdim-1]
|
||||
tmp_vector_int.resize(numUnlocked);
|
||||
set_difference(curind.begin(),curind.end(),lockind.begin(),lockind.end(),tmp_vector_int.begin());
|
||||
const std::vector<int> unlockind(tmp_vector_int); // unlockind = [0 ... curdim-1] - lockind
|
||||
tmp_vector_int.clear();
|
||||
|
||||
//
|
||||
// debug printing
|
||||
if (printer->isVerbosity(Debug)) {
|
||||
printer->print(Debug,"Locking vectors: ");
|
||||
for (unsigned int i=0; i<lockind.size(); i++) {printer->stream(Debug) << " " << lockind[i];}
|
||||
printer->print(Debug,"\n");
|
||||
}
|
||||
|
||||
//
|
||||
// we need primitive ritz vectors/values:
|
||||
// [S,L] = eig(oldKK)
|
||||
//
|
||||
// this will be partitioned as follows:
|
||||
// locked: Sl = S(lockind) // we won't actually need Sl
|
||||
// unlocked: Su = S(unlockind)
|
||||
//
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> S(curdim,curdim);
|
||||
std::vector<MagnitudeType> theta(curdim);
|
||||
{
|
||||
int rank = curdim;
|
||||
int info = msutils::directSolver(curdim,*state.KK,Teuchos::null,S,theta,rank,10);
|
||||
TEST_FOR_EXCEPTION(info != 0 ,std::logic_error,
|
||||
"Anasazi::BlockDavidsonSolMgr::solve(): error calling SolverUtils::directSolver."); // this should never happen
|
||||
TEST_FOR_EXCEPTION(rank != curdim,std::logic_error,
|
||||
"Anasazi::BlockDavidsonSolMgr::solve(): direct solve did not compute all eigenvectors."); // this should never happen
|
||||
//
|
||||
// sort the eigenvalues (so that we can order the eigenvectors)
|
||||
std::vector<int> order(curdim);
|
||||
sorter->sort(bd_solver.get(),curdim,theta,&order);
|
||||
//
|
||||
// apply the same ordering to the primitive ritz vectors
|
||||
msutils::permuteVectors(order,S);
|
||||
}
|
||||
//
|
||||
// select the unlocked ritz vectors
|
||||
// the indexing in unlockind is relative to the ordered primitive ritz vectors
|
||||
// (this is why we ordered theta,S above)
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> Su(curdim,numUnlocked);
|
||||
for (int i=0; i<numUnlocked; i++) {
|
||||
blas.COPY(curdim, S[unlockind[i]], 1, Su[i], 1);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// newV has the following form:
|
||||
// newV = [defV augV]
|
||||
// - defV will be of size curdim - numNewLocked, and contain the generated basis: defV = oldV*Su
|
||||
// - augV will be of size numNewLocked, and contain random directions to make up for the lost space
|
||||
//
|
||||
// we will need a pointer to defV below to generate the off-diagonal block of newKK
|
||||
// go ahead and setup pointer to augV
|
||||
//
|
||||
Teuchos::RCP<MV> defV, augV;
|
||||
if (inSituRestart_ == true) {
|
||||
//
|
||||
// get non-const pointer to solver's basis so we can work in situ
|
||||
Teuchos::RCP<MV> solverbasis = Teuchos::rcp_const_cast<MV>(state.V);
|
||||
//
|
||||
// perform Householder QR of Su = Q [D;0], where D is unit diag.
|
||||
// work on a copy of Su, since we need Su below to build newKK
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> copySu(Su);
|
||||
std::vector<ScalarType> tau(numUnlocked), work(numUnlocked);
|
||||
int info;
|
||||
lapack.GEQRF(curdim,numUnlocked,copySu.values(),copySu.stride(),&tau[0],&work[0],work.size(),&info);
|
||||
TEST_FOR_EXCEPTION(info != 0,std::logic_error,
|
||||
"Anasazi::BlockDavidsonSolMgr::solve(): error calling GEQRF during restarting.");
|
||||
if (printer->isVerbosity(Debug)) {
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> R(Teuchos::Copy,copySu,numUnlocked,numUnlocked);
|
||||
for (int j=0; j<numUnlocked; j++) {
|
||||
R(j,j) = SCT::magnitude(R(j,j)) - 1.0;
|
||||
for (int i=j+1; i<numUnlocked; i++) {
|
||||
R(i,j) = ZERO;
|
||||
}
|
||||
}
|
||||
printer->stream(Debug) << "||Triangular factor of Su - I||: " << R.normFrobenius() << std::endl;
|
||||
}
|
||||
//
|
||||
// perform implicit oldV*Su
|
||||
// this actually performs oldV*[Su Sl*M] = [defV lockV], for some unitary M
|
||||
// we are actually interested in only the first numUnlocked vectors of the result
|
||||
{
|
||||
Teuchos::RCP<MV> oldV = MVT::CloneView(*solverbasis,curind);
|
||||
msutils::applyHouse(numUnlocked,*oldV,copySu,tau,workMV);
|
||||
}
|
||||
std::vector<int> defind(numUnlocked), augind(numNewLocked);
|
||||
for (int i=0; i<numUnlocked ; i++) defind[i] = i;
|
||||
for (int i=0; i<numNewLocked; i++) augind[i] = numUnlocked+i;
|
||||
defV = MVT::CloneView(*solverbasis,defind);
|
||||
augV = MVT::CloneView(*solverbasis,augind);
|
||||
}
|
||||
else { // inSituRestart == false)
|
||||
// defV = oldV*Su, explicitly. workspace is in workMV
|
||||
std::vector<int> defind(numUnlocked), augind(numNewLocked);
|
||||
for (int i=0; i<numUnlocked ; i++) defind[i] = i;
|
||||
for (int i=0; i<numNewLocked; i++) augind[i] = numUnlocked+i;
|
||||
Teuchos::RCP<const MV> oldV = MVT::CloneView(*state.V,curind);
|
||||
defV = MVT::CloneView(*workMV,defind);
|
||||
augV = MVT::CloneView(*workMV,augind);
|
||||
|
||||
MVT::MvTimesMatAddMv(ONE,*oldV,Su,ZERO,*defV);
|
||||
}
|
||||
|
||||
//
|
||||
// lockvecs will be partitioned as follows:
|
||||
// lockvecs = [curlocked augTmp ...]
|
||||
// - augTmp will be used for the storage of M*augV and K*augV
|
||||
// later, the locked vectors (stored in state.X and referenced via const MV view newLocked)
|
||||
// will be moved into lockvecs on top of augTmp when it is no longer needed as workspace.
|
||||
// - curlocked will be used in orthogonalization of augV
|
||||
//
|
||||
// newL is the new locked vectors; newL = oldV*Sl = RitzVectors(lockind)
|
||||
// we will not produce them, but instead retrieve them from RitzVectors
|
||||
//
|
||||
Teuchos::RCP<const MV> curlocked, newLocked;
|
||||
Teuchos::RCP<MV> augTmp;
|
||||
{
|
||||
// setup curlocked
|
||||
if (curNumLocked > 0) {
|
||||
std::vector<int> curlockind(curNumLocked);
|
||||
for (int i=0; i<curNumLocked; i++) curlockind[i] = i;
|
||||
curlocked = MVT::CloneView(*lockvecs,curlockind);
|
||||
}
|
||||
else {
|
||||
curlocked = Teuchos::null;
|
||||
}
|
||||
// setup augTmp
|
||||
std::vector<int> augtmpind(numNewLocked);
|
||||
for (int i=0; i<numNewLocked; i++) augtmpind[i] = curNumLocked+i;
|
||||
augTmp = MVT::CloneView(*lockvecs,augtmpind);
|
||||
// setup newLocked
|
||||
newLocked = MVT::CloneView(*bd_solver->getRitzVectors(),lockind);
|
||||
}
|
||||
|
||||
//
|
||||
// generate augV and perform orthogonalization
|
||||
//
|
||||
MVT::MvRandom(*augV);
|
||||
//
|
||||
// orthogonalize it against auxvecs, defV, and all locked vectors (new and current)
|
||||
// use augTmp as storage for M*augV, if hasM
|
||||
{
|
||||
Teuchos::Array<Teuchos::RCP<const MV> > against;
|
||||
Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > dummy;
|
||||
if (probauxvecs != Teuchos::null) against.push_back(probauxvecs);
|
||||
if (curlocked != Teuchos::null) against.push_back(curlocked);
|
||||
against.push_back(newLocked);
|
||||
against.push_back(defV);
|
||||
if (problem_->getM() != Teuchos::null) {
|
||||
OPT::Apply(*problem_->getM(),*augV,*augTmp);
|
||||
}
|
||||
ortho->projectAndNormalizeMat(*augV,augTmp,dummy,Teuchos::null,against);
|
||||
}
|
||||
|
||||
//
|
||||
// form newKK
|
||||
//
|
||||
// newKK = newV'*K*newV = [Su'*KK*Su defV'*K*augV]
|
||||
// [augV'*K*defV augV'*K*augV]
|
||||
//
|
||||
// first, generate the principal submatrix, the projection of K onto the unlocked portion of oldV
|
||||
//
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> newKK(curdim,curdim);
|
||||
{
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> KKtmp(curdim,numUnlocked),
|
||||
KKold(Teuchos::View,*state.KK,curdim,curdim),
|
||||
KK11(Teuchos::View,newKK,numUnlocked,numUnlocked);
|
||||
int teuchosRet;
|
||||
// KKtmp = KKold*Su
|
||||
teuchosRet = KKtmp.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,ONE,KKold,Su,ZERO);
|
||||
TEST_FOR_EXCEPTION(teuchosRet != 0,std::logic_error,
|
||||
"Anasazi::BlockDavidsonSolMgr::solve(): Logic error calling SerialDenseMatrix::multiply.");
|
||||
// KK11 = Su'*KKtmp = Su'*KKold*Su
|
||||
teuchosRet = KK11.multiply(Teuchos::CONJ_TRANS,Teuchos::NO_TRANS,ONE,Su,KKtmp,ZERO);
|
||||
TEST_FOR_EXCEPTION(teuchosRet != 0,std::logic_error,
|
||||
"Anasazi::BlockDavidsonSolMgr::solve(): Logic error calling SerialDenseMatrix::multiply.");
|
||||
}
|
||||
//
|
||||
// project the stiffness matrix on augV
|
||||
{
|
||||
OPT::Apply(*problem_->getOperator(),*augV,*augTmp);
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> KK12(Teuchos::View,newKK,numUnlocked,numNewLocked,0,numUnlocked),
|
||||
KK22(Teuchos::View,newKK,numNewLocked,numNewLocked,numUnlocked,numUnlocked);
|
||||
MVT::MvTransMv(ONE,*defV,*augTmp,KK12);
|
||||
MVT::MvTransMv(ONE,*augV,*augTmp,KK22);
|
||||
}
|
||||
//
|
||||
// done with defV,augV
|
||||
defV = Teuchos::null;
|
||||
augV = Teuchos::null;
|
||||
//
|
||||
// make it hermitian in memory (fill in KK21)
|
||||
for (int j=0; j<curdim; ++j) {
|
||||
for (int i=j+1; i<curdim; ++i) {
|
||||
newKK(i,j) = SCT::conjugate(newKK(j,i));
|
||||
}
|
||||
}
|
||||
//
|
||||
// we are done using augTmp as storage
|
||||
// put newLocked into lockvecs, new values into lockvals
|
||||
augTmp = Teuchos::null;
|
||||
{
|
||||
std::vector<Value<ScalarType> > allvals = bd_solver->getRitzValues();
|
||||
for (int i=0; i<numNewLocked; i++) {
|
||||
lockvals.push_back(allvals[lockind[i]].realpart);
|
||||
}
|
||||
|
||||
std::vector<int> indlock(numNewLocked);
|
||||
for (int i=0; i<numNewLocked; i++) indlock[i] = curNumLocked+i;
|
||||
MVT::SetBlock(*newLocked,indlock,*lockvecs);
|
||||
newLocked = Teuchos::null;
|
||||
|
||||
curNumLocked += numNewLocked;
|
||||
std::vector<int> curlockind(curNumLocked);
|
||||
for (int i=0; i<curNumLocked; i++) curlockind[i] = i;
|
||||
curlocked = MVT::CloneView(*lockvecs,curlockind);
|
||||
}
|
||||
// add locked vecs as aux vecs, along with aux vecs from problem
|
||||
// add lockvals to convtest
|
||||
// disable locktest if curNumLocked == maxLocked
|
||||
{
|
||||
convtest->setAuxVals(lockvals);
|
||||
|
||||
Teuchos::Array< Teuchos::RCP<const MV> > aux;
|
||||
if (probauxvecs != Teuchos::null) aux.push_back(probauxvecs);
|
||||
aux.push_back(curlocked);
|
||||
bd_solver->setAuxVecs(aux);
|
||||
|
||||
if (curNumLocked == maxLocked_) {
|
||||
// disabled locking now by setting quorum to unreachable number
|
||||
locktest->setQuorum(blockSize_+1);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// prepare new state
|
||||
BlockDavidsonState<ScalarType,MV> rstate;
|
||||
rstate.curDim = curdim;
|
||||
if (inSituRestart_) {
|
||||
// data is already in the solver's memory
|
||||
rstate.V = state.V;
|
||||
}
|
||||
else {
|
||||
// data is in workspace and will be copied to solver memory
|
||||
rstate.V = workMV;
|
||||
}
|
||||
rstate.KK = Teuchos::rcp( &newKK, false );
|
||||
//
|
||||
// pass new state to the solver
|
||||
bd_solver->initialize(rstate);
|
||||
} // end of locking
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// we returned from iterate(), but none of our status tests Passed.
|
||||
// something is wrong, and it is probably our fault.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
else {
|
||||
TEST_FOR_EXCEPTION(true,std::logic_error,"Anasazi::BlockDavidsonSolMgr::solve(): Invalid return from bd_solver::iterate().");
|
||||
}
|
||||
}
|
||||
catch (std::exception e) {
|
||||
printer->stream(Errors) << "Error! Caught exception in BlockDavidson::iterate() at iteration " << bd_solver->getNumIters() << std::endl
|
||||
<< e.what() << std::endl;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
// clear temp space
|
||||
workMV = Teuchos::null;
|
||||
|
||||
sol.numVecs = convtest->howMany();
|
||||
if (sol.numVecs > 0) {
|
||||
sol.Evecs = MVT::Clone(*problem_->getInitVec(),sol.numVecs);
|
||||
sol.Espace = sol.Evecs;
|
||||
sol.Evals.resize(sol.numVecs);
|
||||
std::vector<MagnitudeType> vals(sol.numVecs);
|
||||
|
||||
// copy them into the solution
|
||||
std::vector<int> which = convtest->whichVecs();
|
||||
// indices between [0,blockSize) refer to vectors/values in the solver
|
||||
// indices between [blockSize,blocksize+curNumLocked) refer to locked vectors/values
|
||||
// everything has already been ordered by the solver; we just have to partition the two references
|
||||
std::vector<int> inlocked(0), insolver(0);
|
||||
for (unsigned int i=0; i<which.size(); i++) {
|
||||
if (which[i] < blockSize_) {
|
||||
insolver.push_back(which[i]);
|
||||
}
|
||||
else {
|
||||
// sanity check
|
||||
TEST_FOR_EXCEPTION(which[i] >= curNumLocked+blockSize_,std::logic_error,"Anasazi::BlockDavidsonSolMgr::solve(): indexing mistake.");
|
||||
inlocked.push_back(which[i] - blockSize_);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_FOR_EXCEPTION(insolver.size() + inlocked.size() != (unsigned int)sol.numVecs,std::logic_error,"Anasazi::BlockDavidsonSolMgr::solve(): indexing mistake.");
|
||||
|
||||
// set the vecs,vals in the solution
|
||||
if (insolver.size() > 0) {
|
||||
// set vecs
|
||||
int lclnum = insolver.size();
|
||||
std::vector<int> tosol(lclnum);
|
||||
for (int i=0; i<lclnum; i++) tosol[i] = i;
|
||||
Teuchos::RCP<const MV> v = MVT::CloneView(*bd_solver->getRitzVectors(),insolver);
|
||||
MVT::SetBlock(*v,tosol,*sol.Evecs);
|
||||
// set vals
|
||||
std::vector<Value<ScalarType> > fromsolver = bd_solver->getRitzValues();
|
||||
for (unsigned int i=0; i<insolver.size(); i++) {
|
||||
vals[i] = fromsolver[insolver[i]].realpart;
|
||||
}
|
||||
}
|
||||
|
||||
// get the vecs,vals from locked storage
|
||||
if (inlocked.size() > 0) {
|
||||
int solnum = insolver.size();
|
||||
// set vecs
|
||||
int lclnum = inlocked.size();
|
||||
std::vector<int> tosol(lclnum);
|
||||
for (int i=0; i<lclnum; i++) tosol[i] = solnum + i;
|
||||
Teuchos::RCP<const MV> v = MVT::CloneView(*lockvecs,inlocked);
|
||||
MVT::SetBlock(*v,tosol,*sol.Evecs);
|
||||
// set vals
|
||||
for (unsigned int i=0; i<inlocked.size(); i++) {
|
||||
vals[i+solnum] = lockvals[inlocked[i]];
|
||||
}
|
||||
}
|
||||
|
||||
// sort the eigenvalues and permute the eigenvectors appropriately
|
||||
{
|
||||
std::vector<int> order(sol.numVecs);
|
||||
sorter->sort(bd_solver.get(), sol.numVecs, vals, &order );
|
||||
// store the values in the Eigensolution
|
||||
for (int i=0; i<sol.numVecs; i++) {
|
||||
sol.Evals[i].realpart = vals[i];
|
||||
sol.Evals[i].imagpart = MT::zero();
|
||||
}
|
||||
// now permute the eigenvectors according to order
|
||||
msutils::permuteVectors(sol.numVecs,order,*sol.Evecs);
|
||||
}
|
||||
|
||||
// setup sol.index, remembering that all eigenvalues are real so that index = {0,...,0}
|
||||
sol.index.resize(sol.numVecs,0);
|
||||
}
|
||||
|
||||
// print final summary
|
||||
bd_solver->currentStatus(printer->stream(FinalSummary));
|
||||
|
||||
// print timing information
|
||||
Teuchos::TimeMonitor::summarize(printer->stream(TimingDetails));
|
||||
|
||||
problem_->setSolution(sol);
|
||||
printer->stream(Debug) << "Returning " << sol.numVecs << " eigenpairs to eigenproblem." << std::endl;
|
||||
|
||||
if (sol.numVecs < nev) {
|
||||
return Unconverged; // return from BlockDavidsonSolMgr::solve()
|
||||
}
|
||||
return Converged; // return from BlockDavidsonSolMgr::solve()
|
||||
}
|
||||
|
||||
|
||||
} // end Anasazi namespace
|
||||
|
||||
#endif /* ANASAZI_BLOCKDAVIDSON_SOLMGR_HPP */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,634 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
|
||||
#ifndef ANASAZI_BLOCK_KRYLOV_SCHUR_SOLMGR_HPP
|
||||
#define ANASAZI_BLOCK_KRYLOV_SCHUR_SOLMGR_HPP
|
||||
|
||||
/*! \file AnasaziBlockKrylovSchurSolMgr.hpp
|
||||
* \brief The Anasazi::BlockKrylovSchurSolMgr provides a solver manager for the BlockKrylovSchur eigensolver.
|
||||
*/
|
||||
|
||||
#include "AnasaziConfigDefs.hpp"
|
||||
#include "AnasaziTypes.hpp"
|
||||
|
||||
#include "AnasaziEigenproblem.hpp"
|
||||
#include "AnasaziSolverManager.hpp"
|
||||
|
||||
#include "AnasaziBlockKrylovSchur.hpp"
|
||||
#include "AnasaziBasicSort.hpp"
|
||||
#include "AnasaziSVQBOrthoManager.hpp"
|
||||
#include "AnasaziBasicOrthoManager.hpp"
|
||||
#include "AnasaziStatusTestMaxIters.hpp"
|
||||
#include "AnasaziStatusTestResNorm.hpp"
|
||||
#include "AnasaziStatusTestOrderedResNorm.hpp"
|
||||
#include "AnasaziStatusTestCombo.hpp"
|
||||
#include "AnasaziStatusTestOutput.hpp"
|
||||
#include "AnasaziBasicOutputManager.hpp"
|
||||
#include "AnasaziSolverUtils.hpp"
|
||||
#include "Teuchos_BLAS.hpp"
|
||||
#include "Teuchos_LAPACK.hpp"
|
||||
#include "Teuchos_TimeMonitor.hpp"
|
||||
|
||||
/** \example BlockKrylovSchur/BlockKrylovSchurEpetraEx.cpp
|
||||
This is an example of how to use the Anasazi::BlockKrylovSchurSolMgr solver manager.
|
||||
*/
|
||||
|
||||
/*! \class Anasazi::BlockKrylovSchurSolMgr
|
||||
*
|
||||
* \brief The Anasazi::BlockKrylovSchurSolMgr provides a powerful and fully-featured solver manager over the BlockKrylovSchur eigensolver.
|
||||
|
||||
\ingroup anasazi_solver_framework
|
||||
|
||||
\author Chris Baker, Ulrich Hetmaniuk, Rich Lehoucq, Heidi Thornquist
|
||||
*/
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
template<class ScalarType, class MV, class OP>
|
||||
class BlockKrylovSchurSolMgr : public SolverManager<ScalarType,MV,OP> {
|
||||
|
||||
private:
|
||||
typedef MultiVecTraits<ScalarType,MV> MVT;
|
||||
typedef OperatorTraits<ScalarType,MV,OP> OPT;
|
||||
typedef Teuchos::ScalarTraits<ScalarType> SCT;
|
||||
typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
|
||||
typedef Teuchos::ScalarTraits<MagnitudeType> MT;
|
||||
|
||||
public:
|
||||
|
||||
//! @name Constructors/Destructor
|
||||
//@{
|
||||
|
||||
/*! \brief Basic constructor for BlockKrylovSchurSolMgr.
|
||||
*
|
||||
* This constructor accepts the Eigenproblem to be solved in addition
|
||||
* to a parameter list of options for the solver manager. These options include the following:
|
||||
* - "Which" - a \c string specifying the desired eigenvalues: SM, LM, SR or LR. Default: "LM"
|
||||
* - "Block Size" - a \c int specifying the block size to be used by the underlying block Krylov-Schur solver. Default: 1
|
||||
* - "Num Blocks" - a \c int specifying the number of blocks allocated for the Krylov basis. Default: 3*nev
|
||||
* - "Extra NEV Blocks" - a \c int specifying the number of extra blocks the solver should keep in addition to those
|
||||
required to compute the number of eigenvalues requested. Default: 0
|
||||
* - "Maximum Restarts" - a \c int specifying the maximum number of restarts the underlying solver is allowed to perform. Default: 20
|
||||
* - "Orthogonalization" - a \c string specifying the desired orthogonalization: DGKS and SVQB. Default: "SVQB"
|
||||
* - "Verbosity" - a sum of MsgType specifying the verbosity. Default: Anasazi::Errors
|
||||
* - "Convergence Tolerance" - a \c MagnitudeType specifying the level that residual norms must reach to decide convergence. Default: machine precision.
|
||||
* - "Relative Convergence Tolerance" - a \c bool specifying whether residuals norms should be scaled by their eigenvalues for the purposing of deciding convergence. Default: true
|
||||
*/
|
||||
BlockKrylovSchurSolMgr( const Teuchos::RCP<Eigenproblem<ScalarType,MV,OP> > &problem,
|
||||
Teuchos::ParameterList &pl );
|
||||
|
||||
//! Destructor.
|
||||
virtual ~BlockKrylovSchurSolMgr() {};
|
||||
//@}
|
||||
|
||||
//! @name Accessor methods
|
||||
//@{
|
||||
|
||||
const Eigenproblem<ScalarType,MV,OP>& getProblem() const {
|
||||
return *_problem;
|
||||
}
|
||||
|
||||
/*! \brief Return the Ritz values from the most recent solve.
|
||||
*/
|
||||
std::vector<Value<ScalarType> > getRitzValues() const {
|
||||
std::vector<Value<ScalarType> > ret( _ritzValues );
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*! \brief Return the timers for this object.
|
||||
*
|
||||
* The timers are ordered as follows:
|
||||
* - time spent in solve() routine
|
||||
* - time spent restarting
|
||||
*/
|
||||
Teuchos::Array<Teuchos::RCP<Teuchos::Time> > getTimers() const {
|
||||
return tuple(_timerSolve, _timerRestarting);
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Solver application methods
|
||||
//@{
|
||||
|
||||
/*! \brief This method performs possibly repeated calls to the underlying eigensolver's iterate() routine
|
||||
* until the problem has been solved (as decided by the solver manager) or the solver manager decides to
|
||||
* quit.
|
||||
*
|
||||
* This method calls BlockKrylovSchur::iterate(), which will return either because a specially constructed status test evaluates to ::Passed
|
||||
* or an exception is thrown.
|
||||
*
|
||||
* A return from BlockKrylovSchur::iterate() signifies one of the following scenarios:
|
||||
* - the maximum number of restarts has been exceeded. In this scenario, the solver manager will place\n
|
||||
* all converged eigenpairs into the eigenproblem and return ::Unconverged.
|
||||
* - global convergence has been met. In this case, the most significant NEV eigenpairs in the solver and locked storage \n
|
||||
* have met the convergence criterion. (Here, NEV refers to the number of eigenpairs requested by the Eigenproblem.) \n
|
||||
* In this scenario, the solver manager will return ::Converged.
|
||||
*
|
||||
* \returns ::ReturnType specifying:
|
||||
* - ::Converged: the eigenproblem was solved to the specification required by the solver manager.
|
||||
* - ::Unconverged: the eigenproblem was not solved to the specification desired by the solver manager.
|
||||
*/
|
||||
ReturnType solve();
|
||||
//@}
|
||||
|
||||
private:
|
||||
Teuchos::RCP<Eigenproblem<ScalarType,MV,OP> > _problem;
|
||||
Teuchos::RCP<SortManager<ScalarType,MV,OP> > _sort;
|
||||
|
||||
std::string _whch, _ortho;
|
||||
MagnitudeType _ortho_kappa;
|
||||
|
||||
MagnitudeType _convtol;
|
||||
int _maxRestarts;
|
||||
bool _relconvtol,_conjSplit;
|
||||
int _blockSize, _numBlocks, _stepSize, _nevBlocks, _xtra_nevBlocks;
|
||||
int _verbosity;
|
||||
bool _inSituRestart;
|
||||
|
||||
std::vector<Value<ScalarType> > _ritzValues;
|
||||
|
||||
Teuchos::RCP<Teuchos::Time> _timerSolve, _timerRestarting;
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Constructor
|
||||
template<class ScalarType, class MV, class OP>
|
||||
BlockKrylovSchurSolMgr<ScalarType,MV,OP>::BlockKrylovSchurSolMgr(
|
||||
const Teuchos::RCP<Eigenproblem<ScalarType,MV,OP> > &problem,
|
||||
Teuchos::ParameterList &pl ) :
|
||||
_problem(problem),
|
||||
_whch("LM"),
|
||||
_ortho("SVQB"),
|
||||
_ortho_kappa(-1.0),
|
||||
_convtol(0),
|
||||
_maxRestarts(20),
|
||||
_relconvtol(true),
|
||||
_conjSplit(false),
|
||||
_blockSize(0),
|
||||
_numBlocks(0),
|
||||
_stepSize(0),
|
||||
_nevBlocks(0),
|
||||
_xtra_nevBlocks(0),
|
||||
_verbosity(Anasazi::Errors),
|
||||
_inSituRestart(false),
|
||||
_timerSolve(Teuchos::TimeMonitor::getNewTimer("BKSSolMgr::solve()")),
|
||||
_timerRestarting(Teuchos::TimeMonitor::getNewTimer("BKSSolMgr restarting"))
|
||||
{
|
||||
TEST_FOR_EXCEPTION(_problem == Teuchos::null, std::invalid_argument, "Problem not given to solver manager.");
|
||||
TEST_FOR_EXCEPTION(!_problem->isProblemSet(), std::invalid_argument, "Problem not set.");
|
||||
TEST_FOR_EXCEPTION(_problem->getInitVec() == Teuchos::null, std::invalid_argument, "Problem does not contain initial vectors to clone from.");
|
||||
|
||||
const int nev = _problem->getNEV();
|
||||
|
||||
// convergence tolerance
|
||||
_convtol = pl.get("Convergence Tolerance",MT::prec());
|
||||
_relconvtol = pl.get("Relative Convergence Tolerance",_relconvtol);
|
||||
|
||||
// maximum number of restarts
|
||||
_maxRestarts = pl.get("Maximum Restarts",_maxRestarts);
|
||||
|
||||
// block size: default is 1
|
||||
_blockSize = pl.get("Block Size",1);
|
||||
TEST_FOR_EXCEPTION(_blockSize <= 0, std::invalid_argument,
|
||||
"Anasazi::BlockKrylovSchurSolMgr: \"Block Size\" must be strictly positive.");
|
||||
|
||||
// set the number of blocks we need to save to compute the nev eigenvalues of interest.
|
||||
_xtra_nevBlocks = pl.get("Extra NEV Blocks",0);
|
||||
if (nev%_blockSize) {
|
||||
_nevBlocks = nev/_blockSize + _xtra_nevBlocks + 1;
|
||||
} else {
|
||||
_nevBlocks = nev/_blockSize + _xtra_nevBlocks;
|
||||
}
|
||||
|
||||
_numBlocks = pl.get("Num Blocks",3*_nevBlocks);
|
||||
TEST_FOR_EXCEPTION(_numBlocks <= _nevBlocks, std::invalid_argument,
|
||||
"Anasazi::BlockKrylovSchurSolMgr: \"Num Blocks\" must be strictly positive and large enough to compute the requested eigenvalues.");
|
||||
|
||||
TEST_FOR_EXCEPTION(_numBlocks*_blockSize > MVT::GetVecLength(*_problem->getInitVec()),
|
||||
std::invalid_argument,
|
||||
"Anasazi::BlockKrylovSchurSolMgr: Potentially impossible orthogonality requests. Reduce basis size.");
|
||||
|
||||
// step size: the default is _maxRestarts*_numBlocks, so that Ritz values are only computed every restart.
|
||||
if (_maxRestarts) {
|
||||
_stepSize = pl.get("Step Size", (_maxRestarts+1)*(_numBlocks+1));
|
||||
} else {
|
||||
_stepSize = pl.get("Step Size", _numBlocks+1);
|
||||
}
|
||||
TEST_FOR_EXCEPTION(_stepSize < 1, std::invalid_argument,
|
||||
"Anasazi::BlockKrylovSchurSolMgr: \"Step Size\" must be strictly positive.");
|
||||
|
||||
// get the sort manager
|
||||
if (pl.isParameter("Sort Manager")) {
|
||||
_sort = Teuchos::getParameter<Teuchos::RCP<Anasazi::SortManager<ScalarType,MV,OP> > >(pl,"Sort Manager");
|
||||
} else {
|
||||
// which values to solve for
|
||||
_whch = pl.get("Which",_whch);
|
||||
TEST_FOR_EXCEPTION(_whch != "SM" && _whch != "LM" && _whch != "SR" && _whch != "LR" && _whch != "SI" && _whch != "LI",
|
||||
std::invalid_argument, "Invalid sorting string.");
|
||||
_sort = Teuchos::rcp( new BasicSort<ScalarType,MV,OP>(_whch) );
|
||||
}
|
||||
|
||||
// which orthogonalization to use
|
||||
_ortho = pl.get("Orthogonalization",_ortho);
|
||||
if (_ortho != "DGKS" && _ortho != "SVQB") {
|
||||
_ortho = "SVQB";
|
||||
}
|
||||
|
||||
// which orthogonalization constant to use
|
||||
_ortho_kappa = pl.get("Orthogonalization Constant",_ortho_kappa);
|
||||
|
||||
// verbosity level
|
||||
if (pl.isParameter("Verbosity")) {
|
||||
if (Teuchos::isParameterType<int>(pl,"Verbosity")) {
|
||||
_verbosity = pl.get("Verbosity", _verbosity);
|
||||
} else {
|
||||
_verbosity = (int)Teuchos::getParameter<Anasazi::MsgType>(pl,"Verbosity");
|
||||
}
|
||||
}
|
||||
|
||||
// restarting technique: V*Q or applyHouse(V,H,tau)
|
||||
if (pl.isParameter("In Situ Restarting")) {
|
||||
if (Teuchos::isParameterType<bool>(pl,"In Situ Restarting")) {
|
||||
_inSituRestart = pl.get("In Situ Restarting",_inSituRestart);
|
||||
} else {
|
||||
_inSituRestart = (bool)Teuchos::getParameter<int>(pl,"In Situ Restarting");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// solve()
|
||||
template<class ScalarType, class MV, class OP>
|
||||
ReturnType
|
||||
BlockKrylovSchurSolMgr<ScalarType,MV,OP>::solve() {
|
||||
|
||||
const int nev = _problem->getNEV();
|
||||
ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
|
||||
ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
|
||||
|
||||
Teuchos::BLAS<int,ScalarType> blas;
|
||||
Teuchos::LAPACK<int,ScalarType> lapack;
|
||||
typedef SolverUtils<ScalarType,MV,OP> msutils;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Output manager
|
||||
Teuchos::RCP<BasicOutputManager<ScalarType> > printer = Teuchos::rcp( new BasicOutputManager<ScalarType>(_verbosity) );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Status tests
|
||||
//
|
||||
// convergence
|
||||
Teuchos::RCP<StatusTestOrderedResNorm<ScalarType,MV,OP> > convtest
|
||||
= Teuchos::rcp( new StatusTestOrderedResNorm<ScalarType,MV,OP>(_sort,_convtol,nev,StatusTestOrderedResNorm<ScalarType,MV,OP>::RITZRES_2NORM,_relconvtol) );
|
||||
|
||||
// printing StatusTest
|
||||
Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputtest
|
||||
= Teuchos::rcp( new StatusTestOutput<ScalarType,MV,OP>( printer,convtest,1,Passed ) );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Orthomanager
|
||||
//
|
||||
Teuchos::RCP<OrthoManager<ScalarType,MV> > ortho;
|
||||
if (_ortho=="SVQB") {
|
||||
ortho = Teuchos::rcp( new SVQBOrthoManager<ScalarType,MV,OP>(_problem->getM()) );
|
||||
} else if (_ortho=="DGKS") {
|
||||
if (_ortho_kappa <= 0) {
|
||||
ortho = Teuchos::rcp( new BasicOrthoManager<ScalarType,MV,OP>(_problem->getM()) );
|
||||
}
|
||||
else {
|
||||
ortho = Teuchos::rcp( new BasicOrthoManager<ScalarType,MV,OP>(_problem->getM(),_ortho_kappa) );
|
||||
}
|
||||
} else {
|
||||
TEST_FOR_EXCEPTION(_ortho!="SVQB"&&_ortho!="DGKS",std::logic_error,"Anasazi::BlockKrylovSchurSolMgr::solve(): Invalid orthogonalization type.");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Parameter list
|
||||
Teuchos::ParameterList plist;
|
||||
plist.set("Block Size",_blockSize);
|
||||
plist.set("Num Blocks",_numBlocks);
|
||||
plist.set("Step Size",_stepSize);
|
||||
plist.set("Print Number of Ritz Values",_nevBlocks*_blockSize);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// BlockKrylovSchur solver
|
||||
Teuchos::RCP<BlockKrylovSchur<ScalarType,MV,OP> > bks_solver
|
||||
= Teuchos::rcp( new BlockKrylovSchur<ScalarType,MV,OP>(_problem,_sort,printer,outputtest,ortho,plist) );
|
||||
// set any auxiliary vectors defined in the problem
|
||||
Teuchos::RCP< const MV > probauxvecs = _problem->getAuxVecs();
|
||||
if (probauxvecs != Teuchos::null) {
|
||||
bks_solver->setAuxVecs( Teuchos::tuple< Teuchos::RCP<const MV> >(probauxvecs) );
|
||||
}
|
||||
|
||||
// Create workspace for the Krylov basis generated during a restart
|
||||
// Need at most (_nevBlocks*_blockSize+1) for the updated factorization and another block for the current factorization residual block (F).
|
||||
// ---> (_nevBlocks*_blockSize+1) + _blockSize
|
||||
// If Hermitian, this becomes _nevBlocks*_blockSize + _blockSize
|
||||
// we only need this if there is the possibility of restarting, ex situ
|
||||
Teuchos::RCP<MV> workMV;
|
||||
if (_maxRestarts > 0) {
|
||||
if (_inSituRestart==true) {
|
||||
// still need one work vector for applyHouse()
|
||||
workMV = MVT::Clone( *_problem->getInitVec(), 1 );
|
||||
}
|
||||
else { // inSituRestart == false
|
||||
if (_problem->isHermitian()) {
|
||||
workMV = MVT::Clone( *_problem->getInitVec(), _nevBlocks*_blockSize + _blockSize );
|
||||
} else {
|
||||
workMV = MVT::Clone( *_problem->getInitVec(), _nevBlocks*_blockSize+1 + _blockSize );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
workMV = Teuchos::null;
|
||||
}
|
||||
|
||||
// go ahead and initialize the solution to nothing in case we throw an exception
|
||||
Eigensolution<ScalarType,MV> sol;
|
||||
sol.numVecs = 0;
|
||||
_problem->setSolution(sol);
|
||||
|
||||
int numRestarts = 0;
|
||||
int cur_nevBlocks = 0;
|
||||
|
||||
// enter solve() iterations
|
||||
{
|
||||
Teuchos::TimeMonitor slvtimer(*_timerSolve);
|
||||
|
||||
// tell bks_solver to iterate
|
||||
while (1) {
|
||||
try {
|
||||
bks_solver->iterate();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// check convergence first
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
if (convtest->getStatus() == Passed ) {
|
||||
// we have convergence
|
||||
// convtest->whichVecs() tells us which vectors from solver state are the ones we want
|
||||
// convtest->howMany() will tell us how many
|
||||
break;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// check for restarting, i.e. the subspace is full
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// this is for the Hermitian case, or non-Hermitian conjugate split situation.
|
||||
// --> for the Hermitian case the current subspace dimension needs to match the maximum subspace dimension
|
||||
// --> for the non-Hermitian case:
|
||||
// --> if a conjugate pair was detected in the previous restart then the current subspace dimension needs to match the
|
||||
// maximum subspace dimension (the BKS solver keeps one extra vector if the problem is non-Hermitian).
|
||||
// --> if a conjugate pair was not detected in the previous restart then the current subspace dimension will be one less
|
||||
// than the maximum subspace dimension.
|
||||
else if ( (bks_solver->getCurSubspaceDim() == bks_solver->getMaxSubspaceDim()) ||
|
||||
(!_problem->isHermitian() && !_conjSplit && (bks_solver->getCurSubspaceDim()+1 == bks_solver->getMaxSubspaceDim())) ) {
|
||||
|
||||
Teuchos::TimeMonitor restimer(*_timerRestarting);
|
||||
|
||||
if ( numRestarts >= _maxRestarts ) {
|
||||
break; // break from while(1){bks_solver->iterate()}
|
||||
}
|
||||
numRestarts++;
|
||||
|
||||
printer->stream(Debug) << " Performing restart number " << numRestarts << " of " << _maxRestarts << std::endl << std::endl;
|
||||
|
||||
// Update the Schur form of the projected eigenproblem, then sort it.
|
||||
if (!bks_solver->isSchurCurrent())
|
||||
bks_solver->computeSchurForm( true );
|
||||
|
||||
// Get the most current Ritz values before we continue.
|
||||
_ritzValues = bks_solver->getRitzValues();
|
||||
|
||||
// Get the state.
|
||||
BlockKrylovSchurState<ScalarType,MV> oldState = bks_solver->getState();
|
||||
|
||||
// Get the current dimension of the factorization
|
||||
int curDim = oldState.curDim;
|
||||
|
||||
// Determine if the storage for the nev eigenvalues of interest splits a complex conjugate pair.
|
||||
std::vector<int> ritzIndex = bks_solver->getRitzIndex();
|
||||
if (ritzIndex[_nevBlocks*_blockSize-1]==1) {
|
||||
_conjSplit = true;
|
||||
cur_nevBlocks = _nevBlocks*_blockSize+1;
|
||||
} else {
|
||||
_conjSplit = false;
|
||||
cur_nevBlocks = _nevBlocks*_blockSize;
|
||||
}
|
||||
|
||||
// Update the Krylov-Schur decomposition
|
||||
|
||||
// Get a view of the Schur vectors of interest.
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> Qnev(Teuchos::View, *(oldState.Q), curDim, cur_nevBlocks);
|
||||
|
||||
// Get a view of the current Krylov basis.
|
||||
std::vector<int> curind( curDim );
|
||||
for (int i=0; i<curDim; i++) { curind[i] = i; }
|
||||
Teuchos::RCP<const MV> basistemp = MVT::CloneView( *(oldState.V), curind );
|
||||
|
||||
// Compute the new Krylov basis: Vnew = V*Qnev
|
||||
//
|
||||
// this will occur ex situ in workspace allocated for this purpose (tmpMV)
|
||||
// or in situ in the solver's memory space.
|
||||
//
|
||||
// we will also set a pointer for the location that the current factorization residual block (F),
|
||||
// currently located after the current basis in oldstate.V, will be moved to
|
||||
//
|
||||
Teuchos::RCP<MV> newF;
|
||||
if (_inSituRestart) {
|
||||
//
|
||||
// get non-const pointer to solver's basis so we can work in situ
|
||||
Teuchos::RCP<MV> solverbasis = Teuchos::rcp_const_cast<MV>(oldState.V);
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> copyQnev(Qnev);
|
||||
//
|
||||
// perform Householder QR of copyQnev = Q [D;0], where D is unit diag. We will want D below.
|
||||
std::vector<ScalarType> tau(cur_nevBlocks), work(cur_nevBlocks);
|
||||
int info;
|
||||
lapack.GEQRF(curDim,cur_nevBlocks,copyQnev.values(),copyQnev.stride(),&tau[0],&work[0],work.size(),&info);
|
||||
TEST_FOR_EXCEPTION(info != 0,std::logic_error,
|
||||
"Anasazi::BlockDavidsonSolMgr::solve(): error calling GEQRF during restarting.");
|
||||
// we need to get the diagonal of D
|
||||
std::vector<ScalarType> d(cur_nevBlocks);
|
||||
for (int j=0; j<copyQnev.numCols(); j++) {
|
||||
d[j] = copyQnev(j,j);
|
||||
}
|
||||
if (printer->isVerbosity(Debug)) {
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> R(Teuchos::Copy,copyQnev,cur_nevBlocks,cur_nevBlocks);
|
||||
for (int j=0; j<R.numCols(); j++) {
|
||||
R(j,j) = SCT::magnitude(R(j,j)) - 1.0;
|
||||
for (int i=j+1; i<R.numRows(); i++) {
|
||||
R(i,j) = zero;
|
||||
}
|
||||
}
|
||||
printer->stream(Debug) << "||Triangular factor of Su - I||: " << R.normFrobenius() << std::endl;
|
||||
}
|
||||
//
|
||||
// perform implicit V*Qnev
|
||||
// this actually performs V*[Qnev Qtrunc*M] = [newV truncV], for some unitary M
|
||||
// we are interested in only the first cur_nevBlocks vectors of the result
|
||||
curind.resize(curDim);
|
||||
for (int i=0; i<curDim; i++) curind[i] = i;
|
||||
Teuchos::RCP<MV> oldV = MVT::CloneView(*solverbasis,curind);
|
||||
msutils::applyHouse(cur_nevBlocks,*oldV,copyQnev,tau,workMV);
|
||||
// clear pointer
|
||||
oldV = Teuchos::null;
|
||||
// multiply newV*D
|
||||
// get pointer to new basis
|
||||
curind.resize(cur_nevBlocks);
|
||||
for (int i=0; i<cur_nevBlocks; i++) { curind[i] = i; }
|
||||
oldV = MVT::CloneView( *solverbasis, curind );
|
||||
MVT::MvScale(*oldV,d);
|
||||
oldV = Teuchos::null;
|
||||
// get pointer to new location for F
|
||||
curind.resize(_blockSize);
|
||||
for (int i=0; i<_blockSize; i++) { curind[i] = cur_nevBlocks + i; }
|
||||
newF = MVT::CloneView( *solverbasis, curind );
|
||||
}
|
||||
else {
|
||||
// get pointer to first part of work space
|
||||
curind.resize(cur_nevBlocks);
|
||||
for (int i=0; i<cur_nevBlocks; i++) { curind[i] = i; }
|
||||
Teuchos::RCP<MV> tmp_newV = MVT::CloneView(*workMV, curind );
|
||||
// perform V*Qnev
|
||||
MVT::MvTimesMatAddMv( one, *basistemp, Qnev, zero, *tmp_newV );
|
||||
tmp_newV = Teuchos::null;
|
||||
// get pointer to new location for F
|
||||
curind.resize(_blockSize);
|
||||
for (int i=0; i<_blockSize; i++) { curind[i] = cur_nevBlocks + i; }
|
||||
newF = MVT::CloneView( *workMV, curind );
|
||||
}
|
||||
|
||||
// Move the current factorization residual block (F) to the last block of newV.
|
||||
curind.resize(_blockSize);
|
||||
for (int i=0; i<_blockSize; i++) { curind[i] = curDim + i; }
|
||||
Teuchos::RCP<const MV> oldF = MVT::CloneView( *(oldState.V), curind );
|
||||
for (int i=0; i<_blockSize; i++) { curind[i] = i; }
|
||||
MVT::SetBlock( *oldF, curind, *newF );
|
||||
newF = Teuchos::null;
|
||||
|
||||
// Update the Krylov-Schur quasi-triangular matrix.
|
||||
//
|
||||
// Create storage for the new Schur matrix of the Krylov-Schur factorization
|
||||
// Copy over the current quasi-triangular factorization of oldState.H which is stored in oldState.S.
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> oldS(Teuchos::View, *(oldState.S), cur_nevBlocks+_blockSize, cur_nevBlocks);
|
||||
Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > newH =
|
||||
Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>( oldS ) );
|
||||
//
|
||||
// Get a view of the B block of the current factorization
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> oldB(Teuchos::View, *(oldState.H), _blockSize, _blockSize, curDim, curDim-_blockSize);
|
||||
//
|
||||
// Get a view of the a block row of the Schur vectors.
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> subQ(Teuchos::View, *(oldState.Q), _blockSize, cur_nevBlocks, curDim-_blockSize);
|
||||
//
|
||||
// Get a view of the new B block of the updated Krylov-Schur factorization
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> newB(Teuchos::View, *newH, _blockSize, cur_nevBlocks, cur_nevBlocks);
|
||||
//
|
||||
// Compute the new B block.
|
||||
blas.GEMM( Teuchos::NO_TRANS, Teuchos::NO_TRANS, _blockSize, cur_nevBlocks, _blockSize, one,
|
||||
oldB.values(), oldB.stride(), subQ.values(), subQ.stride(), zero, newB.values(), newB.stride() );
|
||||
|
||||
|
||||
//
|
||||
// Set the new state and initialize the solver.
|
||||
BlockKrylovSchurState<ScalarType,MV> newstate;
|
||||
if (_inSituRestart) {
|
||||
newstate.V = oldState.V;
|
||||
} else {
|
||||
newstate.V = workMV;
|
||||
}
|
||||
newstate.H = newH;
|
||||
newstate.curDim = cur_nevBlocks;
|
||||
bks_solver->initialize(newstate);
|
||||
|
||||
} // end of restarting
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// we returned from iterate(), but none of our status tests Passed.
|
||||
// something is wrong, and it is probably our fault.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
else {
|
||||
TEST_FOR_EXCEPTION(true,std::logic_error,"Anasazi::BlockKrylovSchurSolMgr::solve(): Invalid return from bks_solver::iterate().");
|
||||
}
|
||||
}
|
||||
catch (std::exception e) {
|
||||
printer->stream(Errors) << "Error! Caught exception in BlockKrylovSchur::iterate() at iteration " << bks_solver->getNumIters() << std::endl
|
||||
<< e.what() << std::endl;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// free temporary space
|
||||
workMV = Teuchos::null;
|
||||
|
||||
// Get the most current Ritz values before we return
|
||||
_ritzValues = bks_solver->getRitzValues();
|
||||
|
||||
sol.numVecs = convtest->howMany();
|
||||
if (sol.numVecs > 0) {
|
||||
sol.index = bks_solver->getRitzIndex();
|
||||
sol.Evals = bks_solver->getRitzValues();
|
||||
// Check to see if conjugate pair is on the boundary.
|
||||
if (sol.index[sol.numVecs-1]==1) {
|
||||
sol.numVecs++;
|
||||
sol.Evals.resize(sol.numVecs);
|
||||
sol.index.resize(sol.numVecs);
|
||||
bks_solver->setNumRitzVectors(sol.numVecs);
|
||||
} else {
|
||||
sol.Evals.resize(sol.numVecs);
|
||||
sol.index.resize(sol.numVecs);
|
||||
bks_solver->setNumRitzVectors(sol.numVecs);
|
||||
}
|
||||
bks_solver->computeRitzVectors();
|
||||
sol.Evecs = MVT::CloneCopy( *(bks_solver->getRitzVectors()) );
|
||||
sol.Espace = sol.Evecs;
|
||||
}
|
||||
}
|
||||
|
||||
// print final summary
|
||||
bks_solver->currentStatus(printer->stream(FinalSummary));
|
||||
|
||||
// print timing information
|
||||
Teuchos::TimeMonitor::summarize(printer->stream(TimingDetails));
|
||||
|
||||
_problem->setSolution(sol);
|
||||
printer->stream(Debug) << "Returning " << sol.numVecs << " eigenpairs to eigenproblem." << std::endl;
|
||||
|
||||
if (sol.numVecs < nev) {
|
||||
return Unconverged; // return from BlockKrylovSchurSolMgr::solve()
|
||||
}
|
||||
return Converged; // return from BlockKrylovSchurSolMgr::solve()
|
||||
}
|
||||
|
||||
|
||||
} // end Anasazi namespace
|
||||
|
||||
#endif /* ANASAZI_BLOCK_KRYLOV_SCHUR_SOLMGR_HPP */
|
||||
@@ -0,0 +1,188 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
|
||||
/*! \file AnasaziConfigDefs.hpp
|
||||
\brief Anasazi header file which uses auto-configuration information to include
|
||||
necessary C++ headers
|
||||
*/
|
||||
|
||||
#ifndef ANASAZI_CONFIGDEFS_HPP
|
||||
#define ANASAZI_CONFIGDEFS_HPP
|
||||
|
||||
#ifndef __cplusplus
|
||||
#define __cplusplus
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
||||
/*
|
||||
* The macros PACKAGE, PACKAGE_NAME, etc, get defined for each package and need to
|
||||
* be undef'd here to avoid warnings when this file is included from another package.
|
||||
* KL 11/25/02
|
||||
*/
|
||||
#ifdef PACKAGE
|
||||
#undef PACKAGE
|
||||
#endif
|
||||
|
||||
#ifdef PACKAGE_NAME
|
||||
#undef PACKAGE_NAME
|
||||
#endif
|
||||
|
||||
#ifdef PACKAGE_BUGREPORT
|
||||
#undef PACKAGE_BUGREPORT
|
||||
#endif
|
||||
|
||||
#ifdef PACKAGE_STRING
|
||||
#undef PACKAGE_STRING
|
||||
#endif
|
||||
|
||||
#ifdef PACKAGE_TARNAME
|
||||
#undef PACKAGE_TARNAME
|
||||
#endif
|
||||
|
||||
#ifdef PACKAGE_VERSION
|
||||
#undef PACKAGE_VERSION
|
||||
#endif
|
||||
|
||||
#ifdef VERSION
|
||||
#undef VERSION
|
||||
#endif
|
||||
|
||||
#include <Anasazi_config.h>
|
||||
|
||||
#ifdef HAVE_MPI
|
||||
#ifndef EPETRA_MPI
|
||||
#define EPETRA_MPI
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CSTDLIB
|
||||
#include <cstdlib>
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CSTDIO
|
||||
#include <cstdio>
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING
|
||||
#include <string>
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_VECTOR
|
||||
#include <vector>
|
||||
#else
|
||||
#include <vector.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NUMERIC
|
||||
#include <numeric>
|
||||
#else
|
||||
#include <algo.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_COMPLEX
|
||||
#include <complex>
|
||||
#else
|
||||
#include <complex.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IOSTREAM
|
||||
#include <iostream>
|
||||
#else
|
||||
#include <iostream.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ITERATOR
|
||||
#include <iterator>
|
||||
#else
|
||||
#include <iterator.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_STDEXCEPT
|
||||
#include <stdexcept>
|
||||
#elif HAVE_STDEXCEPT_H
|
||||
#include <stdexcept.h>
|
||||
#endif
|
||||
|
||||
#ifndef JANUS_STLPORT
|
||||
#ifdef HAVE_CMATH
|
||||
#include <cmath>
|
||||
#else
|
||||
#include <math.h>
|
||||
#endif
|
||||
#else /* JANUS_STLPORT */
|
||||
#include <math.h>
|
||||
#endif /* JANUS_STLPORT */
|
||||
|
||||
#else /*HAVE_CONFIG_H is not defined*/
|
||||
|
||||
#include <iterator>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#if defined(SGI) || defined(SGI64) || defined(SGI32) || defined(CPLANT) || defined (TFLOP)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#else
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cmath>
|
||||
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <deque>
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
|
||||
/* Define some macros */
|
||||
#define ANASAZI_MAX(x,y) (( (x) > (y) ) ? (x) : (y) ) /* max function */
|
||||
#define ANASAZI_MIN(x,y) (( (x) < (y) ) ? (x) : (y) ) /* min function */
|
||||
#define ANASAZI_SGN(x) (( (x) < 0.0 ) ? -1.0 : 1.0 ) /* sign function */
|
||||
|
||||
/*
|
||||
* Anasazi_Version() method
|
||||
*/
|
||||
namespace Anasazi {
|
||||
std::string Anasazi_Version();
|
||||
}
|
||||
|
||||
#endif /*ANASAZI_CONFIGDEFS_HPP*/
|
||||
@@ -0,0 +1,178 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
|
||||
#ifndef ANASAZI_EIGENPROBLEM_H
|
||||
#define ANASAZI_EIGENPROBLEM_H
|
||||
|
||||
/*! \file AnasaziEigenproblem.hpp
|
||||
\brief Abstract base class which defines the interface required by an eigensolver and
|
||||
status test class to compute solutions to an eigenproblem
|
||||
*/
|
||||
|
||||
#include "AnasaziConfigDefs.hpp"
|
||||
#include "AnasaziTypes.hpp"
|
||||
#include "Teuchos_SerialDenseMatrix.hpp"
|
||||
#include "Teuchos_RCP.hpp"
|
||||
|
||||
|
||||
/*! \class Anasazi::Eigenproblem
|
||||
\brief This class defines the interface required by an eigensolver and status
|
||||
test class to compute solutions to an eigenproblem.
|
||||
*/
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
template<class ScalarType, class MV, class OP>
|
||||
class Eigenproblem {
|
||||
|
||||
public:
|
||||
|
||||
//! @name Constructors/Destructor
|
||||
//@{
|
||||
|
||||
//! Empty constructor
|
||||
Eigenproblem() {};
|
||||
|
||||
//! Destructor.
|
||||
virtual ~Eigenproblem() {};
|
||||
//@}
|
||||
|
||||
//! @name Set Methods
|
||||
//@{
|
||||
|
||||
/*! \brief Set the operator for which eigenvalues will be computed.
|
||||
*
|
||||
* \note This may be different from the \c A if a spectral transformation
|
||||
* is employed. For example, this operator may apply the operation
|
||||
* \f$(A-\sigma I)^{-1}\f$ if you are looking for eigenvalues of \c A
|
||||
* around \f$\sigma\f$.
|
||||
*/
|
||||
virtual void setOperator( const Teuchos::RCP<const OP> &Op ) = 0;
|
||||
|
||||
//! \brief Set the operator \c A of the eigenvalue problem \f$Ax=\lambda Mx\f$.
|
||||
virtual void setA( const Teuchos::RCP<const OP> &A ) = 0;
|
||||
|
||||
//! \brief Set the operator \c M of the eigenvalue problem \f$Ax=\lambda Mx\f$.
|
||||
virtual void setM( const Teuchos::RCP<const OP> &M ) = 0;
|
||||
|
||||
//! \brief Set the preconditioner for this eigenvalue problem \f$Ax=\lambda Mx\f$.
|
||||
virtual void setPrec( const Teuchos::RCP<const OP> &Prec ) = 0;
|
||||
|
||||
/*! \brief Set the initial guess.
|
||||
*
|
||||
* \note This multivector should have the same number of columns as the blocksize.
|
||||
*/
|
||||
virtual void setInitVec( const Teuchos::RCP<MV> &InitVec ) = 0;
|
||||
|
||||
/*! \brief Set auxiliary vectors.
|
||||
*
|
||||
* \note This multivector can have any number of columns, and most likely
|
||||
* will contain vectors that will be used by the eigensolver to
|
||||
* orthogonalize against.
|
||||
*/
|
||||
virtual void setAuxVecs( const Teuchos::RCP<const MV> &AuxVecs ) = 0;
|
||||
|
||||
//! The number of eigenvalues (NEV) that are requested.
|
||||
virtual void setNEV( int nev ) = 0;
|
||||
|
||||
/*! \brief Specify the symmetry of the eigenproblem.
|
||||
*
|
||||
* This knowledge may allow the solver to take advantage of the eigenproblems' symmetry.
|
||||
* Some computational work may be avoided by setting this properly.
|
||||
*/
|
||||
virtual void setHermitian( bool isSym ) = 0;
|
||||
|
||||
/*! \brief Specify that this eigenproblem is fully defined.
|
||||
*
|
||||
* This routine serves multiple purpose:
|
||||
* <ul>
|
||||
* <li> sanity check that the eigenproblem has been fully and consistently defined
|
||||
* <li> opportunity for the eigenproblem to allocate internal storage for eigenvalues
|
||||
* and eigenvectors (to be used by eigensolvers and solver managers)
|
||||
* </ul>
|
||||
*
|
||||
* \note The user MUST call this routine before they send the eigenproblem to any solver or solver manager.
|
||||
*
|
||||
* \returns \c true signifies success, \c false signifies error.
|
||||
*/
|
||||
virtual bool setProblem() = 0;
|
||||
|
||||
/*! \brief Set the solution to the eigenproblem.
|
||||
*
|
||||
* This mechanism allows an Eigensolution struct to be associated with an Eigenproblem object.
|
||||
* setSolution() is usually called by a solver manager at the end of its SolverManager::solve()
|
||||
* routine.
|
||||
*/
|
||||
virtual void setSolution(const Eigensolution<ScalarType,MV> &sol) = 0;
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Accessor Methods
|
||||
//@{
|
||||
|
||||
//! Get a pointer to the operator for which eigenvalues will be computed.
|
||||
virtual Teuchos::RCP<const OP> getOperator() const = 0;
|
||||
|
||||
//! Get a pointer to the operator \c A of the eigenproblem \f$AX=\lambda Mx\f$.
|
||||
virtual Teuchos::RCP<const OP> getA() const = 0;
|
||||
|
||||
//! Get a pointer to the operator \c M of the eigenproblem \f$AX=\lambda Mx\f$.
|
||||
virtual Teuchos::RCP<const OP> getM() const = 0;
|
||||
|
||||
//! Get a pointer to the preconditioner.
|
||||
virtual Teuchos::RCP<const OP> getPrec() const = 0;
|
||||
|
||||
//! Get a pointer to the initial vector
|
||||
virtual Teuchos::RCP<const MV> getInitVec() const = 0;
|
||||
|
||||
//! Get a pointer to the auxiliary vector
|
||||
virtual Teuchos::RCP<const MV> getAuxVecs() const = 0;
|
||||
|
||||
//! Get the number of eigenvalues (NEV) that are required by this eigenproblem.
|
||||
virtual int getNEV() const = 0;
|
||||
|
||||
//! Get the symmetry information for this eigenproblem.
|
||||
virtual bool isHermitian() const = 0;
|
||||
|
||||
//! If the problem has been set, this method will return true.
|
||||
virtual bool isProblemSet() const = 0;
|
||||
|
||||
/*! \brief Get the solution to the eigenproblem.
|
||||
*
|
||||
* There is no computation associated with this method. It only provides a
|
||||
* mechanism for associating an Eigensolution with a Eigenproblem.
|
||||
*/
|
||||
virtual const Eigensolution<ScalarType,MV> & getSolution() const = 0;
|
||||
|
||||
//@}
|
||||
};
|
||||
|
||||
} // end Anasazi namespace
|
||||
#endif
|
||||
|
||||
// end AnasaziEigenproblem.hpp
|
||||
@@ -0,0 +1,184 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
|
||||
#ifndef ANASAZI_EIGENSOLVER_HPP
|
||||
#define ANASAZI_EIGENSOLVER_HPP
|
||||
|
||||
/*! \file AnasaziEigensolver.hpp
|
||||
\brief Pure virtual base class which describes the basic interface to the iterative eigensolver.
|
||||
*/
|
||||
|
||||
#include "AnasaziConfigDefs.hpp"
|
||||
#include "AnasaziTypes.hpp"
|
||||
|
||||
#include "AnasaziEigensolverDecl.hpp"
|
||||
#include "AnasaziStatusTestDecl.hpp"
|
||||
|
||||
#include "AnasaziEigenproblem.hpp"
|
||||
#include "AnasaziSortManager.hpp"
|
||||
#include "AnasaziOutputManager.hpp"
|
||||
#include "AnasaziOrthoManager.hpp"
|
||||
#include "Teuchos_ParameterList.hpp"
|
||||
#include "Teuchos_RCP.hpp"
|
||||
#include "Teuchos_Array.hpp"
|
||||
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
template<class ScalarType, class MV, class OP>
|
||||
class Eigensolver {
|
||||
|
||||
public:
|
||||
|
||||
//! @name Constructors/Destructor
|
||||
//@{
|
||||
|
||||
//! Default Constructor.
|
||||
Eigensolver() {};
|
||||
|
||||
//! Basic Constructor.
|
||||
/*! This constructor, implemented by all Anasazi eigensolvers, takes an Anasazi::Eigenproblem,
|
||||
Anasazi::SortManager, Anasazi::OutputManager, and Teuchos::ParameterList as input. These
|
||||
four arguments are sufficient enough for constructing any Anasazi::Eigensolver object.
|
||||
*/
|
||||
Eigensolver( const Teuchos::RCP<Eigenproblem<ScalarType,MV,OP> > &problem,
|
||||
const Teuchos::RCP<SortManager<ScalarType,MV,OP> > &sorter,
|
||||
const Teuchos::RCP<OutputManager<ScalarType> > &printer,
|
||||
const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > &tester,
|
||||
const Teuchos::RCP<OrthoManager<ScalarType,MV> > &ortho,
|
||||
Teuchos::ParameterList ¶ms );
|
||||
|
||||
//! Destructor.
|
||||
virtual ~Eigensolver() {};
|
||||
//@}
|
||||
|
||||
|
||||
//! @name Solver methods
|
||||
//@{
|
||||
|
||||
/*! \brief This method performs eigensolvers iterations until the status test
|
||||
indicates the need to stop or an error occurs (in which case, an exception is thrown).
|
||||
*/
|
||||
virtual void iterate() = 0;
|
||||
|
||||
/*! \brief Initialize the solver with the initial vectors from the eigenproblem
|
||||
* or random data.
|
||||
*/
|
||||
virtual void initialize() = 0;
|
||||
|
||||
//@}
|
||||
|
||||
|
||||
//! @name Status methods
|
||||
//@{
|
||||
|
||||
//! \brief Get the current iteration count.
|
||||
virtual int getNumIters() const = 0;
|
||||
|
||||
//! \brief Reset the iteration count.
|
||||
virtual void resetNumIters() = 0;
|
||||
|
||||
/*! \brief Get the Ritz vectors from the previous iteration. These are indexed using getRitzIndex().
|
||||
*
|
||||
* For a description of the indexing scheme, see getRitzIndex().
|
||||
*/
|
||||
virtual Teuchos::RCP<const MV> getRitzVectors() = 0;
|
||||
|
||||
//! \brief Get the Ritz values from the previous iteration.
|
||||
virtual std::vector<Value<ScalarType> > getRitzValues() = 0;
|
||||
|
||||
/*! \brief Get the index used for indexing the compressed storage used for Ritz vectors for real, non-Hermitian problems.
|
||||
*
|
||||
* index has length numVecs, where each entry is 0, +1, or -1. These have the following interpretation:
|
||||
* - index[i] == 0: signifies that the corresponding eigenvector is stored as the i column of Evecs. This will usually be the
|
||||
* case when ScalarType is complex, an eigenproblem is Hermitian, or a real, non-Hermitian eigenproblem has a real eigenvector.
|
||||
* - index[i] == +1: signifies that the corresponding eigenvector is stored in two vectors: the real part in the i column of Evecs and the <i><b>positive</b></i> imaginary part in the i+1 column of Evecs.
|
||||
* - index[i] == -1: signifies that the corresponding eigenvector is stored in two vectors: the real part in the i-1 column of Evecs and the <i><b>negative</b></i> imaginary part in the i column of Evecs
|
||||
*/
|
||||
virtual std::vector<int> getRitzIndex() = 0;
|
||||
|
||||
//! \brief Get the current residual norms
|
||||
/*! \return A vector of length blockSize containing the norms of the residuals,
|
||||
according to the orthogonalization manager norm() method.
|
||||
*/
|
||||
virtual std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> getResNorms() = 0;
|
||||
|
||||
//! Get the current residual 2-norms
|
||||
//! \return A vector of length blockSize containing the 2-norms of the residuals.
|
||||
virtual std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> getRes2Norms() = 0;
|
||||
|
||||
//! Get the 2-norms of the Ritz residuals.
|
||||
//! \return A vector of length blockSize containing the 2-norms of the Ritz residuals.
|
||||
virtual std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> getRitzRes2Norms() = 0;
|
||||
|
||||
//! Get the dimension of the search subspace used to generate the current eigenvectors and eigenvalues.
|
||||
virtual int getCurSubspaceDim() const = 0;
|
||||
|
||||
//! Get the maximum dimension allocated for the search subspace.
|
||||
virtual int getMaxSubspaceDim() const = 0;
|
||||
|
||||
//@}
|
||||
|
||||
|
||||
|
||||
//! @name Accessor methods
|
||||
//@{
|
||||
|
||||
//! Get a constant reference to the eigenvalue problem.
|
||||
virtual const Eigenproblem<ScalarType,MV,OP>& getProblem() const = 0;
|
||||
|
||||
//! Get the blocksize to be used by the iterative solver in solving this eigenproblem.
|
||||
virtual int getBlockSize() const = 0;
|
||||
|
||||
//! \brief Set the blocksize to be used by the iterative solver in solving this eigenproblem.
|
||||
virtual void setBlockSize(int blockSize) = 0;
|
||||
|
||||
//! Set the auxiliary vectors for the solver.
|
||||
virtual void setAuxVecs(const Teuchos::Array<Teuchos::RCP<const MV> > &auxvecs) = 0;
|
||||
|
||||
//! Get the auxiliary vectors for the solver.
|
||||
virtual Teuchos::Array<Teuchos::RCP<const MV> > getAuxVecs() const = 0;
|
||||
|
||||
//! States whether the solver has been initialized or not.
|
||||
virtual bool isInitialized() const = 0;
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Output methods
|
||||
//@{
|
||||
|
||||
//! This method requests that the solver print out its current status to screen.
|
||||
virtual void currentStatus(std::ostream &os) = 0;
|
||||
|
||||
//@}
|
||||
|
||||
};
|
||||
|
||||
} // end Anasazi namespace
|
||||
|
||||
#endif /* ANASAZI_EIGENSOLVER_HPP */
|
||||
@@ -0,0 +1,52 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
|
||||
#ifndef ANASAZI_EIGENSOLVER_DECL_HPP
|
||||
#define ANASAZI_EIGENSOLVER_DECL_HPP
|
||||
|
||||
/*! \file AnasaziEigensolverDecl.hpp
|
||||
\brief Forward declaration of the virtual base class Anasazi::Eigensolver.
|
||||
*/
|
||||
|
||||
#include "AnasaziConfigDefs.hpp"
|
||||
#include "AnasaziTypes.hpp"
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
/*! \class Eigensolver
|
||||
\brief The Eigensolver is a templated virtual base class that defines the
|
||||
basic interface that any eigensolver will support.
|
||||
|
||||
This interface is mainly concerned with providing a set of eigensolver status method that
|
||||
can be requested from any eigensolver by an StatusTest object.
|
||||
*/
|
||||
template<class ScalarType, class MV, class OP>
|
||||
class Eigensolver;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,800 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
|
||||
/*! \file AnasaziEpetraAdapter.hpp
|
||||
\brief Declarations of Anasazi multi-vector and operator classes using Epetra_MultiVector and Epetra_Operator classes
|
||||
*/
|
||||
|
||||
#ifndef ANASAZI_EPETRA_ADAPTER_HPP
|
||||
#define ANASAZI_EPETRA_ADAPTER_HPP
|
||||
|
||||
#include "AnasaziConfigDefs.hpp"
|
||||
#include "AnasaziTypes.hpp"
|
||||
#include "AnasaziMultiVec.hpp"
|
||||
#include "AnasaziOperator.hpp"
|
||||
|
||||
#include "Teuchos_SerialDenseMatrix.hpp"
|
||||
#include "Epetra_MultiVector.h"
|
||||
#include "Epetra_Operator.h"
|
||||
#include "Epetra_Map.h"
|
||||
#include "Epetra_LocalMap.h"
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
//! @name Epetra Adapter Exceptions
|
||||
//@{
|
||||
|
||||
/** \brief EpetraMultiVecFailure is thrown when a return value from an Epetra
|
||||
* call on an Epetra_MultiVector is non-zero.
|
||||
*/
|
||||
class EpetraMultiVecFailure : public AnasaziError {public:
|
||||
EpetraMultiVecFailure(const std::string& what_arg) : AnasaziError(what_arg)
|
||||
{}};
|
||||
|
||||
/** \brief EpetraOpFailure is thrown when a return value from an Epetra
|
||||
* call on an Epetra_Operator is non-zero.
|
||||
*/
|
||||
class EpetraOpFailure : public AnasaziError {public:
|
||||
EpetraOpFailure(const std::string& what_arg) : AnasaziError(what_arg)
|
||||
{}};
|
||||
|
||||
//@}
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
//
|
||||
//--------template class AnasaziEpetraMultiVec-----------------
|
||||
//
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
/*!
|
||||
\brief Basic adapter class for Anasazi::MultiVec that uses Epetra_MultiVector.
|
||||
|
||||
\note The Epetra package performs double-precision arithmetic, so the use of Epetra with Anasazi will
|
||||
only provide a double-precision eigensolver.
|
||||
*/
|
||||
class EpetraMultiVec : public MultiVec<double>, public Epetra_MultiVector {
|
||||
public:
|
||||
//! @name Constructors/Destructors
|
||||
//@{
|
||||
|
||||
//! Basic EpetraMultiVec constructor.
|
||||
/*! @param Map [in] An Epetra_LocalMap, Epetra_Map or Epetra_BlockMap.
|
||||
@param numvecs [in] Number of vectors in multi-vector.
|
||||
|
||||
\returns Pointer to an EpetraMultiVec
|
||||
*/
|
||||
EpetraMultiVec(const Epetra_BlockMap& Map, const int numvecs);
|
||||
|
||||
//! Copy constructor.
|
||||
EpetraMultiVec(const Epetra_MultiVector & P_vec);
|
||||
|
||||
//! Create multi-vector with values from two dimensional array.
|
||||
/*! @param Map [in] An Epetra_LocalMap, Epetra_Map or Epetra_BlockMap
|
||||
@param array [in] Pointer to an array of double precision numbers. The first vector starts at \c array, the
|
||||
second at \c array+stride, and so on. This array is copied.
|
||||
@param numvecs [in] Number of vectors in the multi-vector.
|
||||
@param stride [in] The stride between vectors in memory of \c array.
|
||||
|
||||
\returns Pointer to an EpetraMultiVec
|
||||
*/
|
||||
EpetraMultiVec(const Epetra_BlockMap& Map, double * array, const int numvecs, const int stride=0);
|
||||
|
||||
//! Create multi-vector from list of vectors in an existing EpetraMultiVec.
|
||||
/*! @param CV [in] Enumerated type set to Copy or View.
|
||||
@param P_vec [in] An existing fully constructed Epetra_MultiVector.
|
||||
@param index [in] A integer vector containing the indices of the vectors to copy out of \c P_vec.
|
||||
|
||||
\returns Pointer to an EpetraMultiVec
|
||||
*/
|
||||
EpetraMultiVec(Epetra_DataAccess CV, const Epetra_MultiVector& P_vec, const std::vector<int>& index);
|
||||
|
||||
//! Destructor
|
||||
virtual ~EpetraMultiVec() {};
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Creation methods
|
||||
//@{
|
||||
|
||||
/*! \brief Creates a new empty EpetraMultiVec containing \c numvecs columns.
|
||||
|
||||
\returns Pointer to an EpetraMultiVec
|
||||
*/
|
||||
MultiVec<double> * Clone ( const int numvecs ) const;
|
||||
|
||||
/*! \brief Creates a new EpetraMultiVec and copies contents of \c *this into
|
||||
the new vector (deep copy).
|
||||
|
||||
\returns Pointer to an EpetraMultiVec
|
||||
*/
|
||||
MultiVec<double> * CloneCopy () const;
|
||||
|
||||
/*! \brief Creates a new EpetraMultiVec and copies the selected contents of \c *this
|
||||
into the new vector (deep copy).
|
||||
|
||||
The copied vectors from \c *this are indicated by the \c index.size() indices in \c index.
|
||||
|
||||
\returns Pointer to an EpetraMultiVec
|
||||
*/
|
||||
MultiVec<double> * CloneCopy ( const std::vector<int>& index ) const;
|
||||
|
||||
/*! \brief Creates a new EpetraMultiVec that shares the selected contents of \c *this.
|
||||
|
||||
The index of the \c numvecs vectors shallow copied from \c *this are indicated by the
|
||||
indices given in \c index.
|
||||
|
||||
\returns Pointer to an EpetraMultiVec
|
||||
*/
|
||||
MultiVec<double> * CloneView ( const std::vector<int>& index );
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Attribute methods
|
||||
//@{
|
||||
|
||||
//! Obtain the vector length of *this.
|
||||
int GetNumberVecs () const { return NumVectors(); }
|
||||
|
||||
//! Obtain the number of vectors in *this.
|
||||
int GetVecLength () const { return GlobalLength(); }
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Update methods
|
||||
//@{
|
||||
/*! \brief Update \c *this with \f$\alpha AB + \beta (*this)\f$.
|
||||
*/
|
||||
void MvTimesMatAddMv ( double alpha, const MultiVec<double>& A,
|
||||
const Teuchos::SerialDenseMatrix<int,double>& B,
|
||||
double beta );
|
||||
|
||||
/*! \brief Replace \c *this with \f$\alpha A + \beta B\f$.
|
||||
*/
|
||||
void MvAddMv ( double alpha, const MultiVec<double>& A,
|
||||
double beta, const MultiVec<double>& B);
|
||||
|
||||
/*! \brief Compute a dense matrix \c B through the matrix-matrix multiply \f$\alpha A^T(*this)\f$.
|
||||
*/
|
||||
void MvTransMv ( double alpha, const MultiVec<double>& A, Teuchos::SerialDenseMatrix<int,double>& B
|
||||
#ifdef HAVE_ANASAZI_EXPERIMENTAL
|
||||
, ConjType conj = Anasazi::CONJ
|
||||
#endif
|
||||
) const;
|
||||
|
||||
/*! \brief Compute a vector \c b where the components are the individual dot-products, i.e. \f$ b[i] = A[i]^H(this[i])\f$ where \c A[i] is the i-th column of \c A.
|
||||
*/
|
||||
void MvDot ( const MultiVec<double>& A, std::vector<double>* b
|
||||
#ifdef HAVE_ANASAZI_EXPERIMENTAL
|
||||
, ConjType conj = Anasazi::CONJ
|
||||
#endif
|
||||
) const;
|
||||
|
||||
/*! \brief Scale each element of the vectors in \c *this with \c alpha.
|
||||
*/
|
||||
void MvScale ( double alpha ) {
|
||||
TEST_FOR_EXCEPTION( this->Scale( alpha )!=0, EpetraMultiVecFailure,
|
||||
"Anasazi::EpetraMultiVec::MvScale call to Epetra_MultiVector::Scale() returned a nonzero value.");
|
||||
}
|
||||
|
||||
/*! \brief Scale each element of the \c i-th vector in \c *this with \c alpha[i].
|
||||
*/
|
||||
void MvScale ( const std::vector<double>& alpha );
|
||||
|
||||
//@}
|
||||
//! @name Norm method
|
||||
//@{
|
||||
|
||||
/*! \brief Compute the 2-norm of each individual vector of \c *this.
|
||||
Upon return, \c normvec[i] holds the 2-norm of the \c i-th vector of \c *this
|
||||
*/
|
||||
void MvNorm ( std::vector<double>* normvec ) const {
|
||||
if ((normvec!=NULL) && ((int)normvec->size() >= GetNumberVecs()) ) {
|
||||
TEST_FOR_EXCEPTION( this->Norm2(&(*normvec)[0])!=0, EpetraMultiVecFailure,
|
||||
"Anasazi::EpetraMultiVec::MvNorm call to Epetra_MultiVector::Norm2() returned a nonzero value.");
|
||||
}
|
||||
};
|
||||
//@}
|
||||
|
||||
//! @name Initialization methods
|
||||
//@{
|
||||
/*! \brief Copy the vectors in \c A to a set of vectors in \c *this.
|
||||
|
||||
The \c numvecs vectors in \c A are copied to a subset of vectors in \c *this
|
||||
indicated by the indices given in \c index.
|
||||
*/
|
||||
void SetBlock ( const MultiVec<double>& A, const std::vector<int>& index );
|
||||
|
||||
/*! \brief Fill the vectors in \c *this with random numbers.
|
||||
*/
|
||||
void MvRandom() {
|
||||
TEST_FOR_EXCEPTION( this->Random()!=0, EpetraMultiVecFailure,
|
||||
"Anasazi::EpetraMultiVec::MvRandom call to Epetra_MultiVector::Random() returned a nonzero value.");
|
||||
};
|
||||
|
||||
/*! \brief Replace each element of the vectors in \c *this with \c alpha.
|
||||
*/
|
||||
void MvInit ( double alpha ) {
|
||||
TEST_FOR_EXCEPTION( this->PutScalar( alpha )!=0, EpetraMultiVecFailure,
|
||||
"Anasazi::EpetraMultiVec::MvInit call to Epetra_MultiVector::PutScalar() returned a nonzero value.");
|
||||
};
|
||||
|
||||
//@}
|
||||
//! @name Print method
|
||||
//@{
|
||||
/*! \brief Print \c *this EpetraMultiVec.
|
||||
*/
|
||||
void MvPrint( std::ostream& os ) const { os << *this << std::endl; };
|
||||
//@}
|
||||
|
||||
private:
|
||||
};
|
||||
//-------------------------------------------------------------
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
//
|
||||
//--------template class AnasaziEpetraOp---------------------
|
||||
//
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
/*!
|
||||
\brief Basic adapter class for Anasazi::Operator that uses Epetra_Operator.
|
||||
|
||||
\note The Epetra package performs double-precision arithmetic, so the use of Epetra with Anasazi will
|
||||
only provide a double-precision eigensolver.
|
||||
*/
|
||||
class EpetraOp : public virtual Operator<double> {
|
||||
public:
|
||||
//! @name Constructor/Destructor
|
||||
//@{
|
||||
|
||||
//! Basic constructor. Accepts reference-counted pointer to an Epetra_Operator.
|
||||
EpetraOp(const Teuchos::RCP<Epetra_Operator> &Op );
|
||||
|
||||
//! Destructor
|
||||
~EpetraOp();
|
||||
//@}
|
||||
|
||||
//! @name Operator application method
|
||||
//@{
|
||||
|
||||
/*! \brief This method takes the Anasazi::MultiVec \c X and
|
||||
applies the operator to it resulting in the Anasazi::MultiVec \c Y.
|
||||
*/
|
||||
void Apply ( const MultiVec<double>& X, MultiVec<double>& Y ) const;
|
||||
//@}
|
||||
|
||||
private:
|
||||
Teuchos::RCP<Epetra_Operator> Epetra_Op;
|
||||
};
|
||||
//-------------------------------------------------------------
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
//
|
||||
//--------template class AnasaziEpetraGenOp--------------------
|
||||
//
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
/*!
|
||||
\brief Adapter class for creating an operators often used in solving generalized eigenproblems.
|
||||
|
||||
This class will apply the operation \f$A^{-1}M\f$ [default] or \f$AM\f$, for the \c Apply method of the
|
||||
Epetra_Operator / Anasazi::Operator. The Anasazi::EpetraGenOp operator is useful when spectral
|
||||
transformations are used within eigensolvers. For instance, \f$A^{-1}M\f$ is a shift and invert
|
||||
spectral transformation commonly used with Anasazi::BlockKrylovSchur to compute the smallest-magnitude
|
||||
eigenvalues for the eigenproblem \f$Ax = \lambda Mx\f$.
|
||||
|
||||
\note The Epetra package performs double-precision arithmetic, so the use of Epetra with Anasazi will
|
||||
only provide a double-precision eigensolver.
|
||||
*/
|
||||
|
||||
class EpetraGenOp : public virtual Operator<double>, public virtual Epetra_Operator {
|
||||
public:
|
||||
//! Basic constructor for applying operator \f$A^{-1}M\f$ [default] or \f$AM\f$.
|
||||
/*! If \c isAInverse is true this operator will apply \f$A^{-1}M\f$, else
|
||||
it will apply \f$AM\f$.
|
||||
*/
|
||||
EpetraGenOp(const Teuchos::RCP<Epetra_Operator> &AOp,
|
||||
const Teuchos::RCP<Epetra_Operator> &MOp,
|
||||
bool isAInverse = true );
|
||||
|
||||
//! Destructor
|
||||
~EpetraGenOp();
|
||||
|
||||
//! Apply method [inherited from Anasazi::Operator class]
|
||||
/*! This method will apply \f$A^{-1}M\f$ or \f$AM\f$ to \c X, returning \c Y.
|
||||
*/
|
||||
void Apply ( const MultiVec<double>& X, MultiVec<double>& Y ) const;
|
||||
|
||||
//! Apply method [inherited from Epetra_Operator class]
|
||||
/*! This method will apply \f$A^{-1}M\f$ or \f$AM\f$ to \c X, returning \c Y.
|
||||
*/
|
||||
int Apply(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const;
|
||||
|
||||
//! Apply inverse method [inherited from Epetra_Operator class]
|
||||
/*! This method will apply \f$(A^{-1}M)^{-1}\f$ or \f$(AM)^{-1}\f$ to \c X, returning \c Y.
|
||||
*/
|
||||
int ApplyInverse(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const;
|
||||
|
||||
//! Returns a character string describing the operator.
|
||||
const char* Label() const { return "Epetra_Operator applying A^{-1}M"; };
|
||||
|
||||
//! Returns the current UseTranspose setting [always false for this operator].
|
||||
bool UseTranspose() const { return (false); };
|
||||
|
||||
//! If set true, the transpose of this operator will be applied [not functional for this operator].
|
||||
int SetUseTranspose(bool UseTranspose) { return 0; };
|
||||
|
||||
//! Returns true if this object can provide an approximate inf-norm [always false for this operator].
|
||||
bool HasNormInf() const { return (false); };
|
||||
|
||||
//! Returns the infinity norm of the global matrix [not functional for this operator].
|
||||
double NormInf() const { return (-1.0); };
|
||||
|
||||
//! Returns the Epetra_Comm communicator associated with this operator.
|
||||
const Epetra_Comm& Comm() const { return Epetra_AOp->Comm(); };
|
||||
|
||||
//! Returns the Epetra_Map object associated with the domain of this operator.
|
||||
const Epetra_Map& OperatorDomainMap() const { return Epetra_AOp->OperatorDomainMap(); };
|
||||
|
||||
//! Returns the Epetra_Map object associated with the range of this operator.
|
||||
const Epetra_Map& OperatorRangeMap() const { return Epetra_AOp->OperatorRangeMap(); };
|
||||
|
||||
private:
|
||||
bool isAInverse;
|
||||
Teuchos::RCP<Epetra_Operator> Epetra_AOp;
|
||||
Teuchos::RCP<Epetra_Operator> Epetra_MOp;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
//
|
||||
//--------template class AnasaziEpetraSymOp--------------------
|
||||
//
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
/*!
|
||||
\brief Adapter class for creating a symmetric operator from an Epetra_Operator.
|
||||
|
||||
This class will apply the operation \f$A^TA\f$ [default] or \f$AA^T\f$, for the \c Apply method of the
|
||||
Epetra_Operator / Anasazi::Operator. The Anasazi::EpetraSymOp operator is useful when trying to compute
|
||||
a few singular values of the operator \f$A\f$. The singular values are the square-root of the eigenvalues
|
||||
of \f$A^TA\f$ and \f$AA^T\f$.
|
||||
|
||||
\note The Epetra package performs double-precision arithmetic, so the use of Epetra with Anasazi will
|
||||
only provide a double-precision eigensolver.
|
||||
*/
|
||||
|
||||
class EpetraSymOp : public virtual Operator<double>, public virtual Epetra_Operator {
|
||||
public:
|
||||
//! Basic constructor for applying operator \f$A^TA\f$ [default] or \f$AA^T\f$.
|
||||
/*! If \c isTrans is false this operator will apply \f$A^TA\f$, else it will apply \f$AA^T\f$.
|
||||
*/
|
||||
EpetraSymOp(const Teuchos::RCP<Epetra_Operator> &Op, bool isTrans = false );
|
||||
|
||||
//! Destructor
|
||||
~EpetraSymOp();
|
||||
|
||||
//! Apply method [inherited from Anasazi::Operator class]
|
||||
/*! This method will apply \f$A^TA\f$ or \f$AA^T\f$ to \c X, returning \c Y.
|
||||
*/
|
||||
void Apply ( const MultiVec<double>& X, MultiVec<double>& Y ) const;
|
||||
|
||||
//! Apply method [inherited from Epetra_Operator class]
|
||||
/*! This method will apply \f$A^TA\f$ or \f$AA^T\f$ to \c X, returning \c Y.
|
||||
*/
|
||||
int Apply(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const;
|
||||
|
||||
//! Apply inverse method [inherited from Epetra_Operator class]
|
||||
/*! This method will apply \f$(A^TA)^{-1}\f$ or \f$(AA^T)^{-1}\f$ to \c X, returning \c Y.
|
||||
\note This method is only defined if \f$A^{-1}\f$ is defined for the given Epetra_Operator.
|
||||
*/
|
||||
int ApplyInverse(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const;
|
||||
|
||||
//! Returns a character string describing the operator.
|
||||
const char* Label() const { return "Epetra_Operator applying A^TA or AA^T"; };
|
||||
|
||||
//! Returns the current UseTranspose setting [always false for this operator].
|
||||
bool UseTranspose() const { return (false); };
|
||||
|
||||
//! If set true, the transpose of this operator will be applied [not functional for this operator].
|
||||
int SetUseTranspose(bool UseTranspose) { return 0; };
|
||||
|
||||
//! Returns true if this object can provide an approximate inf-norm [always false for this operator].
|
||||
bool HasNormInf() const { return (false); };
|
||||
|
||||
//! Returns the infinity norm of the global matrix [not functional for this operator].
|
||||
double NormInf() const { return (-1.0); };
|
||||
|
||||
//! Returns the Epetra_Comm communicator associated with this operator.
|
||||
const Epetra_Comm& Comm() const { return Epetra_Op->Comm(); };
|
||||
|
||||
//! Returns the Epetra_Map object associated with the domain of this operator.
|
||||
const Epetra_Map& OperatorDomainMap() const { return Epetra_Op->OperatorDomainMap(); };
|
||||
|
||||
//! Returns the Epetra_Map object associated with the range of this operator.
|
||||
const Epetra_Map& OperatorRangeMap() const { return Epetra_Op->OperatorRangeMap(); };
|
||||
|
||||
private:
|
||||
Teuchos::RCP<Epetra_Operator> Epetra_Op;
|
||||
bool isTrans_;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//--------template class AnasaziEpetraSymMVOp---------------------
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
/*!
|
||||
\brief Adapter class for creating a symmetric operator from an Epetra_MultiVector.
|
||||
|
||||
This class will apply the operation \f$A^TA\f$ [default] or \f$AA^T\f$, for the \c Apply method of the
|
||||
Epetra_Operator / Anasazi::Operator. The Anasazi::EpetraSymMvOp operator is useful when trying to compute
|
||||
a few singular values of the Epetra_MultiVector \f$A\f$. The singular values are the square-root of the
|
||||
eigenvalues of \f$A^TA\f$ and \f$AA^T\f$.
|
||||
|
||||
\note The Epetra package performs double-precision arithmetic, so the use of Epetra with Anasazi will
|
||||
only provide a double-precision eigensolver.
|
||||
*/
|
||||
|
||||
class EpetraSymMVOp : public virtual Operator<double> {
|
||||
public:
|
||||
//! Basic constructor for applying operator \f$A^TA\f$ [default] or \f$AA^T\f$.
|
||||
/*! If \c isTrans is false this operator will apply \f$A^TA\f$, else it will apply \f$AA^T\f$.
|
||||
*/
|
||||
EpetraSymMVOp(const Teuchos::RCP<const Epetra_MultiVector> &MV,
|
||||
bool isTrans = false );
|
||||
|
||||
//! Destructor
|
||||
~EpetraSymMVOp() {};
|
||||
|
||||
//! Apply method
|
||||
/*! This method will apply \f$A^TA\f$ or \f$AA^T\f$ to \c X, returning \c Y.
|
||||
*/
|
||||
void Apply ( const MultiVec<double>& X, MultiVec<double>& Y ) const;
|
||||
|
||||
private:
|
||||
Teuchos::RCP<const Epetra_MultiVector> Epetra_MV;
|
||||
Teuchos::RCP<const Epetra_Map> MV_localmap;
|
||||
Teuchos::RCP<const Epetra_BlockMap> MV_blockmap;
|
||||
bool isTrans_;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//--------template class AnasaziEpetraWSymMVOp---------------------
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
/*!
|
||||
\brief Adapter class for creating a weighted symmetric operator from an Epetra_MultiVector and Epetra_Operator.
|
||||
|
||||
This class will apply the operation \f$(WA)^T*WA\f$ for the \c Apply method of the
|
||||
Anasazi::Operator. The Anasazi::EpetraWSymMvOp operator is useful when trying to compute
|
||||
a few singular values of the Epetra_MultiVector \f$A\f$ under the weighting matrix \f$W\f$.
|
||||
The singular values are the square-root of the eigenvalues of \f$(WA)^T*WA\f$.
|
||||
|
||||
\note The Epetra package performs double-precision arithmetic, so the use of Epetra with Anasazi will
|
||||
only provide a double-precision eigensolver.
|
||||
*/
|
||||
|
||||
class EpetraWSymMVOp : public virtual Operator<double> {
|
||||
public:
|
||||
//! Basic constructor for applying operator \f$A^TA\f$ [default] or \f$AA^T\f$.
|
||||
/*! If \c isTrans is false this operator will apply \f$A^TA\f$, else it will apply \f$AA^T\f$.
|
||||
*/
|
||||
EpetraWSymMVOp(const Teuchos::RCP<const Epetra_MultiVector> &MV,
|
||||
const Teuchos::RCP<Epetra_Operator> &OP );
|
||||
|
||||
//! Destructor
|
||||
~EpetraWSymMVOp() {};
|
||||
|
||||
//! Apply method
|
||||
/*! This method will apply \f$(WA)^T*WA\f$ to \c X, returning \c Y.
|
||||
*/
|
||||
void Apply ( const MultiVec<double>& X, MultiVec<double>& Y ) const;
|
||||
|
||||
private:
|
||||
Teuchos::RCP<const Epetra_MultiVector> Epetra_MV;
|
||||
Teuchos::RCP<Epetra_Operator> Epetra_OP;
|
||||
Teuchos::RCP<Epetra_MultiVector> Epetra_WMV;
|
||||
Teuchos::RCP<const Epetra_Map> MV_localmap;
|
||||
Teuchos::RCP<const Epetra_BlockMap> MV_blockmap;
|
||||
};
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Implementation of the Anasazi::MultiVecTraits for Epetra::MultiVector.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*!
|
||||
\brief Template specialization of Anasazi::MultiVecTraits class using the Epetra_MultiVector class.
|
||||
|
||||
This interface will ensure that any Epetra_MultiVector will be accepted by the Anasazi
|
||||
templated solvers.
|
||||
|
||||
\note The Epetra package performs double-precision arithmetic, so the use of Epetra with Anasazi will
|
||||
only provide a double-precision eigensolver.
|
||||
*/
|
||||
|
||||
template<>
|
||||
class MultiVecTraits<double, Epetra_MultiVector>
|
||||
{
|
||||
public:
|
||||
|
||||
//! @name Creation methods
|
||||
//@{
|
||||
|
||||
/*! \brief Creates a new empty Epetra_MultiVector containing \c numvecs columns.
|
||||
|
||||
\return Reference-counted pointer to the new Epetra_MultiVector.
|
||||
*/
|
||||
static Teuchos::RCP<Epetra_MultiVector> Clone( const Epetra_MultiVector& mv, const int numvecs )
|
||||
{ return Teuchos::rcp( new Epetra_MultiVector(mv.Map(), numvecs) ); }
|
||||
|
||||
/*! \brief Creates a new Epetra_MultiVector and copies contents of \c mv into the new vector (deep copy).
|
||||
|
||||
\return Reference-counted pointer to the new Epetra_MultiVector.
|
||||
*/
|
||||
static Teuchos::RCP<Epetra_MultiVector> CloneCopy( const Epetra_MultiVector& mv )
|
||||
{ return Teuchos::rcp( new Epetra_MultiVector( mv ) ); }
|
||||
|
||||
/*! \brief Creates a new Epetra_MultiVector and copies the selected contents of \c mv into the new vector (deep copy).
|
||||
|
||||
The copied vectors from \c mv are indicated by the \c indeX.size() indices in \c index.
|
||||
\return Reference-counted pointer to the new Epetra_MultiVector.
|
||||
*/
|
||||
static Teuchos::RCP<Epetra_MultiVector> CloneCopy( const Epetra_MultiVector& mv, const std::vector<int>& index )
|
||||
{
|
||||
std::vector<int>& tmp_index = const_cast<std::vector<int> &>( index );
|
||||
return Teuchos::rcp( new Epetra_MultiVector(::Copy, mv, &tmp_index[0], index.size()) );
|
||||
}
|
||||
|
||||
/*! \brief Creates a new Epetra_MultiVector that shares the selected contents of \c mv (shallow copy).
|
||||
|
||||
The index of the \c numvecs vectors shallow copied from \c mv are indicated by the indices given in \c index.
|
||||
\return Reference-counted pointer to the new Epetra_MultiVector.
|
||||
*/
|
||||
static Teuchos::RCP<Epetra_MultiVector> CloneView( Epetra_MultiVector& mv, const std::vector<int>& index )
|
||||
{
|
||||
std::vector<int>& tmp_index = const_cast<std::vector<int> &>( index );
|
||||
return Teuchos::rcp( new Epetra_MultiVector(::View, mv, &tmp_index[0], index.size()) );
|
||||
}
|
||||
|
||||
/*! \brief Creates a new const Epetra_MultiVector that shares the selected contents of \c mv (shallow copy).
|
||||
|
||||
The index of the \c numvecs vectors shallow copied from \c mv are indicated by the indices given in \c index.
|
||||
\return Reference-counted pointer to the new const Epetra_MultiVector.
|
||||
*/
|
||||
static Teuchos::RCP<const Epetra_MultiVector> CloneView( const Epetra_MultiVector& mv, const std::vector<int>& index )
|
||||
{
|
||||
std::vector<int>& tmp_index = const_cast<std::vector<int> &>( index );
|
||||
return Teuchos::rcp( new Epetra_MultiVector(::View, mv, &tmp_index[0], index.size()) );
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Attribute methods
|
||||
//@{
|
||||
|
||||
//! Obtain the vector length of \c mv.
|
||||
static int GetVecLength( const Epetra_MultiVector& mv )
|
||||
{ return mv.GlobalLength(); }
|
||||
|
||||
//! Obtain the number of vectors in \c mv
|
||||
static int GetNumberVecs( const Epetra_MultiVector& mv )
|
||||
{ return mv.NumVectors(); }
|
||||
//@}
|
||||
|
||||
//! @name Update methods
|
||||
//@{
|
||||
|
||||
/*! \brief Update \c mv with \f$ \alpha AB + \beta mv \f$.
|
||||
*/
|
||||
static void MvTimesMatAddMv( double alpha, const Epetra_MultiVector& A,
|
||||
const Teuchos::SerialDenseMatrix<int,double>& B,
|
||||
double beta, Epetra_MultiVector& mv )
|
||||
{
|
||||
Epetra_LocalMap LocalMap(B.numRows(), 0, mv.Map().Comm());
|
||||
Epetra_MultiVector B_Pvec(::Copy, LocalMap, B.values(), B.stride(), B.numCols());
|
||||
|
||||
TEST_FOR_EXCEPTION( mv.Multiply( 'N', 'N', alpha, A, B_Pvec, beta )!=0, EpetraMultiVecFailure,
|
||||
"MultiVecTraits<double, Epetra_MultiVector>::MvNorm call to Epetra_MultiVector::Multiply() returned a nonzero value.");
|
||||
}
|
||||
|
||||
/*! \brief Replace \c mv with \f$\alpha A + \beta B\f$.
|
||||
*/
|
||||
static void MvAddMv( double alpha, const Epetra_MultiVector& A, double beta, const Epetra_MultiVector& B, Epetra_MultiVector& mv )
|
||||
{
|
||||
TEST_FOR_EXCEPTION( mv.Update( alpha, A, beta, B, 0.0 )!=0, EpetraMultiVecFailure,
|
||||
"MultiVecTraits<double, Epetra_MultiVector>::MvAddMv call to Epetra_MultiVector::Update() returned a nonzero value.");
|
||||
}
|
||||
|
||||
/*! \brief Compute a dense matrix \c B through the matrix-matrix multiply \f$ \alpha A^Tmv \f$.
|
||||
*/
|
||||
static void MvTransMv( double alpha, const Epetra_MultiVector& A, const Epetra_MultiVector& mv, Teuchos::SerialDenseMatrix<int,double>& B
|
||||
#ifdef HAVE_ANASAZI_EXPERIMENTAL
|
||||
, ConjType conj = Anasazi::CONJ
|
||||
#endif
|
||||
)
|
||||
{
|
||||
Epetra_LocalMap LocalMap(B.numRows(), 0, mv.Map().Comm());
|
||||
Epetra_MultiVector B_Pvec(::View, LocalMap, B.values(), B.stride(), B.numCols());
|
||||
|
||||
TEST_FOR_EXCEPTION( B_Pvec.Multiply( 'T', 'N', alpha, A, mv, 0.0 )!=0, EpetraMultiVecFailure,
|
||||
"MultiVecTraits<double, Epetra_MultiVector>::MvTransMv call to Epetra_MultiVector::Multiply() returned a nonzero value.");
|
||||
}
|
||||
|
||||
/*! \brief Compute a vector \c b where the components are the individual dot-products of the \c i-th columns of \c A and \c mv, i.e.\f$b[i] = A[i]^Tmv[i]\f$.
|
||||
*/
|
||||
static void MvDot( const Epetra_MultiVector& mv, const Epetra_MultiVector& A, std::vector<double>* b
|
||||
#ifdef HAVE_ANASAZI_EXPERIMENTAL
|
||||
, ConjType conj = Anasazi::CONJ
|
||||
#endif
|
||||
)
|
||||
{
|
||||
TEST_FOR_EXCEPTION( mv.Dot( A, &(*b)[0] )!=0, EpetraMultiVecFailure,
|
||||
"MultiVecTraits<double, Epetra_MultiVector>::MvDot call to Epetra_MultiVector::Dot() returned a nonzero value.");
|
||||
}
|
||||
|
||||
//@}
|
||||
//! @name Norm method
|
||||
//@{
|
||||
|
||||
/*! \brief Compute the 2-norm of each individual vector of \c mv.
|
||||
Upon return, \c normvec[i] holds the value of \f$||mv_i||_2\f$, the \c i-th column of \c mv.
|
||||
*/
|
||||
static void MvNorm( const Epetra_MultiVector& mv, std::vector<double>* normvec )
|
||||
{
|
||||
TEST_FOR_EXCEPTION( mv.Norm2(&(*normvec)[0])!=0, EpetraMultiVecFailure,
|
||||
"MultiVecTraits<double, Epetra_MultiVector>::MvNorm call to Epetra_MultiVector::Norm2() returned a nonzero value.");
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Initialization methods
|
||||
//@{
|
||||
/*! \brief Copy the vectors in \c A to a set of vectors in \c mv indicated by the indices given in \c index.
|
||||
*/
|
||||
static void SetBlock( const Epetra_MultiVector& A, const std::vector<int>& index, Epetra_MultiVector& mv )
|
||||
{
|
||||
// Extract the "numvecs" columns of mv indicated by the index vector.
|
||||
int numvecs = index.size();
|
||||
std::vector<int>& tmp_index = const_cast<std::vector<int> &>( index );
|
||||
Epetra_MultiVector temp_vec(::View, mv, &tmp_index[0], numvecs);
|
||||
|
||||
if ( A.NumVectors() != numvecs ) {
|
||||
std::vector<int> index2( numvecs );
|
||||
for(int i=0; i<numvecs; i++)
|
||||
index2[i] = i;
|
||||
Epetra_MultiVector A_vec(::View, A, &index2[0], numvecs);
|
||||
TEST_FOR_EXCEPTION( temp_vec.Update( 1.0, A_vec, 0.0, A_vec, 0.0 )!=0, EpetraMultiVecFailure,
|
||||
"MultiVecTraits<double, Epetra_MultiVector>::SetBlock call to Epetra_MultiVector::Update() returned a nonzero value.");
|
||||
}
|
||||
else {
|
||||
TEST_FOR_EXCEPTION( temp_vec.Update( 1.0, A, 0.0, A, 0.0 )!=0, EpetraMultiVecFailure,
|
||||
"MultiVecTraits<double, Epetra_MultiVector>::SetBlock call to Epetra_MultiVector::Update() returned a nonzero value.");
|
||||
}
|
||||
}
|
||||
|
||||
/*! \brief Scale each element of the vectors in \c mv with \c alpha.
|
||||
*/
|
||||
static void MvScale ( Epetra_MultiVector& mv, double alpha )
|
||||
{
|
||||
TEST_FOR_EXCEPTION( mv.Scale( alpha )!=0, EpetraMultiVecFailure,
|
||||
"MultiVecTraits<double, Epetra_MultiVector>::MvScale call to Epetra_MultiVector::Scale() returned a nonzero value.");
|
||||
}
|
||||
|
||||
/*! \brief Scale each element of the \c i-th vector in \c mv with \c alpha[i].
|
||||
*/
|
||||
static void MvScale ( Epetra_MultiVector& mv, const std::vector<double>& alpha )
|
||||
{
|
||||
// Check to make sure the vector is as long as the multivector has columns.
|
||||
int numvecs = mv.NumVectors();
|
||||
TEST_FOR_EXCEPTION( (int)alpha.size() != numvecs, std::invalid_argument,
|
||||
"MultiVecTraits<double, Epetra_MultiVector>::MvScale(MV mv,vector alpha) alpha argument size was inconsistent with number of vectors in mv.")
|
||||
|
||||
std::vector<int> tmp_index( 1, 0 );
|
||||
for (int i=0; i<numvecs; i++) {
|
||||
Epetra_MultiVector temp_vec(::View, mv, &tmp_index[0], 1);
|
||||
TEST_FOR_EXCEPTION( temp_vec.Scale( alpha[i] )!=0, EpetraMultiVecFailure,
|
||||
"MultiVecTraits<double, Epetra_MultiVector>::MvScale call to Epetra_MultiVector::Scale() returned a nonzero value.");
|
||||
tmp_index[0]++;
|
||||
}
|
||||
}
|
||||
|
||||
/*! \brief Replace the vectors in \c mv with random vectors.
|
||||
*/
|
||||
static void MvRandom( Epetra_MultiVector& mv )
|
||||
{
|
||||
TEST_FOR_EXCEPTION( mv.Random()!=0, EpetraMultiVecFailure,
|
||||
"MultiVecTraits<double, Epetra_MultiVector>::MvRandom call to Epetra_MultiVector::Random() returned a nonzero value.");
|
||||
}
|
||||
|
||||
/*! \brief Replace each element of the vectors in \c mv with \c alpha.
|
||||
*/
|
||||
static void MvInit( Epetra_MultiVector& mv, double alpha = Teuchos::ScalarTraits<double>::zero() )
|
||||
{
|
||||
TEST_FOR_EXCEPTION( mv.PutScalar(alpha)!=0, EpetraMultiVecFailure,
|
||||
"MultiVecTraits<double, Epetra_MultiVector>::MvInit call to Epetra_MultiVector::PutScalar() returned a nonzero value.");
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Print method
|
||||
//@{
|
||||
|
||||
/*! \brief Print the \c mv multi-vector to the \c os output stream.
|
||||
*/
|
||||
static void MvPrint( const Epetra_MultiVector& mv, std::ostream& os )
|
||||
{ os << mv << std::endl; }
|
||||
|
||||
//@}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Implementation of the Anasazi::OperatorTraits for Epetra::Operator.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*!
|
||||
\brief Template specialization of Anasazi::OperatorTraits class using the Epetra_Operator virtual base class and
|
||||
Epetra_MultiVector class.
|
||||
|
||||
This interface will ensure that any Epetra_Operator and Epetra_MultiVector will be accepted by the Anasazi
|
||||
templated solvers.
|
||||
|
||||
\note The Epetra package performs double-precision arithmetic, so the use of Epetra with Anasazi will
|
||||
only provide a double-precision eigensolver.
|
||||
*/
|
||||
|
||||
template <>
|
||||
class OperatorTraits < double, Epetra_MultiVector, Epetra_Operator >
|
||||
{
|
||||
public:
|
||||
|
||||
/*! \brief This method takes the Epetra_MultiVector \c x and
|
||||
applies the Epetra_Operator \c Op to it resulting in the Epetra_MultiVector \c y.
|
||||
*/
|
||||
static void Apply ( const Epetra_Operator& Op,
|
||||
const Epetra_MultiVector& x,
|
||||
Epetra_MultiVector& y )
|
||||
{
|
||||
TEST_FOR_EXCEPTION( Op.Apply( x, y ) != 0, OperatorError, "Error in Epetra_Operator::Apply()!" );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // end of Anasazi namespace
|
||||
|
||||
#endif
|
||||
// end of file ANASAZI_EPETRA_ADAPTER_HPP
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,797 @@
|
||||
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
|
||||
#ifndef ANASAZI_LOBPCG_SOLMGR_HPP
|
||||
#define ANASAZI_LOBPCG_SOLMGR_HPP
|
||||
|
||||
/*! \file AnasaziLOBPCGSolMgr.hpp
|
||||
* \brief The Anasazi::LOBPCGSolMgr provides a powerful solver manager for the LOBPCG eigensolver.
|
||||
*/
|
||||
|
||||
#include "AnasaziConfigDefs.hpp"
|
||||
#include "AnasaziTypes.hpp"
|
||||
|
||||
#include "AnasaziEigenproblem.hpp"
|
||||
#include "AnasaziSolverManager.hpp"
|
||||
|
||||
#include "AnasaziSolverUtils.hpp"
|
||||
|
||||
#include "AnasaziLOBPCG.hpp"
|
||||
#include "AnasaziBasicSort.hpp"
|
||||
#include "AnasaziSVQBOrthoManager.hpp"
|
||||
#include "AnasaziStatusTestMaxIters.hpp"
|
||||
#include "AnasaziStatusTestResNorm.hpp"
|
||||
#include "AnasaziStatusTestOrderedResNorm.hpp"
|
||||
#include "AnasaziStatusTestCombo.hpp"
|
||||
#include "AnasaziStatusTestOutput.hpp"
|
||||
#include "AnasaziBasicOutputManager.hpp"
|
||||
|
||||
|
||||
/** \example LOBPCG/LOBPCGEpetraEx.cpp
|
||||
This is an example of how to use the Anasazi::LOBPCGSolMgr solver manager to solve a standard eigenvalue problem.
|
||||
*/
|
||||
|
||||
/** \example LOBPCG/LOBPCGEpetraExGen.cpp
|
||||
This is an example of how to use the Anasazi::LOBPCGSolMgr solver manager to solve a generalized eigenvalue problem.
|
||||
*/
|
||||
|
||||
|
||||
/*! \class Anasazi::LOBPCGSolMgr
|
||||
*
|
||||
* \brief The Anasazi::LOBPCGSolMgr provides a powerful and fully-featured solver manager over the LOBPCG eigensolver.
|
||||
*
|
||||
* This solver manager exists to provide a flexible manager over the Anasazi::LOBPCG eigensolver intended for general use. Features
|
||||
* provided by this solver manager include:
|
||||
* - locking of converged eigenpairs
|
||||
* - global convergence on only the significant eigenpairs (instead of any eigenpairs with low residual)
|
||||
* - recovery from Anasazi::LOBPCGRitzFailure when full orthogonalization is disabled
|
||||
*
|
||||
* These options are all driven by a list of parameters handed to the solver manager at construction. For more information, see Anasazi::LOBPCGSolMgr::LOBPCGSolMgr().
|
||||
|
||||
\ingroup anasazi_solver_framework
|
||||
|
||||
\author Chris Baker, Ulrich Hetmaniuk, Rich Lehoucq, Heidi Thornquist
|
||||
*/
|
||||
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
template<class ScalarType, class MV, class OP>
|
||||
class LOBPCGSolMgr : public SolverManager<ScalarType,MV,OP> {
|
||||
|
||||
private:
|
||||
typedef MultiVecTraits<ScalarType,MV> MVT;
|
||||
typedef OperatorTraits<ScalarType,MV,OP> OPT;
|
||||
typedef Teuchos::ScalarTraits<ScalarType> SCT;
|
||||
typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
|
||||
typedef Teuchos::ScalarTraits<MagnitudeType> MT;
|
||||
|
||||
public:
|
||||
|
||||
//! @name Constructors/Destructor
|
||||
//@{
|
||||
|
||||
/*! \brief Basic constructor for LOBPCGSolMgr.
|
||||
*
|
||||
* This constructor accepts the Eigenproblem to be solved in addition
|
||||
* to a parameter list of options for the solver manager. These options include the following:
|
||||
* - \c "Which" - a \c string specifying the desired eigenvalues: SM, LM, SR or LR. Default: "SR"
|
||||
* - \c "Block Size" - a \c int specifying the block size to be used by the underlying LOBPCG solver. Default: problem->getNEV()
|
||||
* - \c "Full Ortho" - a \c bool specifying whether the underlying solver should employ the full orthogonalization scheme. Default: true
|
||||
* - \c "Recover" - a \c bool specifying whether the solver manager should attempt to recover in the case of a LOBPCGRitzFailure when full orthogonalization is disabled. Default: true
|
||||
* - \c "Maximum Iterations" - a \c int specifying the maximum number of iterations the underlying solver is allowed to perform. Default: 100
|
||||
* - \c "Verbosity" - a sum of MsgType specifying the verbosity. Default: Anasazi::Errors
|
||||
* - \c "Convergence Tolerance" - a \c MagnitudeType specifying the level that residual norms must reach to decide convergence. Default: machine precision.
|
||||
* - \c "Relative Convergence Tolerance" - a \c bool specifying whether residuals norms should be scaled by their eigenvalues for the purposing of deciding convergence. Default: true
|
||||
* - \c "Use Locking" - a \c bool specifying whether the algorithm should employ locking of converged eigenpairs. Default: false
|
||||
* - \c "Max Locked" - a \c int specifying the maximum number of eigenpairs to be locked. Default: problem->getNEV()
|
||||
* - \c "Locking Quorum" - a \c int specifying the number of eigenpairs that must meet the locking criteria before locking actually occurs. Default: 1
|
||||
* - \c "Locking Tolerance" - a \c MagnitudeType specifying the level that residual norms must reach to decide locking. Default: 0.1*convergence tolerance
|
||||
* - \c "Relative Locking Tolerance" - a \c bool specifying whether residuals norms should be scaled by their eigenvalues for the purposing of deciding locking. Default: true
|
||||
* - \c "Init" - a LOBPCGState<ScalarType,MV> struct used to initialize the LOBPCG eigensolver.
|
||||
*/
|
||||
LOBPCGSolMgr( const Teuchos::RCP<Eigenproblem<ScalarType,MV,OP> > &problem,
|
||||
Teuchos::ParameterList &pl );
|
||||
|
||||
//! Destructor.
|
||||
virtual ~LOBPCGSolMgr() {};
|
||||
//@}
|
||||
|
||||
//! @name Accessor methods
|
||||
//@{
|
||||
|
||||
const Eigenproblem<ScalarType,MV,OP>& getProblem() const {
|
||||
return *problem_;
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Solver application methods
|
||||
//@{
|
||||
|
||||
/*! \brief This method performs possibly repeated calls to the underlying eigensolver's iterate() routine
|
||||
* until the problem has been solved (as decided by the solver manager) or the solver manager decides to
|
||||
* quit.
|
||||
*
|
||||
* This method calls LOBPCG::iterate(), which will return either because a specially constructed status test evaluates to ::Passed
|
||||
* or an exception is thrown.
|
||||
*
|
||||
* A return from LOBPCG::iterate() signifies one of the following scenarios:
|
||||
* - the maximum number of iterations has been exceeded. In this scenario, the solver manager will place\n
|
||||
* all converged eigenpairs into the eigenproblem and return ::Unconverged.
|
||||
* - the locking conditions have been met. In this scenario, some of the current eigenpairs will be removed\n
|
||||
* from the eigensolver and placed into auxiliary storage. The eigensolver will be restarted with the remaining\n
|
||||
* eigenpairs and some random information to replace the removed eigenpairs.
|
||||
* - global convergence has been met. In this case, the most significant NEV eigenpairs in the solver and locked storage \n
|
||||
* have met the convergence criterion. (Here, NEV refers to the number of eigenpairs requested by the Eigenproblem.) \n
|
||||
* In this scenario, the solver manager will return ::Converged.
|
||||
* - an LOBPCGRitzFailure exception has been thrown. If full orthogonalization is enabled and recovery from this exception\n
|
||||
* is requested, the solver manager will attempt to recover from this exception by gathering the current eigenvectors, \n
|
||||
* preconditioned residual, and search directions from the eigensolver, orthogonormalizing the basis composed of these \n
|
||||
* three, projecting the eigenproblem, and restarting the eigensolver with the solution of the project eigenproblem. Any \n
|
||||
* additional failure that occurs during this recovery effort will result in the eigensolver returning ::Unconverged.
|
||||
*
|
||||
* \returns ::ReturnType specifying:
|
||||
* - ::Converged: the eigenproblem was solved to the specification required by the solver manager.
|
||||
* - ::Unconverged: the eigenproblem was not solved to the specification desired by the solver manager
|
||||
*/
|
||||
ReturnType solve();
|
||||
//@}
|
||||
|
||||
private:
|
||||
Teuchos::RCP<Eigenproblem<ScalarType,MV,OP> > problem_;
|
||||
|
||||
std::string whch_;
|
||||
|
||||
MagnitudeType convtol_, locktol_;
|
||||
int maxIters_;
|
||||
bool useLocking_;
|
||||
bool relconvtol_, rellocktol_;
|
||||
int blockSize_;
|
||||
bool fullOrtho_;
|
||||
int maxLocked_;
|
||||
int verbosity_;
|
||||
int lockQuorum_;
|
||||
bool recover_;
|
||||
Teuchos::RCP<LOBPCGState<ScalarType,MV> > state_;
|
||||
};
|
||||
|
||||
|
||||
// Constructor
|
||||
template<class ScalarType, class MV, class OP>
|
||||
LOBPCGSolMgr<ScalarType,MV,OP>::LOBPCGSolMgr(
|
||||
const Teuchos::RCP<Eigenproblem<ScalarType,MV,OP> > &problem,
|
||||
Teuchos::ParameterList &pl ) :
|
||||
problem_(problem),
|
||||
whch_("SR"),
|
||||
convtol_(MT::prec()),
|
||||
maxIters_(100),
|
||||
useLocking_(false),
|
||||
relconvtol_(true),
|
||||
rellocktol_(true),
|
||||
blockSize_(0),
|
||||
fullOrtho_(true),
|
||||
maxLocked_(0),
|
||||
verbosity_(Anasazi::Errors),
|
||||
lockQuorum_(1),
|
||||
recover_(true)
|
||||
{
|
||||
TEST_FOR_EXCEPTION(problem_ == Teuchos::null, std::invalid_argument, "Problem not given to solver manager.");
|
||||
TEST_FOR_EXCEPTION(!problem_->isProblemSet(), std::invalid_argument, "Problem not set.");
|
||||
TEST_FOR_EXCEPTION(!problem_->isHermitian(), std::invalid_argument, "Problem not symmetric.");
|
||||
TEST_FOR_EXCEPTION(problem_->getInitVec() == Teuchos::null,std::invalid_argument, "Problem does not contain initial vectors to clone from.");
|
||||
|
||||
|
||||
// which values to solve for
|
||||
whch_ = pl.get("Which",whch_);
|
||||
TEST_FOR_EXCEPTION(whch_ != "SM" && whch_ != "LM" && whch_ != "SR" && whch_ != "LR",std::invalid_argument, "Invalid sorting string.");
|
||||
|
||||
// convergence tolerance
|
||||
convtol_ = pl.get("Convergence Tolerance",convtol_);
|
||||
relconvtol_ = pl.get("Relative Convergence Tolerance",relconvtol_);
|
||||
|
||||
// locking tolerance
|
||||
useLocking_ = pl.get("Use Locking",useLocking_);
|
||||
rellocktol_ = pl.get("Relative Locking Tolerance",rellocktol_);
|
||||
// default: should be less than convtol_
|
||||
locktol_ = convtol_/10;
|
||||
locktol_ = pl.get("Locking Tolerance",locktol_);
|
||||
|
||||
// maximum number of iterations
|
||||
maxIters_ = pl.get("Maximum Iterations",maxIters_);
|
||||
|
||||
// block size: default is nev()
|
||||
blockSize_ = pl.get("Block Size",problem_->getNEV());
|
||||
TEST_FOR_EXCEPTION(blockSize_ <= 0, std::invalid_argument,
|
||||
"Anasazi::LOBPCGSolMgr: \"Block Size\" must be strictly positive.");
|
||||
|
||||
// max locked: default is nev(), must satisfy maxLocked_ + blockSize_ >= nev
|
||||
if (useLocking_) {
|
||||
maxLocked_ = pl.get("Max Locked",problem_->getNEV());
|
||||
}
|
||||
else {
|
||||
maxLocked_ = 0;
|
||||
}
|
||||
if (maxLocked_ == 0) {
|
||||
useLocking_ = false;
|
||||
}
|
||||
TEST_FOR_EXCEPTION(maxLocked_ < 0, std::invalid_argument,
|
||||
"Anasazi::LOBPCGSolMgr: \"Max Locked\" must be positive.");
|
||||
TEST_FOR_EXCEPTION(maxLocked_ + blockSize_ < problem_->getNEV(),
|
||||
std::invalid_argument,
|
||||
"Anasazi::LOBPCGSolMgr: Not enough storage space for requested number of eigenpairs.");
|
||||
|
||||
if (useLocking_) {
|
||||
lockQuorum_ = pl.get("Locking Quorum",lockQuorum_);
|
||||
TEST_FOR_EXCEPTION(lockQuorum_ <= 0,
|
||||
std::invalid_argument,
|
||||
"Anasazi::LOBPCGSolMgr: \"Locking Quorum\" must be strictly positive.");
|
||||
}
|
||||
|
||||
// full orthogonalization: default true
|
||||
fullOrtho_ = pl.get("Full Ortho",fullOrtho_);
|
||||
|
||||
// verbosity level
|
||||
if (pl.isParameter("Verbosity")) {
|
||||
if (Teuchos::isParameterType<int>(pl,"Verbosity")) {
|
||||
verbosity_ = pl.get("Verbosity", verbosity_);
|
||||
} else {
|
||||
verbosity_ = (int)Teuchos::getParameter<Anasazi::MsgType>(pl,"Verbosity");
|
||||
}
|
||||
}
|
||||
|
||||
// recover from LOBPCGRitzFailure
|
||||
recover_ = pl.get("Recover",recover_);
|
||||
|
||||
// get (optionally) an initial state
|
||||
if (pl.isParameter("Init")) {
|
||||
state_ = Teuchos::getParameter<Teuchos::RCP<Anasazi::LOBPCGState<ScalarType,MV> > >(pl,"Init");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// solve()
|
||||
template<class ScalarType, class MV, class OP>
|
||||
ReturnType
|
||||
LOBPCGSolMgr<ScalarType,MV,OP>::solve() {
|
||||
|
||||
const int nev = problem_->getNEV();
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Sort manager
|
||||
Teuchos::RCP<BasicSort<ScalarType,MV,OP> > sorter = Teuchos::rcp( new BasicSort<ScalarType,MV,OP>(whch_) );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Output manager
|
||||
Teuchos::RCP<BasicOutputManager<ScalarType> > printer = Teuchos::rcp( new BasicOutputManager<ScalarType>(verbosity_) );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Status tests
|
||||
//
|
||||
// maximum number of iterations: optional test
|
||||
Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > maxtest;
|
||||
if (maxIters_ > 0) {
|
||||
maxtest = Teuchos::rcp( new StatusTestMaxIters<ScalarType,MV,OP>(maxIters_) );
|
||||
}
|
||||
// convergence
|
||||
Teuchos::RCP<StatusTestOrderedResNorm<ScalarType,MV,OP> > convtest
|
||||
= Teuchos::rcp( new StatusTestOrderedResNorm<ScalarType,MV,OP>(sorter,convtol_,nev,StatusTestOrderedResNorm<ScalarType,MV,OP>::RES_ORTH,relconvtol_) );
|
||||
// locking
|
||||
Teuchos::RCP<StatusTestResNorm<ScalarType,MV,OP> > locktest;
|
||||
if (useLocking_) {
|
||||
locktest = Teuchos::rcp( new StatusTestResNorm<ScalarType,MV,OP>(locktol_,lockQuorum_,StatusTestResNorm<ScalarType,MV,OP>::RES_ORTH,rellocktol_) );
|
||||
}
|
||||
Teuchos::Array<Teuchos::RCP<StatusTest<ScalarType,MV,OP> > > alltests;
|
||||
// for an OR test, the order doesn't matter
|
||||
alltests.push_back(convtest);
|
||||
if (maxtest != Teuchos::null) alltests.push_back(maxtest);
|
||||
if (locktest != Teuchos::null) alltests.push_back(locktest);
|
||||
// combo: convergence || locking || max iters
|
||||
Teuchos::RCP<StatusTestCombo<ScalarType,MV,OP> > combotest
|
||||
= Teuchos::rcp( new StatusTestCombo<ScalarType,MV,OP>( StatusTestCombo<ScalarType,MV,OP>::OR, alltests) );
|
||||
// printing StatusTest
|
||||
Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputtest;
|
||||
if ( printer->isVerbosity(Debug) ) {
|
||||
outputtest = Teuchos::rcp( new StatusTestOutput<ScalarType,MV,OP>( printer,combotest,1,Passed+Failed+Undefined ) );
|
||||
}
|
||||
else {
|
||||
outputtest = Teuchos::rcp( new StatusTestOutput<ScalarType,MV,OP>( printer,combotest,1,Passed ) );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Orthomanager
|
||||
Teuchos::RCP<SVQBOrthoManager<ScalarType,MV,OP> > ortho
|
||||
= Teuchos::rcp( new SVQBOrthoManager<ScalarType,MV,OP>(problem_->getM()) );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Parameter list
|
||||
Teuchos::ParameterList plist;
|
||||
plist.set("Block Size",blockSize_);
|
||||
plist.set("Full Ortho",fullOrtho_);
|
||||
|
||||
// utils
|
||||
SolverUtils<ScalarType,MV,OP> msutils;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// LOBPCG solver
|
||||
Teuchos::RCP<LOBPCG<ScalarType,MV,OP> > lobpcg_solver
|
||||
= Teuchos::rcp( new LOBPCG<ScalarType,MV,OP>(problem_,sorter,printer,outputtest,ortho,plist) );
|
||||
// set any auxiliary vectors defined in the problem
|
||||
Teuchos::RCP< const MV > probauxvecs = problem_->getAuxVecs();
|
||||
if (probauxvecs != Teuchos::null) {
|
||||
lobpcg_solver->setAuxVecs( Teuchos::tuple< Teuchos::RCP<const MV> >(probauxvecs) );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Storage
|
||||
//
|
||||
// lockvecs will contain eigenvectors that have been determined "locked" by the status test
|
||||
int numlocked = 0;
|
||||
Teuchos::RCP<MV> lockvecs;
|
||||
if (useLocking_) {
|
||||
lockvecs = MVT::Clone(*problem_->getInitVec(),maxLocked_);
|
||||
}
|
||||
std::vector<MagnitudeType> lockvals;
|
||||
// workMV will be used as work space for LOBPCGRitzFailure recovery and locking
|
||||
// it will be partitioned in these cases as follows:
|
||||
// for LOBPCGRitzFailure recovery:
|
||||
// workMV = [X H P OpX OpH OpP], where OpX OpH OpP will be used for K and M
|
||||
// total size: 2*3*blocksize
|
||||
// for locking
|
||||
// workMV = [X P MX MP], with MX,MP needing storage only if hasM==true
|
||||
// total size: 2*blocksize or 4*blocksize
|
||||
Teuchos::RCP<MV> workMV;
|
||||
if (fullOrtho_ == false && recover_ == true) {
|
||||
workMV = MVT::Clone(*problem_->getInitVec(),2*3*blockSize_);
|
||||
}
|
||||
else if (useLocking_) {
|
||||
if (problem_->getM() != Teuchos::null) {
|
||||
workMV = MVT::Clone(*problem_->getInitVec(),4*blockSize_);
|
||||
}
|
||||
else {
|
||||
workMV = MVT::Clone(*problem_->getInitVec(),2*blockSize_);
|
||||
}
|
||||
}
|
||||
|
||||
// initialize the solution to nothing in case we throw an exception
|
||||
Eigensolution<ScalarType,MV> sol;
|
||||
sol.numVecs = 0;
|
||||
problem_->setSolution(sol);
|
||||
|
||||
// initialize the solver if the user specified a state
|
||||
if (state_ != Teuchos::null) {
|
||||
lobpcg_solver->initialize(*state_);
|
||||
}
|
||||
|
||||
// tell the lobpcg_solver to iterate
|
||||
while (1) {
|
||||
try {
|
||||
lobpcg_solver->iterate();
|
||||
|
||||
// check convergence first
|
||||
if (convtest->getStatus() == Passed || (maxtest != Teuchos::null && maxtest->getStatus() == Passed) ) {
|
||||
// we have convergence or not
|
||||
// convtest->whichVecs() tells us which vectors from lockvecs and solver->getRitzVectors() are the ones we want
|
||||
// convtest->howMany() will tell us how many
|
||||
break;
|
||||
}
|
||||
// check locking if we didn't converge
|
||||
else if (locktest != Teuchos::null && locktest->getStatus() == Passed) {
|
||||
|
||||
// remove the locked vectors,values from lobpcg_solver: put them in newvecs, newvals
|
||||
int numnew = locktest->howMany();
|
||||
TEST_FOR_EXCEPTION(numnew <= 0,std::logic_error,"Anasazi::LOBPCGSolMgr::solve(): status test mistake.");
|
||||
// get the indices
|
||||
std::vector<int> indnew = locktest->whichVecs();
|
||||
|
||||
// don't lock more than maxLocked_; we didn't allocate enough space.
|
||||
if (numlocked + numnew > maxLocked_) {
|
||||
numnew = maxLocked_ - numlocked;
|
||||
indnew.resize(numnew);
|
||||
}
|
||||
|
||||
// the call below to lobpcg_solver->setAuxVecs() will reset the solver to unitialized with hasP() == false
|
||||
// store the hasP() state for use below
|
||||
bool hadP = lobpcg_solver->hasP();
|
||||
|
||||
{
|
||||
// debug printing
|
||||
printer->print(Debug,"Locking vectors: ");
|
||||
for (unsigned int i=0; i<indnew.size(); i++) {printer->stream(Debug) << " " << indnew[i];}
|
||||
printer->print(Debug,"\n");
|
||||
}
|
||||
std::vector<MagnitudeType> newvals(numnew);
|
||||
Teuchos::RCP<const MV> newvecs;
|
||||
{
|
||||
// work in a local scope, to hide the variabes needed for extracting this info
|
||||
// get the vectors
|
||||
newvecs = MVT::CloneView(*lobpcg_solver->getRitzVectors(),indnew);
|
||||
// get the values
|
||||
std::vector<Value<ScalarType> > allvals = lobpcg_solver->getRitzValues();
|
||||
for (int i=0; i<numnew; i++) {
|
||||
newvals[i] = allvals[indnew[i]].realpart;
|
||||
}
|
||||
}
|
||||
// put newvecs into lockvecs
|
||||
{
|
||||
std::vector<int> indlock(numnew);
|
||||
for (int i=0; i<numnew; i++) indlock[i] = numlocked+i;
|
||||
MVT::SetBlock(*newvecs,indlock,*lockvecs);
|
||||
newvecs = Teuchos::null;
|
||||
}
|
||||
// put newvals into lockvals
|
||||
lockvals.insert(lockvals.end(),newvals.begin(),newvals.end());
|
||||
numlocked += numnew;
|
||||
// add locked vecs as aux vecs, along with aux vecs from problem
|
||||
{
|
||||
std::vector<int> indlock(numlocked);
|
||||
for (int i=0; i<numlocked; i++) indlock[i] = i;
|
||||
Teuchos::RCP<const MV> curlocked = MVT::CloneView(*lockvecs,indlock);
|
||||
if (probauxvecs != Teuchos::null) {
|
||||
lobpcg_solver->setAuxVecs( Teuchos::tuple< Teuchos::RCP<const MV> >(probauxvecs,curlocked) );
|
||||
}
|
||||
else {
|
||||
lobpcg_solver->setAuxVecs( Teuchos::tuple< Teuchos::RCP<const MV> >(curlocked) );
|
||||
}
|
||||
}
|
||||
// add locked vals to convtest
|
||||
convtest->setAuxVals(lockvals);
|
||||
// fill out the empty state in the solver
|
||||
{
|
||||
LOBPCGState<ScalarType,MV> state = lobpcg_solver->getState();
|
||||
Teuchos::RCP<MV> newstateX, newstateMX, newstateP, newstateMP;
|
||||
//
|
||||
// workMV will be partitioned as follows: workMV = [X P MX MP],
|
||||
//
|
||||
// make a copy of the current X,MX state
|
||||
std::vector<int> bsind(blockSize_);
|
||||
for (int i=0; i<blockSize_; i++) bsind[i] = i;
|
||||
newstateX = MVT::CloneView(*workMV,bsind);
|
||||
MVT::SetBlock(*state.X,bsind,*newstateX);
|
||||
|
||||
if (state.MX != Teuchos::null) {
|
||||
std::vector<int> block3(blockSize_);
|
||||
for (int i=0; i<blockSize_; i++) block3[i] = 2*blockSize_+i;
|
||||
newstateMX = MVT::CloneView(*workMV,block3);
|
||||
MVT::SetBlock(*state.MX,bsind,*newstateMX);
|
||||
}
|
||||
//
|
||||
// get select part, set to random, apply M
|
||||
{
|
||||
Teuchos::RCP<MV> newX = MVT::CloneView(*newstateX,indnew);
|
||||
MVT::MvRandom(*newX);
|
||||
|
||||
if (newstateMX != Teuchos::null) {
|
||||
Teuchos::RCP<MV> newMX = MVT::CloneView(*newstateMX,indnew);
|
||||
OPT::Apply(*problem_->getM(),*newX,*newMX);
|
||||
}
|
||||
}
|
||||
|
||||
Teuchos::Array<Teuchos::RCP<const MV> > curauxvecs = lobpcg_solver->getAuxVecs();
|
||||
Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > dummy;
|
||||
// ortho X against the aux vectors
|
||||
ortho->projectAndNormalizeMat(*newstateX,newstateMX,dummy,Teuchos::null,curauxvecs);
|
||||
|
||||
if (hadP) {
|
||||
//
|
||||
// get P and optionally MP, orthogonalize against X and auxiliary vectors
|
||||
std::vector<int> block2(blockSize_);
|
||||
for (int i=0; i<blockSize_; i++) block2[i] = blockSize_+i;
|
||||
newstateP = MVT::CloneView(*workMV,block2);
|
||||
MVT::SetBlock(*state.P,bsind,*newstateP);
|
||||
|
||||
if (state.MP != Teuchos::null) {
|
||||
std::vector<int> block4(blockSize_);
|
||||
for (int i=0; i<blockSize_; i++) block4[i] = 3*blockSize_+i;
|
||||
newstateMP = MVT::CloneView(*workMV,block4);
|
||||
MVT::SetBlock(*state.MP,bsind,*newstateMP);
|
||||
}
|
||||
|
||||
if (fullOrtho_) {
|
||||
// ortho P against the new aux vectors and new X
|
||||
curauxvecs.push_back(newstateX);
|
||||
ortho->projectAndNormalizeMat(*newstateP,newstateMP,dummy,Teuchos::null,curauxvecs);
|
||||
}
|
||||
else {
|
||||
// ortho P against the new aux vectors
|
||||
ortho->projectAndNormalizeMat(*newstateP,newstateMP,dummy,Teuchos::null,curauxvecs);
|
||||
}
|
||||
}
|
||||
// set the new state
|
||||
LOBPCGState<ScalarType,MV> newstate;
|
||||
newstate.X = newstateX;
|
||||
newstate.MX = newstateMX;
|
||||
newstate.P = newstateP;
|
||||
newstate.MP = newstateMP;
|
||||
lobpcg_solver->initialize(newstate);
|
||||
}
|
||||
|
||||
if (numlocked == maxLocked_) {
|
||||
// disabled locking now
|
||||
locktest->setQuorum(blockSize_+1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
TEST_FOR_EXCEPTION(true,std::logic_error,"Anasazi::LOBPCGSolMgr::solve(): Invalid return from lobpcg_solver::iterate().");
|
||||
}
|
||||
}
|
||||
catch (LOBPCGRitzFailure re) {
|
||||
if (fullOrtho_==true || recover_==false) {
|
||||
// if we are already using full orthogonalization, there isn't much we can do here.
|
||||
// the most recent information in the status tests is still valid, and can be used to extract/return the
|
||||
// eigenpairs that have converged.
|
||||
printer->stream(Warnings) << "Error! Caught LOBPCGRitzFailure at iteration " << lobpcg_solver->getNumIters() << std::endl
|
||||
<< "Will not try to recover." << std::endl;
|
||||
break; // while(1)
|
||||
}
|
||||
printer->stream(Warnings) << "Error! Caught LOBPCGRitzFailure at iteration " << lobpcg_solver->getNumIters() << std::endl
|
||||
<< "Full orthogonalization is off; will try to recover." << std::endl;
|
||||
// get the current "basis" from the solver, orthonormalize it, do a rayleigh-ritz, and restart with the ritz vectors
|
||||
// if there aren't enough, break and quit with what we have
|
||||
//
|
||||
// workMV = [X H P OpX OpH OpP], where OpX OpH OpP will be used for K and M
|
||||
LOBPCGState<ScalarType,MV> curstate = lobpcg_solver->getState();
|
||||
Teuchos::RCP<MV> restart, Krestart, Mrestart;
|
||||
int localsize = lobpcg_solver->hasP() ? 3*blockSize_ : 2*blockSize_;
|
||||
bool hasM = problem_->getM() != Teuchos::null;
|
||||
{
|
||||
std::vector<int> recind(localsize);
|
||||
for (int i=0; i<localsize; i++) recind[i] = i;
|
||||
restart = MVT::CloneView(*workMV,recind);
|
||||
}
|
||||
{
|
||||
std::vector<int> recind(localsize);
|
||||
for (int i=0; i<localsize; i++) recind[i] = localsize+i;
|
||||
Krestart = MVT::CloneView(*workMV,recind);
|
||||
}
|
||||
if (hasM) {
|
||||
Mrestart = Krestart;
|
||||
}
|
||||
else {
|
||||
Mrestart = restart;
|
||||
}
|
||||
//
|
||||
// set restart = [X H P] and Mrestart = M*[X H P]
|
||||
//
|
||||
// put X into [0 , blockSize)
|
||||
{
|
||||
std::vector<int> blk1(blockSize_);
|
||||
for (int i=0; i < blockSize_; i++) blk1[i] = i;
|
||||
MVT::SetBlock(*curstate.X,blk1,*restart);
|
||||
|
||||
// put MX into [0 , blockSize)
|
||||
if (hasM) {
|
||||
MVT::SetBlock(*curstate.MX,blk1,*Mrestart);
|
||||
}
|
||||
}
|
||||
//
|
||||
// put H into [blockSize_ , 2*blockSize)
|
||||
{
|
||||
std::vector<int> blk2(blockSize_);
|
||||
for (int i=0; i < blockSize_; i++) blk2[i] = blockSize_+i;
|
||||
MVT::SetBlock(*curstate.H,blk2,*restart);
|
||||
|
||||
// put MH into [blockSize_ , 2*blockSize)
|
||||
if (hasM) {
|
||||
MVT::SetBlock(*curstate.MH,blk2,*Mrestart);
|
||||
}
|
||||
}
|
||||
// optionally, put P into [2*blockSize,3*blockSize)
|
||||
if (localsize == 3*blockSize_) {
|
||||
std::vector<int> blk3(blockSize_);
|
||||
for (int i=0; i < blockSize_; i++) blk3[i] = 2*blockSize_+i;
|
||||
MVT::SetBlock(*curstate.P,blk3,*restart);
|
||||
|
||||
// put MP into [2*blockSize,3*blockSize)
|
||||
if (hasM) {
|
||||
MVT::SetBlock(*curstate.MP,blk3,*Mrestart);
|
||||
}
|
||||
}
|
||||
// project against auxvecs and locked vecs, and orthonormalize the basis
|
||||
Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > dummy;
|
||||
Teuchos::Array<Teuchos::RCP<const MV> > Q;
|
||||
{
|
||||
if (numlocked > 0) {
|
||||
std::vector<int> indlock(numlocked);
|
||||
for (int i=0; i<numlocked; i++) indlock[i] = i;
|
||||
Teuchos::RCP<const MV> curlocked = MVT::CloneView(*lockvecs,indlock);
|
||||
Q.push_back(curlocked);
|
||||
}
|
||||
if (probauxvecs != Teuchos::null) {
|
||||
Q.push_back(probauxvecs);
|
||||
}
|
||||
}
|
||||
int rank = ortho->projectAndNormalizeMat(*restart,Mrestart,dummy,Teuchos::null,Q);
|
||||
if (rank < blockSize_) {
|
||||
// quit
|
||||
printer->stream(Errors) << "Error! Recovered basis only rank " << rank << ". Block size is " << blockSize_ << ".\n"
|
||||
<< "Recovery failed." << std::endl;
|
||||
break;
|
||||
}
|
||||
// reduce multivec size if necessary
|
||||
if (rank < localsize) {
|
||||
localsize = rank;
|
||||
std::vector<int> redind(localsize);
|
||||
for (int i=0; i<localsize; i++) redind[i] = i;
|
||||
// grab the first part of restart,Krestart
|
||||
restart = MVT::CloneView(*restart,redind);
|
||||
Krestart = MVT::CloneView(*Krestart,redind);
|
||||
if (hasM) {
|
||||
Mrestart = Krestart;
|
||||
}
|
||||
else {
|
||||
Mrestart = restart;
|
||||
}
|
||||
}
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> KK(localsize,localsize), MM(localsize,localsize), S(localsize,localsize);
|
||||
std::vector<MagnitudeType> theta(localsize);
|
||||
// project the matrices
|
||||
//
|
||||
// MM = restart^H M restart
|
||||
MVT::MvTransMv(1.0,*restart,*Mrestart,MM);
|
||||
//
|
||||
// compute Krestart = K*restart
|
||||
OPT::Apply(*problem_->getOperator(),*restart,*Krestart);
|
||||
//
|
||||
// KK = restart^H K restart
|
||||
MVT::MvTransMv(1.0,*restart,*Krestart,KK);
|
||||
rank = localsize;
|
||||
msutils.directSolver(localsize,KK,Teuchos::rcp(&MM,false),S,theta,rank,1);
|
||||
if (rank < blockSize_) {
|
||||
printer->stream(Errors) << "Error! Recovered basis of rank " << rank << " produced only " << rank << "ritz vectors.\n"
|
||||
<< "Block size is " << blockSize_ << ".\n"
|
||||
<< "Recovery failed." << std::endl;
|
||||
break;
|
||||
}
|
||||
theta.resize(rank);
|
||||
//
|
||||
// sort the ritz values using the sort manager
|
||||
{
|
||||
Teuchos::BLAS<int,ScalarType> blas;
|
||||
std::vector<int> order(rank);
|
||||
// sort
|
||||
sorter->sort( lobpcg_solver.get(), rank, theta, &order ); // don't catch exception
|
||||
// Sort the primitive ritz vectors
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> curS(Teuchos::View,S,rank,rank);
|
||||
msutils.permuteVectors(order,curS);
|
||||
}
|
||||
//
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> S1(Teuchos::View,S,localsize,blockSize_);
|
||||
//
|
||||
// compute the ritz vectors: store them in Krestart
|
||||
LOBPCGState<ScalarType,MV> newstate;
|
||||
Teuchos::RCP<MV> newX;
|
||||
{
|
||||
std::vector<int> bsind(blockSize_);
|
||||
for (int i=0; i<blockSize_; i++) bsind[i] = i;
|
||||
newX = MVT::CloneView(*Krestart,bsind);
|
||||
}
|
||||
MVT::MvTimesMatAddMv(1.0,*restart,S1,0.0,*newX);
|
||||
// send X and theta into the solver
|
||||
newstate.X = newX;
|
||||
theta.resize(blockSize_);
|
||||
newstate.T = Teuchos::rcp( &theta, false );
|
||||
// initialize
|
||||
lobpcg_solver->initialize(newstate);
|
||||
}
|
||||
// don't catch any other exceptions
|
||||
}
|
||||
|
||||
sol.numVecs = convtest->howMany();
|
||||
if (sol.numVecs > 0) {
|
||||
sol.Evecs = MVT::Clone(*problem_->getInitVec(),sol.numVecs);
|
||||
sol.Espace = sol.Evecs;
|
||||
sol.Evals.resize(sol.numVecs);
|
||||
std::vector<MagnitudeType> vals(sol.numVecs);
|
||||
|
||||
// copy them into the solution
|
||||
std::vector<int> which = convtest->whichVecs();
|
||||
// indices between [0,blockSize) refer to vectors/values in the solver
|
||||
// indices between [blockSize,blocksize+numlocked) refer to locked vectors/values
|
||||
// everything has already been ordered by the solver; we just have to partition the two references
|
||||
std::vector<int> inlocked(0), insolver(0);
|
||||
for (unsigned int i=0; i<which.size(); i++) {
|
||||
if (which[i] < blockSize_) {
|
||||
insolver.push_back(which[i]);
|
||||
}
|
||||
else {
|
||||
// sanity check
|
||||
TEST_FOR_EXCEPTION(which[i] >= numlocked+blockSize_,std::logic_error,"Anasazi::LOBPCGSolMgr::solve(): indexing mistake.");
|
||||
inlocked.push_back(which[i] - blockSize_);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_FOR_EXCEPTION(insolver.size() + inlocked.size() != (unsigned int)sol.numVecs,std::logic_error,"Anasazi::LOBPCGSolMgr::solve(): indexing mistake.");
|
||||
|
||||
// set the vecs,vals in the solution
|
||||
if (insolver.size() > 0) {
|
||||
// set vecs
|
||||
int lclnum = insolver.size();
|
||||
std::vector<int> tosol(lclnum);
|
||||
for (int i=0; i<lclnum; i++) tosol[i] = i;
|
||||
Teuchos::RCP<const MV> v = MVT::CloneView(*lobpcg_solver->getRitzVectors(),insolver);
|
||||
MVT::SetBlock(*v,tosol,*sol.Evecs);
|
||||
// set vals
|
||||
std::vector<Value<ScalarType> > fromsolver = lobpcg_solver->getRitzValues();
|
||||
for (unsigned int i=0; i<insolver.size(); i++) {
|
||||
vals[i] = fromsolver[insolver[i]].realpart;
|
||||
}
|
||||
}
|
||||
|
||||
// get the vecs,vals from locked storage
|
||||
if (inlocked.size() > 0) {
|
||||
int solnum = insolver.size();
|
||||
// set vecs
|
||||
int lclnum = inlocked.size();
|
||||
std::vector<int> tosol(lclnum);
|
||||
for (int i=0; i<lclnum; i++) tosol[i] = solnum + i;
|
||||
Teuchos::RCP<const MV> v = MVT::CloneView(*lockvecs,inlocked);
|
||||
MVT::SetBlock(*v,tosol,*sol.Evecs);
|
||||
// set vals
|
||||
for (unsigned int i=0; i<inlocked.size(); i++) {
|
||||
vals[i+solnum] = lockvals[inlocked[i]];
|
||||
}
|
||||
}
|
||||
|
||||
// sort the eigenvalues and permute the eigenvectors appropriately
|
||||
{
|
||||
std::vector<int> order(sol.numVecs);
|
||||
sorter->sort( lobpcg_solver.get(), sol.numVecs, vals, &order );
|
||||
// store the values in the Eigensolution
|
||||
for (int i=0; i<sol.numVecs; i++) {
|
||||
sol.Evals[i].realpart = vals[i];
|
||||
sol.Evals[i].imagpart = MT::zero();
|
||||
}
|
||||
// now permute the eigenvectors according to order
|
||||
msutils.permuteVectors(sol.numVecs,order,*sol.Evecs);
|
||||
}
|
||||
|
||||
// setup sol.index, remembering that all eigenvalues are real so that index = {0,...,0}
|
||||
sol.index.resize(sol.numVecs,0);
|
||||
}
|
||||
|
||||
// print final summary
|
||||
lobpcg_solver->currentStatus(printer->stream(FinalSummary));
|
||||
|
||||
// print timing information
|
||||
Teuchos::TimeMonitor::summarize(printer->stream(TimingDetails));
|
||||
|
||||
problem_->setSolution(sol);
|
||||
printer->stream(Debug) << "Returning " << sol.numVecs << " eigenpairs to eigenproblem." << std::endl;
|
||||
|
||||
if (sol.numVecs < nev) return Unconverged; // return from LOBPCGSolMgr::solve()
|
||||
return Converged; // return from LOBPCGSolMgr::solve()
|
||||
}
|
||||
|
||||
|
||||
} // end Anasazi namespace
|
||||
|
||||
#endif /* ANASAZI_LOBPCG_SOLMGR_HPP */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,421 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
|
||||
/*! \file AnasaziMatOrthoManager.hpp
|
||||
\brief Templated virtual class for providing orthogonalization/orthonormalization methods with matrix-based
|
||||
inner products.
|
||||
*/
|
||||
|
||||
#ifndef ANASAZI_MATORTHOMANAGER_HPP
|
||||
#define ANASAZI_MATORTHOMANAGER_HPP
|
||||
|
||||
/*! \class Anasazi::MatOrthoManager
|
||||
|
||||
\brief Anasazi's templated virtual class for providing routines for orthogonalization and
|
||||
orthonormalization of multivectors using matrix-based inner products.
|
||||
|
||||
This class extends Anasazi::OrthoManager by providing extra calling arguments to orthogonalization
|
||||
routines, to reduce the cost of applying the inner product in cases where the user already
|
||||
has the image of the source multivector under the inner product matrix.
|
||||
|
||||
A concrete implementation of this class is necessary. The user can create
|
||||
their own implementation if those supplied are not suitable for their needs.
|
||||
|
||||
\author Chris Baker, Ulrich Hetmaniuk, Rich Lehoucq, and Heidi Thornquist
|
||||
*/
|
||||
|
||||
#include "AnasaziConfigDefs.hpp"
|
||||
#include "AnasaziTypes.hpp"
|
||||
#include "AnasaziOrthoManager.hpp"
|
||||
#include "AnasaziMultiVecTraits.hpp"
|
||||
#include "AnasaziOperatorTraits.hpp"
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
class MatOrthoManager : public OrthoManager<ScalarType,MV> {
|
||||
public:
|
||||
//! @name Constructor/Destructor
|
||||
//@{
|
||||
//! Default constructor.
|
||||
MatOrthoManager(Teuchos::RCP<const OP> Op = Teuchos::null);
|
||||
|
||||
//! Destructor.
|
||||
virtual ~MatOrthoManager() {};
|
||||
//@}
|
||||
|
||||
//! @name Accessor routines
|
||||
//@{
|
||||
|
||||
//! Set operator used for inner product.
|
||||
void setOp( Teuchos::RCP<const OP> Op );
|
||||
|
||||
//! Get operator used for inner product.
|
||||
Teuchos::RCP<const OP> getOp() const;
|
||||
|
||||
//! Retrieve operator counter.
|
||||
/*! This counter returns the number of applications of the operator specifying the inner
|
||||
* product. When the operator is applied to a multivector, the counter is incremented by the
|
||||
* number of vectors in the multivector. If the operator is not specified, the counter is never
|
||||
* incremented.
|
||||
*/
|
||||
int getOpCounter() const;
|
||||
|
||||
//! Reset the operator counter to zero.
|
||||
/*! See getOpCounter() for more details.
|
||||
*/
|
||||
void resetOpCounter();
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Matrix-based Orthogonality Methods
|
||||
//@{
|
||||
|
||||
/*! \brief Provides a matrix-based inner product.
|
||||
*
|
||||
* Provides the inner product
|
||||
* \f[
|
||||
* \langle x, y \rangle = x^H M y
|
||||
* \f]
|
||||
* Optionally allows the provision of \f$M y\f$. See OrthoManager::innerProd() for more details.
|
||||
*
|
||||
*/
|
||||
void innerProdMat( const MV& X, const MV& Y, Teuchos::RCP<const MV> MY,
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType>& Z ) const;
|
||||
|
||||
/*! \brief Provides the norm induced by the matrix-based inner product.
|
||||
*
|
||||
* Provides the norm:
|
||||
* \f[
|
||||
* \|x\|_M = \sqrt{x^T H y}
|
||||
* \f]
|
||||
* Optionally allows the provision of \f$M x\f$. See OrthoManager::norm() for more details.
|
||||
*/
|
||||
void normMat(const MV& X, Teuchos::RCP<const MV> MX,
|
||||
std::vector< typename Teuchos::ScalarTraits<ScalarType>::magnitudeType > *normvec ) const;
|
||||
|
||||
/*! \brief Provides matrix-based projection method.
|
||||
*
|
||||
* This method optionally allows the provision of \f$M X\f$. See OrthoManager::project() for more details.
|
||||
*/
|
||||
virtual void projectMat (
|
||||
MV &X,
|
||||
Teuchos::RCP<MV> MX = Teuchos::null,
|
||||
Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C = Teuchos::tuple(Teuchos::null),
|
||||
Teuchos::Array<Teuchos::RCP<const MV> > Q = Teuchos::tuple(Teuchos::null) ) const = 0;
|
||||
|
||||
/*! \brief Provides matrix-based orthonormalization method.
|
||||
*
|
||||
* This method optionally allows the provision of \f$M X\f$. See orthoManager::normalize() for more details.
|
||||
*/
|
||||
virtual int normalizeMat (
|
||||
MV &X,
|
||||
Teuchos::RCP<MV> MX = Teuchos::null,
|
||||
Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B = Teuchos::null ) const = 0;
|
||||
|
||||
|
||||
/*! \brief Provides matrix-based projection/orthonormalization method.
|
||||
*
|
||||
* This method optionally allows the provision of \f$M X\f$. See orthoManager::projectAndNormalize() for more details.
|
||||
*/
|
||||
virtual int projectAndNormalizeMat (
|
||||
MV &X, Teuchos::RCP<MV> MX = Teuchos::null,
|
||||
Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C = Teuchos::tuple(Teuchos::null),
|
||||
Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B = Teuchos::null,
|
||||
Teuchos::Array<Teuchos::RCP<const MV> > Q = Teuchos::tuple(Teuchos::null) ) const = 0;
|
||||
|
||||
/*! \brief This method computes the error in orthonormality of a multivector.
|
||||
*
|
||||
* This method optionally allows optionally exploits a caller-provided \c MX.
|
||||
*/
|
||||
virtual typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
|
||||
orthonormErrorMat(const MV &X, Teuchos::RCP<const MV> MX = Teuchos::null) const = 0;
|
||||
|
||||
/*! \brief This method computes the error in orthogonality of two multivectors.
|
||||
*
|
||||
* This method optionally allows optionally exploits a caller-provided \c MX.
|
||||
*/
|
||||
virtual typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
|
||||
orthogErrorMat(const MV &X1, Teuchos::RCP<const MV> MX1, const MV &X2) const = 0;
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Methods implementing Anasazi::OrthoManager
|
||||
//@{
|
||||
|
||||
/*! \brief Implements the interface OrthoManager::innerProd().
|
||||
*
|
||||
* This method calls
|
||||
* \code
|
||||
* innerProdMat(X,Teuchos::null,Y,Z);
|
||||
* \endcode
|
||||
*/
|
||||
void innerProd( const MV& X, const MV& Y, Teuchos::SerialDenseMatrix<int,ScalarType>& Z ) const;
|
||||
|
||||
/*! \brief Implements the interface OrthoManager::norm().
|
||||
*
|
||||
* This method calls
|
||||
* \code
|
||||
* normMat(X,Teuchos::null,normvec);
|
||||
* \endcode
|
||||
*/
|
||||
void norm( const MV& X, std::vector< typename Teuchos::ScalarTraits<ScalarType>::magnitudeType > *normvec ) const;
|
||||
|
||||
/*! \brief Implements the interface OrthoManager::project().
|
||||
*
|
||||
* This method calls
|
||||
* \code
|
||||
* projectMat(X,Teuchos::null,C,Z);
|
||||
* \endcode
|
||||
*/
|
||||
void project ( MV &X,
|
||||
Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C = Teuchos::tuple(Teuchos::null),
|
||||
Teuchos::Array<Teuchos::RCP<const MV> > Q = Teuchos::tuple(Teuchos::null)) const;
|
||||
|
||||
/*! \brief Implements the interface OrthoManager::normalize().
|
||||
*
|
||||
* This method calls
|
||||
* \code
|
||||
* normalizeMat(X,Teuchos::null,B);
|
||||
* \endcode
|
||||
*/
|
||||
int normalize ( MV &X, Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B = Teuchos::null) const;
|
||||
|
||||
/*! \brief Implements the interface OrthoManager::projectAndNormalize().
|
||||
*
|
||||
* This method calls
|
||||
* \code
|
||||
* projectAndNormalizeMat(X,Teuchos::null,C,B,Q);
|
||||
* \endcode
|
||||
*/
|
||||
int projectAndNormalize ( MV &X,
|
||||
Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C = Teuchos::tuple(Teuchos::null),
|
||||
Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B = Teuchos::null,
|
||||
Teuchos::Array<Teuchos::RCP<const MV> > Q = Teuchos::tuple(Teuchos::null) ) const;
|
||||
|
||||
/*! \brief Implements the interface OrthoManager::orthonormError().
|
||||
*
|
||||
* This method calls
|
||||
* \code
|
||||
* orthonormErrorMat(X,Teuchos::null);
|
||||
* \endcode
|
||||
*/
|
||||
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
|
||||
orthonormError(const MV &X) const;
|
||||
|
||||
/*! \brief Implements the interface OrthoManager::orthogError().
|
||||
*
|
||||
* This method calls
|
||||
* \code
|
||||
* orthogErrorMat(X1,Teuchos::null,X2);
|
||||
* \endcode
|
||||
*/
|
||||
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
|
||||
orthogError(const MV &X1, const MV &X2) const;
|
||||
|
||||
//@}
|
||||
|
||||
protected:
|
||||
Teuchos::RCP<const OP> _Op;
|
||||
bool _hasOp;
|
||||
mutable int _OpCounter;
|
||||
|
||||
};
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
MatOrthoManager<ScalarType,MV,OP>::MatOrthoManager(Teuchos::RCP<const OP> Op)
|
||||
: _Op(Op), _hasOp(Op!=Teuchos::null) {}
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
void MatOrthoManager<ScalarType,MV,OP>::setOp( Teuchos::RCP<const OP> Op )
|
||||
{
|
||||
_Op = Op;
|
||||
_hasOp = (_Op != Teuchos::null);
|
||||
}
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
Teuchos::RCP<const OP> MatOrthoManager<ScalarType,MV,OP>::getOp() const
|
||||
{
|
||||
return _Op;
|
||||
}
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
int MatOrthoManager<ScalarType,MV,OP>::getOpCounter() const
|
||||
{
|
||||
return _OpCounter;
|
||||
}
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
void MatOrthoManager<ScalarType,MV,OP>::resetOpCounter()
|
||||
{
|
||||
_OpCounter = 0;
|
||||
}
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
void MatOrthoManager<ScalarType,MV,OP>::innerProd(
|
||||
const MV& X, const MV& Y, Teuchos::SerialDenseMatrix<int,ScalarType>& Z ) const
|
||||
{
|
||||
typedef Teuchos::ScalarTraits<ScalarType> SCT;
|
||||
typedef MultiVecTraits<ScalarType,MV> MVT;
|
||||
typedef OperatorTraits<ScalarType,MV,OP> OPT;
|
||||
|
||||
Teuchos::RCP<const MV> P,Q;
|
||||
Teuchos::RCP<MV> R;
|
||||
|
||||
if (_hasOp) {
|
||||
// attempt to minimize the amount of work in applying
|
||||
if ( MVT::GetNumberVecs(X) < MVT::GetNumberVecs(Y) ) {
|
||||
R = MVT::Clone(X,MVT::GetNumberVecs(X));
|
||||
OPT::Apply(*_Op,X,*R);
|
||||
_OpCounter += MVT::GetNumberVecs(X);
|
||||
P = R;
|
||||
Q = Teuchos::rcp( &Y, false );
|
||||
}
|
||||
else {
|
||||
P = Teuchos::rcp( &X, false );
|
||||
R = MVT::Clone(Y,MVT::GetNumberVecs(Y));
|
||||
OPT::Apply(*_Op,Y,*R);
|
||||
_OpCounter += MVT::GetNumberVecs(Y);
|
||||
Q = R;
|
||||
}
|
||||
}
|
||||
else {
|
||||
P = Teuchos::rcp( &X, false );
|
||||
Q = Teuchos::rcp( &Y, false );
|
||||
}
|
||||
|
||||
MVT::MvTransMv(SCT::one(),*P,*Q,Z);
|
||||
}
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
void MatOrthoManager<ScalarType,MV,OP>::innerProdMat(
|
||||
const MV& X, const MV& Y, Teuchos::RCP<const MV> MY, Teuchos::SerialDenseMatrix<int,ScalarType>& Z ) const
|
||||
{
|
||||
typedef Teuchos::ScalarTraits<ScalarType> SCT;
|
||||
typedef MultiVecTraits<ScalarType,MV> MVT;
|
||||
typedef OperatorTraits<ScalarType,MV,OP> OPT;
|
||||
|
||||
Teuchos::RCP<MV> P,Q;
|
||||
|
||||
if ( MY == Teuchos::null ) {
|
||||
innerProd(X,Y,Z);
|
||||
}
|
||||
else if ( _hasOp ) {
|
||||
// the user has done the matrix vector for us
|
||||
MVT::MvTransMv(SCT::one(),X,*MY,Z);
|
||||
}
|
||||
else {
|
||||
// there is no matrix vector
|
||||
MVT::MvTransMv(SCT::one(),X,Y,Z);
|
||||
}
|
||||
}
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
void MatOrthoManager<ScalarType,MV,OP>::norm(
|
||||
const MV& X, std::vector< typename Teuchos::ScalarTraits<ScalarType>::magnitudeType > *normvec ) const
|
||||
{
|
||||
this->normMat(X,Teuchos::null,normvec);
|
||||
}
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
void MatOrthoManager<ScalarType,MV,OP>::normMat(
|
||||
const MV& X, Teuchos::RCP<const MV> MX,
|
||||
std::vector< typename Teuchos::ScalarTraits<ScalarType>::magnitudeType > *normvec ) const
|
||||
{
|
||||
typedef Teuchos::ScalarTraits<ScalarType> SCT;
|
||||
typedef MultiVecTraits<ScalarType,MV> MVT;
|
||||
typedef OperatorTraits<ScalarType,MV,OP> OPT;
|
||||
|
||||
if (!_hasOp) {
|
||||
MX = Teuchos::rcp(&X,false);
|
||||
}
|
||||
else if (MX == Teuchos::null) {
|
||||
Teuchos::RCP<MV> R = MVT::Clone(X,MVT::GetNumberVecs(X));
|
||||
OPT::Apply(*_Op,X,*R);
|
||||
_OpCounter += MVT::GetNumberVecs(X);
|
||||
MX = R;
|
||||
}
|
||||
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> z(1,1);
|
||||
Teuchos::RCP<const MV> Xi, MXi;
|
||||
std::vector<int> ind(1);
|
||||
for (int i=0; i<MVT::GetNumberVecs(X); i++) {
|
||||
ind[0] = i;
|
||||
Xi = MVT::CloneView(X,ind);
|
||||
MXi = MVT::CloneView(*MX,ind);
|
||||
MVT::MvTransMv(SCT::one(),*Xi,*MXi,z);
|
||||
(*normvec)[i] = SCT::magnitude( SCT::squareroot( z(0,0) ) );
|
||||
}
|
||||
}
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
void MatOrthoManager<ScalarType,MV,OP>::project (
|
||||
MV &X,
|
||||
Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
|
||||
Teuchos::Array<Teuchos::RCP<const MV> > Q) const
|
||||
{
|
||||
this->projectMat(X,Teuchos::null,C,Q);
|
||||
}
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
int MatOrthoManager<ScalarType,MV,OP>::normalize (
|
||||
MV &X, Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B ) const
|
||||
{
|
||||
return this->normalizeMat(X,Teuchos::null,B);
|
||||
}
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
int MatOrthoManager<ScalarType,MV,OP>::projectAndNormalize (
|
||||
MV &X,
|
||||
Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
|
||||
Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
|
||||
Teuchos::Array<Teuchos::RCP<const MV> > Q ) const
|
||||
{
|
||||
return this->projectAndNormalizeMat(X,Teuchos::null,C,B,Q);
|
||||
}
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
|
||||
MatOrthoManager<ScalarType,MV,OP>::orthonormError(const MV &X) const
|
||||
{
|
||||
return this->orthonormErrorMat(X,Teuchos::null);
|
||||
}
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
|
||||
MatOrthoManager<ScalarType,MV,OP>::orthogError(const MV &X1, const MV &X2) const
|
||||
{
|
||||
return this->orthogErrorMat(X1,Teuchos::null,X2);
|
||||
}
|
||||
|
||||
} // end of Anasazi namespace
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// end of file AnasaziMatOrthoManager.hpp
|
||||
@@ -0,0 +1,371 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
|
||||
/*! \file AnasaziMultiVec.hpp
|
||||
\brief Templated virtual class for creating multi-vectors that can interface with the Anasazi::MultiVecTraits class
|
||||
*/
|
||||
|
||||
#ifndef ANASAZI_MULTI_VEC_HPP
|
||||
#define ANASAZI_MULTI_VEC_HPP
|
||||
|
||||
#include "AnasaziConfigDefs.hpp"
|
||||
#include "AnasaziMultiVecTraits.hpp"
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
|
||||
/*! \class MultiVec
|
||||
|
||||
\brief Anasazi's templated virtual class for constructing a multi-vector that can interface with the
|
||||
MultiVecTraits class used by the eigensolvers.
|
||||
|
||||
A concrete implementation of this class is necessary. The user can create
|
||||
their own implementation if those supplied are not suitable for their needs.
|
||||
|
||||
\author Ulrich Hetmaniuk, Rich Lehoucq, and Heidi Thornquist
|
||||
*/
|
||||
template <class ScalarType>
|
||||
class MultiVec {
|
||||
public:
|
||||
|
||||
//! @name Constructor/Destructor
|
||||
//@{
|
||||
//! Anasazi::MultiVec constructor.
|
||||
MultiVec() {};
|
||||
|
||||
//! Anasazi::MultiVec destructor.
|
||||
virtual ~MultiVec () {};
|
||||
|
||||
//@}
|
||||
//! @name Creation methods
|
||||
//@{
|
||||
|
||||
/*! \brief Creates a new empty Anasazi::MultiVec containing \c numvecs columns.
|
||||
|
||||
\return Pointer to the new multivector
|
||||
*/
|
||||
|
||||
virtual MultiVec<ScalarType> * Clone ( const int numvecs ) const = 0;
|
||||
|
||||
/*! \brief Creates a new Anasazi::MultiVec and copies contents of \c *this into
|
||||
the new vector (deep copy).
|
||||
|
||||
\return Pointer to the new multivector
|
||||
*/
|
||||
|
||||
virtual MultiVec<ScalarType> * CloneCopy () const = 0;
|
||||
|
||||
/*! \brief Creates a new Anasazi::MultiVec and copies the selected contents of \c *this
|
||||
into the new vector (deep copy). The copied
|
||||
vectors from \c *this are indicated by the \c index.size() indices in \c index.
|
||||
|
||||
\return Pointer to the new multivector
|
||||
*/
|
||||
|
||||
virtual MultiVec<ScalarType> * CloneCopy ( const std::vector<int>& index ) const = 0;
|
||||
|
||||
/*! \brief Creates a new Anasazi::MultiVec that shares the selected contents of \c *this.
|
||||
The index of the \c numvecs vectors shallow copied from \c *this are indicated by the
|
||||
indices given in \c index.
|
||||
|
||||
\return Pointer to the new multivector
|
||||
*/
|
||||
|
||||
virtual MultiVec<ScalarType> * CloneView ( const std::vector<int>& index ) = 0;
|
||||
//@}
|
||||
|
||||
//! @name Attribute methods
|
||||
//@{
|
||||
//! Obtain the vector length of *this.
|
||||
|
||||
virtual int GetVecLength () const = 0;
|
||||
|
||||
//! Obtain the number of vectors in *this.
|
||||
|
||||
virtual int GetNumberVecs () const = 0;
|
||||
|
||||
//@}
|
||||
//! @name Update methods
|
||||
//@{
|
||||
/*! \brief Update \c *this with \c alpha * \c A * \c B + \c beta * (\c *this).
|
||||
*/
|
||||
|
||||
virtual void MvTimesMatAddMv ( ScalarType alpha, const MultiVec<ScalarType>& A,
|
||||
const Teuchos::SerialDenseMatrix<int,ScalarType>& B, ScalarType beta ) = 0;
|
||||
|
||||
/*! \brief Replace \c *this with \c alpha * \c A + \c beta * \c B.
|
||||
*/
|
||||
|
||||
virtual void MvAddMv ( ScalarType alpha, const MultiVec<ScalarType>& A, ScalarType beta, const MultiVec<ScalarType>& B ) = 0;
|
||||
|
||||
/*! \brief Compute a dense matrix \c B through the matrix-matrix multiply
|
||||
\c alpha * \c A^T * (\c *this).
|
||||
*/
|
||||
|
||||
virtual void MvTransMv ( ScalarType alpha, const MultiVec<ScalarType>& A, Teuchos::SerialDenseMatrix<int,ScalarType>& B
|
||||
#ifdef HAVE_ANASAZI_EXPERIMENTAL
|
||||
, ConjType conj = Anasazi::CONJ
|
||||
#endif
|
||||
) const = 0;
|
||||
|
||||
/*! \brief Compute a vector \c b where the components are the individual dot-products, i.e.\c b[i] = \c A[i]^H*\c this[i] where \c A[i] is the i-th column of A.
|
||||
*/
|
||||
|
||||
virtual void MvDot ( const MultiVec<ScalarType>& A, std::vector<ScalarType>* b
|
||||
#ifdef HAVE_ANASAZI_EXPERIMENTAL
|
||||
, ConjType conj = Anasazi::CONJ
|
||||
#endif
|
||||
) const = 0;
|
||||
|
||||
//@}
|
||||
//! @name Norm method
|
||||
//@{
|
||||
|
||||
/*! \brief Compute the 2-norm of each individual vector of \c *this.
|
||||
Upon return, \c normvec[i] holds the 2-norm of the \c i-th vector of \c *this
|
||||
*/
|
||||
|
||||
virtual void MvNorm ( std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>* normvec ) const = 0;
|
||||
|
||||
//@}
|
||||
//! @name Initialization methods
|
||||
//@{
|
||||
/*! \brief Copy the vectors in \c A to a set of vectors in \c *this. The \c
|
||||
numvecs vectors in \c A are copied to a subset of vectors in \c *this
|
||||
indicated by the indices given in \c index.
|
||||
*/
|
||||
|
||||
virtual void SetBlock ( const MultiVec<ScalarType>& A, const std::vector<int>& index ) = 0;
|
||||
|
||||
/*! \brief Scale each element of the vectors in \c *this with \c alpha.
|
||||
*/
|
||||
|
||||
virtual void MvScale ( ScalarType alpha ) = 0;
|
||||
|
||||
/*! \brief Scale each element of the \c i-th vector in \c *this with \c alpha[i].
|
||||
*/
|
||||
|
||||
virtual void MvScale ( const std::vector<ScalarType>& alpha ) = 0;
|
||||
|
||||
/*! \brief Fill the vectors in \c *this with random numbers.
|
||||
*/
|
||||
|
||||
virtual void MvRandom () = 0;
|
||||
|
||||
/*! \brief Replace each element of the vectors in \c *this with \c alpha.
|
||||
*/
|
||||
|
||||
virtual void MvInit ( ScalarType alpha ) = 0;
|
||||
|
||||
//@}
|
||||
//! @name Print method
|
||||
//@{
|
||||
/*! \brief Print \c *this multivector to the \c os output stream.
|
||||
*/
|
||||
virtual void MvPrint ( std::ostream& os ) const = 0;
|
||||
//@}
|
||||
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Implementation of the Anasazi::MultiVecTraits for Anasazi::MultiVec.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*!
|
||||
\brief Template specialization of Anasazi::MultiVecTraits class using the Anasazi::MultiVec virtual
|
||||
base class.
|
||||
|
||||
Any class that inherits from Anasazi::MultiVec will be accepted by the Anasazi templated solvers due to this
|
||||
interface to the Anasazi::MultiVecTraits class.
|
||||
*/
|
||||
|
||||
template<class ScalarType>
|
||||
class MultiVecTraits<ScalarType,MultiVec<ScalarType> >
|
||||
{
|
||||
public:
|
||||
|
||||
//! @name Creation methods
|
||||
//@{
|
||||
|
||||
/*! \brief Creates a new empty \c Anasazi::MultiVec containing \c numvecs columns.
|
||||
|
||||
\return Reference-counted pointer to the new \c Anasazi::MultiVec.
|
||||
*/
|
||||
static Teuchos::RCP<MultiVec<ScalarType> > Clone( const MultiVec<ScalarType>& mv, const int numvecs )
|
||||
{ return Teuchos::rcp( const_cast<MultiVec<ScalarType>&>(mv).Clone(numvecs) ); }
|
||||
|
||||
/*! \brief Creates a new \c Anasazi::MultiVec and copies contents of \c mv into the new vector (deep copy).
|
||||
|
||||
\return Reference-counted pointer to the new \c Anasazi::MultiVec.
|
||||
*/
|
||||
static Teuchos::RCP<MultiVec<ScalarType> > CloneCopy( const MultiVec<ScalarType>& mv )
|
||||
{ return Teuchos::rcp( const_cast<MultiVec<ScalarType>&>(mv).CloneCopy() ); }
|
||||
|
||||
/*! \brief Creates a new \c Anasazi::MultiVec and copies the selected contents of \c mv into the new vector (deep copy).
|
||||
|
||||
The copied vectors from \c mv are indicated by the \c index.size() indices in \c index.
|
||||
\return Reference-counted pointer to the new \c Anasazi::MultiVec.
|
||||
*/
|
||||
static Teuchos::RCP<MultiVec<ScalarType> > CloneCopy( const MultiVec<ScalarType>& mv, const std::vector<int>& index )
|
||||
{ return Teuchos::rcp( const_cast<MultiVec<ScalarType>&>(mv).CloneCopy(index) ); }
|
||||
|
||||
/*! \brief Creates a new \c Anasazi::MultiVec that shares the selected contents of \c mv (shallow copy).
|
||||
|
||||
The index of the \c numvecs vectors shallow copied from \c mv are indicated by the indices given in \c index.
|
||||
\return Reference-counted pointer to the new \c Anasazi::MultiVec.
|
||||
*/
|
||||
static Teuchos::RCP<MultiVec<ScalarType> > CloneView( MultiVec<ScalarType>& mv, const std::vector<int>& index )
|
||||
{ return Teuchos::rcp( mv.CloneView(index) ); }
|
||||
|
||||
/*! \brief Creates a new const \c Anasazi::MultiVec that shares the selected contents of \c mv (shallow copy).
|
||||
|
||||
The index of the \c numvecs vectors shallow copied from \c mv are indicated by the indices given in \c index.
|
||||
\return Reference-counted pointer to the new const \c Anasazi::MultiVec.
|
||||
*/
|
||||
static Teuchos::RCP<const MultiVec<ScalarType> > CloneView( const MultiVec<ScalarType>& mv, const std::vector<int>& index )
|
||||
{ return Teuchos::rcp( const_cast<MultiVec<ScalarType>&>(mv).CloneView(index) ); }
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Attribute methods
|
||||
//@{
|
||||
|
||||
//! Obtain the vector length of \c mv.
|
||||
static int GetVecLength( const MultiVec<ScalarType>& mv )
|
||||
{ return mv.GetVecLength(); }
|
||||
|
||||
//! Obtain the number of vectors in \c mv
|
||||
static int GetNumberVecs( const MultiVec<ScalarType>& mv )
|
||||
{ return mv.GetNumberVecs(); }
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Update methods
|
||||
//@{
|
||||
|
||||
/*! \brief Update \c mv with \f$ \alpha AB + \beta mv \f$.
|
||||
*/
|
||||
static void MvTimesMatAddMv( ScalarType alpha, const MultiVec<ScalarType>& A,
|
||||
const Teuchos::SerialDenseMatrix<int,ScalarType>& B,
|
||||
ScalarType beta, MultiVec<ScalarType>& mv )
|
||||
{ mv.MvTimesMatAddMv(alpha, A, B, beta); }
|
||||
|
||||
/*! \brief Replace \c mv with \f$\alpha A + \beta B\f$.
|
||||
*/
|
||||
static void MvAddMv( ScalarType alpha, const MultiVec<ScalarType>& A, ScalarType beta, const MultiVec<ScalarType>& B, MultiVec<ScalarType>& mv )
|
||||
{ mv.MvAddMv(alpha, A, beta, B); }
|
||||
|
||||
/*! \brief Compute a dense matrix \c B through the matrix-matrix multiply \f$ \alpha A^Tmv \f$.
|
||||
*/
|
||||
static void MvTransMv( ScalarType alpha, const MultiVec<ScalarType>& A, const MultiVec<ScalarType>& mv, Teuchos::SerialDenseMatrix<int,ScalarType>& B
|
||||
#ifdef HAVE_ANASAZI_EXPERIMENTAL
|
||||
, ConjType conj = Anasazi::CONJ
|
||||
#endif
|
||||
)
|
||||
{ mv.MvTransMv(alpha, A, B
|
||||
#ifdef HAVE_ANASAZI_EXPERIMENTAL
|
||||
, conj
|
||||
#endif
|
||||
); }
|
||||
|
||||
/*! \brief Compute a vector \c b where the components are the individual dot-products of the \c i-th columns of \c A and \c mv, i.e.\f$b[i] = A[i]^H mv[i]\f$.
|
||||
*/
|
||||
static void MvDot( const MultiVec<ScalarType>& mv, const MultiVec<ScalarType>& A, std::vector<ScalarType>* b
|
||||
#ifdef HAVE_ANASAZI_EXPERIMENTAL
|
||||
, ConjType conj = Anasazi::CONJ
|
||||
#endif
|
||||
)
|
||||
{ mv.MvDot( A, b
|
||||
#ifdef HAVE_ANASAZI_EXPERIMENTAL
|
||||
, conj
|
||||
#endif
|
||||
); }
|
||||
|
||||
/*! \brief Scale each element of the vectors in \c *this with \c alpha.
|
||||
*/
|
||||
static void MvScale ( MultiVec<ScalarType>& mv, ScalarType alpha )
|
||||
{ mv.MvScale( alpha ); }
|
||||
|
||||
/*! \brief Scale each element of the \c i-th vector in \c *this with \c alpha[i].
|
||||
*/
|
||||
static void MvScale ( MultiVec<ScalarType>& mv, const std::vector<ScalarType>& alpha )
|
||||
{ mv.MvScale( alpha ); }
|
||||
|
||||
//@}
|
||||
//! @name Norm method
|
||||
//@{
|
||||
|
||||
/*! \brief Compute the 2-norm of each individual vector of \c mv.
|
||||
Upon return, \c normvec[i] holds the value of \f$||mv_i||_2\f$, the \c i-th column of \c mv.
|
||||
*/
|
||||
static void MvNorm( const MultiVec<ScalarType>& mv, std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>* normvec )
|
||||
{ mv.MvNorm(normvec); }
|
||||
|
||||
//@}
|
||||
//! @name Initialization methods
|
||||
//@{
|
||||
/*! \brief Copy the vectors in \c A to a set of vectors in \c mv indicated by the indices given in \c index.
|
||||
|
||||
The \c numvecs vectors in \c A are copied to a subset of vectors in \c mv indicated by the indices given in \c index,
|
||||
i.e.<tt> mv[index[i]] = A[i]</tt>.
|
||||
*/
|
||||
static void SetBlock( const MultiVec<ScalarType>& A, const std::vector<int>& index, MultiVec<ScalarType>& mv )
|
||||
{ mv.SetBlock(A, index); }
|
||||
|
||||
/*! \brief Replace the vectors in \c mv with random vectors.
|
||||
*/
|
||||
static void MvRandom( MultiVec<ScalarType>& mv )
|
||||
{ mv.MvRandom(); }
|
||||
|
||||
/*! \brief Replace each element of the vectors in \c mv with \c alpha.
|
||||
*/
|
||||
static void MvInit( MultiVec<ScalarType>& mv, ScalarType alpha = Teuchos::ScalarTraits<ScalarType>::zero() )
|
||||
{ mv.MvInit(alpha); }
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Print method
|
||||
//@{
|
||||
|
||||
/*! \brief Print the \c mv multi-vector to the \c os output stream.
|
||||
*/
|
||||
static void MvPrint( const MultiVec<ScalarType>& mv, std::ostream& os )
|
||||
{ mv.MvPrint(os); }
|
||||
|
||||
//@}
|
||||
};
|
||||
|
||||
|
||||
} // namespace Anasazi
|
||||
|
||||
#endif
|
||||
|
||||
// end of file AnasaziMultiVec.hpp
|
||||
@@ -0,0 +1,216 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
//
|
||||
#ifndef ANASAZI_MULTI_VEC_TRAITS_HPP
|
||||
#define ANASAZI_MULTI_VEC_TRAITS_HPP
|
||||
|
||||
/*! \file AnasaziMultiVecTraits.hpp
|
||||
\brief Virtual base class which defines basic traits for the multivector type
|
||||
*/
|
||||
|
||||
#include "AnasaziConfigDefs.hpp"
|
||||
#include "AnasaziTypes.hpp"
|
||||
#include "Teuchos_RCP.hpp"
|
||||
#include "Teuchos_SerialDenseMatrix.hpp"
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
/*! \brief This is the default struct used by MultiVecTraits<ScalarType, MV> class to produce a
|
||||
compile time error when the specialization does not exist for multivector type <tt>MV</tt>.
|
||||
*/
|
||||
template< class ScalarType, class MV >
|
||||
struct UndefinedMultiVecTraits
|
||||
{
|
||||
//! This function should not compile if there is an attempt to instantiate!
|
||||
/*! \note Any attempt to compile this function results in a compile time error. This means
|
||||
that the template specialization of Anasazi::MultiVecTraits class for type <tt>MV</tt> does
|
||||
not exist, or is not complete.
|
||||
*/
|
||||
static inline ScalarType notDefined() { return MV::this_type_is_missing_a_specialization(); };
|
||||
};
|
||||
|
||||
|
||||
/*! \brief Virtual base class which defines basic traits for the multi-vector type.
|
||||
|
||||
An adapter for this traits class must exist for the <tt>MV</tt> type.
|
||||
If not, this class will produce a compile-time error.
|
||||
|
||||
\ingroup anasazi_opvec_interfaces
|
||||
*/
|
||||
template<class ScalarType, class MV>
|
||||
class MultiVecTraits
|
||||
{
|
||||
public:
|
||||
|
||||
//! @name Creation methods
|
||||
//@{
|
||||
|
||||
/*! \brief Creates a new empty \c MV containing \c numvecs columns.
|
||||
|
||||
\return Reference-counted pointer to the new multivector of type \c MV.
|
||||
*/
|
||||
static Teuchos::RCP<MV> Clone( const MV& mv, const int numvecs )
|
||||
{ UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); return Teuchos::null; }
|
||||
|
||||
/*! \brief Creates a new \c MV and copies contents of \c mv into the new vector (deep copy).
|
||||
|
||||
\return Reference-counted pointer to the new multivector of type \c MV.
|
||||
*/
|
||||
static Teuchos::RCP<MV> CloneCopy( const MV& mv )
|
||||
{ UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); return Teuchos::null; }
|
||||
|
||||
/*! \brief Creates a new \c MV and copies the selected contents of \c mv into the new vector (deep copy).
|
||||
|
||||
The copied vectors from \c mv are indicated by the \c index.size() indices in \c index.
|
||||
\return Reference-counted pointer to the new multivector of type \c MV.
|
||||
*/
|
||||
static Teuchos::RCP<MV> CloneCopy( const MV& mv, const std::vector<int>& index )
|
||||
{ UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); return Teuchos::null; }
|
||||
|
||||
/*! \brief Creates a new \c MV that shares the selected contents of \c mv (shallow copy).
|
||||
|
||||
The index of the \c numvecs vectors shallow copied from \c mv are indicated by the indices given in \c index.
|
||||
\return Reference-counted pointer to the new multivector of type \c MV.
|
||||
*/
|
||||
static Teuchos::RCP<MV> CloneView( MV& mv, const std::vector<int>& index )
|
||||
{ UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); return Teuchos::null; }
|
||||
|
||||
/*! \brief Creates a new const \c MV that shares the selected contents of \c mv (shallow copy).
|
||||
|
||||
The index of the \c numvecs vectors shallow copied from \c mv are indicated by the indices given in \c index.
|
||||
\return Reference-counted pointer to the new const multivector of type \c MV.
|
||||
*/
|
||||
static Teuchos::RCP<const MV> CloneView( const MV& mv, const std::vector<int>& index )
|
||||
{ UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); return Teuchos::null; }
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Attribute methods
|
||||
//@{
|
||||
|
||||
//! Obtain the vector length of \c mv.
|
||||
static int GetVecLength( const MV& mv )
|
||||
{ UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); return 0; }
|
||||
|
||||
//! Obtain the number of vectors in \c mv
|
||||
static int GetNumberVecs( const MV& mv )
|
||||
{ UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); return 0; }
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Update methods
|
||||
//@{
|
||||
|
||||
/*! \brief Update \c mv with \f$ \alpha AB + \beta mv \f$.
|
||||
*/
|
||||
static void MvTimesMatAddMv( const ScalarType alpha, const MV& A,
|
||||
const Teuchos::SerialDenseMatrix<int,ScalarType>& B,
|
||||
const ScalarType beta, MV& mv )
|
||||
{ UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); }
|
||||
|
||||
/*! \brief Replace \c mv with \f$\alpha A + \beta B\f$.
|
||||
*/
|
||||
static void MvAddMv( const ScalarType alpha, const MV& A, const ScalarType beta, const MV& B, MV& mv )
|
||||
{ UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); }
|
||||
|
||||
/*! \brief Compute a dense matrix \c B through the matrix-matrix multiply \f$ \alpha A^Hmv \f$.
|
||||
*/
|
||||
static void MvTransMv( const ScalarType alpha, const MV& A, const MV& mv, Teuchos::SerialDenseMatrix<int,ScalarType>& B
|
||||
#ifdef HAVE_ANASAZI_EXPERIMENTAL
|
||||
, ConjType conj = Anasazi::CONJ
|
||||
#endif
|
||||
)
|
||||
{ UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); }
|
||||
|
||||
/*! \brief Compute a vector \c b where the components are the individual dot-products of the \c i-th columns of \c A and \c mv, i.e.\f$b[i] = A[i]^Hmv[i]\f$.
|
||||
*/
|
||||
static void MvDot ( const MV& mv, const MV& A, std::vector<ScalarType>* b
|
||||
#ifdef HAVE_ANASAZI_EXPERIMENTAL
|
||||
, ConjType conj = Anasazi::CONJ
|
||||
#endif
|
||||
)
|
||||
{ UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); }
|
||||
|
||||
/*! \brief Scale each element of the vectors in \c mv with \c alpha.
|
||||
*/
|
||||
static void MvScale ( MV& mv, const ScalarType alpha )
|
||||
{ UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); }
|
||||
|
||||
/*! \brief Scale each element of the \c i-th vector in \c mv with \c alpha[i].
|
||||
*/
|
||||
static void MvScale ( MV& mv, const std::vector<ScalarType>& alpha )
|
||||
{ UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); }
|
||||
|
||||
//@}
|
||||
//! @name Norm method
|
||||
//@{
|
||||
|
||||
/*! \brief Compute the 2-norm of each individual vector of \c mv.
|
||||
Upon return, \c normvec[i] holds the value of \f$||mv_i||_2\f$, the \c i-th column of \c mv.
|
||||
*/
|
||||
static void MvNorm( const MV& mv, std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>* normvec )
|
||||
{ UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); }
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Initialization methods
|
||||
//@{
|
||||
/*! \brief Copy the vectors in \c A to a set of vectors in \c mv indicated by the indices given in \c index.
|
||||
|
||||
The \c numvecs vectors in \c A are copied to a subset of vectors in \c mv indicated by the indices given in \c index,
|
||||
i.e.<tt> mv[index[i]] = A[i]</tt>.
|
||||
*/
|
||||
static void SetBlock( const MV& A, const std::vector<int>& index, MV& mv )
|
||||
{ UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); }
|
||||
|
||||
/*! \brief Replace the vectors in \c mv with random vectors.
|
||||
*/
|
||||
static void MvRandom( MV& mv )
|
||||
{ UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); }
|
||||
|
||||
/*! \brief Replace each element of the vectors in \c mv with \c alpha.
|
||||
*/
|
||||
static void MvInit( MV& mv, const ScalarType alpha = Teuchos::ScalarTraits<ScalarType>::zero() )
|
||||
{ UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); }
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Print method
|
||||
//@{
|
||||
|
||||
/*! \brief Print the \c mv multi-vector to the \c os output stream.
|
||||
*/
|
||||
static void MvPrint( const MV& mv, std::ostream& os )
|
||||
{ UndefinedMultiVecTraits<ScalarType, MV>::notDefined(); }
|
||||
|
||||
//@}
|
||||
};
|
||||
|
||||
} // namespace Anasazi
|
||||
|
||||
#endif // ANASAZI_MULTI_VEC_TRAITS_HPP
|
||||
@@ -0,0 +1,115 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
|
||||
/*! \file AnasaziOperator.hpp
|
||||
\brief Templated virtual class for creating operators that can interface with the Anasazi::OperatorTraits class
|
||||
*/
|
||||
|
||||
#ifndef ANASAZI_OPERATOR_HPP
|
||||
#define ANASAZI_OPERATOR_HPP
|
||||
|
||||
#include "AnasaziConfigDefs.hpp"
|
||||
#include "AnasaziOperatorTraits.hpp"
|
||||
#include "AnasaziMultiVec.hpp"
|
||||
#include "Teuchos_ScalarTraits.hpp"
|
||||
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
/*!
|
||||
\brief Anasazi's templated virtual class for constructing an operator that can interface with the
|
||||
OperatorTraits class used by the eigensolvers.
|
||||
|
||||
A concrete implementation of this class is necessary. The user can create their own implementation
|
||||
if those supplied are not suitable for their needs.
|
||||
|
||||
\author Ulrich Hetmaniuk, Rich Lehoucq, and Heidi Thornquist
|
||||
*/
|
||||
template <class ScalarType>
|
||||
class Operator {
|
||||
public:
|
||||
//! @name Constructor/Destructor
|
||||
//@{
|
||||
//! Default constructor.
|
||||
Operator() {};
|
||||
|
||||
//! Destructor.
|
||||
virtual ~Operator() {};
|
||||
//@}
|
||||
|
||||
//! @name Operator application method
|
||||
//@{
|
||||
|
||||
/*! \brief This method takes the Anasazi::MultiVec \c x and
|
||||
applies the operator to it resulting in the Anasazi::MultiVec \c y.
|
||||
*/
|
||||
virtual void Apply ( const MultiVec<ScalarType>& x, MultiVec<ScalarType>& y ) const = 0;
|
||||
|
||||
//@}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Implementation of the Anasazi::OperatorTraits for Anasazi::Operator
|
||||
// and Anasazi::MultiVec.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*!
|
||||
\brief Template specialization of Anasazi::OperatorTraits class using Anasazi::Operator and Anasazi::MultiVec virtual
|
||||
base classes.
|
||||
|
||||
Any class that inherits from Anasazi::Operator will be accepted by the Anasazi templated solvers due to this
|
||||
interface to the Anasazi::OperatorTraits class.
|
||||
*/
|
||||
|
||||
template <class ScalarType>
|
||||
class OperatorTraits < ScalarType, MultiVec<ScalarType>, Operator<ScalarType> >
|
||||
{
|
||||
public:
|
||||
|
||||
//! @name Operator application method
|
||||
//@{
|
||||
|
||||
/*! \brief This method takes the Anasazi::MultiVec \c x and
|
||||
applies the Anasazi::Operator \c Op to it resulting in the Anasazi::MultiVec \c y.
|
||||
*/
|
||||
static void Apply ( const Operator<ScalarType>& Op,
|
||||
const MultiVec<ScalarType>& x,
|
||||
MultiVec<ScalarType>& y )
|
||||
{ Op.Apply( x, y ); }
|
||||
|
||||
//@}
|
||||
|
||||
};
|
||||
|
||||
} // end of Anasazi namespace
|
||||
|
||||
#endif
|
||||
|
||||
// end of file AnasaziOperator.hpp
|
||||
@@ -0,0 +1,92 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
|
||||
#ifndef ANASAZI_OPERATOR_TRAITS_HPP
|
||||
#define ANASAZI_OPERATOR_TRAITS_HPP
|
||||
|
||||
/*! \file AnasaziOperatorTraits.hpp
|
||||
\brief Virtual base class which defines basic traits for the operator type
|
||||
*/
|
||||
|
||||
#include "AnasaziConfigDefs.hpp"
|
||||
#include "AnasaziTypes.hpp"
|
||||
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
|
||||
//! \brief Exceptions thrown to signal error in operator application.
|
||||
class OperatorError : public AnasaziError
|
||||
{public: OperatorError(const std::string& what_arg) : AnasaziError(what_arg) {}};
|
||||
|
||||
|
||||
/*! \brief This is the default struct used by OperatorTraits<ScalarType, MV, OP> class to produce a
|
||||
compile time error when the specialization does not exist for operator type <tt>OP</tt>.
|
||||
*/
|
||||
template< class ScalarType, class MV, class OP >
|
||||
struct UndefinedOperatorTraits
|
||||
{
|
||||
//! This function should not compile if there is an attempt to instantiate!
|
||||
/*! \note Any attempt to compile this function results in a compile time error. This means
|
||||
that the template specialization of Anasazi::OperatorTraits class does not exist for type
|
||||
<tt>OP</tt>, or is not complete.
|
||||
*/
|
||||
static inline void notDefined() { return OP::this_type_is_missing_a_specialization(); };
|
||||
};
|
||||
|
||||
|
||||
/*! \brief Virtual base class which defines basic traits for the operator type.
|
||||
|
||||
An adapter for this traits class must exist for the <tt>MV</tt> and <tt>OP</tt> types.
|
||||
If not, this class will produce a compile-time error.
|
||||
|
||||
\ingroup anasazi_opvec_interfaces
|
||||
*/
|
||||
template <class ScalarType, class MV, class OP>
|
||||
class OperatorTraits
|
||||
{
|
||||
public:
|
||||
|
||||
//! @name Operator application method.
|
||||
//@{
|
||||
|
||||
//! Application method which performs operation <b>y = Op*x</b>. An OperatorError exception is thrown if there is an error.
|
||||
static void Apply ( const OP& Op,
|
||||
const MV& x,
|
||||
MV& y )
|
||||
{ UndefinedOperatorTraits<ScalarType, MV, OP>::notDefined(); };
|
||||
|
||||
//@}
|
||||
|
||||
};
|
||||
|
||||
} // end Anasazi namespace
|
||||
|
||||
#endif // ANASAZI_OPERATOR_TRAITS_HPP
|
||||
|
||||
// end of file AnasaziOperatorTraits.hpp
|
||||
@@ -0,0 +1,268 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
|
||||
/*! \file AnasaziOrthoManager.hpp
|
||||
\brief Templated virtual class for providing orthogonalization/orthonormalization methods.
|
||||
*/
|
||||
|
||||
#ifndef ANASAZI_ORTHOMANAGER_HPP
|
||||
#define ANASAZI_ORTHOMANAGER_HPP
|
||||
|
||||
/*! \class Anasazi::OrthoManager
|
||||
|
||||
\brief Anasazi's templated virtual class for providing routines for orthogonalization and
|
||||
orthonormalization of multivectors.
|
||||
|
||||
This class defines concepts of orthogonality through the definition of an
|
||||
inner product. It also provides computational routines for orthogonalization.
|
||||
|
||||
A concrete implementation of this class is necessary. The user can create
|
||||
their own implementation if those supplied are not suitable for their needs.
|
||||
|
||||
\author Chris Baker, Ulrich Hetmaniuk, Rich Lehoucq, and Heidi Thornquist
|
||||
*/
|
||||
|
||||
#include "AnasaziConfigDefs.hpp"
|
||||
#include "AnasaziTypes.hpp"
|
||||
#include "Teuchos_ScalarTraits.hpp"
|
||||
#include "Teuchos_RCP.hpp"
|
||||
#include "Teuchos_SerialDenseMatrix.hpp"
|
||||
#include "Teuchos_Array.hpp"
|
||||
|
||||
|
||||
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
|
||||
//! @name OrthoManager Exceptions
|
||||
//@{
|
||||
|
||||
/** \brief Exception thrown to signal error in an orthogonalization manager method.
|
||||
*/
|
||||
class OrthoError : public AnasaziError
|
||||
{public: OrthoError(const std::string& what_arg) : AnasaziError(what_arg) {}};
|
||||
|
||||
//@}
|
||||
|
||||
template <class ScalarType, class MV>
|
||||
class OrthoManager {
|
||||
public:
|
||||
//! @name Constructor/Destructor
|
||||
//@{
|
||||
//! Default constructor.
|
||||
OrthoManager() {};
|
||||
|
||||
//! Destructor.
|
||||
virtual ~OrthoManager() {};
|
||||
//@}
|
||||
|
||||
//! @name Orthogonalization methods
|
||||
//@{
|
||||
|
||||
/*! \brief Provides the inner product defining the orthogonality concepts.
|
||||
|
||||
All concepts of orthogonality discussed in this class are defined with respect to this inner product.
|
||||
|
||||
\note This is potentially different from MultiVecTraits::MvTransMv(). For example, it is customary in many
|
||||
eigensolvers to exploit a mass matrix \c M for the inner product: \f$x^HMx\f$.
|
||||
|
||||
@param Z [out] <tt>Z(i,j)</tt> contains the inner product of <tt>X[i]</tt> and <tt>Y[i]</tt>:
|
||||
\f[
|
||||
Z(i,j) = \langle X[i], Y[i] \rangle
|
||||
\f]
|
||||
|
||||
*/
|
||||
virtual void innerProd( const MV &X, const MV &Y, Teuchos::SerialDenseMatrix<int,ScalarType>& Z ) const = 0;
|
||||
|
||||
|
||||
/*! \brief Provides the norm induced by innerProd().
|
||||
*
|
||||
* This computes the norm for each column of a multivector. This is the norm induced by innerProd():
|
||||
* \f[ \|x\| = \sqrt{\langle x, x \rangle} \f]
|
||||
*
|
||||
* @param normvec [out] Vector of norms, whose \c i-th entry corresponds to the \c i-th column of \c X
|
||||
*/
|
||||
virtual void norm( const MV& X, std::vector< typename Teuchos::ScalarTraits<ScalarType>::magnitudeType > *normvec ) const = 0;
|
||||
|
||||
/*! \brief Given a list of mutually orthogonal and internally orthonormal bases \c Q, this method
|
||||
* projects a multivector \c X onto the space orthogonal to the individual <tt>Q[i]</tt>,
|
||||
* optionally returning the coefficients of \c X for the individual <tt>Q[i]</tt>. All of this is done with respect
|
||||
* to the inner product innerProd().
|
||||
*
|
||||
* After calling this routine, \c X will be orthogonal to each of the <tt>Q[i]</tt>.
|
||||
*
|
||||
@param X [in/out] The multivector to be modified.<br>
|
||||
On output, the columns of \c X will be orthogonal to each <tt>Q[i]</tt>, satisfying
|
||||
\f[
|
||||
X_{out} = X_{in} - \sum_i Q[i] \langle Q[i], X_{in} \rangle
|
||||
\f]
|
||||
|
||||
@param C [out] The coefficients of \c X in the bases <tt>Q[i]</tt>. If <tt>C[i]</tt> is a non-null pointer
|
||||
and <tt>C[i]</tt> matches the dimensions of \c X and <tt>Q[i]</tt>, then the coefficients computed during the orthogonalization
|
||||
routine will be stored in the matrix <tt>C[i]</tt>, similar to calling
|
||||
\code
|
||||
innerProd( Q[i], X, C[i] );
|
||||
\endcode
|
||||
If <tt>C[i]</tt> points to a Teuchos::SerialDenseMatrix with size
|
||||
inconsistent with \c X and \c <tt>Q[i]</tt>, then a std::invalid_argument
|
||||
exception will be thrown. Otherwise, if <tt>C.size() < i</tt> or
|
||||
<tt>C[i]</tt> is a null pointer, the caller will not have access to the
|
||||
computed coefficients.
|
||||
|
||||
@param Q [in] A list of multivector bases specifying the subspaces to be orthogonalized against, satisfying
|
||||
\f[
|
||||
\langle Q[i], Q[j] \rangle = I \quad\textrm{if}\quad i=j
|
||||
\f]
|
||||
and
|
||||
\f[
|
||||
\langle Q[i], Q[j] \rangle = 0 \quad\textrm{if}\quad i \neq j\ .
|
||||
\f]
|
||||
*/
|
||||
virtual void project (
|
||||
MV &X,
|
||||
Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C = Teuchos::tuple(Teuchos::null),
|
||||
Teuchos::Array<Teuchos::RCP<const MV> > Q = Teuchos::tuple(Teuchos::null) ) const = 0;
|
||||
|
||||
/*! \brief This method takes a multivector \c X and attempts to compute a basis for \f$colspan(X)\f$. This basis is orthonormal with respect to innerProd().
|
||||
*
|
||||
* This routine returns an integer \c rank stating the rank of the computed basis. If \c X does not have full rank and the normalize() routine does
|
||||
* not attempt to augment the subspace, then \c rank may be smaller than the number of columns in \c X. In this case, only the first \c rank columns of
|
||||
* output \c X and first \c rank rows of \c B will be valid.
|
||||
*
|
||||
@param X [in/out] The multivector to be modified.<br>
|
||||
On output, the first \c rank columns of \c X satisfy
|
||||
\f[
|
||||
\langle X[i], X[j] \rangle = \delta_{ij}\ .
|
||||
\f]
|
||||
Also,
|
||||
\f[
|
||||
X_{in}(1:m,1:n) = X_{out}(1:m,1:rank) B(1:rank,1:n)
|
||||
\f]
|
||||
where \c m is the number of rows in \c X and \c n is the number of columns in \c X.
|
||||
|
||||
@param B [out] The coefficients of the original \c X with respect to the computed basis. If \c B is a non-null pointer and \c B matches the dimensions of \c B, then the
|
||||
coefficients computed during the orthogonalization routine will be stored in \c B, similar to calling
|
||||
\code
|
||||
innerProd( Xout, Xin, B );
|
||||
\endcode
|
||||
If \c B points to a Teuchos::SerialDenseMatrix with size inconsistent with \c X, then a std::invalid_argument exception will be thrown. Otherwise, if \c B is null, the caller will not have
|
||||
access to the computed coefficients. This matrix is not necessarily triangular (as in a QR factorization); see the documentation of specific orthogonalization managers.
|
||||
|
||||
@return Rank of the basis computed by this method, less than or equal to the number of columns in \c X. This specifies how many columns in the returned \c X and rows in the returned \c B are valid.
|
||||
*/
|
||||
virtual int normalize (
|
||||
MV &X,
|
||||
Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B = Teuchos::null) const = 0;
|
||||
|
||||
|
||||
/*! \brief Given a set of bases <tt>Q[i]</tt> and a multivector \c X, this method computes an orthonormal basis for \f$colspan(X) - \sum_i colspan(Q[i])\f$.
|
||||
*
|
||||
* This routine returns an integer \c rank stating the rank of the computed basis. If the subspace \f$colspan(X) - \sum_i colspan(Q[i])\f$ does not
|
||||
* have dimension as large as the number of columns of \c X and the orthogonalization manager does not attempt to augment the subspace, then \c rank
|
||||
* may be smaller than the number of columns of \c X. In this case, only the first \c rank columns of output \c X and first \c rank rows of \c B will
|
||||
* be valid.
|
||||
*
|
||||
* \note This routine guarantees both the orthogonality of the returned basis against the <tt>Q[i]</tt> as well as the orthonormality of the returned basis. Therefore,
|
||||
* this method is not necessarily equivalent to calling project() followed by a call to normalize(); see the documentation for specific orthogonalization managers.
|
||||
*
|
||||
@param X [in/out]
|
||||
On output, the first \c rank columns of \c X satisfy
|
||||
\f[
|
||||
\langle X[i], X[j] \rangle = \delta_{ij} \quad \textrm{and} \quad \langle X, Q[i] \rangle = 0\ .
|
||||
\f]
|
||||
Also,
|
||||
\f[
|
||||
X_{in}(1:m,1:n) = X_{out}(1:m,1:rank) B(1:rank,1:n) + \sum_i Q[i] C[i]
|
||||
\f]
|
||||
where \c m is the number of rows in \c X and \c n is the number of columns in \c X.
|
||||
|
||||
@param C [out] The coefficients of \c X in the <tt>Q[i]</tt>. If <tt>C[i]</tt> is a non-null pointer
|
||||
and <tt>C[i]</tt> matches the dimensions of \c X and <tt>Q[i]</tt>, then the coefficients computed during the orthogonalization
|
||||
routine will be stored in the matrix <tt>C[i]</tt>, similar to calling
|
||||
\code
|
||||
innerProd( Q[i], X, C[i] );
|
||||
\endcode
|
||||
If <tt>C[i]</tt> points to a Teuchos::SerialDenseMatrix with size
|
||||
inconsistent with \c X and \c <tt>Q[i]</tt>, then a std::invalid_argument
|
||||
exception will be thrown. Otherwise, if <tt>C.size() < i</tt> or
|
||||
<tt>C[i]</tt> is a null pointer, the caller will not have access to the
|
||||
computed coefficients.
|
||||
|
||||
@param B [out] The coefficients of the original \c X with respect to the computed basis. If \c B is a non-null pointer and \c B matches the dimensions of \c B, then the
|
||||
coefficients computed during the orthogonalization routine will be stored in \c B, similar to calling
|
||||
\code
|
||||
innerProd( Xout, Xin, B );
|
||||
\endcode
|
||||
If \c B points to a Teuchos::SerialDenseMatrix with size inconsistent with \c X, then a std::invalid_argument exception will be thrown. Otherwise, if \c B is null, the caller will not have
|
||||
access to the computed coefficients. This matrix is not necessarily triangular (as in a QR factorization); see the documentation of specific orthogonalization managers.
|
||||
|
||||
@param Q [in] A list of multivector bases specifying the subspaces to be orthogonalized against, satisfying
|
||||
\f[
|
||||
\langle Q[i], Q[j] \rangle = I \quad\textrm{if}\quad i=j
|
||||
\f]
|
||||
and
|
||||
\f[
|
||||
\langle Q[i], Q[j] \rangle = 0 \quad\textrm{if}\quad i \neq j\ .
|
||||
\f]
|
||||
|
||||
@return Rank of the basis computed by this method, less than or equal to the number of columns in \c X. This specifies how many columns in the returned \c X and rows in the returned \c B are valid.
|
||||
*/
|
||||
virtual int projectAndNormalize (
|
||||
MV &X,
|
||||
Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C = Teuchos::tuple(Teuchos::null),
|
||||
Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B = Teuchos::null,
|
||||
Teuchos::Array<Teuchos::RCP<const MV> > Q = Teuchos::tuple(Teuchos::null) ) const = 0;
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Error methods
|
||||
//@{
|
||||
|
||||
/*! \brief This method computes the error in orthonormality of a multivector.
|
||||
*
|
||||
* This method return some measure of \f$\| \langle X, X \rangle - I \| \f$. See the documentation of specific orthogonalization managers.
|
||||
*/
|
||||
virtual typename Teuchos::ScalarTraits< ScalarType >::magnitudeType orthonormError(const MV &X) const = 0;
|
||||
|
||||
/*! \brief This method computes the error in orthogonality of two multivectors.
|
||||
*
|
||||
* This method return some measure of \f$\| \langle X1, X2 \rangle - 0 \| \f$. See the documentation of specific orthogonalization managers.
|
||||
*/
|
||||
virtual typename Teuchos::ScalarTraits<ScalarType>::magnitudeType orthogError(const MV &X1, const MV &X2) const = 0;
|
||||
|
||||
//@}
|
||||
|
||||
};
|
||||
|
||||
} // end of Anasazi namespace
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// end of file AnasaziOrthoManager.hpp
|
||||
@@ -0,0 +1,114 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
|
||||
#ifndef ANASAZI_OUTPUT_MANAGER_HPP
|
||||
#define ANASAZI_OUTPUT_MANAGER_HPP
|
||||
|
||||
/*! \file AnasaziOutputManager.hpp
|
||||
\brief Abstract class definition for Anasazi Output Managers.
|
||||
*/
|
||||
|
||||
#include "AnasaziConfigDefs.hpp"
|
||||
#include "AnasaziTypes.hpp"
|
||||
|
||||
/*! \class Anasazi::OutputManager
|
||||
|
||||
\brief Output managers remove the need for the eigensolver to know any information
|
||||
about the required output. Calling isVerbosity( MsgType type ) informs the solver if
|
||||
it is supposed to output the information corresponding to the message type.
|
||||
|
||||
\author Chris Baker, Ulrich Hetmaniuk, Rich Lehoucq, and Heidi Thornquist
|
||||
*/
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
template <class ScalarType>
|
||||
class OutputManager {
|
||||
|
||||
public:
|
||||
|
||||
//!@name Constructors/Destructor
|
||||
//@{
|
||||
|
||||
//! Default constructor
|
||||
OutputManager( int vb = Anasazi::Errors ) : vb_(vb) {};
|
||||
|
||||
//! Destructor.
|
||||
virtual ~OutputManager() {};
|
||||
//@}
|
||||
|
||||
//! @name Set/Get methods
|
||||
//@{
|
||||
|
||||
//! Set the message output types for this manager.
|
||||
virtual void setVerbosity( int vb ) { vb_ = vb; }
|
||||
|
||||
//! Get the message output types for this manager.
|
||||
virtual int getVerbosity( ) const { return vb_; }
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Output methods
|
||||
//@{
|
||||
|
||||
//! Find out whether we need to print out information for this message type.
|
||||
/*! This method is used by the solver to determine whether computations are
|
||||
necessary for this message type.
|
||||
*/
|
||||
virtual bool isVerbosity( MsgType type ) const = 0;
|
||||
|
||||
//! Send output to the output manager.
|
||||
virtual void print( MsgType type, const std::string output ) = 0;
|
||||
|
||||
//! Create a stream for outputting to.
|
||||
virtual std::ostream &stream( MsgType type ) = 0;
|
||||
|
||||
//@}
|
||||
|
||||
private:
|
||||
|
||||
//! @name Undefined methods
|
||||
//@{
|
||||
|
||||
//! Copy constructor.
|
||||
OutputManager( const OutputManager<ScalarType>& OM );
|
||||
|
||||
//! Assignment operator.
|
||||
OutputManager<ScalarType>& operator=( const OutputManager<ScalarType>& OM );
|
||||
|
||||
//@}
|
||||
|
||||
protected:
|
||||
int vb_;
|
||||
};
|
||||
|
||||
} // end Anasazi namespace
|
||||
|
||||
#endif
|
||||
|
||||
// end of file AnasaziOutputManager.hpp
|
||||
@@ -0,0 +1,818 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
|
||||
|
||||
/*! \file AnasaziSVQBOrthoManager.hpp
|
||||
\brief Orthogonalization manager based on the SVQB technique described in
|
||||
"A Block Orthogonalization Procedure With Constant Synchronization Requirements", A. Stathapoulos and K. Wu
|
||||
*/
|
||||
|
||||
#ifndef ANASAZI_SVQB_ORTHOMANAGER_HPP
|
||||
#define ANASAZI_SVQB_ORTHOMANAGER_HPP
|
||||
|
||||
/*! \class Anasazi::SVQBOrthoManager
|
||||
\brief An implementation of the Anasazi::MatOrthoManager that performs orthogonalization
|
||||
using the SVQB iterative orthogonalization technique described by Stathapoulos and Wu. This orthogonalization routine,
|
||||
while not returning the upper triangular factors of the popular Gram-Schmidt method, has a communication
|
||||
cost (measured in number of communication calls) that is independent of the number of columns in the basis.
|
||||
|
||||
\author Chris Baker, Ulrich Hetmaniuk, Rich Lehoucq, and Heidi Thornquist
|
||||
*/
|
||||
|
||||
#include "AnasaziConfigDefs.hpp"
|
||||
#include "AnasaziMultiVecTraits.hpp"
|
||||
#include "AnasaziOperatorTraits.hpp"
|
||||
#include "AnasaziMatOrthoManager.hpp"
|
||||
#include "Teuchos_LAPACK.hpp"
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
template<class ScalarType, class MV, class OP>
|
||||
class SVQBOrthoManager : public MatOrthoManager<ScalarType,MV,OP> {
|
||||
|
||||
private:
|
||||
typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
|
||||
typedef Teuchos::ScalarTraits<ScalarType> SCT;
|
||||
typedef Teuchos::ScalarTraits<MagnitudeType> SCTM;
|
||||
typedef MultiVecTraits<ScalarType,MV> MVT;
|
||||
typedef OperatorTraits<ScalarType,MV,OP> OPT;
|
||||
std::string dbgstr;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//! @name Constructor/Destructor
|
||||
//@{
|
||||
//! Constructor specifying re-orthogonalization tolerance.
|
||||
SVQBOrthoManager( Teuchos::RCP<const OP> Op = Teuchos::null, bool debug = false );
|
||||
|
||||
|
||||
//! Destructor
|
||||
~SVQBOrthoManager() {};
|
||||
//@}
|
||||
|
||||
|
||||
//! @name Methods implementing Anasazi::MatOrthoManager
|
||||
//@{
|
||||
|
||||
|
||||
/*! \brief Given a list of mutually orthogonal and internally orthonormal bases \c Q, this method
|
||||
* projects a multivector \c X onto the space orthogonal to the individual <tt>Q[i]</tt>,
|
||||
* optionally returning the coefficients of \c X for the individual <tt>Q[i]</tt>. All of this is done with respect
|
||||
* to the inner product innerProd().
|
||||
*
|
||||
* After calling this routine, \c X will be orthogonal to each of the <tt>Q[i]</tt>.
|
||||
*
|
||||
@param X [in/out] The multivector to be modified.<br>
|
||||
On output, the columns of \c X will be orthogonal to each <tt>Q[i]</tt>, satisfying
|
||||
\f[
|
||||
X_{out} = X_{in} - \sum_i Q[i] \langle Q[i], X_{in} \rangle
|
||||
\f]
|
||||
|
||||
@param MX [in/out] The image of \c X under the inner product operator \c Op.
|
||||
If \f$ MX != 0\f$: On input, this is expected to be consistent with \c Op \cdot X. On output, this is updated consistent with updates to \c X.
|
||||
If \f$ MX == 0\f$ or \f$ Op == 0\f$: \c MX is not referenced.
|
||||
|
||||
@param C [out] The coefficients of \c X in the bases <tt>Q[i]</tt>. If <tt>C[i]</tt> is a non-null pointer
|
||||
and <tt>C[i]</tt> matches the dimensions of \c X and <tt>Q[i]</tt>, then the coefficients computed during the orthogonalization
|
||||
routine will be stored in the matrix <tt>C[i]</tt>, similar to calling
|
||||
\code
|
||||
innerProd( Q[i], X, C[i] );
|
||||
\endcode
|
||||
If <tt>C[i]</tt> points to a Teuchos::SerialDenseMatrix with size
|
||||
inconsistent with \c X and \c <tt>Q[i]</tt>, then a std::invalid_argument
|
||||
exception will be thrown. Otherwise, if <tt>C.size() < i</tt> or
|
||||
<tt>C[i]</tt> is a null pointer, the caller will not have access to the
|
||||
computed coefficients.
|
||||
|
||||
@param Q [in] A list of multivector bases specifying the subspaces to be orthogonalized against, satisfying
|
||||
\f[
|
||||
\langle Q[i], Q[j] \rangle = I \quad\textrm{if}\quad i=j
|
||||
\f]
|
||||
and
|
||||
\f[
|
||||
\langle Q[i], Q[j] \rangle = 0 \quad\textrm{if}\quad i \neq j\ .
|
||||
\f]
|
||||
*/
|
||||
void projectMat (
|
||||
MV &X,
|
||||
Teuchos::RCP<MV> MX = Teuchos::null,
|
||||
Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C = Teuchos::tuple(Teuchos::null),
|
||||
Teuchos::Array<Teuchos::RCP<const MV> > Q = Teuchos::tuple(Teuchos::null) ) const;
|
||||
|
||||
|
||||
/*! \brief This method takes a multivector \c X and attempts to compute an orthonormal basis for \f$colspan(X)\f$, with respect to innerProd().
|
||||
*
|
||||
* This method does not compute an upper triangular coefficient matrix \c B.
|
||||
*
|
||||
* This routine returns an integer \c rank stating the rank of the computed basis. If \c X does not have full rank and the normalize() routine does
|
||||
* not attempt to augment the subspace, then \c rank may be smaller than the number of columns in \c X. In this case, only the first \c rank columns of
|
||||
* output \c X and first \c rank rows of \c B will be valid.
|
||||
*
|
||||
* The method attempts to find a basis with dimension equal to the number of columns in \c X. It does this by augmenting linearly dependent
|
||||
* vectors in \c X with random directions. A finite number of these attempts will be made; therefore, it is possible that the dimension of the
|
||||
* computed basis is less than the number of vectors in \c X.
|
||||
*
|
||||
@param X [in/out] The multivector to be modified.<br>
|
||||
On output, the first \c rank columns of \c X satisfy
|
||||
\f[
|
||||
\langle X[i], X[j] \rangle = \delta_{ij}\ .
|
||||
\f]
|
||||
Also,
|
||||
\f[
|
||||
X_{in}(1:m,1:n) = X_{out}(1:m,1:rank) B(1:rank,1:n)
|
||||
\f]
|
||||
where \c m is the number of rows in \c X and \c n is the number of columns in \c X.
|
||||
|
||||
@param MX [in/out] The image of \c X under the inner product operator \c Op.
|
||||
If \f$ MX != 0\f$: On input, this is expected to be consistent with \c Op \cdot X. On output, this is updated consistent with updates to \c X.
|
||||
If \f$ MX == 0\f$ or \f$ Op == 0\f$: \c MX is not referenced.
|
||||
|
||||
@param B [out] The coefficients of the original \c X with respect to the computed basis. If \c B is a non-null pointer and \c B matches the dimensions of \c B, then the
|
||||
coefficients computed during the orthogonalization routine will be stored in \c B, similar to calling
|
||||
\code
|
||||
innerProd( Xout, Xin, B );
|
||||
\endcode
|
||||
If \c B points to a Teuchos::SerialDenseMatrix with size inconsistent with \c X, then a std::invalid_argument exception will be thrown. Otherwise, if \c B is null, the caller will not have
|
||||
access to the computed coefficients. This matrix is not necessarily triangular (as in a QR factorization); see the documentation of specific orthogonalization managers.<br>
|
||||
In general, \c B has no non-zero structure.
|
||||
|
||||
@return Rank of the basis computed by this method, less than or equal to the number of columns in \c X. This specifies how many columns in the returned \c X and rows in the returned \c B are valid.
|
||||
*/
|
||||
int normalizeMat (
|
||||
MV &X,
|
||||
Teuchos::RCP<MV> MX = Teuchos::null,
|
||||
Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B = Teuchos::tuple(Teuchos::null) ) const;
|
||||
|
||||
|
||||
/*! \brief Given a set of bases <tt>Q[i]</tt> and a multivector \c X, this method computes an orthonormal basis for \f$colspan(X) - \sum_i colspan(Q[i])\f$.
|
||||
*
|
||||
* This routine returns an integer \c rank stating the rank of the computed basis. If the subspace \f$colspan(X) - \sum_i colspan(Q[i])\f$ does not
|
||||
* have dimension as large as the number of columns of \c X and the orthogonalization manager doe not attempt to augment the subspace, then \c rank
|
||||
* may be smaller than the number of columns of \c X. In this case, only the first \c rank columns of output \c X and first \c rank rows of \c B will
|
||||
* be valid.
|
||||
*
|
||||
* The method attempts to find a basis with dimension the same as the number of columns in \c X. It does this by augmenting linearly dependent
|
||||
* vectors with random directions. A finite number of these attempts will be made; therefore, it is possible that the dimension of the
|
||||
* computed basis is less than the number of vectors in \c X.
|
||||
*
|
||||
@param X [in/out] The multivector to be modified.<br>
|
||||
On output, the first \c rank columns of \c X satisfy
|
||||
\f[
|
||||
\langle X[i], X[j] \rangle = \delta_{ij} \quad \textrm{and} \quad \langle X, Q[i] \rangle = 0\ .
|
||||
\f]
|
||||
Also,
|
||||
\f[
|
||||
X_{in}(1:m,1:n) = X_{out}(1:m,1:rank) B(1:rank,1:n) + \sum_i Q[i] C[i]
|
||||
\f]
|
||||
where \c m is the number of rows in \c X and \c n is the number of columns in \c X.
|
||||
|
||||
@param MX [in/out] The image of \c X under the inner product operator \c Op.
|
||||
If \f$ MX != 0\f$: On input, this is expected to be consistent with \c Op \cdot X. On output, this is updated consistent with updates to \c X.
|
||||
If \f$ MX == 0\f$ or \f$ Op == 0\f$: \c MX is not referenced.
|
||||
|
||||
@param C [out] The coefficients of \c X in the <tt>Q[i]</tt>. If <tt>C[i]</tt> is a non-null pointer
|
||||
and <tt>C[i]</tt> matches the dimensions of \c X and <tt>Q[i]</tt>, then the coefficients computed during the orthogonalization
|
||||
routine will be stored in the matrix <tt>C[i]</tt>, similar to calling
|
||||
\code
|
||||
innerProd( Q[i], X, C[i] );
|
||||
\endcode
|
||||
If <tt>C[i]</tt> points to a Teuchos::SerialDenseMatrix with size
|
||||
inconsistent with \c X and \c <tt>Q[i]</tt>, then a std::invalid_argument
|
||||
exception will be thrown. Otherwise, if <tt>C.size() < i</tt> or
|
||||
<tt>C[i]</tt> is a null pointer, the caller will not have access to the
|
||||
computed coefficients.
|
||||
|
||||
@param B [out] The coefficients of the original \c X with respect to the computed basis. If \c B is a non-null pointer and \c B matches the dimensions of \c B, then the
|
||||
coefficients computed during the orthogonalization routine will be stored in \c B, similar to calling
|
||||
\code
|
||||
innerProd( Xout, Xin, B );
|
||||
\endcode
|
||||
If \c B points to a Teuchos::SerialDenseMatrix with size inconsistent with \c X, then a std::invalid_argument exception will be thrown. Otherwise, if \c B is null, the caller will not have
|
||||
access to the computed coefficients. This matrix is not necessarily triangular (as in a QR factorization); see the documentation of specific orthogonalization managers.<br>
|
||||
In general, \c B has no non-zero structure.
|
||||
|
||||
@param Q [in] A list of multivector bases specifying the subspaces to be orthogonalized against, satisfying
|
||||
\f[
|
||||
\langle Q[i], Q[j] \rangle = I \quad\textrm{if}\quad i=j
|
||||
\f]
|
||||
and
|
||||
\f[
|
||||
\langle Q[i], Q[j] \rangle = 0 \quad\textrm{if}\quad i \neq j\ .
|
||||
\f]
|
||||
|
||||
@return Rank of the basis computed by this method, less than or equal to the number of columns in \c X. This specifies how many columns in the returned \c X and rows in the returned \c B are valid.
|
||||
|
||||
*/
|
||||
int projectAndNormalizeMat (
|
||||
MV &X,
|
||||
Teuchos::RCP<MV> MX = Teuchos::null,
|
||||
Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C = Teuchos::tuple(Teuchos::null),
|
||||
Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B = Teuchos::null,
|
||||
Teuchos::Array<Teuchos::RCP<const MV> > Q = Teuchos::tuple(Teuchos::null) ) const;
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Error methods
|
||||
//@{
|
||||
|
||||
/*! \brief This method computes the error in orthonormality of a multivector, measured
|
||||
* as the Frobenius norm of the difference <tt>innerProd(X,Y) - I</tt>.
|
||||
* The method has the option of exploiting a caller-provided \c MX.
|
||||
*/
|
||||
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
|
||||
orthonormErrorMat(const MV &X, Teuchos::RCP<const MV> MX = Teuchos::null) const;
|
||||
|
||||
/*! \brief This method computes the error in orthogonality of two multivectors, measured
|
||||
* as the Frobenius norm of <tt>innerProd(X,Y)</tt>.
|
||||
* The method has the option of exploiting a caller-provided \c MX.
|
||||
*/
|
||||
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
|
||||
orthogErrorMat(const MV &X1, Teuchos::RCP<const MV> MX1, const MV &X2) const;
|
||||
|
||||
//@}
|
||||
|
||||
private:
|
||||
|
||||
MagnitudeType eps_;
|
||||
bool debug_;
|
||||
|
||||
// ! Routine to find an orthogonal/orthonormal basis for the
|
||||
int findBasis( MV &X, Teuchos::RCP<MV> MX,
|
||||
Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
|
||||
Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
|
||||
Teuchos::Array<Teuchos::RCP<const MV> > Q,
|
||||
bool normalize ) const;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
template<class ScalarType, class MV, class OP>
|
||||
SVQBOrthoManager<ScalarType,MV,OP>::SVQBOrthoManager( Teuchos::RCP<const OP> Op, bool debug)
|
||||
: MatOrthoManager<ScalarType,MV,OP>(Op), dbgstr(" *** "), debug_(debug) {
|
||||
|
||||
Teuchos::LAPACK<int,MagnitudeType> lapack;
|
||||
eps_ = lapack.LAMCH('E');
|
||||
if (debug_) {
|
||||
std::cout << "eps_ == " << eps_ << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Compute the distance from orthonormality
|
||||
template<class ScalarType, class MV, class OP>
|
||||
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
|
||||
SVQBOrthoManager<ScalarType,MV,OP>::orthonormErrorMat(const MV &X, Teuchos::RCP<const MV> MX) const {
|
||||
const ScalarType ONE = SCT::one();
|
||||
int rank = MVT::GetNumberVecs(X);
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> xTx(rank,rank);
|
||||
innerProdMat(X,X,MX,xTx);
|
||||
for (int i=0; i<rank; i++) {
|
||||
xTx(i,i) -= ONE;
|
||||
}
|
||||
return xTx.normFrobenius();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Compute the distance from orthogonality
|
||||
template<class ScalarType, class MV, class OP>
|
||||
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
|
||||
SVQBOrthoManager<ScalarType,MV,OP>::orthogErrorMat(const MV &X1, Teuchos::RCP<const MV> MX1, const MV &X2) const {
|
||||
int r1 = MVT::GetNumberVecs(X1);
|
||||
int r2 = MVT::GetNumberVecs(X2);
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> xTx(r2,r1);
|
||||
innerProdMat(X2,X1,MX1,xTx);
|
||||
return xTx.normFrobenius();
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Find an Op-orthonormal basis for span(X) - span(W)
|
||||
template<class ScalarType, class MV, class OP>
|
||||
int SVQBOrthoManager<ScalarType, MV, OP>::projectAndNormalizeMat(
|
||||
MV &X, Teuchos::RCP<MV> MX,
|
||||
Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
|
||||
Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
|
||||
Teuchos::Array<Teuchos::RCP<const MV> > Q ) const {
|
||||
|
||||
return findBasis(X,MX,C,B,Q,true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Find an Op-orthonormal basis for span(X), with rank numvectors(X)
|
||||
template<class ScalarType, class MV, class OP>
|
||||
int SVQBOrthoManager<ScalarType, MV, OP>::normalizeMat(
|
||||
MV &X, Teuchos::RCP<MV> MX,
|
||||
Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B ) const {
|
||||
Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C;
|
||||
Teuchos::Array<Teuchos::RCP<const MV> > Q;
|
||||
return findBasis(X,MX,C,B,Q,true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<class ScalarType, class MV, class OP>
|
||||
void SVQBOrthoManager<ScalarType, MV, OP>::projectMat(
|
||||
MV &X, Teuchos::RCP<MV> MX,
|
||||
Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
|
||||
Teuchos::Array<Teuchos::RCP<const MV> > Q) const {
|
||||
findBasis(X,MX,C,Teuchos::null,Q,false);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Find an Op-orthonormal basis for span(X), with the option of extending the subspace so that
|
||||
// the rank is numvectors(X)
|
||||
//
|
||||
// Tracking the coefficients (C[i] and B) for this code is complicated by the fact that the loop
|
||||
// structure looks like
|
||||
// do
|
||||
// project
|
||||
// do
|
||||
// ortho
|
||||
// end
|
||||
// end
|
||||
// However, the recurrence for the coefficients is not complicated:
|
||||
// B = I
|
||||
// C = 0
|
||||
// do
|
||||
// project yields newC
|
||||
// C = C + newC*B
|
||||
// do
|
||||
// ortho yields newR
|
||||
// B = newR*B
|
||||
// end
|
||||
// end
|
||||
// This holds for each individual C[i] (which correspond to the list of bases we are orthogonalizing
|
||||
// against).
|
||||
//
|
||||
template<class ScalarType, class MV, class OP>
|
||||
int SVQBOrthoManager<ScalarType, MV, OP>::findBasis(
|
||||
MV &X, Teuchos::RCP<MV> MX,
|
||||
Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > C,
|
||||
Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > B,
|
||||
Teuchos::Array<Teuchos::RCP<const MV> > Q,
|
||||
bool normalize) const {
|
||||
|
||||
const ScalarType ONE = SCT::one();
|
||||
const MagnitudeType MONE = SCTM::one();
|
||||
const MagnitudeType ZERO = SCTM::zero();
|
||||
|
||||
int numGS = 0,
|
||||
numSVQB = 0,
|
||||
numRand = 0;
|
||||
|
||||
// get sizes of X,MX
|
||||
int xc = MVT::GetNumberVecs(X);
|
||||
int xr = MVT::GetVecLength( X );
|
||||
|
||||
// get sizes of Q[i]
|
||||
int nq = Q.length();
|
||||
int qr = (nq == 0) ? 0 : MVT::GetVecLength(*Q[0]);
|
||||
int qsize = 0;
|
||||
std::vector<int> qcs(nq);
|
||||
for (int i=0; i<nq; i++) {
|
||||
qcs[i] = MVT::GetNumberVecs(*Q[i]);
|
||||
qsize += qcs[i];
|
||||
}
|
||||
|
||||
if (normalize == true && qsize + xc > xr) {
|
||||
// not well-posed
|
||||
TEST_FOR_EXCEPTION( true, std::invalid_argument,
|
||||
"Anasazi::SVQBOrthoManager::findBasis(): Orthogonalization constraints not feasible" );
|
||||
}
|
||||
|
||||
// try to short-circuit as early as possible
|
||||
if (normalize == false && (qsize == 0 || xc == 0)) {
|
||||
// nothing to do
|
||||
return 0;
|
||||
}
|
||||
else if (normalize == true && (xc == 0 || xr == 0)) {
|
||||
// normalize requires X not empty
|
||||
TEST_FOR_EXCEPTION( true, std::invalid_argument,
|
||||
"Anasazi::SVQBOrthoManager::findBasis(): X must be non-empty" );
|
||||
}
|
||||
|
||||
// check that Q matches X
|
||||
TEST_FOR_EXCEPTION( qsize != 0 && qr != xr , std::invalid_argument,
|
||||
"Anasazi::SVQBOrthoManager::findBasis(): Size of X not consistant with size of Q" );
|
||||
|
||||
/* If we don't have enough C, expanding it creates null references
|
||||
* If we have too many, resizing just throws away the later ones
|
||||
* If we have exactly as many as we have Q, this call has no effect
|
||||
*/
|
||||
C.resize(nq);
|
||||
Teuchos::Array<Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > > newC(nq);
|
||||
// check the size of the C[i] against the Q[i] and consistency between Q[i]
|
||||
for (int i=0; i<nq; i++) {
|
||||
// check size of Q[i]
|
||||
TEST_FOR_EXCEPTION( MVT::GetVecLength( *Q[i] ) != qr, std::invalid_argument,
|
||||
"Anasazi::SVQBOrthoManager::findBasis(): Size of Q not mutually consistant" );
|
||||
TEST_FOR_EXCEPTION( qr < qcs[i], std::invalid_argument,
|
||||
"Anasazi::SVQBOrthoManager::findBasis(): Q has less rows than columns" );
|
||||
// check size of C[i]
|
||||
if ( C[i] == Teuchos::null ) {
|
||||
C[i] = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>(qcs[i],xc) );
|
||||
}
|
||||
else {
|
||||
TEST_FOR_EXCEPTION( C[i]->numRows() != qcs[i] || C[i]->numCols() != xc, std::invalid_argument,
|
||||
"Anasazi::SVQBOrthoManager::findBasis(): Size of Q not consistant with C" );
|
||||
}
|
||||
// clear C[i]
|
||||
C[i]->putScalar(ZERO);
|
||||
newC[i] = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>(*C[i]) );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// Allocate necessary storage
|
||||
// C were allocated above
|
||||
// Allocate MX and B (if necessary)
|
||||
// Set B = I
|
||||
if (normalize == true) {
|
||||
if ( B == Teuchos::null ) {
|
||||
B = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>(xc,xc) );
|
||||
}
|
||||
TEST_FOR_EXCEPTION( B->numRows() != xc || B->numCols() != xc, std::invalid_argument,
|
||||
"Anasazi::SVQBOrthoManager::findBasis(): Size of B not consistant with X" );
|
||||
// set B to I
|
||||
B->putScalar(ZERO);
|
||||
for (int i=0; i<xc; i++) {
|
||||
(*B)(i,i) = MONE;
|
||||
}
|
||||
}
|
||||
/******************************************
|
||||
* If _hasOp == false, DO NOT MODIFY MX *
|
||||
******************************************
|
||||
* if Op==null, MX == X (via pointer)
|
||||
* Otherwise, either the user passed in MX or we will allocate and compute it
|
||||
*
|
||||
* workX will be a multivector of the same size as X, used to perform X*S when normalizing
|
||||
*/
|
||||
Teuchos::RCP<MV> workX;
|
||||
if (normalize) {
|
||||
workX = MVT::Clone(X,xc);
|
||||
}
|
||||
if (this->_hasOp) {
|
||||
if (MX == Teuchos::null) {
|
||||
// we need to allocate space for MX
|
||||
MX = MVT::Clone(X,xc);
|
||||
OPT::Apply(*(this->_Op),X,*MX);
|
||||
this->_OpCounter += MVT::GetNumberVecs(X);
|
||||
}
|
||||
}
|
||||
else {
|
||||
MX = Teuchos::rcp(&X,false);
|
||||
}
|
||||
std::vector<MagnitudeType> normX(xc), invnormX(xc);
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> XtMX(xc,xc), workU(1,1);
|
||||
Teuchos::LAPACK<int,ScalarType> lapack;
|
||||
/**********************************************************************
|
||||
* allocate storage for eigenvectors,eigenvalues of X^T Op X, and for
|
||||
* the work space needed to compute this xc-by-xc eigendecomposition
|
||||
**********************************************************************/
|
||||
std::vector<ScalarType> work;
|
||||
std::vector<MagnitudeType> lambda, lambdahi, rwork;
|
||||
if (normalize) {
|
||||
// get size of work from ILAENV
|
||||
int lwork = lapack.ILAENV(1,"hetrd","VU",xc,-1,-1,-1);
|
||||
// lwork >= (nb+1)*n for complex
|
||||
// lwork >= (nb+2)*n for real
|
||||
TEST_FOR_EXCEPTION( lwork < 0, OrthoError,
|
||||
"Anasazi::SVQBOrthoManager::findBasis(): Error code from ILAENV" );
|
||||
|
||||
lwork = (lwork+2)*xc;
|
||||
work.resize(lwork);
|
||||
// size of rwork is max(1,3*xc-2)
|
||||
lwork = (3*xc-2 > 1) ? 3*xc - 2 : 1;
|
||||
rwork.resize(lwork);
|
||||
// size of lambda is xc
|
||||
lambda.resize(xc);
|
||||
lambdahi.resize(xc);
|
||||
workU.reshape(xc,xc);
|
||||
}
|
||||
|
||||
// test sizes of X,MX
|
||||
int mxc = (this->_hasOp) ? MVT::GetNumberVecs( *MX ) : xc;
|
||||
int mxr = (this->_hasOp) ? MVT::GetVecLength( *MX ) : xr;
|
||||
TEST_FOR_EXCEPTION( xc != mxc || xr != mxr, std::invalid_argument,
|
||||
"Anasazi::SVQBOrthoManager::findBasis(): Size of X not consistant with MX" );
|
||||
|
||||
// sentinel to continue the outer loop (perform another projection step)
|
||||
bool doGramSchmidt = true;
|
||||
// variable for testing orthonorm/orthog
|
||||
MagnitudeType tolerance = MONE/SCTM::squareroot(eps_);
|
||||
|
||||
// outer loop
|
||||
while (doGramSchmidt) {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// perform projection
|
||||
if (qsize > 0) {
|
||||
|
||||
numGS++;
|
||||
|
||||
// Compute the norms of the vectors
|
||||
normMat(X,MX,&normX);
|
||||
// normalize the vectors
|
||||
Teuchos::RCP<MV> Xi,MXi;
|
||||
std::vector<int> ind(1);
|
||||
for (int i=0; i<xc; i++) {
|
||||
invnormX[i] = (normX[i] == ZERO) ? ZERO : MONE/normX[i];
|
||||
ind[0] = i;
|
||||
Xi = MVT::CloneView(X,ind);
|
||||
MVT::MvAddMv(ZERO,*Xi,invnormX[i],*Xi,*Xi);
|
||||
Xi = Teuchos::null;
|
||||
if (this->_hasOp) {
|
||||
MXi = MVT::CloneView(*MX,ind);
|
||||
MVT::MvAddMv(ZERO,*MXi,invnormX[i],*MXi,*MXi);
|
||||
MXi = Teuchos::null;
|
||||
}
|
||||
}
|
||||
// check that vectors are normalized now
|
||||
if (debug_) {
|
||||
std::vector<MagnitudeType> nrm2(xc);
|
||||
std::cout << dbgstr << "max post-scale norm: (with/without MX) : ";
|
||||
MagnitudeType maxpsnw = ZERO, maxpsnwo = ZERO;
|
||||
normMat(X,MX,&nrm2);
|
||||
for (int i=0; i<xc; i++) {
|
||||
maxpsnw = (nrm2[i] > maxpsnw ? nrm2[i] : maxpsnw);
|
||||
}
|
||||
MatOrthoManager<ScalarType,MV,OP>::norm(X,&nrm2);
|
||||
for (int i=0; i<xc; i++) {
|
||||
maxpsnwo = (nrm2[i] > maxpsnwo ? nrm2[i] : maxpsnwo);
|
||||
}
|
||||
std::cout << "(" << maxpsnw << "," << maxpsnwo << ")" << std::endl;
|
||||
}
|
||||
// project the vectors onto the Qi
|
||||
for (int i=0; i<nq; i++) {
|
||||
innerProdMat(*Q[i],X,MX,*newC[i]);
|
||||
}
|
||||
// remove the components in Qi from X
|
||||
for (int i=0; i<nq; i++) {
|
||||
MVT::MvTimesMatAddMv(-ONE,*Q[i],*newC[i],ONE,X);
|
||||
}
|
||||
// un-scale the vectors
|
||||
for (int i=0; i<xc; i++) {
|
||||
ind[0] = i;
|
||||
Xi = MVT::CloneView(X,ind);
|
||||
MVT::MvAddMv(ZERO,*Xi,normX[i],*Xi,*Xi);
|
||||
Xi = Teuchos::null;
|
||||
}
|
||||
// Recompute the vectors in MX
|
||||
if (this->_hasOp) {
|
||||
OPT::Apply(*(this->_Op),X,*MX);
|
||||
this->_OpCounter += MVT::GetNumberVecs(X);
|
||||
}
|
||||
|
||||
//
|
||||
// Compute largest column norm of
|
||||
// ( C[0] )
|
||||
// C = ( .... )
|
||||
// ( C[nq-1] )
|
||||
MagnitudeType maxNorm = ZERO;
|
||||
for (int j=0; j<xc; j++) {
|
||||
MagnitudeType sum = ZERO;
|
||||
for (int k=0; k<nq; k++) {
|
||||
for (int i=0; i<qcs[k]; i++) {
|
||||
sum += SCT::magnitude((*newC[k])(i,j))*SCT::magnitude((*newC[k])(i,j));
|
||||
}
|
||||
}
|
||||
maxNorm = (sum > maxNorm) ? sum : maxNorm;
|
||||
}
|
||||
|
||||
// do we perform another GS?
|
||||
if (maxNorm < 0.36) {
|
||||
doGramSchmidt = false;
|
||||
}
|
||||
|
||||
// unscale newC to reflect the scaling of X
|
||||
for (int k=0; k<nq; k++) {
|
||||
for (int j=0; j<xc; j++) {
|
||||
for (int i=0; i<qcs[k]; i++) {
|
||||
(*newC[k])(i,j) *= normX[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
// accumulate into C
|
||||
if (normalize) {
|
||||
// we are normalizing
|
||||
int info;
|
||||
for (int i=0; i<nq; i++) {
|
||||
info = C[i]->multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,ONE,*newC[i],*B,ONE);
|
||||
TEST_FOR_EXCEPTION(info != 0, std::logic_error, "Anasazi::SVQBOrthoManager::findBasis(): Input error to SerialDenseMatrix::multiply.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
// not normalizing
|
||||
for (int i=0; i<nq; i++) {
|
||||
(*C[i]) += *newC[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // qsize == 0... don't perform projection
|
||||
// don't do any more outer loops; all we need is to call the normalize code below
|
||||
doGramSchmidt = false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// perform normalization
|
||||
if (normalize) {
|
||||
|
||||
MagnitudeType condT = tolerance;
|
||||
|
||||
while (condT >= tolerance) {
|
||||
|
||||
numSVQB++;
|
||||
|
||||
// compute X^T Op X
|
||||
innerProdMat(X,X,MX,XtMX);
|
||||
|
||||
// compute scaling matrix for XtMX: D^{.5} and D^{-.5} (D-half and D-half-inv)
|
||||
std::vector<MagnitudeType> Dh(xc), Dhi(xc);
|
||||
for (int i=0; i<xc; i++) {
|
||||
Dh[i] = SCT::magnitude(SCT::squareroot(XtMX(i,i)));
|
||||
Dhi[i] = (Dh[i] == ZERO ? ZERO : MONE/Dh[i]);
|
||||
}
|
||||
// scale XtMX : S = D^{-.5} * XtMX * D^{-.5}
|
||||
for (int i=0; i<xc; i++) {
|
||||
for (int j=0; j<xc; j++) {
|
||||
XtMX(i,j) *= Dhi[i]*Dhi[j];
|
||||
}
|
||||
}
|
||||
|
||||
// compute the eigenvalue decomposition of S=U*Lambda*U^T (using upper part)
|
||||
int info;
|
||||
lapack.HEEV('V', 'U', xc, XtMX.values(), XtMX.stride(), &lambda[0], &work[0], work.size(), &rwork[0], &info);
|
||||
TEST_FOR_EXCEPTION( info != 0, OrthoError,
|
||||
"Anasazi::SVQBOrthoManager::findBasis(): Error code from HEEV" );
|
||||
if (debug_) {
|
||||
std::cout << dbgstr << "eigenvalues of XtMX: (";
|
||||
for (int i=0; i<xc-1; i++) {
|
||||
std::cout << lambda[i] << ",";
|
||||
}
|
||||
std::cout << lambda[xc-1] << ")" << std::endl;
|
||||
}
|
||||
|
||||
// remember, HEEV orders the eigenvalues from smallest to largest
|
||||
// examine condition number of Lambda, compute Lambda^{-.5}
|
||||
MagnitudeType maxLambda = lambda[xc-1],
|
||||
minLambda = lambda[0];
|
||||
int iZeroMax = -1;
|
||||
for (int i=0; i<xc; i++) {
|
||||
if (lambda[i] < 10*eps_*maxLambda) { // finish: this was eps_*eps_*maxLambda
|
||||
iZeroMax = i;
|
||||
lambda[i] = ZERO;
|
||||
lambdahi[i] = ZERO;
|
||||
}
|
||||
/*
|
||||
else if (lambda[i] < eps_*maxLambda) {
|
||||
lambda[i] = SCTM::squareroot(eps_*maxLambda);
|
||||
lambdahi[i] = MONE/lambda[i];
|
||||
}
|
||||
*/
|
||||
else {
|
||||
lambda[i] = SCTM::squareroot(lambda[i]);
|
||||
lambdahi[i] = MONE/lambda[i];
|
||||
}
|
||||
}
|
||||
|
||||
// compute X * D^{-.5} * U * Lambda^{-.5} and new Op*X
|
||||
//
|
||||
// copy X into workX
|
||||
std::vector<int> ind(xc);
|
||||
for (int i=0; i<xc; i++) {ind[i] = i;}
|
||||
MVT::SetBlock(X,ind,*workX);
|
||||
//
|
||||
// compute D^{-.5}*U*Lambda^{-.5} into workU
|
||||
workU.assign(XtMX);
|
||||
for (int j=0; j<xc; j++) {
|
||||
for (int i=0; i<xc; i++) {
|
||||
workU(i,j) *= Dhi[i]*lambdahi[j];
|
||||
}
|
||||
}
|
||||
// compute workX * workU into X
|
||||
MVT::MvTimesMatAddMv(ONE,*workX,workU,ZERO,X);
|
||||
//
|
||||
// note, it seems important to apply Op exactly for large condition numbers.
|
||||
// for small condition numbers, we can update MX "implicitly"
|
||||
// this trick reduces the number of applications of Op
|
||||
if (this->_hasOp) {
|
||||
if (maxLambda >= tolerance * minLambda) {
|
||||
// explicit update of MX
|
||||
OPT::Apply(*(this->_Op),X,*MX);
|
||||
this->_OpCounter += MVT::GetNumberVecs(X);
|
||||
}
|
||||
else {
|
||||
// implicit update of MX
|
||||
// copy MX into workX
|
||||
MVT::SetBlock(*MX,ind,*workX);
|
||||
//
|
||||
// compute workX * workU into MX
|
||||
MVT::MvTimesMatAddMv(ONE,*workX,workU,ZERO,*MX);
|
||||
}
|
||||
}
|
||||
|
||||
// accumulate new B into previous B
|
||||
// B = Lh * U^H * Dh * B
|
||||
for (int j=0; j<xc; j++) {
|
||||
for (int i=0; i<xc; i++) {
|
||||
workU(i,j) = Dh[i] * (*B)(i,j);
|
||||
}
|
||||
}
|
||||
info = B->multiply(Teuchos::CONJ_TRANS,Teuchos::NO_TRANS,ONE,XtMX,workU,ZERO);
|
||||
TEST_FOR_EXCEPTION(info != 0, std::logic_error, "Anasazi::SVQBOrthoManager::findBasis(): Input error to SerialDenseMatrix::multiply.");
|
||||
for (int j=0; j<xc ;j++) {
|
||||
for (int i=0; i<xc; i++) {
|
||||
(*B)(i,j) *= lambda[i];
|
||||
}
|
||||
}
|
||||
|
||||
// check iZeroMax (rank indicator)
|
||||
if (iZeroMax >= 0) {
|
||||
if (debug_) {
|
||||
std::cout << dbgstr << "augmenting multivec with " << iZeroMax+1 << " random directions" << std::endl;
|
||||
}
|
||||
|
||||
numRand++;
|
||||
// put random info in the first iZeroMax+1 vectors of X,MX
|
||||
std::vector<int> ind(iZeroMax+1);
|
||||
for (int i=0; i<iZeroMax+1; i++) {
|
||||
ind[i] = i;
|
||||
}
|
||||
Teuchos::RCP<MV> Xnull,MXnull;
|
||||
Xnull = MVT::CloneView(X,ind);
|
||||
MVT::MvRandom(*Xnull);
|
||||
if (this->_hasOp) {
|
||||
MXnull = MVT::CloneView(*MX,ind);
|
||||
OPT::Apply(*(this->_Op),*Xnull,*MXnull);
|
||||
this->_OpCounter += MVT::GetNumberVecs(*Xnull);
|
||||
MXnull = Teuchos::null;
|
||||
}
|
||||
Xnull = Teuchos::null;
|
||||
condT = tolerance;
|
||||
doGramSchmidt = true;
|
||||
break; // break from while(condT > tolerance)
|
||||
}
|
||||
|
||||
condT = SCTM::magnitude(maxLambda / minLambda);
|
||||
if (debug_) {
|
||||
std::cout << dbgstr << "condT: " << condT << std::endl;
|
||||
}
|
||||
|
||||
} // end while (condT >= tolerance)
|
||||
|
||||
if ((doGramSchmidt == false) && (condT > SCTM::squareroot(tolerance))) {
|
||||
doGramSchmidt = true;
|
||||
}
|
||||
}
|
||||
// end if(normalize)
|
||||
|
||||
} // end while (doGramSchmidt)
|
||||
|
||||
if (debug_) {
|
||||
std::cout << dbgstr << "(numGS,numSVQB,numRand) : "
|
||||
<< "(" << numGS
|
||||
<< "," << numSVQB
|
||||
<< "," << numRand
|
||||
<< ")" << std::endl;
|
||||
}
|
||||
|
||||
return xc;
|
||||
}
|
||||
|
||||
} // namespace Anasazi
|
||||
|
||||
#endif // ANASAZI_SVQB_ORTHOMANAGER_HPP
|
||||
|
||||
@@ -0,0 +1,398 @@
|
||||
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
|
||||
#ifndef ANASAZI_SIMPLE_LOBPCG_SOLMGR_HPP
|
||||
#define ANASAZI_SIMPLE_LOBPCG_SOLMGR_HPP
|
||||
|
||||
/*! \file AnasaziSimpleLOBPCGSolMgr.hpp
|
||||
\brief The Anasazi::SimpleLOBPCGSolMgr provides a simple solver manager over the LOBPCG
|
||||
eigensolver.
|
||||
*/
|
||||
|
||||
#include "AnasaziConfigDefs.hpp"
|
||||
#include "AnasaziTypes.hpp"
|
||||
|
||||
#include "AnasaziEigenproblem.hpp"
|
||||
#include "AnasaziSolverManager.hpp"
|
||||
|
||||
#include "AnasaziLOBPCG.hpp"
|
||||
#include "AnasaziBasicSort.hpp"
|
||||
#include "AnasaziSVQBOrthoManager.hpp"
|
||||
#include "AnasaziStatusTestMaxIters.hpp"
|
||||
#include "AnasaziStatusTestResNorm.hpp"
|
||||
#include "AnasaziStatusTestCombo.hpp"
|
||||
#include "AnasaziStatusTestOutput.hpp"
|
||||
#include "AnasaziBasicOutputManager.hpp"
|
||||
#include "AnasaziSolverUtils.hpp"
|
||||
|
||||
#include "Teuchos_TimeMonitor.hpp"
|
||||
|
||||
/** \example LOBPCG/LOBPCGEpetraExSimple.cpp
|
||||
This is an example of how to use the Anasazi::SimpleLOBPCGSolMgr solver manager.
|
||||
*/
|
||||
|
||||
/*! \class Anasazi::SimpleLOBPCGSolMgr
|
||||
\brief The Anasazi::SimpleLOBPCGSolMgr provides a simple solver
|
||||
manager over the LOBPCG eigensolver.
|
||||
|
||||
Anasazi::SimpleLOBPCGSolMgr allows the user to specify convergence
|
||||
tolerance, verbosity level and block size. When block size is less than the
|
||||
number of requested eigenvalues specified in the eigenproblem, checkpointing
|
||||
is activated.
|
||||
|
||||
The purpose of this solver manager was to provide an example of a simple
|
||||
solver manager, useful for demonstration as well as a jumping-off point for
|
||||
solvermanager development. Also, the solver manager is useful for testing
|
||||
some of the features of the Anasazi::LOBPCG eigensolver, principally the use
|
||||
of auxiliary vectors.
|
||||
|
||||
This solver manager does not verify before quitting that the nev eigenvectors
|
||||
that have converged are also the smallest nev eigenvectors that are known.
|
||||
|
||||
\ingroup anasazi_solver_framework
|
||||
|
||||
\author Chris Baker, Ulrich Hetmaniuk, Rich Lehoucq, Heidi Thornquist
|
||||
*/
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
template<class ScalarType, class MV, class OP>
|
||||
class SimpleLOBPCGSolMgr : public SolverManager<ScalarType,MV,OP> {
|
||||
|
||||
private:
|
||||
typedef MultiVecTraits<ScalarType,MV> MVT;
|
||||
typedef Teuchos::ScalarTraits<ScalarType> SCT;
|
||||
typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
|
||||
typedef Teuchos::ScalarTraits<MagnitudeType> MT;
|
||||
|
||||
public:
|
||||
|
||||
//!@name Constructors/Destructor
|
||||
//@{
|
||||
|
||||
/*! \brief Basic constructor for SimpleLOBPCGSolMgr.
|
||||
*
|
||||
* This constructor accepts the Eigenproblem to be solved in addition
|
||||
* to a parameter list of options for the solver manager. These options include the following:
|
||||
* - "Which" - a \c string specifying the desired eigenvalues: SM, LM, SR or LR. Default: SR
|
||||
* - "Block Size" - a \c int specifying the block size to be used by the underlying LOBPCG solver. Default: problem->getNEV()
|
||||
* - "Maximum Iterations" - a \c int specifying the maximum number of iterations the underlying solver is allowed to perform. Default: 100
|
||||
* - "Verbosity" - a sum of MsgType specifying the verbosity. Default: Anasazi::Errors
|
||||
* - "Convergence Tolerance" - a \c MagnitudeType specifying the level that residual norms must reach to decide convergence. Default: machine precision
|
||||
*/
|
||||
SimpleLOBPCGSolMgr( const Teuchos::RCP<Eigenproblem<ScalarType,MV,OP> > &problem,
|
||||
Teuchos::ParameterList &pl );
|
||||
|
||||
//! Destructor.
|
||||
virtual ~SimpleLOBPCGSolMgr() {};
|
||||
//@}
|
||||
|
||||
//! @name Accessor methods
|
||||
//@{
|
||||
|
||||
const Eigenproblem<ScalarType,MV,OP>& getProblem() const {
|
||||
return *problem_;
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Solver application methods
|
||||
//@{
|
||||
|
||||
/*! \brief This method performs possibly repeated calls to the underlying eigensolver's iterate() routine
|
||||
* until the problem has been solved (as decided by the solver manager) or the solver manager decides to
|
||||
* quit.
|
||||
*
|
||||
* \returns ::ReturnType specifying:
|
||||
* - ::Converged: the eigenproblem was solved to the specification required by the solver manager.
|
||||
* - ::Unconverged: the eigenproblem was not solved to the specification desired by the solver manager
|
||||
*/
|
||||
ReturnType solve();
|
||||
//@}
|
||||
|
||||
private:
|
||||
Teuchos::RCP<Eigenproblem<ScalarType,MV,OP> > problem_;
|
||||
std::string whch_;
|
||||
MagnitudeType tol_;
|
||||
int verb_;
|
||||
int blockSize_;
|
||||
int maxIters_;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<class ScalarType, class MV, class OP>
|
||||
SimpleLOBPCGSolMgr<ScalarType,MV,OP>::SimpleLOBPCGSolMgr(
|
||||
const Teuchos::RCP<Eigenproblem<ScalarType,MV,OP> > &problem,
|
||||
Teuchos::ParameterList &pl ) :
|
||||
problem_(problem),
|
||||
whch_("LM"),
|
||||
tol_(1e-6),
|
||||
verb_(Anasazi::Errors),
|
||||
blockSize_(0),
|
||||
maxIters_(100)
|
||||
{
|
||||
TEST_FOR_EXCEPTION(problem_ == Teuchos::null, std::invalid_argument, "Problem not given to solver manager.");
|
||||
TEST_FOR_EXCEPTION(!problem_->isProblemSet(), std::invalid_argument, "Problem not set.");
|
||||
TEST_FOR_EXCEPTION(!problem_->isHermitian(), std::invalid_argument, "Problem not symmetric.");
|
||||
TEST_FOR_EXCEPTION(problem_->getInitVec() == Teuchos::null,std::invalid_argument, "Problem does not contain initial vectors to clone from.");
|
||||
|
||||
whch_ = pl.get("Which","SR");
|
||||
TEST_FOR_EXCEPTION(whch_ != "SM" && whch_ != "LM" && whch_ != "SR" && whch_ != "LR",
|
||||
AnasaziError,
|
||||
"SimpleLOBPCGSolMgr: \"Which\" parameter must be SM, LM, SR or LR.");
|
||||
|
||||
tol_ = pl.get("Convergence Tolerance",tol_);
|
||||
TEST_FOR_EXCEPTION(tol_ <= 0,
|
||||
AnasaziError,
|
||||
"SimpleLOBPCGSolMgr: \"Tolerance\" parameter must be strictly postiive.");
|
||||
|
||||
// verbosity level
|
||||
if (pl.isParameter("Verbosity")) {
|
||||
if (Teuchos::isParameterType<int>(pl,"Verbosity")) {
|
||||
verb_ = pl.get("Verbosity", verb_);
|
||||
} else {
|
||||
verb_ = (int)Teuchos::getParameter<Anasazi::MsgType>(pl,"Verbosity");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
blockSize_= pl.get("Block Size",problem_->getNEV());
|
||||
TEST_FOR_EXCEPTION(blockSize_ <= 0,
|
||||
AnasaziError,
|
||||
"SimpleLOBPCGSolMgr: \"Block Size\" parameter must be strictly positive.");
|
||||
|
||||
maxIters_ = pl.get("Maximum Iterations",maxIters_);
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<class ScalarType, class MV, class OP>
|
||||
ReturnType
|
||||
SimpleLOBPCGSolMgr<ScalarType,MV,OP>::solve() {
|
||||
|
||||
// sort manager
|
||||
Teuchos::RCP<BasicSort<ScalarType,MV,OP> > sorter = Teuchos::rcp( new BasicSort<ScalarType,MV,OP>(whch_) );
|
||||
// output manager
|
||||
Teuchos::RCP<BasicOutputManager<ScalarType> > printer = Teuchos::rcp( new BasicOutputManager<ScalarType>(verb_) );
|
||||
// status tests
|
||||
Teuchos::RCP<StatusTestMaxIters<ScalarType,MV,OP> > max;
|
||||
if (maxIters_ > 0) {
|
||||
max = Teuchos::rcp( new StatusTestMaxIters<ScalarType,MV,OP>(maxIters_) );
|
||||
}
|
||||
else {
|
||||
max = Teuchos::null;
|
||||
}
|
||||
Teuchos::RCP<StatusTestResNorm<ScalarType,MV,OP> > norm
|
||||
= Teuchos::rcp( new StatusTestResNorm<ScalarType,MV,OP>(tol_) );
|
||||
Teuchos::Array< Teuchos::RCP<StatusTest<ScalarType,MV,OP> > > alltests;
|
||||
alltests.push_back(norm);
|
||||
if (max != Teuchos::null) alltests.push_back(max);
|
||||
Teuchos::RCP<StatusTestCombo<ScalarType,MV,OP> > combo
|
||||
= Teuchos::rcp( new StatusTestCombo<ScalarType,MV,OP>(
|
||||
StatusTestCombo<ScalarType,MV,OP>::OR, alltests
|
||||
));
|
||||
// printing StatusTest
|
||||
Teuchos::RCP<StatusTestOutput<ScalarType,MV,OP> > outputtest
|
||||
= Teuchos::rcp( new StatusTestOutput<ScalarType,MV,OP>( printer,combo,1,Passed ) );
|
||||
// orthomanager
|
||||
Teuchos::RCP<SVQBOrthoManager<ScalarType,MV,OP> > ortho
|
||||
= Teuchos::rcp( new SVQBOrthoManager<ScalarType,MV,OP>(problem_->getM()) );
|
||||
// parameter list
|
||||
Teuchos::ParameterList plist;
|
||||
plist.set("Block Size",blockSize_);
|
||||
plist.set("Full Ortho",true);
|
||||
|
||||
// create an LOBPCG solver
|
||||
Teuchos::RCP<LOBPCG<ScalarType,MV,OP> > lobpcg_solver
|
||||
= Teuchos::rcp( new LOBPCG<ScalarType,MV,OP>(problem_,sorter,printer,outputtest,ortho,plist) );
|
||||
// add the auxillary vecs from the eigenproblem to the solver
|
||||
if (problem_->getAuxVecs() != Teuchos::null) {
|
||||
lobpcg_solver->setAuxVecs( Teuchos::tuple<Teuchos::RCP<const MV> >(problem_->getAuxVecs()) );
|
||||
}
|
||||
|
||||
int numfound = 0;
|
||||
int nev = problem_->getNEV();
|
||||
Teuchos::Array< Teuchos::RCP<MV> > foundvecs;
|
||||
Teuchos::Array< Teuchos::RCP< std::vector<MagnitudeType> > > foundvals;
|
||||
while (numfound < nev) {
|
||||
// reduce the strain on norm test, if we are almost done
|
||||
if (nev - numfound < blockSize_) {
|
||||
norm->setQuorum(nev-numfound);
|
||||
}
|
||||
|
||||
// tell the solver to iterate
|
||||
try {
|
||||
lobpcg_solver->iterate();
|
||||
}
|
||||
catch (std::exception e) {
|
||||
// we are a simple solver manager. we don't catch exceptions. set solution empty, then rethrow.
|
||||
printer->stream(Anasazi::Errors) << "Exception: " << e.what() << std::endl;
|
||||
Eigensolution<ScalarType,MV> sol;
|
||||
sol.numVecs = 0;
|
||||
problem_->setSolution(sol);
|
||||
throw;
|
||||
}
|
||||
|
||||
// check the status tests
|
||||
if (norm->getStatus() == Passed) {
|
||||
|
||||
int num = norm->howMany();
|
||||
// if num < blockSize_, it is because we are on the last iteration: num+numfound>=nev
|
||||
TEST_FOR_EXCEPTION(num < blockSize_ && num+numfound < nev,
|
||||
std::logic_error,
|
||||
"Anasazi::SimpleLOBPCGSolMgr::solve(): logic error.");
|
||||
std::vector<int> ind = norm->whichVecs();
|
||||
// just grab the ones that we need
|
||||
if (num + numfound > nev) {
|
||||
num = nev - numfound;
|
||||
ind.resize(num);
|
||||
}
|
||||
|
||||
// copy the converged eigenvectors
|
||||
Teuchos::RCP<MV> newvecs = MVT::CloneCopy(*lobpcg_solver->getRitzVectors(),ind);
|
||||
// store them
|
||||
foundvecs.push_back(newvecs);
|
||||
// add them as auxiliary vectors
|
||||
Teuchos::Array<Teuchos::RCP<const MV> > auxvecs = lobpcg_solver->getAuxVecs();
|
||||
auxvecs.push_back(newvecs);
|
||||
// setAuxVecs() will reset the solver to uninitialized, without messing with numIters()
|
||||
lobpcg_solver->setAuxVecs(auxvecs);
|
||||
|
||||
// copy the converged eigenvalues
|
||||
Teuchos::RCP<std::vector<MagnitudeType> > newvals = Teuchos::rcp( new std::vector<MagnitudeType>(num) );
|
||||
std::vector<Value<ScalarType> > all = lobpcg_solver->getRitzValues();
|
||||
for (int i=0; i<num; i++) {
|
||||
(*newvals)[i] = all[ind[i]].realpart;
|
||||
}
|
||||
foundvals.push_back(newvals);
|
||||
|
||||
numfound += num;
|
||||
}
|
||||
else if (max != Teuchos::null && max->getStatus() == Passed) {
|
||||
|
||||
int num = norm->howMany();
|
||||
std::vector<int> ind = norm->whichVecs();
|
||||
|
||||
if (num > 0) {
|
||||
// copy the converged eigenvectors
|
||||
Teuchos::RCP<MV> newvecs = MVT::CloneCopy(*lobpcg_solver->getRitzVectors(),ind);
|
||||
// orthornormalize to be safe
|
||||
ortho->normalizeMat(*newvecs,Teuchos::null,Teuchos::null);
|
||||
// store them
|
||||
foundvecs.push_back(newvecs);
|
||||
// don't bother adding them as auxiliary vectors; we have reached maxiters and are going to quit
|
||||
|
||||
// copy the converged eigenvalues
|
||||
Teuchos::RCP<std::vector<MagnitudeType> > newvals = Teuchos::rcp( new std::vector<MagnitudeType>(num) );
|
||||
std::vector<Value<ScalarType> > all = lobpcg_solver->getRitzValues();
|
||||
for (int i=0; i<num; i++) {
|
||||
(*newvals)[i] = all[ind[i]].realpart;
|
||||
}
|
||||
foundvals.push_back(newvals);
|
||||
|
||||
numfound += num;
|
||||
}
|
||||
break; // while(numfound < nev)
|
||||
}
|
||||
else {
|
||||
TEST_FOR_EXCEPTION(true,std::logic_error,"Anasazi::SimpleLOBPCGSolMgr::solve(): solver returned without satisfy status test.");
|
||||
}
|
||||
} // end of while(numfound < nev)
|
||||
|
||||
TEST_FOR_EXCEPTION(foundvecs.size() != foundvals.size(),std::logic_error,"Anasazi::SimpleLOBPCGSolMgr::solve(): inconsistent array sizes");
|
||||
|
||||
// create contiguous storage for all eigenvectors, eigenvalues
|
||||
Eigensolution<ScalarType,MV> sol;
|
||||
sol.numVecs = numfound;
|
||||
if (numfound > 0) {
|
||||
// allocate space for eigenvectors
|
||||
sol.Evecs = MVT::Clone(*problem_->getInitVec(),numfound);
|
||||
}
|
||||
else {
|
||||
sol.Evecs = Teuchos::null;
|
||||
}
|
||||
sol.Espace = sol.Evecs;
|
||||
// allocate space for eigenvalues
|
||||
std::vector<MagnitudeType> vals(numfound);
|
||||
sol.Evals.resize(numfound);
|
||||
// all real eigenvalues: set index vectors [0,...,numfound-1]
|
||||
sol.index.resize(numfound,0);
|
||||
// store eigenvectors, eigenvalues
|
||||
int curttl = 0;
|
||||
for (unsigned int i=0; i<foundvals.size(); i++) {
|
||||
TEST_FOR_EXCEPTION((signed int)(foundvals[i]->size()) != MVT::GetNumberVecs(*foundvecs[i]), std::logic_error, "Anasazi::SimpleLOBPCGSolMgr::solve(): inconsistent sizes");
|
||||
unsigned int lclnum = foundvals[i]->size();
|
||||
std::vector<int> lclind(lclnum);
|
||||
for (unsigned int j=0; j<lclnum; j++) lclind[j] = curttl+j;
|
||||
// put the eigenvectors
|
||||
MVT::SetBlock(*foundvecs[i],lclind,*sol.Evecs);
|
||||
// put the eigenvalues
|
||||
copy( foundvals[i]->begin(), foundvals[i]->end(), vals.begin()+curttl );
|
||||
|
||||
curttl += lclnum;
|
||||
}
|
||||
TEST_FOR_EXCEPTION( curttl != sol.numVecs, std::logic_error, "Anasazi::SimpleLOBPCGSolMgr::solve(): inconsistent sizes");
|
||||
|
||||
// sort the eigenvalues and permute the eigenvectors appropriately
|
||||
if (numfound > 0) {
|
||||
std::vector<int> order(sol.numVecs);
|
||||
sorter->sort( lobpcg_solver.get(), sol.numVecs, vals, &order );
|
||||
// store the values in the Eigensolution
|
||||
for (int i=0; i<sol.numVecs; i++) {
|
||||
sol.Evals[i].realpart = vals[i];
|
||||
sol.Evals[i].imagpart = MT::zero();
|
||||
}
|
||||
// now permute the eigenvectors according to order
|
||||
SolverUtils<ScalarType,MV,OP> msutils;
|
||||
msutils.permuteVectors(sol.numVecs,order,*sol.Evecs);
|
||||
}
|
||||
|
||||
// print final summary
|
||||
lobpcg_solver->currentStatus(printer->stream(FinalSummary));
|
||||
|
||||
// print timing information
|
||||
Teuchos::TimeMonitor::summarize(printer->stream(TimingDetails));
|
||||
|
||||
// send the solution to the eigenproblem
|
||||
problem_->setSolution(sol);
|
||||
printer->stream(Debug) << "Returning " << sol.numVecs << " eigenpairs to eigenproblem." << std::endl;
|
||||
|
||||
// return from SolMgr::solve()
|
||||
if (sol.numVecs < nev) return Unconverged;
|
||||
return Converged;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // end Anasazi namespace
|
||||
|
||||
#endif /* ANASAZI_SIMPLE_LOBPCG_SOLMGR_HPP */
|
||||
@@ -0,0 +1,90 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
|
||||
#ifndef ANASAZI_SOLVERMANAGER_HPP
|
||||
#define ANASAZI_SOLVERMANAGER_HPP
|
||||
|
||||
/*! \file AnasaziSolverManager.hpp
|
||||
\brief Pure virtual base class which describes the basic interface for a solver manager.
|
||||
*/
|
||||
|
||||
#include "AnasaziConfigDefs.hpp"
|
||||
#include "AnasaziTypes.hpp"
|
||||
#include "AnasaziEigenproblem.hpp"
|
||||
|
||||
#include "Teuchos_ParameterList.hpp"
|
||||
#include "Teuchos_RCP.hpp"
|
||||
|
||||
/*! \class Anasazi::SolverManager
|
||||
\brief The Anasazi::SolverManager is a templated virtual base class that defines the
|
||||
basic interface that any solver manager will support.
|
||||
*/
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
template<class ScalarType, class MV, class OP>
|
||||
class SolverManager {
|
||||
|
||||
public:
|
||||
|
||||
//!@name Constructors/Destructor
|
||||
//@{
|
||||
|
||||
//! Empty constructor.
|
||||
SolverManager() {};
|
||||
|
||||
//! Destructor.
|
||||
virtual ~SolverManager() {};
|
||||
//@}
|
||||
|
||||
//! @name Accessor methods
|
||||
//@{
|
||||
|
||||
virtual const Eigenproblem<ScalarType,MV,OP>& getProblem() const = 0;
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Solver application methods
|
||||
//@{
|
||||
|
||||
/*! \brief This method performs possibly repeated calls to the underlying eigensolver's iterate() routine
|
||||
* until the problem has been solved (as decided by the solver manager) or the solver manager decides to
|
||||
* quit.
|
||||
*
|
||||
* \returns ::ReturnType specifying:
|
||||
* - ::Converged: the eigenproblem was solved to the specification required by the solver manager.
|
||||
* - ::Unconverged: the eigenproblem was not solved to the specification desired by the solver manager
|
||||
*/
|
||||
virtual ReturnType solve() = 0;
|
||||
//@}
|
||||
|
||||
};
|
||||
|
||||
} // end Anasazi namespace
|
||||
|
||||
#endif /* ANASAZI_SOLVERMANAGER_HPP */
|
||||
@@ -0,0 +1,680 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
|
||||
#ifndef ANASAZI_SOLVER_UTILS_HPP
|
||||
#define ANASAZI_SOLVER_UTILS_HPP
|
||||
|
||||
/*! \file AnasaziSolverUtils.hpp
|
||||
\brief Class which provides internal utilities for the Anasazi solvers.
|
||||
*/
|
||||
|
||||
/*! \class Anasazi::SolverUtils
|
||||
\brief Anasazi's templated, static class providing utilities for
|
||||
the solvers.
|
||||
|
||||
This class provides concrete, templated implementations of utilities necessary
|
||||
for the solvers. These utilities include
|
||||
sorting, orthogonalization, projecting/solving local eigensystems, and sanity
|
||||
checking. These are internal utilties, so the user should not alter this class.
|
||||
|
||||
\author Ulrich Hetmaniuk, Rich Lehoucq, and Heidi Thornquist
|
||||
*/
|
||||
|
||||
#include "AnasaziConfigDefs.hpp"
|
||||
#include "AnasaziMultiVecTraits.hpp"
|
||||
#include "AnasaziOperatorTraits.hpp"
|
||||
#include "Teuchos_ScalarTraits.hpp"
|
||||
|
||||
#include "AnasaziOutputManager.hpp"
|
||||
#include "Teuchos_BLAS.hpp"
|
||||
#include "Teuchos_LAPACK.hpp"
|
||||
#include "Teuchos_SerialDenseMatrix.hpp"
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
template<class ScalarType, class MV, class OP>
|
||||
class SolverUtils
|
||||
{
|
||||
public:
|
||||
typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
|
||||
typedef typename Teuchos::ScalarTraits<ScalarType> SCT;
|
||||
|
||||
//! @name Constructor/Destructor
|
||||
//@{
|
||||
|
||||
//! Constructor.
|
||||
SolverUtils();
|
||||
|
||||
//! Destructor.
|
||||
virtual ~SolverUtils() {};
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Sorting Methods
|
||||
//@{
|
||||
|
||||
//! Permute the vectors in a multivector according to the permutation vector \c perm, and optionally the residual vector \c resids
|
||||
static void permuteVectors(const int n, const std::vector<int> &perm, MV &Q, std::vector< typename Teuchos::ScalarTraits<ScalarType>::magnitudeType >* resids = 0);
|
||||
|
||||
//! Permute the columns of a Teuchos::SerialDenseMatrix according to the permutation vector \c perm
|
||||
static void permuteVectors(const std::vector<int> &perm, Teuchos::SerialDenseMatrix<int,ScalarType> &Q);
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Basis update methods
|
||||
//@{
|
||||
|
||||
//! Apply a sequence of Householder reflectors (from \c GEQRF) to a multivector, using minimal workspace.
|
||||
/*!
|
||||
@param k [in] the number of Householder reflectors composing the product
|
||||
@param V [in/out] the multivector to be modified, with \f$n\f$ columns
|
||||
@param H [in] a \f$n \times k\f$ matrix containing the encoded Householder vectors, as returned from \c GEQRF (see below)
|
||||
@param tau [in] the \f$n\f$ coefficients for the Householder reflects, as returned from \c GEQRF
|
||||
@param workMV [work] (optional) a multivector used for workspace. it need contain only a single vector; it if contains more, only the first vector will be modified.
|
||||
|
||||
This routine applies a sequence of Householder reflectors, \f$H_1 H_2 \cdots H_k\f$, to a multivector \f$V\f$. The
|
||||
reflectors are applied individually, as rank-one updates to the multivector. The benefit of this is that the only
|
||||
required workspace is a one-column multivector. This workspace can be provided by the user. If it is not, it will
|
||||
be allocated locally on each call to applyHouse.
|
||||
|
||||
Each \f$H_i\f$ (\f$i=1,\ldots,k \leq n\f$) has the form<br>
|
||||
\f$ H_i = I - \tau_i v_i v_i^T \f$ <br>
|
||||
where \f$\tau_i\f$ is a scalar and \f$v_i\f$ is a vector with
|
||||
\f$v_i(1:i-1) = 0\f$ and \f$e_i^T v_i = 1\f$; \f$v(i+1:n)\f$ is stored below <tt>H(i,i)</tt>
|
||||
and \f$\tau_i\f$ in <tt>tau[i-1]</tt>. (Note: zero-based indexing used for data structures \c H and \c tau, while one-based indexing used for mathematic object \f$v_i\f$).
|
||||
|
||||
If the multivector is \f$m \times n\f$ and we apply \f$k\f$ Householder reflectors, the total cost of the method is
|
||||
\f$4mnk - 2m(k^2-k)\f$ flops. For \f$k=n\f$, this becomes \f$2mn^2\f$, the same as for a matrix-matrix multiplication by the accumulated Householder reflectors.
|
||||
*/
|
||||
static void applyHouse(int k, MV &V, const Teuchos::SerialDenseMatrix<int,ScalarType> &H, const std::vector<ScalarType> &tau, Teuchos::RCP<MV> workMV = Teuchos::null);
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Eigensolver Projection Methods
|
||||
//@{
|
||||
|
||||
//! Routine for computing the first NEV generalized eigenpairs of the Hermitian pencil <tt>(KK, MM)</tt>
|
||||
/*!
|
||||
@param size [in] Dimension of the eigenproblem (KK, MM)
|
||||
@param KK [in] Hermitian "stiffness" matrix
|
||||
@param MM [in] Hermitian positive-definite "mass" matrix
|
||||
@param EV [in] Dense matrix to store the nev eigenvectors
|
||||
@param theta [in] Array to store the eigenvalues (Size = nev )
|
||||
@param nev [in/out] Number of the smallest eigenvalues requested (in) / computed (out)
|
||||
@param esType [in] Flag to select the algorithm
|
||||
<ul>
|
||||
<li> esType = 0 (default) Uses LAPACK routine (Cholesky factorization of MM)
|
||||
with deflation of MM to get orthonormality of
|
||||
eigenvectors (\f$S^TMMS = I\f$)
|
||||
<li> esType = 1 Uses LAPACK routine (Cholesky factorization of MM)
|
||||
(no check of orthonormality)
|
||||
<li> esType = 10 Uses LAPACK routine for simple eigenproblem on KK
|
||||
(MM is not referenced in this case)
|
||||
</ul>
|
||||
|
||||
\note The code accesses only the upper triangular part of KK and MM.
|
||||
\return Integer \c info on the status of the computation
|
||||
// Return the integer info on the status of the computation
|
||||
<ul>
|
||||
<li> info = 0 >> Success
|
||||
<li> info = - 20 >> Failure in LAPACK routine
|
||||
</ul>
|
||||
*/
|
||||
static int directSolver(int size, const Teuchos::SerialDenseMatrix<int,ScalarType> &KK,
|
||||
Teuchos::RCP<const Teuchos::SerialDenseMatrix<int,ScalarType> > MM,
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> &EV,
|
||||
std::vector< typename Teuchos::ScalarTraits<ScalarType>::magnitudeType > &theta,
|
||||
int &nev, int esType = 0);
|
||||
//@}
|
||||
|
||||
//! @name Sanity Checking Methods
|
||||
//@{
|
||||
|
||||
//! Return the maximum coefficient of the matrix \f$M * X - MX\f$ scaled by the maximum coefficient of \c MX.
|
||||
/*! \note When \c M is not specified, the identity is used.
|
||||
*/
|
||||
static typename Teuchos::ScalarTraits<ScalarType>::magnitudeType errorEquality(const MV &X, const MV &MX, Teuchos::RCP<const OP> M = Teuchos::null);
|
||||
|
||||
//@}
|
||||
|
||||
private:
|
||||
|
||||
//! @name Internal Typedefs
|
||||
//@{
|
||||
|
||||
typedef MultiVecTraits<ScalarType,MV> MVT;
|
||||
typedef OperatorTraits<ScalarType,MV,OP> OPT;
|
||||
|
||||
//@}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// CONSTRUCTOR
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template<class ScalarType, class MV, class OP>
|
||||
SolverUtils<ScalarType, MV, OP>::SolverUtils() {}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// SORTING METHODS
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// permuteVectors for MV
|
||||
template<class ScalarType, class MV, class OP>
|
||||
void SolverUtils<ScalarType, MV, OP>::permuteVectors(
|
||||
const int n,
|
||||
const std::vector<int> &perm,
|
||||
MV &Q,
|
||||
std::vector< typename Teuchos::ScalarTraits<ScalarType>::magnitudeType >* resids)
|
||||
{
|
||||
// Permute the vectors according to the permutation vector \c perm, and
|
||||
// optionally the residual vector \c resids
|
||||
|
||||
int i, j;
|
||||
std::vector<int> permcopy(perm), swapvec(n-1);
|
||||
std::vector<int> index(1);
|
||||
ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
|
||||
ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
|
||||
|
||||
TEST_FOR_EXCEPTION(n > MVT::GetNumberVecs(Q), std::invalid_argument, "Anasazi::SolverUtils::permuteVectors(): argument n larger than width of input multivector.");
|
||||
|
||||
// We want to recover the elementary permutations (individual swaps)
|
||||
// from the permutation vector. Do this by constructing the inverse
|
||||
// of the permutation, by sorting them to {1,2,...,n}, and recording
|
||||
// the elementary permutations of the inverse.
|
||||
for (i=0; i<n-1; i++) {
|
||||
//
|
||||
// find i in the permcopy vector
|
||||
for (j=i; j<n; j++) {
|
||||
if (permcopy[j] == i) {
|
||||
// found it at index j
|
||||
break;
|
||||
}
|
||||
TEST_FOR_EXCEPTION(j == n-1, std::invalid_argument, "Anasazi::SolverUtils::permuteVectors(): permutation index invalid.");
|
||||
}
|
||||
//
|
||||
// Swap two scalars
|
||||
std::swap<int>( permcopy[j], permcopy[i] );
|
||||
|
||||
swapvec[i] = j;
|
||||
}
|
||||
|
||||
// now apply the elementary permutations of the inverse in reverse order
|
||||
for (i=n-2; i>=0; i--) {
|
||||
j = swapvec[i];
|
||||
//
|
||||
// Swap (i,j)
|
||||
//
|
||||
// Swap residuals (if they exist)
|
||||
if (resids) {
|
||||
std::swap<MagnitudeType>( (*resids)[i], (*resids)[j] );
|
||||
}
|
||||
//
|
||||
// Swap corresponding vectors
|
||||
index[0] = j;
|
||||
Teuchos::RCP<MV> tmpQ = MVT::CloneCopy( Q, index );
|
||||
Teuchos::RCP<MV> tmpQj = MVT::CloneView( Q, index );
|
||||
index[0] = i;
|
||||
Teuchos::RCP<MV> tmpQi = MVT::CloneView( Q, index );
|
||||
MVT::MvAddMv( one, *tmpQi, zero, *tmpQi, *tmpQj );
|
||||
MVT::MvAddMv( one, *tmpQ, zero, *tmpQ, *tmpQi );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// permuteVectors for MV
|
||||
template<class ScalarType, class MV, class OP>
|
||||
void SolverUtils<ScalarType, MV, OP>::permuteVectors(
|
||||
const std::vector<int> &perm,
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> &Q)
|
||||
{
|
||||
// Permute the vectors in Q according to the permutation vector \c perm, and
|
||||
// optionally the residual vector \c resids
|
||||
Teuchos::BLAS<int,ScalarType> blas;
|
||||
const int n = perm.size();
|
||||
const int m = Q.numRows();
|
||||
|
||||
TEST_FOR_EXCEPTION(n != Q.numCols(), std::invalid_argument, "Anasazi::SolverUtils::permuteVectors(): size of permutation vector not equal to number of columns.");
|
||||
|
||||
// Sort the primitive ritz vectors
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> copyQ( Q );
|
||||
for (int i=0; i<n; i++) {
|
||||
blas.COPY(m, copyQ[perm[i]], 1, Q[i], 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// BASIS UPDATE METHODS
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// apply householder reflectors to multivector
|
||||
template<class ScalarType, class MV, class OP>
|
||||
void SolverUtils<ScalarType, MV, OP>::applyHouse(int k, MV &V, const Teuchos::SerialDenseMatrix<int,ScalarType> &H, const std::vector<ScalarType> &tau, Teuchos::RCP<MV> workMV) {
|
||||
|
||||
const int n = MVT::GetNumberVecs(V);
|
||||
const ScalarType ONE = SCT::one();
|
||||
const ScalarType ZERO = SCT::zero();
|
||||
|
||||
// early exit if V has zero-size or if k==0
|
||||
if (MVT::GetNumberVecs(V) == 0 || MVT::GetVecLength(V) == 0 || k == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (workMV == Teuchos::null) {
|
||||
// user did not give us any workspace; allocate some
|
||||
workMV = MVT::Clone(V,1);
|
||||
}
|
||||
else if (MVT::GetNumberVecs(*workMV) > 1) {
|
||||
std::vector<int> first(1);
|
||||
first[0] = 0;
|
||||
workMV = MVT::CloneView(*workMV,first);
|
||||
}
|
||||
else {
|
||||
TEST_FOR_EXCEPTION(MVT::GetNumberVecs(*workMV) < 1,std::invalid_argument,"Anasazi::SolverUtils::applyHouse(): work multivector was empty.");
|
||||
}
|
||||
// Q = H_1 ... H_k is square, with as many rows as V has vectors
|
||||
// however, H need only have k columns, one each for the k reflectors.
|
||||
TEST_FOR_EXCEPTION( H.numCols() != k, std::invalid_argument,"Anasazi::SolverUtils::applyHouse(): H must have at least k columns.");
|
||||
TEST_FOR_EXCEPTION( (int)tau.size() != k, std::invalid_argument,"Anasazi::SolverUtils::applyHouse(): tau must have at least k entries.");
|
||||
TEST_FOR_EXCEPTION( H.numRows() != MVT::GetNumberVecs(V), std::invalid_argument,"Anasazi::SolverUtils::applyHouse(): Size of H,V are inconsistent.");
|
||||
|
||||
// perform the loop
|
||||
// flops: Sum_{i=0:k-1} 4 m (n-i) == 4mnk - 2m(k^2- k)
|
||||
for (int i=0; i<k; i++) {
|
||||
// apply V H_i+1 = V - tau_i+1 (V v_i+1) v_i+1^T
|
||||
// because of the structure of v_i+1, this transform does not affect the first i columns of V
|
||||
std::vector<int> activeind(n-i);
|
||||
for (int j=0; j<n-i; j++) activeind[j] = j+i;
|
||||
Teuchos::RCP<MV> actV = MVT::CloneView(V,activeind);
|
||||
|
||||
// note, below H_i, v_i and tau_i are mathematical objects which use 1-based indexing
|
||||
// while H, v and tau are data structures using 0-based indexing
|
||||
|
||||
// get v_i+1: i-th column of H
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> v(Teuchos::Copy,H,n-i,1,i,i);
|
||||
// v_i+1(1:i) = 0: this isn't part of v
|
||||
// e_i+1^T v_i+1 = 1 = v(0)
|
||||
v(0,0) = ONE;
|
||||
|
||||
// compute -tau_i V v_i
|
||||
// tau_i+1 is tau[i]
|
||||
// flops: 2 m n-i
|
||||
MVT::MvTimesMatAddMv(-tau[i],*actV,v,ZERO,*workMV);
|
||||
|
||||
// perform V = V + workMV v_i^T
|
||||
// flops: 2 m n-i
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> vT(v,Teuchos::CONJ_TRANS);
|
||||
MVT::MvTimesMatAddMv(ONE,*workMV,vT,ONE,*actV);
|
||||
|
||||
actV = Teuchos::null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// EIGENSOLVER PROJECTION METHODS
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template<class ScalarType, class MV, class OP>
|
||||
int SolverUtils<ScalarType, MV, OP>::directSolver(
|
||||
int size,
|
||||
const Teuchos::SerialDenseMatrix<int,ScalarType> &KK,
|
||||
Teuchos::RCP<const Teuchos::SerialDenseMatrix<int,ScalarType> > MM,
|
||||
Teuchos::SerialDenseMatrix<int,ScalarType> &EV,
|
||||
std::vector< typename Teuchos::ScalarTraits<ScalarType>::magnitudeType > &theta,
|
||||
int &nev, int esType)
|
||||
{
|
||||
// Routine for computing the first NEV generalized eigenpairs of the symmetric pencil (KK, MM)
|
||||
//
|
||||
// Parameter variables:
|
||||
//
|
||||
// size : Dimension of the eigenproblem (KK, MM)
|
||||
//
|
||||
// KK : Hermitian "stiffness" matrix
|
||||
//
|
||||
// MM : Hermitian positive-definite "mass" matrix
|
||||
//
|
||||
// EV : Matrix to store the nev eigenvectors
|
||||
//
|
||||
// theta : Array to store the eigenvalues (Size = nev )
|
||||
//
|
||||
// nev : Number of the smallest eigenvalues requested (input)
|
||||
// Number of the smallest computed eigenvalues (output)
|
||||
// Routine may compute and return more or less eigenvalues than requested.
|
||||
//
|
||||
// esType : Flag to select the algorithm
|
||||
//
|
||||
// esType = 0 (default) Uses LAPACK routine (Cholesky factorization of MM)
|
||||
// with deflation of MM to get orthonormality of
|
||||
// eigenvectors (S^T MM S = I)
|
||||
//
|
||||
// esType = 1 Uses LAPACK routine (Cholesky factorization of MM)
|
||||
// (no check of orthonormality)
|
||||
//
|
||||
// esType = 10 Uses LAPACK routine for simple eigenproblem on KK
|
||||
// (MM is not referenced in this case)
|
||||
//
|
||||
// Note: The code accesses only the upper triangular part of KK and MM.
|
||||
//
|
||||
// Return the integer info on the status of the computation
|
||||
//
|
||||
// info = 0 >> Success
|
||||
//
|
||||
// info < 0 >> error in the info-th argument
|
||||
// info = - 20 >> Failure in LAPACK routine
|
||||
|
||||
// Define local arrays
|
||||
|
||||
// Create blas/lapack objects.
|
||||
Teuchos::LAPACK<int,ScalarType> lapack;
|
||||
Teuchos::BLAS<int,ScalarType> blas;
|
||||
|
||||
int rank = 0;
|
||||
int info = 0;
|
||||
|
||||
if (size < nev || size < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (KK.numCols() < size || KK.numRows() < size) {
|
||||
return -2;
|
||||
}
|
||||
if ((esType == 0 || esType == 1)) {
|
||||
if (MM == Teuchos::null) {
|
||||
return -3;
|
||||
}
|
||||
else if (MM->numCols() < size || MM->numRows() < size) {
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
if (EV.numCols() < size || EV.numRows() < size) {
|
||||
return -4;
|
||||
}
|
||||
if (theta.size() < (unsigned int) size) {
|
||||
return -5;
|
||||
}
|
||||
if (nev <= 0) {
|
||||
return -6;
|
||||
}
|
||||
|
||||
// Query LAPACK for the "optimal" block size for HEGV
|
||||
std::string lapack_name = "hetrd";
|
||||
std::string lapack_opts = "u";
|
||||
int NB = lapack.ILAENV(1, lapack_name, lapack_opts, size, -1, -1, -1);
|
||||
int lwork = size*(NB+1);
|
||||
std::vector<ScalarType> work(lwork);
|
||||
std::vector<MagnitudeType> rwork(3*size-2);
|
||||
// tt contains the eigenvalues from HEGV, which are necessarily real, and
|
||||
// HEGV expects this vector to be real as well
|
||||
std::vector<MagnitudeType> tt( size );
|
||||
typedef typename std::vector<MagnitudeType>::iterator MTIter;
|
||||
|
||||
MagnitudeType tol = SCT::magnitude(SCT::squareroot(SCT::eps()));
|
||||
// MagnitudeType tol = 1e-12;
|
||||
ScalarType zero = Teuchos::ScalarTraits<ScalarType>::zero();
|
||||
ScalarType one = Teuchos::ScalarTraits<ScalarType>::one();
|
||||
|
||||
Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > KKcopy, MMcopy;
|
||||
Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > U;
|
||||
|
||||
switch (esType) {
|
||||
default:
|
||||
case 0:
|
||||
//
|
||||
// Use LAPACK to compute the generalized eigenvectors
|
||||
//
|
||||
for (rank = size; rank > 0; --rank) {
|
||||
|
||||
U = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>(rank,rank) );
|
||||
//
|
||||
// Copy KK & MM
|
||||
//
|
||||
KKcopy = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::Copy, KK, rank, rank ) );
|
||||
MMcopy = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::Copy, *MM, rank, rank ) );
|
||||
//
|
||||
// Solve the generalized eigenproblem with LAPACK
|
||||
//
|
||||
info = 0;
|
||||
lapack.HEGV(1, 'V', 'U', rank, KKcopy->values(), KKcopy->stride(),
|
||||
MMcopy->values(), MMcopy->stride(), &tt[0], &work[0], lwork,
|
||||
&rwork[0], &info);
|
||||
//
|
||||
// Treat error messages
|
||||
//
|
||||
if (info < 0) {
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "Anasazi::SolverUtils::directSolver(): In HEGV, argument " << -info << "has an illegal value.\n";
|
||||
std::cerr << std::endl;
|
||||
return -20;
|
||||
}
|
||||
if (info > 0) {
|
||||
if (info > rank)
|
||||
rank = info - rank;
|
||||
continue;
|
||||
}
|
||||
//
|
||||
// Check the quality of eigenvectors ( using mass-orthonormality )
|
||||
//
|
||||
MMcopy = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::Copy, *MM, rank, rank ) );
|
||||
for (int i = 0; i < rank; ++i) {
|
||||
for (int j = 0; j < i; ++j) {
|
||||
(*MMcopy)(i,j) = SCT::conjugate((*MM)(j,i));
|
||||
}
|
||||
}
|
||||
// U = 0*U + 1*MMcopy*KKcopy = MMcopy * KKcopy
|
||||
TEST_FOR_EXCEPTION(
|
||||
U->multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,one,*MMcopy,*KKcopy,zero) != 0,
|
||||
std::logic_error, "Anasazi::SolverUtils::directSolver() call to Teuchos::SerialDenseMatrix::multiply() returned an error.");
|
||||
// MMcopy = 0*MMcopy + 1*KKcopy^H*U = KKcopy^H * MMcopy * KKcopy
|
||||
TEST_FOR_EXCEPTION(
|
||||
MMcopy->multiply(Teuchos::CONJ_TRANS,Teuchos::NO_TRANS,one,*KKcopy,*U,zero) != 0,
|
||||
std::logic_error, "Anasazi::SolverUtils::directSolver() call to Teuchos::SerialDenseMatrix::multiply() returned an error.");
|
||||
MagnitudeType maxNorm = SCT::magnitude(zero);
|
||||
MagnitudeType maxOrth = SCT::magnitude(zero);
|
||||
for (int i = 0; i < rank; ++i) {
|
||||
for (int j = i; j < rank; ++j) {
|
||||
if (j == i)
|
||||
maxNorm = SCT::magnitude((*MMcopy)(i,j) - one) > maxNorm
|
||||
? SCT::magnitude((*MMcopy)(i,j) - one) : maxNorm;
|
||||
else
|
||||
maxOrth = SCT::magnitude((*MMcopy)(i,j)) > maxOrth
|
||||
? SCT::magnitude((*MMcopy)(i,j)) : maxOrth;
|
||||
}
|
||||
}
|
||||
/* if (verbose > 4) {
|
||||
std::cout << " >> Local eigensolve >> Size: " << rank;
|
||||
std::cout.precision(2);
|
||||
std::cout.setf(std::ios::scientific, std::ios::floatfield);
|
||||
std::cout << " Normalization error: " << maxNorm;
|
||||
std::cout << " Orthogonality error: " << maxOrth;
|
||||
std::cout << endl;
|
||||
}*/
|
||||
if ((maxNorm <= tol) && (maxOrth <= tol)) {
|
||||
break;
|
||||
}
|
||||
} // for (rank = size; rank > 0; --rank)
|
||||
//
|
||||
// Copy the computed eigenvectors and eigenvalues
|
||||
// ( they may be less than the number requested because of deflation )
|
||||
//
|
||||
// std::cout << "directSolve rank: " << rank << "\tsize: " << size << endl;
|
||||
nev = (rank < nev) ? rank : nev;
|
||||
EV.putScalar( zero );
|
||||
std::copy(tt.begin(),tt.begin()+nev,theta.begin());
|
||||
for (int i = 0; i < nev; ++i) {
|
||||
blas.COPY( rank, (*KKcopy)[i], 1, EV[i], 1 );
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
//
|
||||
// Use the Cholesky factorization of MM to compute the generalized eigenvectors
|
||||
//
|
||||
// Copy KK & MM
|
||||
//
|
||||
KKcopy = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::Copy, KK, size, size ) );
|
||||
MMcopy = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::Copy, *MM, size, size ) );
|
||||
//
|
||||
// Solve the generalized eigenproblem with LAPACK
|
||||
//
|
||||
info = 0;
|
||||
lapack.HEGV(1, 'V', 'U', size, KKcopy->values(), KKcopy->stride(),
|
||||
MMcopy->values(), MMcopy->stride(), &tt[0], &work[0], lwork,
|
||||
&rwork[0], &info);
|
||||
//
|
||||
// Treat error messages
|
||||
//
|
||||
if (info < 0) {
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "Anasazi::SolverUtils::directSolver(): In HEGV, argument " << -info << "has an illegal value.\n";
|
||||
std::cerr << std::endl;
|
||||
return -20;
|
||||
}
|
||||
if (info > 0) {
|
||||
if (info > size)
|
||||
nev = 0;
|
||||
else {
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "Anasazi::SolverUtils::directSolver(): In HEGV, DPOTRF or DHEEV returned an error code (" << info << ").\n";
|
||||
std::cerr << std::endl;
|
||||
return -20;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Copy the eigenvectors and eigenvalues
|
||||
//
|
||||
std::copy(tt.begin(),tt.begin()+nev,theta.begin());
|
||||
for (int i = 0; i < nev; ++i) {
|
||||
blas.COPY( size, (*KKcopy)[i], 1, EV[i], 1 );
|
||||
}
|
||||
break;
|
||||
|
||||
case 10:
|
||||
//
|
||||
// Simple eigenproblem
|
||||
//
|
||||
// Copy KK
|
||||
//
|
||||
KKcopy = Teuchos::rcp( new Teuchos::SerialDenseMatrix<int,ScalarType>( Teuchos::Copy, KK, size, size ) );
|
||||
//
|
||||
// Solve the generalized eigenproblem with LAPACK
|
||||
//
|
||||
lapack.HEEV('V', 'U', size, KKcopy->values(), KKcopy->stride(), &tt[0], &work[0], lwork, &rwork[0], &info);
|
||||
//
|
||||
// Treat error messages
|
||||
if (info != 0) {
|
||||
std::cerr << std::endl;
|
||||
if (info < 0)
|
||||
std::cerr << "Anasazi::SolverUtils::directSolver(): In DHEEV, argument " << -info << " has an illegal value\n";
|
||||
else
|
||||
std::cerr << "Anasazi::SolverUtils::directSolver(): In DHEEV, the algorithm failed to converge (" << info << ").\n";
|
||||
std::cerr << std::endl;
|
||||
info = -20;
|
||||
break;
|
||||
}
|
||||
//
|
||||
// Copy the eigenvectors
|
||||
//
|
||||
std::copy(tt.begin(),tt.begin()+nev,theta.begin());
|
||||
for (int i = 0; i < nev; ++i) {
|
||||
blas.COPY( size, (*KKcopy)[i], 1, EV[i], 1 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// SANITY CHECKING METHODS
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template<class ScalarType, class MV, class OP>
|
||||
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType
|
||||
SolverUtils<ScalarType, MV, OP>::errorEquality(const MV &X, const MV &MX, Teuchos::RCP<const OP> M)
|
||||
{
|
||||
// Return the maximum coefficient of the matrix M * X - MX
|
||||
// scaled by the maximum coefficient of MX.
|
||||
// When M is not specified, the identity is used.
|
||||
|
||||
MagnitudeType maxDiff = SCT::magnitude(SCT::zero());
|
||||
|
||||
int xc = MVT::GetNumberVecs(X);
|
||||
int mxc = MVT::GetNumberVecs(MX);
|
||||
|
||||
TEST_FOR_EXCEPTION(xc != mxc,std::invalid_argument,"Anasazi::SolverUtils::errorEquality(): input multivecs have different number of columns.");
|
||||
if (xc == 0) {
|
||||
return maxDiff;
|
||||
}
|
||||
|
||||
MagnitudeType maxCoeffX = SCT::magnitude(SCT::zero());
|
||||
std::vector<MagnitudeType> tmp( xc );
|
||||
MVT::MvNorm(MX, &tmp);
|
||||
|
||||
for (int i = 0; i < xc; ++i) {
|
||||
maxCoeffX = (tmp[i] > maxCoeffX) ? tmp[i] : maxCoeffX;
|
||||
}
|
||||
|
||||
std::vector<int> index( 1 );
|
||||
Teuchos::RCP<MV> MtimesX;
|
||||
if (M != Teuchos::null) {
|
||||
MtimesX = MVT::Clone( X, xc );
|
||||
OPT::Apply( *M, X, *MtimesX );
|
||||
}
|
||||
else {
|
||||
MtimesX = MVT::CloneCopy(X);
|
||||
}
|
||||
MVT::MvAddMv( -1.0, MX, 1.0, *MtimesX, *MtimesX );
|
||||
MVT::MvNorm( *MtimesX, &tmp );
|
||||
|
||||
for (int i = 0; i < xc; ++i) {
|
||||
maxDiff = (tmp[i] > maxDiff) ? tmp[i] : maxDiff;
|
||||
}
|
||||
|
||||
return (maxCoeffX == 0.0) ? maxDiff : maxDiff/maxCoeffX;
|
||||
|
||||
}
|
||||
|
||||
} // end namespace Anasazi
|
||||
|
||||
#endif // ANASAZI_SOLVER_UTILS_HPP
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
|
||||
#ifndef ANASAZI_SORTMANAGER_HPP
|
||||
#define ANASAZI_SORTMANAGER_HPP
|
||||
|
||||
/*! \file AnasaziSortManager.hpp
|
||||
\brief Virtual base class which defines the interface between an eigensolver and a class whose
|
||||
job is the sorting of the computed eigenvalues
|
||||
*/
|
||||
|
||||
/*! \class Anasazi::SortManager
|
||||
\brief Anasazi's templated pure virtual class for managing the sorting of
|
||||
approximate eigenvalues computed by the eigensolver.
|
||||
|
||||
A concrete implementation of this class is necessary. The user can create
|
||||
their own implementation if those supplied are not suitable for their needs.
|
||||
|
||||
\author Ulrich Hetmaniuk, Rich Lehoucq, and Heidi Thornquist
|
||||
*/
|
||||
|
||||
#include "AnasaziConfigDefs.hpp"
|
||||
#include "AnasaziTypes.hpp"
|
||||
#include "Teuchos_TestForException.hpp"
|
||||
|
||||
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
//! @name LOBPCG Exceptions
|
||||
//@{
|
||||
/** \brief SortManagerError is thrown when the Anasazi::SortManager is unable to sort the numbers,
|
||||
* due to some failure of the sort method or error in calling it.
|
||||
*/
|
||||
class SortManagerError : public AnasaziError
|
||||
{public: SortManagerError(const std::string& what_arg) : AnasaziError(what_arg) {}};
|
||||
|
||||
//@}
|
||||
|
||||
template<class ScalarType, class MV, class OP>
|
||||
class Eigensolver;
|
||||
|
||||
template<class ScalarType, class MV, class OP>
|
||||
class SortManager {
|
||||
|
||||
public:
|
||||
|
||||
//! Default Constructor
|
||||
SortManager() {};
|
||||
|
||||
//! Destructor
|
||||
virtual ~SortManager() {};
|
||||
|
||||
//! Sort the vector of eigenvalues, optionally returning the permutation vector.
|
||||
/**
|
||||
@param solver [in] Eigensolver that is calling the sorting routine
|
||||
|
||||
@param n [in] Number of values in evals to be sorted.
|
||||
|
||||
@param evals [in/out] Vector of length n containing the eigenvalues to be sorted
|
||||
|
||||
@param perm [out] Vector of length n to store the permutation index (optional)
|
||||
*/
|
||||
virtual void sort(Eigensolver<ScalarType,MV,OP>* solver, const int n, std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &evals, std::vector<int> *perm = 0) const = 0;
|
||||
|
||||
/*! \brief Sort the vectors of eigenpairs, optionally returning the permutation vector.
|
||||
|
||||
This routine takes two vectors, one for each part of a complex
|
||||
eigenvalue. This is helpful for solving real, non-symmetric eigenvalue
|
||||
problems.
|
||||
|
||||
@param solver [in] Eigensolver that is calling the sorting routine
|
||||
|
||||
@param n [in] Number of values in r_evals,i_evals to be sorted.
|
||||
|
||||
@param r_evals [in/out] Vector of length n containing the real part of the eigenvalues to be sorted
|
||||
|
||||
@param i_evals [in/out] Vector of length n containing the imaginary part of the eigenvalues to be sorted
|
||||
|
||||
@param perm [out] Vector of length n to store the permutation index (optional)
|
||||
*/
|
||||
virtual void sort(Eigensolver<ScalarType,MV,OP>* solver,
|
||||
const int n,
|
||||
std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &r_evals,
|
||||
std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &i_evals,
|
||||
std::vector<int> *perm = 0) const = 0;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // ANASAZI_SORTMANAGER_HPP
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
//
|
||||
|
||||
#ifndef ANASAZI_STATUS_TEST_HPP
|
||||
#define ANASAZI_STATUS_TEST_HPP
|
||||
|
||||
/*!
|
||||
\file AnasaziStatusTest.hpp
|
||||
\brief Pure virtual base class for defining the status testing capabilities of Anasazi.
|
||||
*/
|
||||
|
||||
|
||||
#include "AnasaziConfigDefs.hpp"
|
||||
#include "AnasaziTypes.hpp"
|
||||
|
||||
#include "AnasaziStatusTestDecl.hpp"
|
||||
#include "AnasaziEigensolverDecl.hpp"
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
//! @name StatusTest Exceptions
|
||||
//@{
|
||||
|
||||
/** \brief Exception thrown to signal error in a status test during Anasazi::StatusTest::checkStatus().
|
||||
*/
|
||||
class StatusTestError : public AnasaziError
|
||||
{public: StatusTestError(const std::string& what_arg) : AnasaziError(what_arg) {}};
|
||||
|
||||
//@}
|
||||
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
class StatusTest {
|
||||
|
||||
public:
|
||||
//! @name Constructors/destructors
|
||||
//@{
|
||||
|
||||
//! Constructor
|
||||
StatusTest() {};
|
||||
|
||||
//! Destructor
|
||||
virtual ~StatusTest() {};
|
||||
//@}
|
||||
|
||||
//! @name Status methods
|
||||
//@{
|
||||
/*! Check status as defined by test.
|
||||
|
||||
\return TestStatus indicating whether the test passed or failed.
|
||||
*/
|
||||
virtual TestStatus checkStatus( Eigensolver<ScalarType,MV,OP>* solver ) = 0;
|
||||
|
||||
//! Return the result of the most recent checkStatus call, or undefined if it has not been run.
|
||||
virtual TestStatus getStatus() const = 0;
|
||||
//@}
|
||||
|
||||
//! @name Reset methods
|
||||
//@{
|
||||
//! Informs the status test that it should reset its internal configuration to the uninitialized state.
|
||||
/*! This is necessary for the case when the status test is being reused by another solver or for another
|
||||
eigenvalue problem. The status test may have information that pertains to a particular problem or solver
|
||||
state. The internal information will be reset back to the uninitialized state. The user specified information
|
||||
that the convergence test uses will remain.
|
||||
*/
|
||||
virtual void reset() = 0;
|
||||
|
||||
//! Clears the results of the last status test.
|
||||
/*! This should be distinguished from the reset() method, as it only clears the cached result from the last
|
||||
* status test, so that a call to getStatus() will return ::Undefined. This is necessary for the SEQOR and SEQAND
|
||||
* tests in the StatusTestCombo class, which may short circuit and not evaluate all of the StatusTests contained
|
||||
* in them.
|
||||
*/
|
||||
virtual void clearStatus() = 0;
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Print methods
|
||||
//@{
|
||||
|
||||
//! Output formatted description of stopping test to output stream.
|
||||
virtual std::ostream& print(std::ostream& os, int indent = 0) const = 0;
|
||||
|
||||
//@}
|
||||
|
||||
};
|
||||
|
||||
} // end of Anasazi namespace
|
||||
|
||||
#endif /* ANASAZI_STATUS_TEST_HPP */
|
||||
@@ -0,0 +1,344 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
//
|
||||
|
||||
#ifndef ANASAZI_STATUS_TEST_COMBO_HPP
|
||||
#define ANASAZI_STATUS_TEST_COMBO_HPP
|
||||
|
||||
/*!
|
||||
\file AnasaziStatusTestCombo.hpp
|
||||
\brief Status test for forming logical combinations of other status tests.
|
||||
*/
|
||||
|
||||
|
||||
#include "AnasaziTypes.hpp"
|
||||
#include "AnasaziStatusTest.hpp"
|
||||
#include "Teuchos_Array.hpp"
|
||||
|
||||
/*!
|
||||
\class Anasazi::StatusTestCombo
|
||||
\brief Status test for forming logical combinations of other status tests.
|
||||
|
||||
Test types include OR, AND, SEQOR and SEQAND. The OR and AND tests
|
||||
evaluate all of the tests, in the order they were passed to the
|
||||
StatusTestCombo. The SEQOR and SEQAND run only the tests necessary to
|
||||
determine the final outcome, short-circuiting on the first test that
|
||||
conclusively decides the outcome. More formally, SEQAND runs the tests in
|
||||
the order they were given to the StatusTestCombo class and stops after the
|
||||
first test that evaluates ::Failed. SEQOR run the tests in the order they
|
||||
were given to the StatusTestCombo class and stops after the first test that
|
||||
evaluates ::Passed.
|
||||
*/
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
class StatusTestCombo : public StatusTest<ScalarType,MV,OP> {
|
||||
|
||||
private:
|
||||
typedef Teuchos::Array< Teuchos::RCP< StatusTest<ScalarType,MV,OP> > > STPArray;
|
||||
|
||||
public:
|
||||
|
||||
//! \brief Enumerated type to list the types of StatusTestCombo combo types.
|
||||
enum ComboType
|
||||
{
|
||||
OR, /*!< Logical OR which evaluates all tests */
|
||||
AND, /*!< Logical AND which evaluates all tests */
|
||||
SEQOR, /*!< Short-circuited logical OR */
|
||||
SEQAND /*!< Short-circuited logical AND */
|
||||
};
|
||||
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
|
||||
typedef Teuchos::Array< Teuchos::RCP< StatusTest<ScalarType,MV,OP> > > t_arr;
|
||||
typedef std::vector< Teuchos::RCP< StatusTest<ScalarType,MV,OP> > > st_vector;
|
||||
typedef typename st_vector::iterator iterator;
|
||||
typedef typename st_vector::const_iterator const_iterator;
|
||||
|
||||
#endif // DOXYGEN_SHOULD_SKIP_THIS
|
||||
|
||||
//! @name Constructors/destructors
|
||||
//@{
|
||||
|
||||
//! Constructor
|
||||
//! \brief Default constructor has no tests and initializes to ComboType OR.
|
||||
StatusTestCombo() : state_(Undefined) {}
|
||||
|
||||
//! Constructor
|
||||
//! \brief Constructor specifying the ComboType and the tests.
|
||||
StatusTestCombo(ComboType type, Teuchos::Array< Teuchos::RCP< StatusTest<ScalarType,MV,OP> > > tests) :
|
||||
state_(Undefined),
|
||||
type_(type)
|
||||
{
|
||||
setTests(tests);
|
||||
};
|
||||
|
||||
//! Destructor
|
||||
virtual ~StatusTestCombo() {};
|
||||
//@}
|
||||
|
||||
//! @name Status methods
|
||||
//@{
|
||||
/*! Check status as defined by test.
|
||||
|
||||
\return TestStatus indicating whether the test passed or failed.
|
||||
*/
|
||||
TestStatus checkStatus( Eigensolver<ScalarType,MV,OP>* solver );
|
||||
|
||||
//! Return the result of the most recent checkStatus call.
|
||||
TestStatus getStatus() const {
|
||||
return state_;
|
||||
}
|
||||
//@}
|
||||
|
||||
//! @name Accessor methods
|
||||
//@{
|
||||
|
||||
/*! \brief Set the maximum number of iterations.
|
||||
* This also resets the test status to ::Undefined.
|
||||
*/
|
||||
void setComboType(ComboType type) {
|
||||
type_ = type;
|
||||
state_ = Undefined;
|
||||
}
|
||||
|
||||
//! Get the maximum number of iterations.
|
||||
ComboType getComboType() const {return type_;}
|
||||
|
||||
/*! \brief Set the tests
|
||||
* This also resets the test status to ::Undefined.
|
||||
*/
|
||||
void setTests(Teuchos::Array<Teuchos::RCP<StatusTest<ScalarType,MV,OP> > > tests) {
|
||||
tests_ = tests;
|
||||
state_ = Undefined;
|
||||
}
|
||||
|
||||
//! Get the tests
|
||||
Teuchos::Array<Teuchos::RCP<StatusTest<ScalarType,MV,OP> > > getTests() const {return tests_;}
|
||||
|
||||
/*! \brief Add a test to the combination.
|
||||
*
|
||||
* This also resets the test status to ::Undefined.
|
||||
*/
|
||||
void addTest(Teuchos::RCP<StatusTest<ScalarType,MV,OP> > test) {
|
||||
tests_.push_back(test);
|
||||
state_ = Undefined;
|
||||
}
|
||||
|
||||
/*! \brief Removes a test from the combination, if it exists in the tester.
|
||||
*
|
||||
* This also resets the test status to ::Undefined, if a test was removed.
|
||||
*/
|
||||
void removeTest(const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > &test);
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Reset methods
|
||||
//@{
|
||||
//! \brief Informs the status test that it should reset its internal configuration to the uninitialized state.
|
||||
/*! The StatusTestCombo class has no internal state, but children classes might, so this method will call
|
||||
reset() on all child status tests. It also resets the test status to ::Undefined.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
//! \brief Clears the results of the last status test.
|
||||
/*! This should be distinguished from the reset() method, as it only clears the cached result from the last
|
||||
* status test, so that a call to getStatus() will return ::Undefined. This is necessary for the SEQOR and SEQAND
|
||||
* tests in the StatusTestCombo class, which may short circuit and not evaluate all of the StatusTests contained
|
||||
* in them.
|
||||
*/
|
||||
void clearStatus();
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Print methods
|
||||
//@{
|
||||
|
||||
//! Output formatted description of stopping test to output stream.
|
||||
std::ostream& print(std::ostream& os, int indent = 0) const;
|
||||
|
||||
//@}
|
||||
private:
|
||||
|
||||
TestStatus evalOR(Eigensolver<ScalarType,MV,OP>* solver);
|
||||
TestStatus evalAND(Eigensolver<ScalarType,MV,OP>* solver);
|
||||
TestStatus evalSEQOR(Eigensolver<ScalarType,MV,OP>* solver);
|
||||
TestStatus evalSEQAND(Eigensolver<ScalarType,MV,OP>* solver);
|
||||
|
||||
TestStatus state_;
|
||||
ComboType type_;
|
||||
STPArray tests_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
void StatusTestCombo<ScalarType,MV,OP>::removeTest(const Teuchos::RCP<StatusTest<ScalarType,MV,OP> > &test)
|
||||
{
|
||||
typename STPArray::iterator iter1;
|
||||
iter1 = find(tests_.begin(),tests_.end(),test);
|
||||
if (iter1 != tests_.end()) {
|
||||
tests_.erase(iter1);
|
||||
state_ = Undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
TestStatus StatusTestCombo<ScalarType,MV,OP>::checkStatus( Eigensolver<ScalarType,MV,OP>* solver ) {
|
||||
clearStatus();
|
||||
switch (type_) {
|
||||
case OR:
|
||||
state_ = evalOR(solver);
|
||||
break;
|
||||
case AND:
|
||||
state_ = evalAND(solver);
|
||||
break;
|
||||
case SEQOR:
|
||||
state_ = evalSEQOR(solver);
|
||||
break;
|
||||
case SEQAND:
|
||||
state_ = evalSEQAND(solver);
|
||||
break;
|
||||
}
|
||||
return state_;
|
||||
}
|
||||
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
void StatusTestCombo<ScalarType,MV,OP>::reset() {
|
||||
state_ = Undefined;
|
||||
for (iterator i=tests_.begin(); i != tests_.end(); i++) {
|
||||
(*i)->reset();
|
||||
}
|
||||
}
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
void StatusTestCombo<ScalarType,MV,OP>::clearStatus() {
|
||||
state_ = Undefined;
|
||||
for (iterator i=tests_.begin(); i != tests_.end(); i++) {
|
||||
(*i)->clearStatus();
|
||||
}
|
||||
}
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
std::ostream& StatusTestCombo<ScalarType,MV,OP>::print(std::ostream& os, int indent) const {
|
||||
std::string ind(indent,' ');
|
||||
os << ind << "- StatusTestCombo: ";
|
||||
switch (state_) {
|
||||
case Passed:
|
||||
os << "Passed" << std::endl;
|
||||
break;
|
||||
case Failed:
|
||||
os << "Failed" << std::endl;
|
||||
break;
|
||||
case Undefined:
|
||||
os << "Undefined" << std::endl;
|
||||
break;
|
||||
}
|
||||
// print children, with extra indention
|
||||
for (const_iterator i=tests_.begin(); i != tests_.end(); i++) {
|
||||
(*i)->print(os,indent+2);
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
TestStatus StatusTestCombo<ScalarType,MV,OP>::evalOR( Eigensolver<ScalarType,MV,OP>* solver ) {
|
||||
state_ = Failed;
|
||||
for (iterator i=tests_.begin(); i != tests_.end(); i++) {
|
||||
TestStatus r = (*i)->checkStatus(solver);
|
||||
if (r == Passed) {
|
||||
state_ = Passed;
|
||||
}
|
||||
else {
|
||||
TEST_FOR_EXCEPTION(r != Failed,StatusTestError,
|
||||
"Anasazi::StatusTestCombo::evalOR(): child test gave invalid return");
|
||||
}
|
||||
}
|
||||
return state_;
|
||||
}
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
TestStatus StatusTestCombo<ScalarType,MV,OP>::evalSEQOR( Eigensolver<ScalarType,MV,OP>* solver ) {
|
||||
state_ = Failed;
|
||||
for (iterator i=tests_.begin(); i != tests_.end(); i++) {
|
||||
TestStatus r = (*i)->checkStatus(solver);
|
||||
if (r == Passed) {
|
||||
state_ = Passed;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
TEST_FOR_EXCEPTION(r != Failed,StatusTestError,
|
||||
"Anasazi::StatusTestCombo::evalSEQOR(): child test gave invalid return");
|
||||
}
|
||||
}
|
||||
return state_;
|
||||
}
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
TestStatus StatusTestCombo<ScalarType,MV,OP>::evalAND( Eigensolver<ScalarType,MV,OP>* solver ) {
|
||||
state_ = Passed;
|
||||
for (iterator i=tests_.begin(); i != tests_.end(); i++) {
|
||||
TestStatus r = (*i)->checkStatus(solver);
|
||||
if (r == Failed) {
|
||||
state_ = Failed;
|
||||
}
|
||||
else {
|
||||
TEST_FOR_EXCEPTION(r != Passed,StatusTestError,
|
||||
"Anasazi::StatusTestCombo::evalAND(): child test gave invalid return");
|
||||
}
|
||||
}
|
||||
return state_;
|
||||
}
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
TestStatus StatusTestCombo<ScalarType,MV,OP>::evalSEQAND( Eigensolver<ScalarType,MV,OP>* solver ) {
|
||||
state_ = Passed;
|
||||
for (iterator i=tests_.begin(); i != tests_.end(); i++) {
|
||||
TestStatus r = (*i)->checkStatus(solver);
|
||||
if (r == Failed) {
|
||||
state_ = Failed;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
TEST_FOR_EXCEPTION(r != Passed,StatusTestError,
|
||||
"Anasazi::StatusTestCombo::evalAND(): child test gave invalid return");
|
||||
}
|
||||
}
|
||||
return state_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // end of Anasazi namespace
|
||||
|
||||
#endif /* ANASAZI_STATUS_TEST_COMBO_HPP */
|
||||
@@ -0,0 +1,56 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Belos: Block Linear Solvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
//
|
||||
|
||||
#ifndef ANASAZI_STATUS_TEST_DECL_HPP
|
||||
#define ANASAZI_STATUS_TEST_DECL_HPP
|
||||
|
||||
/*!
|
||||
\file AnasaziStatusTestDecl.hpp
|
||||
\brief Forward declaration of pure virtual base class Anasazi::StatusTest.
|
||||
*/
|
||||
|
||||
#include "AnasaziConfigDefs.hpp"
|
||||
#include "AnasaziTypes.hpp"
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
/*!
|
||||
\class StatusTest
|
||||
\brief A pure virtual class for defining the status tests for the ::Anasazi iterative solvers
|
||||
|
||||
StatusTest is an interface that can be implemented to create convergence tests for
|
||||
all Anasazi solvers. Almost any kind of test can be expressed using this mechanism,
|
||||
including composite tests (see StatusTestCombo).
|
||||
*/
|
||||
template <class ScalarType, class MV, class OP>
|
||||
class StatusTest;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,185 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
//
|
||||
|
||||
#ifndef ANASAZI_STATUS_TEST_MAXITER_HPP
|
||||
#define ANASAZI_STATUS_TEST_MAXITER_HPP
|
||||
|
||||
/*!
|
||||
\file AnasaziStatusTestMaxIters.hpp
|
||||
\brief Status test for testing the number of iterations.
|
||||
*/
|
||||
|
||||
|
||||
#include "AnasaziStatusTest.hpp"
|
||||
|
||||
|
||||
/*!
|
||||
\class Anasazi::StatusTestMaxIters
|
||||
\brief A status test for testing the number of iterations.
|
||||
|
||||
Anasazi::StatusTestMaxIters will test true when an eigensolver has reached some number
|
||||
of iterations. Specifically,
|
||||
<pre>
|
||||
{ Passed, if solver->getNumIters() >= maxIter
|
||||
status(solver) = {
|
||||
{ Failed, if solver->getNumIters() < maxIter
|
||||
</pre>
|
||||
where maxIter is the parameter given to the status tester.
|
||||
|
||||
This status test also supports negation, so that it negates the need for a
|
||||
StatusTestMinIters status tester. In this way, all tests on the range of iterations
|
||||
can be constructed through the appropriate use of StatusTestMaxIters and StatusTestCombo.
|
||||
*/
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
class StatusTestMaxIters : public StatusTest<ScalarType,MV,OP> {
|
||||
|
||||
public:
|
||||
//! @name Constructors/destructors
|
||||
//@{
|
||||
|
||||
//! Constructor
|
||||
StatusTestMaxIters(int maxIter, bool negate = false) : state_(Undefined), negate_(negate) {
|
||||
setMaxIters(maxIter);
|
||||
};
|
||||
|
||||
//! Destructor
|
||||
virtual ~StatusTestMaxIters() {};
|
||||
//@}
|
||||
|
||||
//! @name Status methods
|
||||
//@{
|
||||
|
||||
/*! \brief Check status as defined by test.
|
||||
\return TestStatus indicating whether the test passed or failed.
|
||||
*/
|
||||
TestStatus checkStatus( Eigensolver<ScalarType,MV,OP>* solver ) {
|
||||
state_ = (solver->getNumIters() >= maxIters_) ? Passed : Failed;
|
||||
if (negate_) {
|
||||
if (state_ == Passed) state_ = Failed;
|
||||
else state_ = Passed;
|
||||
}
|
||||
return state_;
|
||||
}
|
||||
|
||||
//! \brief Return the result of the most recent checkStatus call.
|
||||
TestStatus getStatus() const {
|
||||
return state_;
|
||||
}
|
||||
//@}
|
||||
|
||||
//! @name Accessor methods
|
||||
//@{
|
||||
|
||||
/*! \brief Set the maximum number of iterations.
|
||||
* \note This also resets the test status to ::Undefined.
|
||||
*/
|
||||
void setMaxIters(int maxIters) {
|
||||
state_ = Undefined;
|
||||
maxIters_ = maxIters;
|
||||
}
|
||||
|
||||
//! \brief Get the maximum number of iterations.
|
||||
int getMaxIters() {return maxIters_;}
|
||||
|
||||
/*! \brief Set the negation policy for the status test.
|
||||
* \note This also reset the test status to ::Undefined.
|
||||
*/
|
||||
void setNegate(bool negate) {
|
||||
state_ = Undefined;
|
||||
negate_ = negate;
|
||||
}
|
||||
|
||||
//! \brief Get the negation policy for the status test.
|
||||
bool getNegate() const {
|
||||
return negate_;
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Reset methods
|
||||
//@{
|
||||
//! Informs the status test that it should reset its internal configuration to the uninitialized state.
|
||||
/*! The StatusTestMaxIters class has no internal state, so this call is equivalent to calling clearStatus().
|
||||
eigenvalue problem. The status test may have information that pertains to a particular problem or solver
|
||||
state. The internal information will be reset back to the uninitialized state. The user specified information
|
||||
that the convergence test uses will remain.
|
||||
*/
|
||||
void reset() {
|
||||
state_ = Undefined;
|
||||
}
|
||||
|
||||
//! \brief Clears the results of the last status test.
|
||||
/*! This should be distinguished from the reset() method, as it only clears the cached result from the last
|
||||
* status test, so that a call to getStatus() will return ::Undefined. This is necessary for the SEQOR and SEQAND
|
||||
* tests in the StatusTestCombo class, which may short circuit and not evaluate all of the StatusTests contained
|
||||
* in them.
|
||||
*/
|
||||
void clearStatus() {
|
||||
state_ = Undefined;
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Print methods
|
||||
//@{
|
||||
|
||||
//! Output formatted description of stopping test to output stream.
|
||||
std::ostream& print(std::ostream& os, int indent = 0) const {
|
||||
std::string ind(indent,' ');
|
||||
os << ind << "- StatusTestMaxIters: ";
|
||||
switch (state_) {
|
||||
case Passed:
|
||||
os << "Passed" << std::endl;
|
||||
break;
|
||||
case Failed:
|
||||
os << "Failed" << std::endl;
|
||||
break;
|
||||
case Undefined:
|
||||
os << "Undefined" << std::endl;
|
||||
break;
|
||||
}
|
||||
os << ind << " MaxIters: " << maxIters_ << std::endl;
|
||||
return os;
|
||||
}
|
||||
|
||||
//@}
|
||||
private:
|
||||
int maxIters_;
|
||||
TestStatus state_;
|
||||
bool negate_;
|
||||
|
||||
};
|
||||
|
||||
} // end of Anasazi namespace
|
||||
|
||||
#endif /* ANASAZI_STATUS_TEST_MAXITER_HPP */
|
||||
@@ -0,0 +1,377 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
//
|
||||
|
||||
#ifndef ANASAZI_STATUS_TEST_ORDEREDRESNORM_HPP
|
||||
#define ANASAZI_STATUS_TEST_ORDEREDRESNORM_HPP
|
||||
|
||||
/*!
|
||||
\file AnasaziStatusTestOrderedResNorm.hpp
|
||||
\brief A status test for testing the norm of the eigenvectors residuals along with a
|
||||
set of auxiliary eigenvalues.
|
||||
*/
|
||||
|
||||
|
||||
#include "AnasaziStatusTest.hpp"
|
||||
#include "Teuchos_ScalarTraits.hpp"
|
||||
#include "Teuchos_LAPACK.hpp"
|
||||
|
||||
/*!
|
||||
\class Anasazi::StatusTestOrderedResNorm
|
||||
|
||||
\brief A status test for testing the norm of the eigenvectors residuals
|
||||
along with a set of auxiliary eigenvalues.
|
||||
|
||||
The test evaluates to ::Passed when then the most significant of the
|
||||
eigenvalues all have a residual below a certain threshhold. The purpose of
|
||||
the test is to not only test convergence for some number of eigenvalues,
|
||||
but to test convergence for the correct ones.
|
||||
|
||||
In addition to specifying the tolerance, the user may specify:
|
||||
<ul>
|
||||
<li> the norm to be used: 2-norm or OrthoManager::norm() or getRitzRes2Norms()
|
||||
<li> the scale: absolute or relative to magnitude of Ritz value
|
||||
<li> the quorum: the number of vectors required for the test to
|
||||
evaluate as ::Passed.
|
||||
</ul>
|
||||
|
||||
Finally, the user must specify the Anasazi::SortManager used for deciding
|
||||
significance.
|
||||
*/
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
class StatusTestOrderedResNorm : public StatusTest<ScalarType,MV,OP> {
|
||||
|
||||
private:
|
||||
typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
|
||||
typedef Teuchos::ScalarTraits<MagnitudeType> MT;
|
||||
|
||||
public:
|
||||
|
||||
//! @name Enums
|
||||
//@{
|
||||
|
||||
/*! \enum ResType
|
||||
\brief Enumerated type used to specify which residual norm used by this status test.
|
||||
*/
|
||||
enum ResType {
|
||||
RES_ORTH,
|
||||
RES_2NORM,
|
||||
RITZRES_2NORM
|
||||
};
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Constructors/destructors
|
||||
//@{
|
||||
|
||||
//! Constructor
|
||||
StatusTestOrderedResNorm(Teuchos::RCP<SortManager<ScalarType,MV,OP> > sorter, typename Teuchos::ScalarTraits<ScalarType>::magnitudeType tol, int quorum = -1, ResType whichNorm = RES_ORTH, bool scaled = true);
|
||||
|
||||
//! Destructor
|
||||
virtual ~StatusTestOrderedResNorm() {};
|
||||
//@}
|
||||
|
||||
//! @name Status methods
|
||||
//@{
|
||||
/*! Check status as defined by test.
|
||||
\return TestStatus indicating whether the test passed or failed.
|
||||
*/
|
||||
TestStatus checkStatus( Eigensolver<ScalarType,MV,OP>* solver );
|
||||
|
||||
//! Return the result of the most recent checkStatus call.
|
||||
TestStatus getStatus() const { return state_; }
|
||||
//@}
|
||||
|
||||
//! @name Accessor methods
|
||||
//@{
|
||||
|
||||
/*! \brief Set tolerance.
|
||||
* This also resets the test status to ::Undefined.
|
||||
*/
|
||||
void setTolerance(typename Teuchos::ScalarTraits<ScalarType>::magnitudeType tol) {
|
||||
state_ = Undefined;
|
||||
tol_ = tol;
|
||||
}
|
||||
|
||||
//! Get tolerance.
|
||||
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType getTolerance() {return tol_;}
|
||||
|
||||
/*! \brief Set the residual norm to be used by the status test.
|
||||
*
|
||||
* This also resets the test status to ::Undefined.
|
||||
*/
|
||||
void setWhichNorm(ResType whichNorm) {
|
||||
state_ = Undefined;
|
||||
whichNorm_ = whichNorm;
|
||||
}
|
||||
|
||||
//! Return the residual norm used by the status test.
|
||||
ResType getWhichNorm() {return whichNorm_;}
|
||||
|
||||
/*! \brief Instruct test to scale norms by eigenvalue estimates (relative scale).
|
||||
* This also resets the test status to ::Undefined.
|
||||
*/
|
||||
void setScale(bool relscale) {
|
||||
state_ = Undefined;
|
||||
scaled_ = relscale;
|
||||
}
|
||||
|
||||
//! Returns true if the test scales the norms by the eigenvalue estimates (relative scale).
|
||||
bool getScale() {return scaled_;}
|
||||
|
||||
//! Get the indices for the vectors that passed the test.
|
||||
std::vector<int> whichVecs() {
|
||||
return ind_;
|
||||
}
|
||||
|
||||
//! Get the number of vectors that passed the test.
|
||||
int howMany() {
|
||||
return ind_.size();
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Reset methods
|
||||
//@{
|
||||
//! Informs the status test that it should reset its internal configuration to the uninitialized state.
|
||||
/*! This is necessary for the case when the status test is being reused by another solver or for another
|
||||
eigenvalue problem. The status test may have information that pertains to a particular problem or solver
|
||||
state. The internal information will be reset back to the uninitialized state. The user specified information
|
||||
that the convergence test uses will remain.
|
||||
*/
|
||||
void reset() {
|
||||
state_ = Undefined;
|
||||
}
|
||||
|
||||
//! Clears the results of the last status test.
|
||||
/*! This should be distinguished from the reset() method, as it only clears the cached result from the last
|
||||
* status test, so that a call to getStatus() will return ::Undefined. This is necessary for the SEQOR and SEQAND
|
||||
* tests in the StatusTestCombo class, which may short circuit and not evaluate all of the StatusTests contained
|
||||
* in them.
|
||||
*/
|
||||
void clearStatus() {
|
||||
state_ = Undefined;
|
||||
}
|
||||
|
||||
/*! \brief Set the auxiliary eigenvalues.
|
||||
*
|
||||
* This routine sets only the real part of the auxiliary eigenvalues; the imaginary part is set to zero. This routine also resets the state to ::Undefined.
|
||||
*/
|
||||
void setAuxVals(const std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &vals) {
|
||||
rvals_ = vals;
|
||||
ivals_.resize(rvals_.size(),MT::zero());
|
||||
state_ = Undefined;
|
||||
}
|
||||
|
||||
/*! \brief Set the auxiliary eigenvalues.
|
||||
*
|
||||
* This routine sets both the real and imaginary parts of the auxiliary eigenvalues. This routine also resets the state to ::Undefined.
|
||||
*/
|
||||
void setAuxVals(const std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &rvals, const std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &ivals) {
|
||||
rvals_ = rvals;
|
||||
ivals_ = ivals;
|
||||
state_ = Undefined;
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Print methods
|
||||
//@{
|
||||
|
||||
//! Output formatted description of stopping test to output stream.
|
||||
std::ostream& print(std::ostream& os, int indent = 0) const;
|
||||
|
||||
//@}
|
||||
private:
|
||||
TestStatus state_;
|
||||
MagnitudeType tol_;
|
||||
std::vector<int> ind_;
|
||||
int quorum_;
|
||||
bool scaled_;
|
||||
ResType whichNorm_;
|
||||
std::vector<MagnitudeType> rvals_, ivals_;
|
||||
Teuchos::RCP<SortManager<ScalarType,MV,OP> > sorter_;
|
||||
};
|
||||
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
StatusTestOrderedResNorm<ScalarType,MV,OP>::StatusTestOrderedResNorm(Teuchos::RCP<SortManager<ScalarType,MV,OP> > sorter, typename Teuchos::ScalarTraits<ScalarType>::magnitudeType tol, int quorum, ResType whichNorm, bool scaled)
|
||||
: state_(Undefined), quorum_(quorum), scaled_(scaled), whichNorm_(whichNorm), sorter_(sorter)
|
||||
{
|
||||
TEST_FOR_EXCEPTION(sorter_ == Teuchos::null, StatusTestError, "StatusTestOrderedResNorm::constructor() was passed null pointer for SortManager.");
|
||||
setTolerance(tol);
|
||||
}
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
TestStatus StatusTestOrderedResNorm<ScalarType,MV,OP>::checkStatus( Eigensolver<ScalarType,MV,OP>* solver ) {
|
||||
|
||||
|
||||
// get the eigenvector/ritz residuals norms (using the appropriate norm)
|
||||
// get the eigenvalues/ritzvalues as well
|
||||
std::vector<MagnitudeType> res;
|
||||
std::vector<Value<ScalarType> > vals = solver->getRitzValues();
|
||||
switch (whichNorm_) {
|
||||
case RES_2NORM:
|
||||
res = solver->getRes2Norms();
|
||||
vals.resize(res.size());
|
||||
break;
|
||||
case RES_ORTH:
|
||||
res = solver->getResNorms();
|
||||
vals.resize(res.size());
|
||||
break;
|
||||
case RITZRES_2NORM:
|
||||
res = solver->getRitzRes2Norms();
|
||||
break;
|
||||
}
|
||||
|
||||
int numaux = rvals_.size();
|
||||
int bs = res.size();
|
||||
int num = bs + numaux;
|
||||
|
||||
if (num == 0) {
|
||||
ind_.resize(0);
|
||||
return Failed;
|
||||
}
|
||||
|
||||
// extract the real and imaginary parts from the
|
||||
std::vector<MagnitudeType> allrvals(bs), allivals(bs);
|
||||
for (int i=0; i<bs; i++) {
|
||||
allrvals[i] = vals[i].realpart;
|
||||
allivals[i] = vals[i].imagpart;
|
||||
}
|
||||
|
||||
// put the auxiliary values in the vectors as well
|
||||
allrvals.insert(allrvals.end(),rvals_.begin(),rvals_.end());
|
||||
allivals.insert(allivals.end(),ivals_.begin(),ivals_.end());
|
||||
|
||||
// if appropriate, scale the norms by the magnitude of the eigenvalue estimate
|
||||
Teuchos::LAPACK<int,MagnitudeType> lapack;
|
||||
if (scaled_) {
|
||||
for (unsigned int i=0; i<res.size(); i++) {
|
||||
MagnitudeType tmp = lapack.LAPY2(allrvals[i],allivals[i]);
|
||||
if ( tmp != MT::zero() ) {
|
||||
res[i] /= tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
// add -1 residuals for the auxiliary values (because -1 < tol_)
|
||||
res.insert(res.end(),numaux,-MT::one());
|
||||
|
||||
// we don't actually need the sorted eigenvalues; just the permutation vector
|
||||
std::vector<int> perm(num,-1);
|
||||
sorter_->sort(solver,num,allrvals,allivals,&perm);
|
||||
|
||||
// apply the sorting to the residuals and original indices
|
||||
std::vector<MagnitudeType> oldres = res;
|
||||
for (int i=0; i<num; i++) {
|
||||
res[i] = oldres[perm[i]];
|
||||
}
|
||||
|
||||
// indices: [0,bs) are from solver, [bs,bs+numaux) are from auxiliary values
|
||||
ind_.resize(num);
|
||||
|
||||
// test the norms: we want res [0,quorum) to be <= tol
|
||||
int have = 0;
|
||||
int need = (quorum_ == -1) ? num : quorum_;
|
||||
int tocheck = need > num ? num : need;
|
||||
for (int i=0; i<tocheck; i++) {
|
||||
TEST_FOR_EXCEPTION( MT::isnaninf(res[i]), StatusTestError, "StatusTestOrderedResNorm::checkStatus(): residual norm is nan or inf" );
|
||||
if (res[i] < tol_) {
|
||||
ind_[have] = perm[i];
|
||||
have++;
|
||||
}
|
||||
}
|
||||
ind_.resize(have);
|
||||
state_ = (have >= need) ? Passed : Failed;
|
||||
return state_;
|
||||
}
|
||||
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
std::ostream& StatusTestOrderedResNorm<ScalarType,MV,OP>::print(std::ostream& os, int indent) const {
|
||||
std::string ind(indent,' ');
|
||||
os << ind << "- StatusTestOrderedResNorm: ";
|
||||
switch (state_) {
|
||||
case Passed:
|
||||
os << "Passed" << std::endl;
|
||||
break;
|
||||
case Failed:
|
||||
os << "Failed" << std::endl;
|
||||
break;
|
||||
case Undefined:
|
||||
os << "Undefined" << std::endl;
|
||||
break;
|
||||
}
|
||||
os << ind << " (Tolerance,WhichNorm,Scaled,Quorum): "
|
||||
<< "(" << tol_;
|
||||
switch (whichNorm_) {
|
||||
case RES_ORTH:
|
||||
os << ",RES_ORTH";
|
||||
break;
|
||||
case RES_2NORM:
|
||||
os << ",RES_2NORM";
|
||||
break;
|
||||
case RITZRES_2NORM:
|
||||
os << ",RITZRES_2NORM";
|
||||
break;
|
||||
}
|
||||
os << "," << (scaled_ ? "true" : "false")
|
||||
<< "," << quorum_
|
||||
<< ")" << std::endl;
|
||||
os << ind << " Auxiliary values: ";
|
||||
if (rvals_.size() > 0) {
|
||||
for (unsigned int i=0; i<rvals_.size(); i++) {
|
||||
os << "(" << rvals_[i] << ", " << ivals_[i] << ") ";
|
||||
}
|
||||
os << std::endl;
|
||||
}
|
||||
else {
|
||||
os << "[empty]" << std::endl;
|
||||
}
|
||||
|
||||
if (state_ != Undefined) {
|
||||
os << ind << " Which vectors: ";
|
||||
if (ind_.size() > 0) {
|
||||
for (unsigned int i=0; i<ind_.size(); i++) os << ind_[i] << " ";
|
||||
os << std::endl;
|
||||
}
|
||||
else {
|
||||
os << "[empty]" << std::endl;
|
||||
}
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
} // end of Anasazi namespace
|
||||
|
||||
#endif /* ANASAZI_STATUS_TEST_ORDEREDRESNORM_HPP */
|
||||
@@ -0,0 +1,221 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
//
|
||||
|
||||
#ifndef ANASAZI_STATUS_TEST_OUTPUT_HPP
|
||||
#define ANASAZI_STATUS_TEST_OUTPUT_HPP
|
||||
|
||||
/*!
|
||||
\file AnasaziStatusTestOutput.hpp
|
||||
\brief Special StatusTest for printing status tests.
|
||||
*/
|
||||
|
||||
|
||||
#include "AnasaziConfigDefs.hpp"
|
||||
#include "AnasaziTypes.hpp"
|
||||
#include "AnasaziEigensolver.hpp"
|
||||
|
||||
#include "AnasaziStatusTest.hpp"
|
||||
|
||||
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
/*!
|
||||
\class StatusTestOutput
|
||||
\brief A special StatusTest for printing other status tests.
|
||||
|
||||
StatusTestOutput is a wrapper around another StatusTest that calls
|
||||
StatusTest::print() on the underlying object on calls to StatusTestOutput::checkStatus().
|
||||
The frequency and occasion of the printing can be dictated according to some parameters passed to
|
||||
StatusTestOutput::StatusTestOutput().
|
||||
*/
|
||||
template <class ScalarType, class MV, class OP>
|
||||
class StatusTestOutput : public StatusTest<ScalarType,MV,OP> {
|
||||
|
||||
public:
|
||||
//! @name Constructors/destructors
|
||||
//@{
|
||||
|
||||
/*! \brief Constructor
|
||||
*
|
||||
* The StatusTestOutput requires an OutputManager for printing the underlying StatusTest on
|
||||
* calls to checkStatus(), as well as an underlying StatusTest.
|
||||
*
|
||||
* The last two parameters, described below, in addition to the verbosity level of the OutputManager, control when printing is
|
||||
* called. When both the \c mod criterion and the \c printStates criterion are satisfied, the status test will be printed to the
|
||||
* OutputManager with ::MsgType of ::StatusTestDetails.
|
||||
*
|
||||
* @param[in] mod A positive number describes how often the output should be printed. On every call to checkStatus(), an internal counter
|
||||
* is incremented. Printing may only occur when this counter is congruent to zero modulo \c mod. Default: 1 (attempt to print on every call to checkStatus())
|
||||
* @param[in] printStates A combination of ::TestStatus values for which the output may be printed. Default: ::Passed (attempt to print whenever checkStatus() will return ::Passed)
|
||||
*
|
||||
*/
|
||||
StatusTestOutput(const Teuchos::RCP<OutputManager<ScalarType> > &printer,
|
||||
Teuchos::RCP<StatusTest<ScalarType,MV,OP> > test,
|
||||
int mod = 1,
|
||||
int printStates = Passed)
|
||||
: printer_(printer), test_(test), state_(Undefined), stateTest_(printStates), modTest_(mod), numCalls_(0) {}
|
||||
|
||||
//! Destructor
|
||||
virtual ~StatusTestOutput() {};
|
||||
//@}
|
||||
|
||||
//! @name Status methods
|
||||
//@{
|
||||
/*! Check and return status of underlying StatusTest.
|
||||
|
||||
This method calls checkStatus() on the StatusTest object passed in the constructor. If appropriate, the
|
||||
method will follow this call with a call to print() on the underlying object, using the OutputManager passed via the constructor
|
||||
with verbosity level ::StatusTestDetails.
|
||||
|
||||
The internal counter will be incremented during this call, but only after
|
||||
performing the tests to decide whether or not to print the underlying
|
||||
StatusTest. This way, the very first call to checkStatus() following
|
||||
initialization or reset() will enable the underlying StatusTest to be
|
||||
printed, regardless of the mod parameter, as the current number of calls
|
||||
will be zero.
|
||||
|
||||
If the specified Teuchos::RCP for the child class is Teuchos::null, then calling checkStatus() will result in a StatusTestError exception being thrown.
|
||||
|
||||
\return ::TestStatus indicating whether the underlying test passed or failed.
|
||||
*/
|
||||
TestStatus checkStatus( Eigensolver<ScalarType,MV,OP>* solver ) {
|
||||
TEST_FOR_EXCEPTION(test_ == Teuchos::null,StatusTestError,"StatusTestOutput::checkStatus(): child pointer is null.");
|
||||
state_ = test_->checkStatus(solver);
|
||||
|
||||
if (numCalls_++ % modTest_ == 0) {
|
||||
if ( (state_ & stateTest_) == state_) {
|
||||
if ( printer_->isVerbosity(StatusTestDetails) ) {
|
||||
print( printer_->stream(StatusTestDetails) );
|
||||
}
|
||||
else if ( printer_->isVerbosity(Debug) ) {
|
||||
print( printer_->stream(Debug) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return state_;
|
||||
}
|
||||
|
||||
//! Return the result of the most recent checkStatus call, or undefined if it has not been run.
|
||||
TestStatus getStatus() const {
|
||||
return state_;
|
||||
}
|
||||
//@}
|
||||
|
||||
|
||||
//! @name Accessor methods
|
||||
//@{
|
||||
|
||||
/*! \brief Set child test.
|
||||
*
|
||||
* \note This also resets the test status to ::Undefined.
|
||||
*/
|
||||
void setChild(Teuchos::RCP<StatusTest<ScalarType,MV,OP> > test) {
|
||||
test_ = test;
|
||||
state_ = Undefined;
|
||||
}
|
||||
|
||||
//! \brief Get child test.
|
||||
Teuchos::RCP<StatusTest<ScalarType,MV,OP> > getChild() const {
|
||||
return test_;
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
|
||||
//! @name Reset methods
|
||||
//@{
|
||||
/*! \brief Informs the status test that it should reset its internal configuration to the uninitialized state.
|
||||
*
|
||||
* This resets the cached state to an ::Undefined state and calls reset() on the underlying test. It also
|
||||
* resets the counter for the number of calls to checkStatus().
|
||||
*/
|
||||
void reset() {
|
||||
state_ = Undefined;
|
||||
test_->reset();
|
||||
numCalls_ = 0;
|
||||
}
|
||||
|
||||
//! Clears the results of the last status test.
|
||||
//! This resets the cached state to an ::Undefined state and calls clearStatus() on the underlying test.
|
||||
void clearStatus() {
|
||||
state_ = Undefined;
|
||||
test_->clearStatus();
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Print methods
|
||||
//@{
|
||||
|
||||
//! Output formatted description of stopping test to output stream.
|
||||
std::ostream& print(std::ostream& os, int indent = 0) const {
|
||||
std::string ind(indent,' ');
|
||||
os << ind << "- StatusTestOutput: ";
|
||||
switch (state_) {
|
||||
case Passed:
|
||||
os << "Passed" << std::endl;
|
||||
break;
|
||||
case Failed:
|
||||
os << "Failed" << std::endl;
|
||||
break;
|
||||
case Undefined:
|
||||
os << "Undefined" << std::endl;
|
||||
break;
|
||||
}
|
||||
os << ind << " (Num calls,Mod test,State test): " << "(" << numCalls_ << ", " << modTest_ << ",";
|
||||
if (stateTest_ == 0) {
|
||||
os << " none )" << std::endl;
|
||||
}
|
||||
else {
|
||||
if ( (stateTest_ & Passed) == Passed ) os << " Passed";
|
||||
if ( (stateTest_ & Failed) == Failed ) os << " Failed";
|
||||
if ( (stateTest_ & Undefined) == Undefined ) os << " Undefined";
|
||||
os << " )" << std::endl;
|
||||
}
|
||||
// print child, with extra indention
|
||||
test_->print(os,indent+3);
|
||||
return os;
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
private:
|
||||
Teuchos::RCP<OutputManager<ScalarType> > printer_;
|
||||
Teuchos::RCP<StatusTest<ScalarType,MV,OP> > test_;
|
||||
TestStatus state_;
|
||||
int stateTest_;
|
||||
int modTest_;
|
||||
int numCalls_;
|
||||
};
|
||||
|
||||
} // end of Anasazi namespace
|
||||
|
||||
#endif /* ANASAZI_STATUS_TEST_OUTPUT_HPP */
|
||||
@@ -0,0 +1,317 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
//
|
||||
|
||||
#ifndef ANASAZI_STATUS_TEST_RESNORM_HPP
|
||||
#define ANASAZI_STATUS_TEST_RESNORM_HPP
|
||||
|
||||
/*!
|
||||
\file AnasaziStatusTestResNorm.hpp
|
||||
\brief A status test for testing the norm of the eigenvectors residuals.
|
||||
*/
|
||||
|
||||
|
||||
#include "AnasaziStatusTest.hpp"
|
||||
#include "Teuchos_ScalarTraits.hpp"
|
||||
|
||||
/*!
|
||||
\class Anasazi::StatusTestResNorm
|
||||
\brief A status test for testing the norm of the eigenvectors residuals.
|
||||
|
||||
Anasazi::StatusTestResNorm was designed to be used as a test for
|
||||
convergence. The tester compares the norms of the residual vectors against
|
||||
a user specified tolerance.
|
||||
|
||||
In addition to specifying the tolerance, the user may specify:
|
||||
<ul>
|
||||
<li> the norm to be used: 2-norm or OrthoManager::norm() or getRitzRes2Norms()
|
||||
<li> the scale: absolute or relative to magnitude of Ritz value
|
||||
<li> the quorum: the number of vectors required for the test to
|
||||
evaluate as ::Passed.
|
||||
</ul>
|
||||
*/
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
class StatusTestResNorm : public StatusTest<ScalarType,MV,OP> {
|
||||
|
||||
typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
|
||||
|
||||
public:
|
||||
|
||||
//! @name Enums
|
||||
//@{
|
||||
|
||||
/*! \enum ResType
|
||||
\brief Enumerated type used to specify which residual norm used by this status test.
|
||||
*/
|
||||
enum ResType {
|
||||
RES_ORTH,
|
||||
RES_2NORM,
|
||||
RITZRES_2NORM
|
||||
};
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Constructors/destructors
|
||||
//@{
|
||||
|
||||
//! Constructor
|
||||
StatusTestResNorm(typename Teuchos::ScalarTraits<ScalarType>::magnitudeType tol, int quorum = -1, ResType whichNorm = RES_ORTH, bool scaled = true);
|
||||
|
||||
//! Destructor
|
||||
virtual ~StatusTestResNorm() {};
|
||||
//@}
|
||||
|
||||
//! @name Status methods
|
||||
//@{
|
||||
/*! Check status as defined by test.
|
||||
\return TestStatus indicating whether the test passed or failed.
|
||||
*/
|
||||
TestStatus checkStatus( Eigensolver<ScalarType,MV,OP>* solver );
|
||||
|
||||
//! Return the result of the most recent checkStatus call.
|
||||
TestStatus getStatus() const { return state_; }
|
||||
//@}
|
||||
|
||||
//! @name Accessor methods
|
||||
//@{
|
||||
|
||||
/*! \brief Set quorum.
|
||||
*
|
||||
* Setting quorum to -1 signifies that all residuals from the solver must meet the tolerance.
|
||||
* This also resets the test status to ::Undefined.
|
||||
*/
|
||||
void setQuorum(int quorum) {
|
||||
state_ = Undefined;
|
||||
quorum_ = quorum;
|
||||
}
|
||||
|
||||
/*! \brief Get quorum.
|
||||
*/
|
||||
int getQuorum() {
|
||||
return quorum_;
|
||||
}
|
||||
|
||||
/*! \brief Set tolerance.
|
||||
* This also resets the test status to ::Undefined.
|
||||
*/
|
||||
void setTolerance(typename Teuchos::ScalarTraits<ScalarType>::magnitudeType tol) {
|
||||
state_ = Undefined;
|
||||
tol_ = tol;
|
||||
}
|
||||
|
||||
//! Get tolerance.
|
||||
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType getTolerance() {return tol_;}
|
||||
|
||||
/*! \brief Set the residual norm to be used by the status test.
|
||||
*
|
||||
* This also resets the test status to ::Undefined.
|
||||
*/
|
||||
void setWhichNorm(ResType whichNorm) {
|
||||
state_ = Undefined;
|
||||
whichNorm_ = whichNorm;
|
||||
}
|
||||
|
||||
//! Return the residual norm used by the status test.
|
||||
ResType getWhichNorm() {return whichNorm_;}
|
||||
|
||||
/*! \brief Instruct test to scale norms by eigenvalue estimates (relative scale).
|
||||
* This also resets the test status to ::Undefined.
|
||||
*/
|
||||
void setScale(bool relscale) {
|
||||
state_ = Undefined;
|
||||
scaled_ = relscale;
|
||||
}
|
||||
|
||||
//! Returns true if the test scales the norms by the eigenvalue estimates (relative scale).
|
||||
bool getScale() {return scaled_;}
|
||||
|
||||
//! Get the indices for the vectors that passed the test.
|
||||
std::vector<int> whichVecs() {
|
||||
return ind_;
|
||||
}
|
||||
|
||||
//! Get the number of vectors that passed the test.
|
||||
int howMany() {
|
||||
return ind_.size();
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Reset methods
|
||||
//@{
|
||||
//! Informs the status test that it should reset its internal configuration to the uninitialized state.
|
||||
/*! This is necessary for the case when the status test is being reused by another solver or for another
|
||||
eigenvalue problem. The status test may have information that pertains to a particular problem or solver
|
||||
state. The internal information will be reset back to the uninitialized state. The user specified information
|
||||
that the convergence test uses will remain.
|
||||
*/
|
||||
void reset() {
|
||||
state_ = Undefined;
|
||||
}
|
||||
|
||||
//! Clears the results of the last status test.
|
||||
/*! This should be distinguished from the reset() method, as it only clears the cached result from the last
|
||||
* status test, so that a call to getStatus() will return ::Undefined. This is necessary for the SEQOR and SEQAND
|
||||
* tests in the StatusTestCombo class, which may short circuit and not evaluate all of the StatusTests contained
|
||||
* in them.
|
||||
*/
|
||||
void clearStatus() {
|
||||
state_ = Undefined;
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Print methods
|
||||
//@{
|
||||
|
||||
//! Output formatted description of stopping test to output stream.
|
||||
std::ostream& print(std::ostream& os, int indent = 0) const;
|
||||
|
||||
//@}
|
||||
private:
|
||||
TestStatus state_;
|
||||
MagnitudeType tol_;
|
||||
std::vector<int> ind_;
|
||||
int quorum_;
|
||||
bool scaled_;
|
||||
ResType whichNorm_;
|
||||
};
|
||||
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
StatusTestResNorm<ScalarType,MV,OP>::StatusTestResNorm(typename Teuchos::ScalarTraits<ScalarType>::magnitudeType tol, int quorum, ResType whichNorm, bool scaled)
|
||||
: state_(Undefined), tol_(tol), quorum_(quorum), scaled_(scaled), whichNorm_(whichNorm) {}
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
TestStatus StatusTestResNorm<ScalarType,MV,OP>::checkStatus( Eigensolver<ScalarType,MV,OP>* solver ) {
|
||||
typedef Teuchos::ScalarTraits<MagnitudeType> MT;
|
||||
|
||||
std::vector<MagnitudeType> res;
|
||||
|
||||
// get the eigenvector/ritz residuals norms (using the appropriate norm)
|
||||
// get the eigenvalues/ritzvalues and ritz index as well
|
||||
std::vector<Value<ScalarType> > vals = solver->getRitzValues();
|
||||
switch (whichNorm_) {
|
||||
case RES_2NORM:
|
||||
res = solver->getRes2Norms();
|
||||
// we want only the ritz values corresponding to our eigenvector residuals
|
||||
vals.resize(res.size());
|
||||
break;
|
||||
case RES_ORTH:
|
||||
res = solver->getResNorms();
|
||||
// we want only the ritz values corresponding to our eigenvector residuals
|
||||
vals.resize(res.size());
|
||||
break;
|
||||
case RITZRES_2NORM:
|
||||
res = solver->getRitzRes2Norms();
|
||||
break;
|
||||
}
|
||||
|
||||
// if appropriate, scale the norms by the magnitude of the eigenvalue estimate
|
||||
if (scaled_) {
|
||||
Teuchos::LAPACK<int,MagnitudeType> lapack;
|
||||
|
||||
for (unsigned int i=0; i<res.size(); i++) {
|
||||
MagnitudeType tmp = lapack.LAPY2(vals[i].realpart,vals[i].imagpart);
|
||||
// scale by the newly computed magnitude of the ritz values
|
||||
if ( tmp != MT::zero() ) {
|
||||
res[i] /= tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// test the norms
|
||||
int have = 0;
|
||||
ind_.resize(res.size());
|
||||
for (unsigned int i=0; i<res.size(); i++) {
|
||||
TEST_FOR_EXCEPTION( MT::isnaninf(res[i]), StatusTestError, "StatusTestResNorm::checkStatus(): residual norm is nan or inf" );
|
||||
if (res[i] < tol_) {
|
||||
ind_[have] = i;
|
||||
have++;
|
||||
}
|
||||
}
|
||||
ind_.resize(have);
|
||||
int need = (quorum_ == -1) ? res.size() : quorum_;
|
||||
state_ = (have >= need) ? Passed : Failed;
|
||||
return state_;
|
||||
}
|
||||
|
||||
|
||||
template <class ScalarType, class MV, class OP>
|
||||
std::ostream& StatusTestResNorm<ScalarType,MV,OP>::print(std::ostream& os, int indent) const {
|
||||
std::string ind(indent,' ');
|
||||
os << ind << "- StatusTestResNorm: ";
|
||||
switch (state_) {
|
||||
case Passed:
|
||||
os << "Passed" << std::endl;
|
||||
break;
|
||||
case Failed:
|
||||
os << "Failed" << std::endl;
|
||||
break;
|
||||
case Undefined:
|
||||
os << "Undefined" << std::endl;
|
||||
break;
|
||||
}
|
||||
os << ind << " (Tolerance,WhichNorm,Scaled,Quorum): "
|
||||
<< "(" << tol_;
|
||||
switch (whichNorm_) {
|
||||
case RES_ORTH:
|
||||
os << ",RES_ORTH";
|
||||
break;
|
||||
case RES_2NORM:
|
||||
os << ",RES_2NORM";
|
||||
break;
|
||||
case RITZRES_2NORM:
|
||||
os << ",RITZRES_2NORM";
|
||||
break;
|
||||
}
|
||||
os << "," << (scaled_ ? "true" : "false")
|
||||
<< "," << quorum_
|
||||
<< ")" << std::endl;
|
||||
|
||||
if (state_ != Undefined) {
|
||||
os << ind << " Which vectors: ";
|
||||
if (ind_.size() > 0) {
|
||||
for (unsigned int i=0; i<ind_.size(); i++) os << ind_[i] << " ";
|
||||
os << std::endl;
|
||||
}
|
||||
else {
|
||||
os << "[empty]" << std::endl;
|
||||
}
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
} // end of Anasazi namespace
|
||||
|
||||
#endif /* ANASAZI_STATUS_TEST_RESNORM_HPP */
|
||||
@@ -0,0 +1,153 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Anasazi: Block Eigensolvers Package
|
||||
// Copyright (2004) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
|
||||
#ifndef ANASAZI_TYPES_HPP
|
||||
#define ANASAZI_TYPES_HPP
|
||||
|
||||
#include "AnasaziConfigDefs.hpp"
|
||||
#include "Teuchos_RCP.hpp"
|
||||
#include "Teuchos_ScalarTraits.hpp"
|
||||
|
||||
/*! \file AnasaziTypes.hpp
|
||||
\brief Types and exceptions used within Anasazi solvers and interfaces.
|
||||
*/
|
||||
|
||||
namespace Anasazi {
|
||||
|
||||
//! @name Anasazi Exceptions
|
||||
//@{
|
||||
|
||||
/*! \class AnasaziError
|
||||
\brief An exception class parent to all Anasazi exceptions.
|
||||
*/
|
||||
class AnasaziError : public std::logic_error {
|
||||
public: AnasaziError(const std::string& what_arg) : std::logic_error(what_arg) {}
|
||||
};
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Anasazi Structs
|
||||
//@{
|
||||
|
||||
//! This struct is used for storing eigenvalues and Ritz values, as a pair of real values.
|
||||
template <class ScalarType>
|
||||
struct Value {
|
||||
//! The real component of the eigenvalue.
|
||||
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType realpart;
|
||||
//! The imaginary component of the eigenvalue.
|
||||
typename Teuchos::ScalarTraits<ScalarType>::magnitudeType imagpart;
|
||||
void set(const typename Teuchos::ScalarTraits<ScalarType>::magnitudeType &rp, const typename Teuchos::ScalarTraits<ScalarType>::magnitudeType &ip){
|
||||
realpart=rp;imagpart=ip;
|
||||
}
|
||||
Value<ScalarType> &operator=(const Value<ScalarType> &rhs) {
|
||||
realpart=rhs.realpart;imagpart=rhs.imagpart;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
//! Struct for storing an eigenproblem solution.
|
||||
template <class ScalarType, class MV>
|
||||
struct Eigensolution {
|
||||
//! The computed eigenvectors
|
||||
Teuchos::RCP<MV> Evecs;
|
||||
//! An orthonormal basis for the computed eigenspace
|
||||
Teuchos::RCP<MV> Espace;
|
||||
//! The computed eigenvalues
|
||||
std::vector<Value<ScalarType> > Evals;
|
||||
/*! \brief An index into Evecs to allow compressed storage of eigenvectors for real, non-Hermitian problems.
|
||||
*
|
||||
* index has length numVecs, where each entry is 0, +1, or -1. These have the following interpretation:
|
||||
* - index[i] == 0: signifies that the corresponding eigenvector is stored as the i column of Evecs. This will usually be the
|
||||
* case when ScalarType is complex, an eigenproblem is Hermitian, or a real, non-Hermitian eigenproblem has a real eigenvector.
|
||||
* - index[i] == +1: signifies that the corresponding eigenvector is stored in two vectors: the real part in the i column of Evecs and the <i><b>positive</b></i> imaginary part in the i+1 column of Evecs.
|
||||
* - index[i] == -1: signifies that the corresponding eigenvector is stored in two vectors: the real part in the i-1 column of Evecs and the <i><b>negative</b></i> imaginary part in the i column of Evecs
|
||||
*/
|
||||
std::vector<int> index;
|
||||
//! The number of computed eigenpairs
|
||||
int numVecs;
|
||||
|
||||
Eigensolution() : Evecs(),Espace(),Evals(0),index(0),numVecs(0) {}
|
||||
};
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Anasazi Enumerations
|
||||
//@{
|
||||
|
||||
/*! \enum ReturnType
|
||||
\brief Enumerated type used to pass back information from a solver manager.
|
||||
*/
|
||||
enum ReturnType
|
||||
{
|
||||
Converged, /*!< The solver manager computed the requested eigenvalues. */
|
||||
Unconverged /*!< This solver manager did not compute all of the requested eigenvalues. */
|
||||
};
|
||||
|
||||
|
||||
/*! \enum ConjType
|
||||
*
|
||||
* \brief Enumerated types used to specify conjugation arguments.
|
||||
*/
|
||||
enum ConjType
|
||||
{
|
||||
NO_CONJ, /*!< Not conjugated */
|
||||
CONJ /*!< Conjugated */
|
||||
};
|
||||
|
||||
|
||||
/*! \enum TestStatus
|
||||
\brief Enumerated type used to pass back information from a StatusTest
|
||||
*/
|
||||
enum TestStatus
|
||||
{
|
||||
Passed = 0x1, /*!< The solver passed the test */
|
||||
Failed = 0x2, /*!< The solver failed the test */
|
||||
Undefined = 0x4 /*!< The test has not been evaluated on the solver */
|
||||
};
|
||||
|
||||
|
||||
/*! \enum MsgType
|
||||
\brief Enumerated list of available message types recognized by the eigensolvers.
|
||||
*/
|
||||
enum MsgType
|
||||
{
|
||||
Errors = 0, /*!< Errors [ always printed ] */
|
||||
Warnings = 0x1, /*!< Internal warnings */
|
||||
IterationDetails = 0x2, /*!< Approximate eigenvalues, errors */
|
||||
OrthoDetails = 0x4, /*!< Orthogonalization/orthonormalization details */
|
||||
FinalSummary = 0x8, /*!< Final computational summary */
|
||||
TimingDetails = 0x10, /*!< Timing details */
|
||||
StatusTestDetails = 0x20, /*!< Status test details */
|
||||
Debug = 0x40 /*!< Debugging information */
|
||||
};
|
||||
|
||||
//@}
|
||||
|
||||
} // end of namespace Anasazi
|
||||
#endif
|
||||
// end of file AnasaziTypes.hpp
|
||||
@@ -0,0 +1,214 @@
|
||||
/* src/Anasazi_config.h. Generated from Anasazi_config.h.in by configure. */
|
||||
/* src/Anasazi_config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to dummy `main' function (if any) required to link to the Fortran
|
||||
libraries. */
|
||||
/* #undef F77_DUMMY_MAIN */
|
||||
|
||||
/* Define to a macro mangling the given C identifier (in lower and upper
|
||||
case), which must not contain underscores, for linking with Fortran. */
|
||||
#define F77_FUNC(name,NAME) name ## _
|
||||
|
||||
/* As F77_FUNC, but for C identifiers containing underscores. */
|
||||
#define F77_FUNC_(name,NAME) name ## __
|
||||
|
||||
/* Define if F77 and FC dummy `main' functions are identical. */
|
||||
/* #undef FC_DUMMY_MAIN_EQ_F77 */
|
||||
|
||||
/* Define to 1 if you have the <algorithm> header file. */
|
||||
#define HAVE_ALGORITHM 1
|
||||
|
||||
/* Define to 1 if you have the <algorithm.h> header file. */
|
||||
/* #undef HAVE_ALGORITHM_H */
|
||||
|
||||
/* Define to 1 if you have the <algo.h> header file. */
|
||||
/* #undef HAVE_ALGO_H */
|
||||
|
||||
/* Define if want to build with anasazi enabled */
|
||||
/* #undef HAVE_ANASAZI_AMESOS */
|
||||
|
||||
/* Define if want to build with anasazi enabled */
|
||||
/* #undef HAVE_ANASAZI_AZTECOO */
|
||||
|
||||
/* Define if want to build with anasazi enabled */
|
||||
/* #undef HAVE_ANASAZI_BELOS */
|
||||
|
||||
/* Define if want to build with anasazi enabled */
|
||||
/* #undef HAVE_ANASAZI_EPETRAEXT */
|
||||
|
||||
/* Define if want to build anasazi-examples */
|
||||
#define HAVE_ANASAZI_EXAMPLES
|
||||
|
||||
/* Define if want to build anasazi-experimental */
|
||||
/* #undef HAVE_ANASAZI_EXPERIMENTAL */
|
||||
|
||||
/* Define if want to build with anasazi enabled */
|
||||
/* #undef HAVE_ANASAZI_IFPACK */
|
||||
|
||||
/* Define if want to build anasazi-tests */
|
||||
#define HAVE_ANASAZI_TESTS
|
||||
|
||||
/* Define if want to build with anasazi enabled */
|
||||
/* #undef HAVE_ANASAZI_THYRA */
|
||||
|
||||
/* Define if want to build with anasazi enabled */
|
||||
/* #undef HAVE_ANASAZI_TPETRA */
|
||||
|
||||
/* Define if want to build with anasazi enabled */
|
||||
/* #undef HAVE_ANASAZI_TRIUTILS */
|
||||
|
||||
/* Define if you have a BLAS library. */
|
||||
#define HAVE_BLAS 1
|
||||
|
||||
/* define if bool is a built-in type */
|
||||
#define HAVE_BOOL
|
||||
|
||||
/* Define to 1 if you have the <cmath> header file. */
|
||||
#define HAVE_CMATH 1
|
||||
|
||||
/* Define to 1 if you have the <complex> header file. */
|
||||
#define HAVE_COMPLEX 1
|
||||
|
||||
/* Define to 1 if you have the <complex.h> header file. */
|
||||
/* #undef HAVE_COMPLEX_H */
|
||||
|
||||
/* Define to 1 if you have the <cstdio> header file. */
|
||||
#define HAVE_CSTDIO 1
|
||||
|
||||
/* Define to 1 if you have the <cstdlib> header file. */
|
||||
#define HAVE_CSTDLIB 1
|
||||
|
||||
/* Define if want to build with epetra enabled */
|
||||
/* #undef HAVE_EPETRA_THYRA */
|
||||
|
||||
/* Define if want to build examples */
|
||||
#define HAVE_EXAMPLES
|
||||
|
||||
/* Define if you want to build export makefiles. */
|
||||
#define HAVE_EXPORT_MAKEFILES
|
||||
|
||||
/* Define if you are using gnumake - this will shorten your link lines. */
|
||||
/* #undef HAVE_GNUMAKE */
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <iomanip> header file. */
|
||||
#define HAVE_IOMANIP 1
|
||||
|
||||
/* Define to 1 if you have the <iomanip.h> header file. */
|
||||
/* #undef HAVE_IOMANIP_H */
|
||||
|
||||
/* Define to 1 if you have the <iostream> header file. */
|
||||
#define HAVE_IOSTREAM 1
|
||||
|
||||
/* Define to 1 if you have the <iostream.h> header file. */
|
||||
/* #undef HAVE_IOSTREAM_H */
|
||||
|
||||
/* Define to 1 if you have the <iterator> header file. */
|
||||
#define HAVE_ITERATOR 1
|
||||
|
||||
/* Define to 1 if you have the <iterator.h> header file. */
|
||||
/* #undef HAVE_ITERATOR_H */
|
||||
|
||||
/* Define if you have LAPACK library. */
|
||||
#define HAVE_LAPACK 1
|
||||
|
||||
/* Define if want to build libcheck */
|
||||
#define HAVE_LIBCHECK
|
||||
|
||||
/* Define to 1 if you have the <math.h> header file. */
|
||||
/* #undef HAVE_MATH_H */
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* define if we want to use MPI */
|
||||
/* #undef HAVE_MPI */
|
||||
|
||||
/* define if the compiler supports the mutable keyword */
|
||||
#define HAVE_MUTABLE
|
||||
|
||||
/* define if the compiler implements namespaces */
|
||||
#define HAVE_NAMESPACES
|
||||
|
||||
/* define if the compiler accepts the new for scoping rules */
|
||||
#define HAVE_NEW_FOR_SCOPING
|
||||
|
||||
/* Define to 1 if you have the <numeric> header file. */
|
||||
#define HAVE_NUMERIC 1
|
||||
|
||||
/* Define to 1 if you have the <stdexcept> header file. */
|
||||
#define HAVE_STDEXCEPT 1
|
||||
|
||||
/* Define to 1 if you have the <stdexcept.h> header file. */
|
||||
/* #undef HAVE_STDEXCEPT_H */
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdio.h> header file. */
|
||||
/* #undef HAVE_STDIO_H */
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* define if std::sprintf is supported */
|
||||
#define HAVE_STD_SPRINTF
|
||||
|
||||
/* define if the compiler supports Standard Template Library */
|
||||
#define HAVE_STL
|
||||
|
||||
/* Define to 1 if you have the <string> header file. */
|
||||
#define HAVE_STRING 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define if want to build tests */
|
||||
#define HAVE_TESTS
|
||||
|
||||
/* Define if want to build teuchos-complex */
|
||||
#define HAVE_TEUCHOS_COMPLEX
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the <vector> header file. */
|
||||
#define HAVE_VECTOR 1
|
||||
|
||||
/* Define to 1 if you have the <vector.h> header file. */
|
||||
/* #undef HAVE_VECTOR_H */
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "hkthorn@sandia.gov"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "anasazi"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "anasazi 2.1"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "anasazi"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "2.1"
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
/* #undef inline */
|
||||
#endif
|
||||
@@ -0,0 +1,166 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_BLAS_H
|
||||
#define EPETRA_BLAS_H
|
||||
|
||||
#include "Epetra_Object.h"
|
||||
|
||||
//! Epetra_BLAS: The Epetra BLAS Wrapper Class.
|
||||
/*! The Epetra_BLAS class is a wrapper that encapsulates the BLAS
|
||||
(Basic Linear Algebra Subprograms). The BLAS provide portable, high-
|
||||
performance implementations of kernels such as dense vectoer multiplication,
|
||||
dot products, dense matrix-vector multiplication and dense matrix-matrix
|
||||
multiplication.
|
||||
|
||||
The standard BLAS interface is Fortran-specific. Unfortunately, the
|
||||
interface between C++ and Fortran is not standard across all computer
|
||||
platforms. The Epetra_BLAS class provides C++ wrappers for the BLAS
|
||||
kernels in order to insulate the rest of Epetra from the details of C++ to Fortran
|
||||
translation.
|
||||
A Epetra_BLAS object is essentially nothing, but allows access to the BLAS wrapper
|
||||
functions.
|
||||
|
||||
Epetra_BLAS is a serial interface only. This is appropriate since the standard
|
||||
BLAS are only specified for serial execution (or shared memory parallel).
|
||||
*/
|
||||
|
||||
|
||||
class Epetra_BLAS {
|
||||
|
||||
public:
|
||||
//! @name Constructors/Destructor
|
||||
//@{
|
||||
//! Epetra_BLAS Constructor.
|
||||
/*! Builds an instance of a serial BLAS object.
|
||||
*/
|
||||
Epetra_BLAS(void);
|
||||
|
||||
|
||||
//! Epetra_BLAS Copy Constructor.
|
||||
/*! Makes an exact copy of an existing Epetra_BLAS instance.
|
||||
*/
|
||||
Epetra_BLAS(const Epetra_BLAS& BLAS);
|
||||
|
||||
//! Epetra_BLAS Destructor.
|
||||
virtual ~Epetra_BLAS(void);
|
||||
//@}
|
||||
|
||||
//! @name Level 1 BLAS
|
||||
//@{
|
||||
//! Epetra_BLAS one norm function (SASUM).
|
||||
float ASUM(const int N, const float * X, const int INCX = 1) const;
|
||||
//! Epetra_BLAS one norm function (DASUM).
|
||||
double ASUM(const int N, const double * X, const int INCX = 1) const;
|
||||
|
||||
//! Epetra_BLAS dot product function (SDOT).
|
||||
float DOT(const int N, const float * X, const float * Y, const int INCX = 1, const int INCY = 1) const;
|
||||
//! Epetra_BLAS dot product function (DDOT).
|
||||
double DOT(const int N, const double * X, const double * Y, const int INCX = 1, const int INCY = 1) const;
|
||||
|
||||
//! Epetra_BLAS norm function (SNRM2).
|
||||
float NRM2(const int N, const float * X, const int INCX = 1) const;
|
||||
//! Epetra_BLAS norm function (DNRM2).
|
||||
double NRM2(const int N, const double * X, const int INCX = 1) const;
|
||||
|
||||
//! Epetra_BLAS vector scale function (SSCAL)
|
||||
void SCAL( const int N, const float ALPHA, float * X, const int INCX = 1) const;
|
||||
//! Epetra_BLAS vector scale function (DSCAL)
|
||||
void SCAL( const int N, const double ALPHA, double * X, const int INCX = 1) const;
|
||||
|
||||
//! Epetra_BLAS vector copy function (SCOPY)
|
||||
void COPY( const int N, const float * X, float * Y, const int INCX = 1, const int INCY = 1) const;
|
||||
//! Epetra_BLAS vector scale function (DCOPY)
|
||||
void COPY( const int N, const double * X, double * Y, const int INCX = 1, const int INCY = 1) const;
|
||||
|
||||
//! Epetra_BLAS arg maximum of absolute value function (ISAMAX)
|
||||
int IAMAX( const int N, const float * X, const int INCX = 1) const;
|
||||
//! Epetra_BLAS arg maximum of absolute value function (IDAMAX)
|
||||
int IAMAX( const int N, const double * X, const int INCX = 1) const;
|
||||
|
||||
//! Epetra_BLAS vector update function (SAXPY)
|
||||
void AXPY( const int N, const float ALPHA, const float * X, float * Y, const int INCX = 1, const int INCY = 1) const;
|
||||
//! Epetra_BLAS vector update function (DAXPY)
|
||||
void AXPY( const int N, const double ALPHA, const double * X, double * Y, const int INCX = 1, const int INCY = 1) const;
|
||||
//@}
|
||||
|
||||
//! @name Level 2 BLAS
|
||||
//@{
|
||||
//! Epetra_BLAS matrix-vector multiply function (SGEMV)
|
||||
void GEMV(const char TRANS, const int M, const int N,
|
||||
const float ALPHA, const float * A, const int LDA, const float * X,
|
||||
const float BETA, float * Y, const int INCX = 1, const int INCY = 1) const;
|
||||
//! Epetra_BLAS matrix-vector multiply function (DGEMV)
|
||||
void GEMV(const char TRANS, const int M, const int N,
|
||||
const double ALPHA, const double * A, const int LDA, const double * X,
|
||||
const double BETA, double * Y, const int INCX = 1, const int INCY = 1) const;
|
||||
//@}
|
||||
|
||||
|
||||
//! @name Level 3 BLAS
|
||||
//@{
|
||||
//! Epetra_BLAS matrix-matrix multiply function (SGEMM)
|
||||
void GEMM(const char TRANSA, const char TRANSB, const int M, const int N, const int K,
|
||||
const float ALPHA, const float * A, const int LDA, const float * B,
|
||||
const int LDB, const float BETA, float * C, const int LDC) const;
|
||||
//! Epetra_BLAS matrix-matrix multiply function (DGEMM)
|
||||
void GEMM(const char TRANSA, const char TRANSB, const int M, const int N, const int K,
|
||||
const double ALPHA, const double * A, const int LDA, const double * B,
|
||||
const int LDB, const double BETA, double * C, const int LDC) const;
|
||||
|
||||
//! Epetra_BLAS symmetric matrix-matrix multiply function (SSYMM)
|
||||
void SYMM(const char SIDE, const char UPLO, const int M, const int N,
|
||||
const float ALPHA, const float * A, const int LDA, const float * B,
|
||||
const int LDB, const float BETA, float * C, const int LDC) const;
|
||||
//! Epetra_BLAS matrix-matrix multiply function (DSYMM)
|
||||
void SYMM(const char SIDE, const char UPLO, const int M, const int N,
|
||||
const double ALPHA, const double * A, const int LDA, const double * B,
|
||||
const int LDB, const double BETA, double * C, const int LDC) const;
|
||||
|
||||
//! Epetra_BLAS triangular matrix-matrix multiply function (STRMM)
|
||||
void TRMM(const char SIDE, const char UPLO, const char TRANSA, const char DIAG, const int M, const int N,
|
||||
const float ALPHA, const float * A, const int LDA, float * B,
|
||||
const int LDB) const;
|
||||
//! Epetra_BLAS triangular matrix-matrix multiply function (DTRMM)
|
||||
void TRMM(const char SIDE, const char UPLO, const char TRANSA, const char DIAG, const int M, const int N,
|
||||
const double ALPHA, const double * A, const int LDA, double * B,
|
||||
const int LDB) const;
|
||||
//@}
|
||||
};
|
||||
|
||||
// Epetra_BLAS constructor
|
||||
inline Epetra_BLAS::Epetra_BLAS(void){}
|
||||
// Epetra_BLAS constructor
|
||||
inline Epetra_BLAS::Epetra_BLAS(const Epetra_BLAS& BLAS){(void)BLAS;}
|
||||
// Epetra_BLAS destructor
|
||||
inline Epetra_BLAS::~Epetra_BLAS(){}
|
||||
|
||||
#endif /* EPETRA_BLAS_H */
|
||||
@@ -0,0 +1,266 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_BLAS_WRAPPERS_H
|
||||
#define EPETRA_BLAS_WRAPPERS_H
|
||||
|
||||
#include "Epetra_ConfigDefs.h"
|
||||
/* #include <stdio.h> */
|
||||
/* #include <string.h> */
|
||||
|
||||
|
||||
/* Define fcd (Fortran Epetra_fcd descriptor) for non-standard situations */
|
||||
|
||||
#if defined(CRAY_T3X) || defined(INTEL_CXML) || defined(INTEL_MKL)
|
||||
|
||||
|
||||
#if defined(CRAY_T3X)
|
||||
|
||||
#include <fortran.h>
|
||||
#define PREFIX
|
||||
#define Epetra_fcd fcd
|
||||
|
||||
#define DASUM_F77 SASUM
|
||||
#define DAXPY_F77 SAXPY
|
||||
#define DCOPY_F77 SCOPY
|
||||
#define DDOT_F77 SDOT
|
||||
#define DNRM2_F77 SNRM2
|
||||
#define DSCAL_F77 SSCAL
|
||||
#define IDAMAX_F77 ISAMAX
|
||||
#define DGEMV_F77 SGEMV
|
||||
#define DGER_F77 SGER
|
||||
#define DTRMV_F77 STRMV
|
||||
#define DGEMM_F77 SGEMM
|
||||
#define DSYMM_F77 SSYMM
|
||||
#define DTRMM_F77 STRMM
|
||||
#define DTRSM_F77 STRSM
|
||||
#define EPETRA_DCRSMV_F77 EPETRA_DCRSMV
|
||||
#define EPETRA_DCRSMM_F77 EPETRA_DCRSMM
|
||||
#define EPETRA_DCRSSV_F77 EPETRA_DCRSSV
|
||||
#define EPETRA_DCRSSM_F77 EPETRA_DCRSSM
|
||||
|
||||
#elif defined(INTEL_CXML)
|
||||
|
||||
#define PREFIX __stdcall
|
||||
#define Epetra_fcd const char *, const unsigned int
|
||||
|
||||
#elif defined(INTEL_MKL)
|
||||
|
||||
#define PREFIX
|
||||
#define Epetra_fcd const char *
|
||||
|
||||
#endif
|
||||
|
||||
/* All three of these machines use a simple uppercase mangling of Fortran names */
|
||||
|
||||
/* if F77_FUNC is defined undefine it because we want to redefine */
|
||||
|
||||
#ifdef F77_FUNC
|
||||
#undef F77_FUNC
|
||||
#endif
|
||||
|
||||
#ifdef F77_FUNC_
|
||||
#undef F77_FUNC_
|
||||
#endif
|
||||
|
||||
|
||||
#define F77_FUNC(lcase,UCASE) UCASE
|
||||
#define F77_FUNC_(lcase,UCASE) UCASE
|
||||
|
||||
#else /* Define Epetra_fcd for all other machines */
|
||||
|
||||
#define PREFIX
|
||||
#define Epetra_fcd const char *
|
||||
|
||||
/* Use autoconf's definition of F77_FUNC
|
||||
unless using old make system */
|
||||
|
||||
#ifndef HAVE_CONFIG_H
|
||||
|
||||
#ifdef F77_FUNC
|
||||
#undef F77_FUNC
|
||||
#endif
|
||||
#ifdef F77_FUNC_
|
||||
#undef F77_FUNC_
|
||||
#endif
|
||||
|
||||
#ifdef TRILINOS_HAVE_NO_FORTRAN_UNDERSCORE
|
||||
#define F77_FUNC(lcase,UCASE) lcase
|
||||
#define F77_FUNC_(lcase,UCASE) lcase
|
||||
#else /* TRILINOS_HAVE_NO_FORTRAN_UNDERSCORE not defined*/
|
||||
#define F77_FUNC(lcase,UCASE) lcase ## _
|
||||
#define F77_FUNC_(lcase,UCASE) lcase ## __
|
||||
#endif /* TRILINOS_HAVE_NO_FORTRAN_UNDERSCORE */
|
||||
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#endif /* defined(CRAY_T3X) || defined(INTEL_CXML) || defined(INTEL_MKL) */
|
||||
|
||||
#ifndef CRAY_T3X /* Double declarations already done for the Cray */
|
||||
|
||||
#define DASUM_F77 F77_FUNC(dasum,DASUM)
|
||||
#define DAXPY_F77 F77_FUNC(daxpy,DAXPY)
|
||||
#define DCOPY_F77 F77_FUNC(dcopy,DCOPY)
|
||||
#define DDOT_F77 F77_FUNC(ddot,DDOT)
|
||||
#define DNRM2_F77 F77_FUNC(dnrm2,DNRM2)
|
||||
#define DSCAL_F77 F77_FUNC(dscal,DSCAL)
|
||||
#define IDAMAX_F77 F77_FUNC(idamax,IDAMAX)
|
||||
#define DGEMV_F77 F77_FUNC(dgemv,DGEMV)
|
||||
#define DGER_F77 F77_FUNC(dger,DGER)
|
||||
#define DTRMV_F77 F77_FUNC(dtrmv,DTRMV)
|
||||
#define DGEMM_F77 F77_FUNC(dgemm,DGEMM)
|
||||
#define DSYMM_F77 F77_FUNC(dsymm,DSYMM)
|
||||
#define DTRMM_F77 F77_FUNC(dtrmm,DTRMM)
|
||||
#define DTRSM_F77 F77_FUNC(dtrsm,DTRSM)
|
||||
|
||||
#ifdef __GNUC__ /* standard Epetra implementation */
|
||||
|
||||
#define EPETRA_DCRSMV_F77 F77_FUNC_(epetra_dcrsmv,EPETRA_DCRSMV)
|
||||
#define EPETRA_DCRSMM_F77 F77_FUNC_(epetra_dcrsmm,EPETRA_DCRSMM)
|
||||
#define EPETRA_DCRSSV_F77 F77_FUNC_(epetra_dcrssv,EPETRA_DCRSSV)
|
||||
#define EPETRA_DCRSSM_F77 F77_FUNC_(epetra_dcrssm,EPETRA_DCRSSM)
|
||||
|
||||
#else /* MSE: 3/17/05 - patch for Solaris/OSF/IRIX */
|
||||
|
||||
#define EPETRA_DCRSMV_F77 F77_FUNC(epetra_dcrsmv,EPETRA_DCRSMV)
|
||||
#define EPETRA_DCRSMM_F77 F77_FUNC(epetra_dcrsmm,EPETRA_DCRSMM)
|
||||
#define EPETRA_DCRSSV_F77 F77_FUNC(epetra_dcrssv,EPETRA_DCRSSV)
|
||||
#define EPETRA_DCRSSM_F77 F77_FUNC(epetra_dcrssm,EPETRA_DCRSSM)
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
|
||||
/* End of defines for double precision when not on a T3X */
|
||||
|
||||
#endif
|
||||
|
||||
/* The following defines are good for all platforms */
|
||||
|
||||
|
||||
#define SSCAL_F77 F77_FUNC(sscal,SSCAL)
|
||||
#define SCOPY_F77 F77_FUNC(scopy,SCOPY)
|
||||
#define SAXPY_F77 F77_FUNC(saxpy,SAXPY)
|
||||
#define SDOT_F77 F77_FUNC(sdot,SDOT)
|
||||
#define SNRM2_F77 F77_FUNC(snrm2,SNRM2)
|
||||
#define SASUM_F77 F77_FUNC(sasum,SASUM)
|
||||
#define ISAMAX_F77 F77_FUNC(isamax,ISAMAX)
|
||||
|
||||
#define SGEMV_F77 F77_FUNC(sgemv,SGEMV)
|
||||
#define SGER_F77 F77_FUNC(sger,SGER)
|
||||
#define STRMV_F77 F77_FUNC(strmv,STRMV)
|
||||
#define SGEMM_F77 F77_FUNC(sgemm,SGEMM)
|
||||
#define SSYMM_F77 F77_FUNC(ssymm,SSYMM)
|
||||
#define STRMM_F77 F77_FUNC(strmm,STRMM)
|
||||
#define STRSM_F77 F77_FUNC(strsm,STRSM)
|
||||
|
||||
/* Explicitly define each F77 name for all BLAS kernels */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Double precision BLAS 1 */
|
||||
double PREFIX DASUM_F77(const int* n, const double x[], const int* incx);
|
||||
void PREFIX DAXPY_F77(const int* n, const double* alpha, const double x[], const int* incx, double y[], const int* incy);
|
||||
void PREFIX DCOPY_F77(const int* n, const double *x, const int* incx, double *y, const int* incy);
|
||||
double PREFIX DDOT_F77(const int* n, const double x[], const int* incx, const double y[], const int* incy);
|
||||
double PREFIX DNRM2_F77(const int* n, const double x[], const int* incx);
|
||||
void PREFIX DSCAL_F77(const int* n, const double* alpha, double *x, const int* incx);
|
||||
int PREFIX IDAMAX_F77(const int* n, const double *x, const int* incx);
|
||||
|
||||
/* Single precision BLAS 1 */
|
||||
float PREFIX SASUM_F77(const int* n, const float x[], const int* incx);
|
||||
void PREFIX SAXPY_F77(const int* n, const float* alpha, const float x[], const int* incx, float y[], const int* incy);
|
||||
void PREFIX SCOPY_F77(const int* n, const float *x, const int* incx, float *y, const int* incy);
|
||||
float PREFIX SDOT_F77(const int* n, const float x[], const int* incx, const float y[], const int* incy);
|
||||
float PREFIX SNRM2_F77(const int* n, const float x[], const int* incx);
|
||||
void PREFIX SSCAL_F77(const int* n, const float* alpha, float *x, const int* incx);
|
||||
int PREFIX ISAMAX_F77(const int* n, const float *x, const int* incx);
|
||||
|
||||
/* Double precision BLAS 2 */
|
||||
void PREFIX DGEMV_F77(Epetra_fcd, const int* m, const int* n, const double* alpha, const double A[], const int* lda,
|
||||
const double x[], const int* incx, const double* beta, double y[], const int* incy);
|
||||
void PREFIX DTRMV_F77(Epetra_fcd, Epetra_fcd, Epetra_fcd, const int *n,
|
||||
const double *a, const int *lda, double *x, const int *incx);
|
||||
void PREFIX DGER_F77(const int *m, const int *n, const double *alpha, const double *x, const int *incx, const double *y,
|
||||
const int *incy, double *a, const int *lda);
|
||||
|
||||
|
||||
/* Single precision BLAS 2 */
|
||||
void PREFIX SGEMV_F77(Epetra_fcd, const int* m, const int* n, const float* alpha, const float A[], const int* lda,
|
||||
const float x[], const int* incx, const float* beta, float y[], const int* incy);
|
||||
void PREFIX STRMV_F77(Epetra_fcd, Epetra_fcd, Epetra_fcd, const int *n,
|
||||
const float *a, const int *lda, float *x, const int *incx);
|
||||
void PREFIX SGER_F77(const int *m, const int *n, const float *alpha, const float *x, const int *incx, const float *y,
|
||||
const int *incy, float *a, const int *lda);
|
||||
|
||||
/* Double precision BLAS 3 */
|
||||
void PREFIX DGEMM_F77(Epetra_fcd, Epetra_fcd, const int *m, const int *
|
||||
n, const int *k, const double *alpha, const double *a, const int *lda,
|
||||
const double *b, const int *ldb, const double *beta, double *c, const int *ldc);
|
||||
void PREFIX DSYMM_F77(Epetra_fcd, Epetra_fcd, const int *m, const int * n,
|
||||
const double *alpha, const double *a, const int *lda,
|
||||
const double *b, const int *ldb, const double *beta, double *c, const int *ldc);
|
||||
void PREFIX DTRMM_F77(Epetra_fcd, Epetra_fcd, Epetra_fcd, Epetra_fcd,
|
||||
const int *m, const int *n, const double *alpha, const double *a, const int * lda, double *b, const int *ldb);
|
||||
void PREFIX DTRSM_F77(Epetra_fcd, Epetra_fcd, Epetra_fcd, Epetra_fcd,
|
||||
const int *m, const int *n, const double *alpha, const double *a, const int *
|
||||
lda, double *b, const int *ldb);
|
||||
void PREFIX EPETRA_DCRSMV_F77(const int *, const int *, const int *, const double *, const int *,
|
||||
const int *, double *, double *);
|
||||
void PREFIX EPETRA_DCRSMM_F77(const int *, const int *, const int *, const double *, const int *,
|
||||
const int *, double *, int *, double *, int *, int *);
|
||||
void PREFIX EPETRA_DCRSSV_F77(const int *, const int *, const int *, const int *, const int *,
|
||||
const int *, const double *, const int *, const int *, double *,
|
||||
double *, const int *);
|
||||
void PREFIX EPETRA_DCRSSM_F77(const int *, const int *, const int *, const int *, const int *,
|
||||
const int *, const double *, const int *, const int *, double *,
|
||||
const int *, double *, const int *, const int *, const int *);
|
||||
|
||||
/* Single precision BLAS 3 */
|
||||
void PREFIX SGEMM_F77(Epetra_fcd, Epetra_fcd, const int *m, const int *
|
||||
n, const int *k, const float *alpha, const float *a, const int *lda,
|
||||
const float *b, const int *ldb, const float *beta, float *c, const int *ldc);
|
||||
void PREFIX SSYMM_F77(Epetra_fcd, Epetra_fcd, const int *m, const int * n,
|
||||
const float *alpha, const float *a, const int *lda,
|
||||
const float *b, const int *ldb, const float *beta, float *c, const int *ldc);
|
||||
void PREFIX STRMM_F77(Epetra_fcd, Epetra_fcd, Epetra_fcd, Epetra_fcd,
|
||||
const int *m, const int *n, const float *alpha, const float *a, const int * lda, float *b, const int *ldb);
|
||||
void PREFIX STRSM_F77(Epetra_fcd, Epetra_fcd, Epetra_fcd, Epetra_fcd,
|
||||
const int *m, const int *n, const float *alpha, const float *a, const int *
|
||||
lda, float *b, const int *ldb);
|
||||
|
||||
void PREFIX XERBLA_F77(Epetra_fcd, int *info);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* EPETRA_BLAS_WRAPPERS_H */
|
||||
@@ -0,0 +1,176 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_BASICDIRECTORY_H
|
||||
#define EPETRA_BASICDIRECTORY_H
|
||||
|
||||
#include "Epetra_Object.h"
|
||||
#include "Epetra_Directory.h"
|
||||
#include "Epetra_Map.h"
|
||||
|
||||
//! Epetra_BasicDirectory: This class allows Epetra_Map objects to reference non-local elements.
|
||||
|
||||
/*! For Epetra_BlockMap objects, a Epetra_Directory object must be created to allow referencing
|
||||
of non-local elements. The Epetra_BasicDirectory produces and contains a uniform linear
|
||||
Epetra_BlockMap and a ProcList_ allowing blocks of non-local elements to be accessed
|
||||
by dereferencing throught the Epetra_BasicDirectory.
|
||||
|
||||
This class currently has one constructor, taking a Epetra_BlockMap object.
|
||||
|
||||
*/
|
||||
|
||||
class Epetra_BasicDirectory: public virtual Epetra_Directory {
|
||||
|
||||
public:
|
||||
|
||||
//! @name Constructors/Destructor
|
||||
//@{
|
||||
//! Epetra_BasicDirectory constructor
|
||||
Epetra_BasicDirectory(const Epetra_BlockMap & Map );
|
||||
|
||||
//! Epetra_BasicDirectory copy constructor.
|
||||
|
||||
Epetra_BasicDirectory(const Epetra_BasicDirectory& Directory);
|
||||
|
||||
//! Epetra_BasicDirectory destructor.
|
||||
|
||||
virtual ~Epetra_BasicDirectory(void);
|
||||
//@}
|
||||
|
||||
//! @name Query method
|
||||
//@{
|
||||
//! GetDirectoryEntries : Returns proc and local id info for non-local map entries
|
||||
/*! Given a list of Global Entry IDs, this function returns the list of
|
||||
processor IDs and local IDs on the owning processor that correspond
|
||||
to the list of entries. If LocalEntries is 0, then local IDs are
|
||||
not returned. If EntrySizes is nonzero, it will contain a list of corresponding
|
||||
element sizes for the requested global entries.
|
||||
\param In
|
||||
NumEntries - Number of Global IDs being passed in.
|
||||
\param In
|
||||
GlobalEntries - List of Global IDs being passed in.
|
||||
\param InOut
|
||||
Procs - User allocated array of length at least NumEntries. On return contains list of processors
|
||||
owning the Global IDs in question. If any of the GIDs is shared by more than
|
||||
one processor, then the lowest-numbered processor is listed in this array, unless the optional
|
||||
argument 'high_rank_sharing_procs' is given as true.
|
||||
\param InOut
|
||||
LocalEntries - User allocated array of length at least NumEntries. On return contains the local ID of
|
||||
the global on the owning processor. If LocalEntries is zero, no local ID information is returned.
|
||||
\param InOut
|
||||
EntrySizes - User allocated array of length at least NumEntries. On return contains the size of the
|
||||
object associated with this global ID. If LocalEntries is zero, no size information is returned.
|
||||
|
||||
\param In
|
||||
high_rank_sharing_procs Optional argument, defaults to true. If any GIDs appear on multiple
|
||||
processors (referred to as "sharing procs"), this specifies whether the lowest-rank proc or the
|
||||
highest-rank proc is chosen as the "owner".
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int GetDirectoryEntries( const Epetra_BlockMap& Map,
|
||||
const int NumEntries,
|
||||
const int * GlobalEntries,
|
||||
int * Procs,
|
||||
int * LocalEntries,
|
||||
int * EntrySizes,
|
||||
bool high_rank_sharing_procs=false) const;
|
||||
|
||||
//!GIDsAllUniquelyOwned: returns true if all GIDs appear on just one processor.
|
||||
/*! If any GIDs are owned by multiple processors, returns false.
|
||||
*/
|
||||
bool GIDsAllUniquelyOwned() const;
|
||||
//@}
|
||||
|
||||
//! @name I/O Methods
|
||||
//@{
|
||||
//! Print method
|
||||
virtual void Print(ostream & os) const;
|
||||
//@}
|
||||
|
||||
private:
|
||||
Epetra_BasicDirectory& operator=(const Epetra_BasicDirectory& src);
|
||||
|
||||
void create_ProcListArrays();
|
||||
|
||||
void addProcToList(int proc, int LID);
|
||||
|
||||
//! Generate: Sets up Directory tables.
|
||||
int Generate(const Epetra_BlockMap& Map);
|
||||
|
||||
//! Returns the Epetra_Map containing the directory
|
||||
const Epetra_Map & DirectoryMap() const {return(*DirectoryMap_);};
|
||||
|
||||
Epetra_Map* DirectoryMap_;
|
||||
|
||||
//ProcList_ is a list containing the associated processor for each
|
||||
//directory entry. If any directory entry has more than one associated
|
||||
//processor, then the corresponding ProcList_ entry will be the lowest-
|
||||
//numbered of those processors. In that case, refer to ProcListLists_
|
||||
//for more info.
|
||||
|
||||
int * ProcList_;
|
||||
|
||||
//ProcListLists_ will usually be unallocated, and set to NULL. But if
|
||||
//at least one directory entry is associcated with more than one proc,
|
||||
//then ProcListLists_ is a list of lists -- it holds, for each
|
||||
//directory-entry, a list of processors.
|
||||
//But even then, it will have a NULL list for all directory entries that
|
||||
//are associated with only one processor.
|
||||
//
|
||||
//Each list's length will be stored in ProcListLens_.
|
||||
//Example:
|
||||
//
|
||||
//if (numProcLists_ > 0) {
|
||||
// int entry_LID = DirectoryMap_->LID(GID);
|
||||
//
|
||||
// for(int i=0; i<ProcListLens_[entry_LID]; ++i) {
|
||||
// cout << "entry "<<GID<<" associated with proc "
|
||||
// <<ProcListLists_[entry_LID][i]<<endl;
|
||||
// }
|
||||
//}
|
||||
int** ProcListLists_;
|
||||
int* ProcListLens_;
|
||||
int numProcLists_;
|
||||
|
||||
//true if any directory entry appears on multiple processors
|
||||
bool entryOnMultipleProcs_;
|
||||
|
||||
int * LocalIndexList_;
|
||||
int * SizeList_;
|
||||
bool SizeIsConst_;
|
||||
|
||||
int * AllMinGIDs_;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif /* EPETRA_BASICDIRECTORY_H */
|
||||
@@ -0,0 +1,508 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_BASICROWMATRIX_H
|
||||
#define EPETRA_BASICROWMATRIX_H
|
||||
|
||||
#include "Epetra_RowMatrix.h"
|
||||
#include "Epetra_Object.h"
|
||||
#include "Epetra_CompObject.h"
|
||||
#include "Epetra_Map.h"
|
||||
#include "Epetra_Comm.h"
|
||||
#include "Epetra_SerialDenseVector.h"
|
||||
#include "Epetra_IntSerialDenseVector.h"
|
||||
#include "Epetra_MultiVector.h"
|
||||
|
||||
class Epetra_Vector;
|
||||
class Epetra_Import;
|
||||
class Epetra_Export;
|
||||
|
||||
//! Epetra_BasicRowMatrix: A class for simplifying the development of Epetra_RowMatrix adapters.
|
||||
|
||||
/*! The Epetra_BasicRowMatrix is an adapter class for Epetra_RowMatrix that implements most of the Epetra_RowMatrix
|
||||
methods using reasonable default implementations. The Epetra_RowMatrix class has 39 pure virtual methods, requiring
|
||||
the adapter class to implement all of them.
|
||||
Epetra_BasicRowMatrix has only 4 pure virtual methods that must be implemented (See Epetra_JadMatrix for an example):
|
||||
<ol>
|
||||
<li> ExtractMyRowCopy: Provide a row of values and indices for a specified local row.
|
||||
<li> ExtractMyEntryView (const and non-const versions): Provide the memory address of the ith nonzero term stored on the
|
||||
calling processor, along with its corresponding local row and column index, where i goes from 0 to the NumMyNonzeros()-1.
|
||||
The order in which the nonzeros are traversed is not specified and is up to the adapter implementation.
|
||||
<li> NumMyRowEntries: Provide the number of entries for a specified local row.
|
||||
</ol>
|
||||
|
||||
An alternative is possible if you do not want to provide a non-trivial implementation of the ExtraMyEntryView
|
||||
methods (See Epetra_VbrRowMatrix for and example):
|
||||
<ol>
|
||||
<li> Implement ExtractMyRowCopy and NumMyRowEntries as above.
|
||||
<li> Implement ExtractMyEntryView (both versions) returning a -1 integer code with no other executable code.
|
||||
<li> Implement the RightScale and LeftScale methods non-trivially.
|
||||
</ol>
|
||||
|
||||
In addition, most adapters will probably re-implement the Multiply() method and perhaps the Solve() method, although one or the other
|
||||
may be implemented to return -1, signaling that there is no valid implementation. By default, the Multiply() method is implemented using
|
||||
ExtractMyRowCopy, which can usual be improved upon. By default Solve() and ApplyInverse() are implemented to return -1 (not implemented).
|
||||
|
||||
All other implemented methods in Epetra_BasicRowMatrix should not exhibit a signficant performance degradation, either because they are relatively
|
||||
small and fast, or because they are not a significant portion of the runtime for most codes. All methods are virtual, so they can be re-implemented
|
||||
by the adapter.
|
||||
|
||||
In addition to implementing the above methods, an adapter must inherit the Epetra_BasicRowMatrix interface and call the Epetra_BasicRowMatrix
|
||||
constructor as part of the adapter constructor. There are two constructors. The first requires the user to pass in the RowMap and ColMap, both
|
||||
of which are Epetra_Map objects. On each processor the RowMap (ColMap) must contain the global IDs (GIDs) of the rows (columns) that the processor cares about.
|
||||
The first constructor requires only these two maps, assuming that the RowMap will also serve as the DomainMap and RangeMap. In this case, the
|
||||
RowMap must be 1-to-1, meaning that if a global ID appears on one processor, it appears only once on that processor and does not appear on any other
|
||||
processor. For many sparse matrix data structures, it is the case that a given row is completely owned by one processor and that the global matrix
|
||||
is square. The first constructor is for this situation.
|
||||
|
||||
The second constructor allows the caller to specify all four maps. In this case the DomainMap, the layout of multivectors/vectors that are in the
|
||||
domain of the matrix (the x vector if computing y = A*x), must be 1-to-1. Also, the RangeMap, the layout of y must be 1-to-1. The RowMap and ColMap
|
||||
do not need to be 1-to-1, but the GIDs must be found in the RangeMap and DomainMap, respectively.
|
||||
|
||||
Note that Epetra_Operator is a base class for Epetra_RowMatrix, so any adapter
|
||||
for Epetra_BasicRowMatrix (or Epetra_RowMatrix) is also an adapter for Epetra_Operator.
|
||||
|
||||
An example of how to provide an adapter for Epetra_BasicRowMatrix can be found by looking at Epetra_JadMatrix.
|
||||
|
||||
*/
|
||||
|
||||
class Epetra_BasicRowMatrix: public Epetra_CompObject, public Epetra_Object, public virtual Epetra_RowMatrix {
|
||||
|
||||
public:
|
||||
|
||||
//! @name Constructor/Destructor
|
||||
//@{
|
||||
//! Epetra_BasicRowMatrix constuctor.
|
||||
/* This constructor requires a valid Epetra_Comm object as its only argument. The constructor will use Comm to build
|
||||
Epetra_Maps objects: RowMap, ColMap, DomainMap and RangeMap. However, these will be zero-length (trivial) maps that
|
||||
\e must be reset by calling one of the two SetMap() methods listed below.
|
||||
\param Comm (In) An Epetra_Comm containing a valid Comm object.
|
||||
*/
|
||||
Epetra_BasicRowMatrix(const Epetra_Comm & Comm);
|
||||
|
||||
//! Epetra_BasicRowMatrix Destructor
|
||||
virtual ~Epetra_BasicRowMatrix();
|
||||
//@}
|
||||
|
||||
//! @name Setup functions
|
||||
//@{
|
||||
//! Set maps (Version 1); call this function or the next, but not both.
|
||||
/* This method takes a row and column map. On each processor these maps describe the global rows and columns, resp,
|
||||
that the processor will care about. Note that the ColMap does not have to be one-to-one. In other words, a column ID can appear
|
||||
on more than one processor. The RowMap \e must be 1-to-1.
|
||||
\param RowMap (In) An Epetra_Map containing on each processor a list of GIDs of rows that the processor cares about.
|
||||
\param ColMap (In) An Epetra_Map containing on each processor a list of GIDs of columns that the processor cares about.
|
||||
|
||||
In this method, the domain and range maps are assumed to be the same as the row map. Note that this requires that
|
||||
the global matrix be square. If the matrix is not square, or the domain vectors or range vectors do not have the same layout
|
||||
as the rows, then the second constructor should be called.
|
||||
*/
|
||||
void SetMaps(const Epetra_Map & RowMap, const Epetra_Map & ColMap);
|
||||
|
||||
//! Set maps (Version 2); call this function or the previous, but not both.
|
||||
/* This constructor takes a row, column, domain and range map. On each processor these maps describe the global rows, columns, domain
|
||||
and range, resp, that the processor will care about. The domain and range maps must be one-to-one, but note that the row and column
|
||||
maps do not have to be one-to-one. In other words, a row ID can appear
|
||||
on more than one processor, as can a column ID.
|
||||
\param RowMap (In) An Epetra_Map containing on each processor a list of GIDs of rows that the processor cares about.
|
||||
\param ColMap (In) An Epetra_Map containing on each processor a list of GIDs of columns that the processor cares about.
|
||||
\param DomainMap (In) An Epetra_Map describing the distribution of domain vectors and multivectors.
|
||||
\param RangeMap (In) An Epetra_Map describing the distribution of range vectors and multivectors.
|
||||
|
||||
*/
|
||||
void SetMaps(const Epetra_Map & RowMap, const Epetra_Map & ColMap,
|
||||
const Epetra_Map & DomainMap, const Epetra_Map & RangeMap);
|
||||
|
||||
//@}
|
||||
|
||||
|
||||
//! @name User-required implementation methods
|
||||
//@{
|
||||
|
||||
//! Returns a copy of the specified local row in user-provided arrays.
|
||||
/*!
|
||||
\param MyRow (In) - Local row to extract.
|
||||
\param Length (In) - Length of Values and Indices.
|
||||
\param NumEntries (Out) - Number of nonzero entries extracted.
|
||||
\param Values (Out) - Extracted values for this row.
|
||||
\param Indices (Out) - Extracted global column indices for the corresponding values.
|
||||
|
||||
\return Integer error code, set to 0 if successful, set to -1 if MyRow not valid, -2 if Length is too short (NumEntries will have required length).
|
||||
*/
|
||||
virtual int ExtractMyRowCopy(int MyRow, int Length, int & NumEntries, double *Values, int * Indices) const = 0;
|
||||
|
||||
//! Returns a reference to the ith entry in the matrix, along with its row and column index.
|
||||
/*!
|
||||
\param CurEntry (In) - Index of local entry (from 0 to NumMyNonzeros()-1) to extract.
|
||||
\param Value (Out) - Extracted reference to current values.
|
||||
\param RowIndex (Out) - Row index for current entry.
|
||||
\param ColIndex (Out) - Column index for current entry.
|
||||
|
||||
\return Integer error code, set to 0 if successful, set to -1 if CurEntry not valid.
|
||||
*/
|
||||
virtual int ExtractMyEntryView(int CurEntry, double * & Value, int & RowIndex, int & ColIndex) = 0;
|
||||
|
||||
//! Returns a const reference to the ith entry in the matrix, along with its row and column index.
|
||||
/*!
|
||||
\param CurEntry (In) - Index of local entry (from 0 to NumMyNonzeros()-1) to extract.
|
||||
\param Value (Out) - Extracted reference to current values.
|
||||
\param RowIndex (Out) - Row index for current entry.
|
||||
\param ColIndex (Out) - Column index for current entry.
|
||||
|
||||
\return Integer error code, set to 0 if successful, set to -1 if CurEntry not valid.
|
||||
*/
|
||||
virtual int ExtractMyEntryView(int CurEntry, double const * & Value, int & RowIndex, int & ColIndex) const = 0;
|
||||
|
||||
//! Return the current number of values stored for the specified local row.
|
||||
/*! Similar to NumMyEntries() except NumEntries is returned as an argument
|
||||
and error checking is done on the input value MyRow.
|
||||
\param MyRow (In) - Local row.
|
||||
\param NumEntries (Out) - Number of nonzero values.
|
||||
|
||||
\return Integer error code, set to 0 if successful, set to -1 if MyRow not valid.
|
||||
*/
|
||||
virtual int NumMyRowEntries(int MyRow, int & NumEntries) const = 0;
|
||||
//@}
|
||||
|
||||
//! @name Computational methods
|
||||
//@{
|
||||
|
||||
//! Returns the result of a Epetra_BasicRowMatrix multiplied by a Epetra_MultiVector X in Y.
|
||||
/*!
|
||||
\param TransA (In) - If true, multiply by the transpose of matrix, otherwise just use matrix.
|
||||
\param X (Out) - An Epetra_MultiVector of dimension NumVectors to multiply with matrix.
|
||||
\param Y (Out) - An Epetra_MultiVector of dimension NumVectorscontaining result.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual int Multiply(bool TransA, const Epetra_MultiVector& X, Epetra_MultiVector& Y) const;
|
||||
|
||||
//! Returns the result of a Epetra_BasicRowMatrix solve with a Epetra_MultiVector X in Y (not implemented).
|
||||
/*!
|
||||
\param Upper (In) - If true, solve Ux = y, otherwise solve Lx = y.
|
||||
\param Trans (In) - If true, solve transpose problem.
|
||||
\param UnitDiagonal (In) - If true, assume diagonal is unit (whether it's stored or not).
|
||||
\param X (In) - An Epetra_MultiVector of dimension NumVectors to solve for.
|
||||
\param Y (Out) - An Epetra_MultiVector of dimension NumVectors containing result.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual int Solve(bool Upper, bool Trans, bool UnitDiagonal,
|
||||
const Epetra_MultiVector& X,
|
||||
Epetra_MultiVector& Y) const
|
||||
{
|
||||
(void)Upper;
|
||||
(void)Trans;
|
||||
(void)UnitDiagonal;
|
||||
(void)X;
|
||||
(void)Y;
|
||||
return(-1);
|
||||
}
|
||||
|
||||
//! Returns a copy of the main diagonal in a user-provided vector.
|
||||
/*!
|
||||
\param Diagonal (Out) - Extracted main diagonal.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual int ExtractDiagonalCopy(Epetra_Vector & Diagonal) const;
|
||||
|
||||
//! Computes the sum of absolute values of the rows of the Epetra_BasicRowMatrix, results returned in x.
|
||||
/*! The vector x will return such that x[i] will contain the inverse of sum of the absolute values of the
|
||||
\e this matrix will be scaled such that A(i,j) = x(i)*A(i,j) where i denotes the global row number of A
|
||||
and j denotes the global column number of A. Using the resulting vector from this function as input to LeftScale()
|
||||
will make the infinity norm of the resulting matrix exactly 1.
|
||||
\param x (Out) - An Epetra_Vector containing the row sums of the \e this matrix.
|
||||
\warning It is assumed that the distribution of x is the same as the rows of \e this.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual int InvRowSums(Epetra_Vector& x) const;
|
||||
|
||||
//! Scales the Epetra_BasicRowMatrix on the left with a Epetra_Vector x.
|
||||
/*! The \e this matrix will be scaled such that A(i,j) = x(i)*A(i,j) where i denotes the row number of A
|
||||
and j denotes the column number of A.
|
||||
\param x (In) - An Epetra_Vector to solve for.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual int LeftScale(const Epetra_Vector& x);
|
||||
|
||||
//! Computes the sum of absolute values of the columns of the Epetra_BasicRowMatrix, results returned in x.
|
||||
/*! The vector x will return such that x[j] will contain the inverse of sum of the absolute values of the
|
||||
\e this matrix will be sca such that A(i,j) = x(j)*A(i,j) where i denotes the global row number of A
|
||||
and j denotes the global column number of A. Using the resulting vector from this function as input to
|
||||
RighttScale() will make the one norm of the resulting matrix exactly 1.
|
||||
\param x (Out) - An Epetra_Vector containing the column sums of the \e this matrix.
|
||||
\warning It is assumed that the distribution of x is the same as the rows of \e this.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual int InvColSums(Epetra_Vector& x) const;
|
||||
|
||||
//! Scales the Epetra_BasicRowMatrix on the right with a Epetra_Vector x.
|
||||
/*! The \e this matrix will be scaled such that A(i,j) = x(j)*A(i,j) where i denotes the global row number of A
|
||||
and j denotes the global column number of A.
|
||||
\param x (In) - The Epetra_Vector used for scaling \e this.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual int RightScale(const Epetra_Vector& x);
|
||||
//@}
|
||||
|
||||
//! @name Matrix Properties Query Methods
|
||||
//@{
|
||||
|
||||
|
||||
//! If FillComplete() has been called, this query returns true, otherwise it returns false, presently always returns true.
|
||||
virtual bool Filled() const {return(true);}
|
||||
|
||||
//! If matrix is lower triangular, this query returns true, otherwise it returns false.
|
||||
bool LowerTriangular() const {if (!HaveNumericConstants_) ComputeNumericConstants(); return(LowerTriangular_);}
|
||||
|
||||
//! If matrix is upper triangular, this query returns true, otherwise it returns false.
|
||||
virtual bool UpperTriangular() const {if (!HaveNumericConstants_) ComputeNumericConstants(); return(UpperTriangular_);}
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Atribute access functions
|
||||
//@{
|
||||
|
||||
//! Returns the infinity norm of the global matrix.
|
||||
/* Returns the quantity \f$ \| A \|_\infty\f$ such that
|
||||
\f[\| A \|_\infty = \max_{1\lei\lem} \sum_{j=1}^n |a_{ij}| \f].
|
||||
|
||||
\warning This method is supported if and only if the Epetra_RowMatrix Object that was used to create this supports this method.
|
||||
|
||||
*/
|
||||
virtual double NormInf() const{if (!HaveNumericConstants_) ComputeNumericConstants(); return(NormInf_);}
|
||||
|
||||
//! Returns the one norm of the global matrix.
|
||||
/* Returns the quantity \f$ \| A \|_1\f$ such that
|
||||
\f[\| A \|_1= \max_{1\lej\len} \sum_{i=1}^m |a_{ij}| \f].
|
||||
|
||||
\warning This method is supported if and only if the Epetra_RowMatrix Object that was used to create this supports this method.
|
||||
|
||||
*/
|
||||
virtual double NormOne() const{if (!HaveNumericConstants_) ComputeNumericConstants(); return(NormOne_);}
|
||||
|
||||
//! Returns the number of nonzero entries in the global matrix.
|
||||
/* Note that if the data decomposition is defined such that some nonzeros
|
||||
appear on multiple processors, then those nonzeros will be counted
|
||||
multiple times.
|
||||
*/
|
||||
virtual int NumGlobalNonzeros() const{if (!HaveStructureConstants_) ComputeStructureConstants(); return(NumGlobalNonzeros_);}
|
||||
|
||||
//! Returns the number of global matrix rows.
|
||||
virtual int NumGlobalRows() const {return(OperatorRangeMap().NumGlobalPoints());}
|
||||
|
||||
//! Returns the number of global matrix columns.
|
||||
virtual int NumGlobalCols() const {return(OperatorDomainMap().NumGlobalPoints());}
|
||||
|
||||
//! Returns the number of global nonzero diagonal entries.
|
||||
virtual int NumGlobalDiagonals() const{return(OperatorDomainMap().NumGlobalPoints());}
|
||||
|
||||
//! Returns the number of nonzero entries in the calling processor's portion of the matrix.
|
||||
virtual int NumMyNonzeros() const{if (!HaveStructureConstants_) ComputeStructureConstants(); return(NumMyNonzeros_);}
|
||||
|
||||
//! Returns the number of matrix rows owned by the calling processor.
|
||||
virtual int NumMyRows() const {return(OperatorRangeMap().NumMyPoints());}
|
||||
|
||||
//! Returns the number of matrix columns owned by the calling processor.
|
||||
virtual int NumMyCols() const {return(RowMatrixColMap().NumMyPoints());}
|
||||
|
||||
//! Returns the number of local nonzero diagonal entries.
|
||||
virtual int NumMyDiagonals() const {return(OperatorRangeMap().NumMyPoints());}
|
||||
|
||||
//! Returns the maximum number of nonzero entries across all rows on this processor.
|
||||
virtual int MaxNumEntries() const{ if (!HaveStructureConstants_) ComputeStructureConstants(); return(MaxNumEntries_);}
|
||||
|
||||
//! Returns the Epetra_Map object associated with the domain of this operator.
|
||||
virtual const Epetra_Map & OperatorDomainMap() const {return(OperatorDomainMap_);}
|
||||
|
||||
//! Returns the Epetra_Map object associated with the range of this operator (same as domain).
|
||||
virtual const Epetra_Map & OperatorRangeMap() const {return(OperatorRangeMap_);}
|
||||
|
||||
//! Implement the Epetra_SrcDistObjec::Map() function.
|
||||
virtual const Epetra_BlockMap& Map() const {return(RowMatrixRowMap());}
|
||||
|
||||
//! Returns the Row Map object needed for implementing Epetra_RowMatrix.
|
||||
virtual const Epetra_Map & RowMatrixRowMap() const {return(RowMatrixRowMap_);}
|
||||
|
||||
//! Returns the Column Map object needed for implementing Epetra_RowMatrix.
|
||||
virtual const Epetra_Map & RowMatrixColMap() const {return(RowMatrixColMap_);}
|
||||
|
||||
//! Returns the Epetra_Import object that contains the import operations for distributed operations.
|
||||
virtual const Epetra_Import * RowMatrixImporter() const {return(Importer_);}
|
||||
|
||||
//! Returns a pointer to the Epetra_Comm communicator associated with this matrix.
|
||||
virtual const Epetra_Comm & Comm() const {return(*Comm_);}
|
||||
//@}
|
||||
|
||||
|
||||
//! @name I/O Methods
|
||||
//@{
|
||||
|
||||
//! Print method
|
||||
virtual void Print(ostream & os) const;
|
||||
//@}
|
||||
|
||||
//! @name Additional methods required to support the Epetra_RowMatrix interface
|
||||
//@{
|
||||
|
||||
//! If set true, transpose of this operator will be applied.
|
||||
/*! This flag allows the transpose of the given operator to be used implicitly. Setting this flag
|
||||
affects only the Apply() and ApplyInverse() methods. If the implementation of this interface
|
||||
does not support transpose use, this method should return a value of -1.
|
||||
|
||||
\param UseTranspose (In) - If true, multiply by the transpose of operator, otherwise just use operator.
|
||||
|
||||
\return Always returns 0.
|
||||
*/
|
||||
virtual int SetUseTranspose(bool UseTranspose) {UseTranspose_ = UseTranspose; return(0);}
|
||||
|
||||
//! Returns a character string describing the operator
|
||||
virtual const char* Label() const {return(Epetra_Object::Label());}
|
||||
|
||||
//! Returns the result of a Epetra_RowMatrix applied to a Epetra_MultiVector X in Y.
|
||||
/*!
|
||||
\param X (In) - A Epetra_MultiVector of dimension NumVectors to multiply with matrix.
|
||||
\param Y (Out) - A Epetra_MultiVector of dimension NumVectors containing result.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual int Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const {
|
||||
return(Multiply(Epetra_BasicRowMatrix::UseTranspose(), X, Y));}
|
||||
|
||||
//! Returns the result of a Epetra_RowMatrix inverse applied to an Epetra_MultiVector X in Y.
|
||||
/*!
|
||||
|
||||
\param X (In) - A Epetra_MultiVector of dimension NumVectors to solve for.
|
||||
\param Y (Out) - A Epetra_MultiVector of dimension NumVectors containing result.
|
||||
|
||||
\return Integer error code = -1.
|
||||
\warning This method is NOT supported.
|
||||
*/
|
||||
virtual int ApplyInverse(const Epetra_MultiVector& X,
|
||||
Epetra_MultiVector& Y) const
|
||||
{
|
||||
(void)X;
|
||||
(void)Y;
|
||||
return(-1);
|
||||
}
|
||||
|
||||
//! Returns true because this class can compute an Inf-norm.
|
||||
bool HasNormInf() const {return(true);}
|
||||
|
||||
//! Returns the current UseTranspose setting.
|
||||
virtual bool UseTranspose() const {return(UseTranspose_);}
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Additional accessor methods
|
||||
//@{
|
||||
|
||||
//! Returns the Epetra_Import object that contains the import operations for distributed operations, returns zero if none.
|
||||
/*! If RowMatrixColMap!=OperatorDomainMap, then this method returns a pointer to an Epetra_Import object that imports objects
|
||||
from an OperatorDomainMap layout to a RowMatrixColMap layout. This operation is needed for sparse matrix-vector
|
||||
multiplication, y = Ax, to gather x elements for local multiplication operations.
|
||||
|
||||
If RowMatrixColMap==OperatorDomainMap, then the pointer will be returned as 0.
|
||||
|
||||
\return Raw pointer to importer. This importer will be valid as long as the Epetra_RowMatrix object is valid.
|
||||
*/
|
||||
virtual const Epetra_Import* Importer() const {return(Importer_);}
|
||||
|
||||
//! Returns the Epetra_Export object that contains the export operations for distributed operations, returns zero if none.
|
||||
/*! If RowMatrixRowMap!=OperatorRangeMap, then this method returns a pointer to an Epetra_Export object that exports objects
|
||||
from an RowMatrixRowMap layout to a OperatorRangeMap layout. This operation is needed for sparse matrix-vector
|
||||
multiplication, y = Ax, to scatter-add y elements generated during local multiplication operations.
|
||||
|
||||
If RowMatrixRowMap==OperatorRangeMap, then the pointer will be returned as 0. For a typical Epetra_RowMatrix object,
|
||||
this pointer will be zero since it is often the case that RowMatrixRowMap==OperatorRangeMap.
|
||||
|
||||
\return Raw pointer to exporter. This exporter will be valid as long as the Epetra_RowMatrix object is valid.
|
||||
*/
|
||||
virtual const Epetra_Export* Exporter() const {return(Exporter_);}
|
||||
|
||||
//@}
|
||||
|
||||
protected:
|
||||
|
||||
//! @name Post-construction modifications
|
||||
//@{
|
||||
//! Update the constants associated with the structure of the matrix: Call only if structure changes from the initial RowMatrix.
|
||||
/* Several constants are pre-computed to save excess computations. However, if the structure of the
|
||||
problem changes, specifically if the nonzero count in any given row changes, then this function should be called
|
||||
to update these constants.
|
||||
*/
|
||||
virtual void ComputeStructureConstants() const;
|
||||
//! Update the constants associated with the values of the matrix: Call only if values changes from the initial RowMatrix.
|
||||
/* Several numeric constants are pre-computed to save excess computations. However, if the values of the
|
||||
problem change, then this function should be called to update these constants.
|
||||
*/
|
||||
virtual void ComputeNumericConstants() const;
|
||||
//@}
|
||||
|
||||
void Setup();
|
||||
void UpdateImportVector(int NumVectors) const;
|
||||
void UpdateExportVector(int NumVectors) const;
|
||||
void SetImportExport();
|
||||
Epetra_Comm * Comm_;
|
||||
Epetra_Map OperatorDomainMap_;
|
||||
Epetra_Map OperatorRangeMap_;
|
||||
Epetra_Map RowMatrixRowMap_;
|
||||
Epetra_Map RowMatrixColMap_;
|
||||
|
||||
mutable int NumMyNonzeros_;
|
||||
mutable int NumGlobalNonzeros_;
|
||||
mutable int MaxNumEntries_;
|
||||
mutable double NormInf_;
|
||||
mutable double NormOne_;
|
||||
int NumMyRows_;
|
||||
int NumMyCols_;
|
||||
|
||||
bool UseTranspose_;
|
||||
bool HasNormInf_;
|
||||
mutable bool LowerTriangular_;
|
||||
mutable bool UpperTriangular_;
|
||||
mutable bool HaveStructureConstants_;
|
||||
mutable bool HaveNumericConstants_;
|
||||
mutable bool HaveMaps_;
|
||||
|
||||
|
||||
mutable Epetra_MultiVector * ImportVector_;
|
||||
mutable Epetra_MultiVector * ExportVector_;
|
||||
Epetra_Import * Importer_;
|
||||
Epetra_Export * Exporter_;
|
||||
|
||||
};
|
||||
#endif /* EPETRA_BASICROWMATRIX_H */
|
||||
@@ -0,0 +1,535 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_BLOCKMAP_H
|
||||
#define EPETRA_BLOCKMAP_H
|
||||
|
||||
#include "Epetra_Object.h"
|
||||
#include "Epetra_BlockMapData.h"
|
||||
|
||||
|
||||
//! Epetra_BlockMap: A class for partitioning block element vectors and matrices.
|
||||
|
||||
/*! It is often the case that multiple matrix and vector objects have an identical distribution
|
||||
of elements on a parallel machine. The Epetra_BlockMap class keeps information that describes
|
||||
this distribution for matrices and vectors that have block elements. The definition of an
|
||||
element can vary depending on the situation. For vectors (and multi-vectors), an element
|
||||
is a span of one or more contiguous entries. For matrices, it is a span of one or more matrix rows.
|
||||
More generally, an element in the BlockMap class is an ordered list of points. (NOTE:
|
||||
Points do not have global ID's.) Two additional definitions useful in understanding
|
||||
the BlockMap class follow:
|
||||
<ul>
|
||||
<li> BlockMap - A distributed ordered list of elements.
|
||||
<li> First Point - First ordered point in an element
|
||||
</ul>
|
||||
|
||||
This class has a variety of constructors that can be separated into two categories:
|
||||
<ol>
|
||||
<li> Fixed element size constructors:
|
||||
All map elements have an identical size.
|
||||
This corresponds to a block partitioning of matrices and vectors where the element
|
||||
size is the same for all elements. A common example is multiple degrees of freedom
|
||||
per mesh node in finite element computations where the number of degrees of
|
||||
freedom is the same for all nodes.
|
||||
<li> Variable element size constructor:
|
||||
Map element sizes may vary and are individually defined via a list of element sizes.
|
||||
This is the most general case and corresponds to a variable block partitioning of the
|
||||
matrices and vectors. A common example is
|
||||
multiple degrees of freedom per mesh node in finite element computations where the
|
||||
number of degrees of freedom varies. This happens, for example, if regions have differing
|
||||
material types or there are chemical reactions in the simulation.
|
||||
</ol>
|
||||
|
||||
Epetra_BlockMap allows the storage and retrieval of the following information. Depending on the
|
||||
constructor that is used, some of the information is defined by the user and some is
|
||||
determined by the constructor. Once an Epetra_BlockMap is constructed any of the following can
|
||||
be obtained
|
||||
by calling a query function that has the same name as the attribute, e.g. to get the
|
||||
value of NumGlobalElements, you can call a function NumGlobalElements(). For attributes that
|
||||
are lists, the query functions return the list values in a user allocated array.
|
||||
|
||||
<ul>
|
||||
<li> NumGlobalElements - The total number of elements across all processors. If this parameter and
|
||||
NumMyElements are both passed in to the constructor, one of the three cases will apply:
|
||||
<ol>
|
||||
<li> If NumGlobalElements = NumMyElements (and not equal to zero)
|
||||
the map is defined to be a local replicated
|
||||
map. In this case, objects constructed using this map will be identically replicated across
|
||||
all processors in the communicator.
|
||||
<li> If NumGlobalElements = -1 and NumMyElements is passed in then NumGlobalElements will
|
||||
be computed as the sum of NumMyElements across all processors.
|
||||
<li> If neither of the above is true, NumGlobalElements will be checked against the sum of
|
||||
NumMyElements across all processors. An error is issued if the comparison is not equal.
|
||||
</ol>
|
||||
<li> NumMyElements - The number of elements owned by the calling processor.
|
||||
<li> MyGlobalElements - A list of length NumMyElements that contains the global element IDs
|
||||
of the elements owned by the calling processor.
|
||||
<li> ElementSize - The size of elements if the size of all elements is the same.
|
||||
This will be the case if the query function ConstantElementSize() returns true.
|
||||
Otherwise this value will be set to zero.
|
||||
<li> ElementSizeList - A list of the element sizes for elements owned by the calling
|
||||
processor. This list is always accessible, even if the element sizes are all one
|
||||
or of constant value. However, in these cases, the ElementSizeList will not be
|
||||
generated unless a query for the list is called.
|
||||
<li> IndexBase - The base integer value for indexed array references. Typically this is 0
|
||||
for C/C++ and 1 for Fortran, but it can be set to any integer value.
|
||||
<li> Comm - The Epetra_Comm communicator. This communicator can in turn be queried for
|
||||
processor rank and size information.
|
||||
</ul>
|
||||
|
||||
|
||||
In addition to the information above that is passed in to or created by the Epetra_BlockMap constructor,
|
||||
the following attributes are computed and available via query to the user using the same scheme
|
||||
as above, e.g., use NumGlobalPoints() to get the value of NumGlobalPoints.
|
||||
|
||||
<ul>
|
||||
<li> NumGlobalPoints - The total number of points across all processors.
|
||||
<li> NumMyPoints - The number of points on the calling processor.
|
||||
<li> MinAllGID - The minimum global index value across all processors.
|
||||
<li> MaxAllGID - The maximum global index value across all processors.
|
||||
<li> MinMyGID - The minimum global index value on the calling processor.
|
||||
<li> MaxMyGID - The maximum global index value on the calling processor.
|
||||
<li> MinLID - The minimum local index value on the calling processor.
|
||||
<li> MaxLID - The maximum local index value on the calling processor.
|
||||
<li> MinElementSize - The minimum element size across all processors.
|
||||
<li> MaxElementSize - The maximum element size across all processors.
|
||||
</ul>
|
||||
|
||||
The following functions allow boolean tests for certain properties.
|
||||
|
||||
<ul>
|
||||
<li> ConstantElementSize() - Returns true if the element size for this map is the same
|
||||
for all elements.
|
||||
<li> LinearMap() - Returns true if the elements are distributed linear across processors, i.e.,
|
||||
processor 0 gets the first n/p elements, processor 1 gets the next n/p elements, etc. where
|
||||
n is the number of elements and p is the number of processors.
|
||||
<li> DistributedGlobal() - Returns true if the element space of the map spans more than one processor.
|
||||
This will be true in most cases, but will be false on in serial and for objects
|
||||
that are created via the derived Epetra_LocalMap class.
|
||||
</ul>
|
||||
|
||||
\warning A Epetra_Comm object is required for all Epetra_BlockMap constructors.
|
||||
|
||||
\bf {error handling}
|
||||
|
||||
Most methods in Epetra_BlockMap return an integer error code. If the error code is 0, then no error occurred.
|
||||
If > 0 then a warning error occurred. If < 0 then a fatal error occurred.
|
||||
|
||||
Epetra_BlockMap constructors will throw an exception of an error occurrs. These exceptions will alway be negative integer values
|
||||
as follows:
|
||||
<ol>
|
||||
<li> -1 NumGlobalElements < -1. Should be >= -1 (Should be >= 0 for first BlockMap constructor).
|
||||
<li> -2 NumMyElements < 0. Should be >= 0.
|
||||
<li> -3 ElementSize <= 0. Should be > 0.
|
||||
<li> -4 Invalid NumGlobalElements. Should equal sum of MyGlobalElements, or set to -1 to compute automatically.
|
||||
<li> -5 Minimum global element index is less than index base.
|
||||
<li> -99 Internal Epetra_BlockMap error. Contact developer.
|
||||
</ol>
|
||||
|
||||
For robust code, Epetra_BlockMap constructor calls should be caught using the try {...} catch {...} mechanism. For example:
|
||||
|
||||
\verbatim
|
||||
try {
|
||||
|
||||
Epetra_BlockMap * map = new Epetra_BlockMap(NumGlobalElements, ElementSize, IndexBase, Comm);
|
||||
}
|
||||
catch (int Error) {
|
||||
if (Error==-1) { // handle error }
|
||||
if (Error==-2) ...
|
||||
\endverbatim
|
||||
|
||||
|
||||
\note
|
||||
{
|
||||
In the current implementation, Epetra_BlockMap is the base class for:
|
||||
<ul>
|
||||
<li> Epetra_Map.
|
||||
<li> Epetra_LocalBlockMap.
|
||||
</ul>
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
class Epetra_BlockMap: public Epetra_Object {
|
||||
friend class Epetra_Directory;
|
||||
friend class Epetra_LocalMap;
|
||||
public:
|
||||
//! @name Constructors/destructors
|
||||
//@{
|
||||
//! Epetra_BlockMap constructor for a Epetra-defined uniform linear distribution of constant size elements.
|
||||
/*! Creates a map that distributes NumGlobalElements elements evenly across all processors in the
|
||||
Epetra_Comm communicator. If NumGlobalElements does not divide exactly into the number of processors,
|
||||
the first processors in the communicator get one extra element until the remainder is gone.
|
||||
|
||||
The elements are defined to have a constant fixed size specified by ElementSize.
|
||||
|
||||
\param In
|
||||
NumGlobalElements - Number of elements to distribute.
|
||||
|
||||
\param In
|
||||
ElementSize - Number of points or vector entries per element.
|
||||
|
||||
\param In
|
||||
IndexBase - Minimum index value used for arrays that use this map. Typically 0 for
|
||||
C/C++ and 1 for Fortran.
|
||||
|
||||
\param In
|
||||
Comm - Epetra_Comm communicator containing information on the number of
|
||||
processors.
|
||||
|
||||
\return Pointer to a Epetra_BlockMap object.
|
||||
|
||||
*/
|
||||
Epetra_BlockMap(int NumGlobalElements, int ElementSize, int IndexBase, const Epetra_Comm& Comm);
|
||||
|
||||
//! Epetra_BlockMap constructor for a user-defined linear distribution of constant size elements.
|
||||
/*! Creates a map that puts NumMyElements on the calling processor. If
|
||||
NumGlobalElements=-1, the number of global elements will be
|
||||
the computed sum of NumMyElements across all processors in the
|
||||
Epetra_Comm communicator.
|
||||
|
||||
The elements are defined to have a constant fixed size specified by ElementSize.
|
||||
|
||||
\param In
|
||||
NumGlobalElements - Number of elements to distribute. Must be
|
||||
either -1 or equal to the computed sum of NumMyElements across all
|
||||
processors in the Epetra_Comm communicator.
|
||||
|
||||
\param In
|
||||
NumMyElements - Number of elements owned by the calling processor.
|
||||
|
||||
\param In
|
||||
ElementSize - Number of points or vector entries per element.
|
||||
|
||||
\param In
|
||||
IndexBase - Minimum index value used for arrays that use this map. Typically 0 for
|
||||
C/C++ and 1 for Fortran.
|
||||
|
||||
\param In
|
||||
Comm - Epetra_Comm communicator containing information on the number of
|
||||
processors.
|
||||
|
||||
\return Pointer to a Epetra_BlockMap object.
|
||||
|
||||
*/
|
||||
Epetra_BlockMap(int NumGlobalElements, int NumMyElements,
|
||||
int ElementSize, int IndexBase, const Epetra_Comm& Comm);
|
||||
|
||||
//! Epetra_BlockMap constructor for a user-defined arbitrary distribution of constant size elements.
|
||||
/*! Creates a map that puts NumMyElements on the calling processor. The indices of the elements
|
||||
are determined from the list MyGlobalElements. If NumGlobalElements=-1,
|
||||
the number of global elements will be the computed sum of NumMyElements
|
||||
across all processors in the Epetra_Comm communicator.
|
||||
|
||||
The elements are defined to have a constant fixed size specified by ElementSize.
|
||||
|
||||
\param In
|
||||
NumGlobalElements - Number of elements to distribute. Must be
|
||||
either -1 or equal to the computed sum of NumMyElements across all
|
||||
processors in the Epetra_Comm communicator.
|
||||
|
||||
\param In
|
||||
NumMyElements - Number of elements owned by the calling processor.
|
||||
|
||||
\param In
|
||||
MyGlobalElements - Integer array of length NumMyElements. The ith entry contains the
|
||||
global index value of the ith element on this processor. Index values are not required to
|
||||
be contiguous on a processor, or to be within the range of 0 to NumGlobalElements. As
|
||||
long as the index values are consistently defined and used, any set of NumGlobalElements
|
||||
distinct integer values is acceptable.
|
||||
|
||||
\param In
|
||||
ElementSize - Number of points or vector entries per element.
|
||||
|
||||
\param In
|
||||
IndexBase - Minimum index value used for arrays that use this map. Typically 0 for
|
||||
C/C++ and 1 for Fortran.
|
||||
|
||||
\param In
|
||||
Comm - Epetra_Comm communicator containing information on the number of
|
||||
processors.
|
||||
|
||||
\return Pointer to a Epetra_BlockMap object.
|
||||
|
||||
*/
|
||||
Epetra_BlockMap(int NumGlobalElements, int NumMyElements,
|
||||
const int *MyGlobalElements,
|
||||
int ElementSize, int IndexBase, const Epetra_Comm& Comm);
|
||||
|
||||
//! Epetra_BlockMap constructor for a user-defined arbitrary distribution of variable size elements.
|
||||
/*! Creates a map that puts NumMyElements on the calling processor. If
|
||||
NumGlobalElements=-1, the number of global elements will be
|
||||
the computed sum of NumMyElements across all processors in the
|
||||
Epetra_Comm communicator.
|
||||
|
||||
The elements are defined to have a variable size defined by ElementSizeList.
|
||||
|
||||
\param In
|
||||
NumGlobalElements - Number of elements to distribute. Must be
|
||||
either -1 or equal to the computed sum of NumMyElements across all
|
||||
processors in the Epetra_Comm communicator.
|
||||
|
||||
\param In
|
||||
NumMyElements - Number of elements owned by the calling processor.
|
||||
|
||||
\param In
|
||||
MyGlobalElements - Integer array of length NumMyElements. The ith entry contains the
|
||||
global index value of the ith element on this processor. Index values are not required to
|
||||
be contiguous on a processor, or to be within the range of 0 to NumGlobalElements. As
|
||||
long as the index values are consistently defined and used, any set of NumGlobalElements
|
||||
distinct integer values is acceptable.
|
||||
|
||||
\param In
|
||||
ElementSizeList - A list of the element sizes for elements owned by the calling
|
||||
processor. The ith entry contains the element size of the ith element on this processor.
|
||||
|
||||
\param In
|
||||
IndexBase - Minimum index value used for arrays that use this map. Typically 0 for
|
||||
C/C++ and 1 for Fortran.
|
||||
|
||||
\param In
|
||||
Comm - Epetra_Comm communicator containing information on the number of
|
||||
processors.
|
||||
|
||||
\return Pointer to a Epetra_BlockMap object.
|
||||
|
||||
*/
|
||||
Epetra_BlockMap(int NumGlobalElements, int NumMyElements,
|
||||
const int *MyGlobalElements,
|
||||
const int *ElementSizeList, int IndexBase,
|
||||
const Epetra_Comm& Comm);
|
||||
|
||||
//! Epetra_BlockMap copy constructor.
|
||||
Epetra_BlockMap(const Epetra_BlockMap& map);
|
||||
|
||||
//! Epetra_BlockMap destructor.
|
||||
virtual ~Epetra_BlockMap(void);
|
||||
//@}
|
||||
|
||||
//! @name Local/Global ID accessor methods
|
||||
//@{
|
||||
//! Returns the processor IDs and corresponding local index value for a given list of global indices
|
||||
/*! For each element (GID) of a given list of global element numbers (stored in GIDList) of length NumIDs,
|
||||
this function returns (in PIDList) the with processor that owns the GID for this map and returns the
|
||||
local index (in LIDList) of the GID on that processor.
|
||||
*/
|
||||
int RemoteIDList(int NumIDs, const int * GIDList, int * PIDList, int * LIDList) const {
|
||||
return(RemoteIDList(NumIDs, GIDList, PIDList, LIDList, 0));
|
||||
};
|
||||
|
||||
//! Returns the processor IDs, corresponding local index value, and element size for a given list of global indices
|
||||
/*! For each element (GID) of a given a list of global element numbers (stored in GIDList) of length NumIDs,
|
||||
this function returns (in PIDList) the with processor that owns the GID for this map and returns the
|
||||
local index (in LIDList) of the GID on that processor. Finally it returns the element sizes in
|
||||
SizeList.
|
||||
*/
|
||||
int RemoteIDList(int NumIDs, const int * GIDList, int * PIDList, int * LIDList, int * SizeList) const;
|
||||
|
||||
//! Returns local ID of global ID, return -1 if not found on this processor.
|
||||
int LID(int GID) const;
|
||||
|
||||
//! Returns global ID of local ID, return IndexBase-1 if not found on this processor.
|
||||
int GID(int LID) const;
|
||||
|
||||
//! Returns the LID of the element that contains the given local PointID, and the Offset of the point in that element.
|
||||
int FindLocalElementID(int PointID, int & ElementID, int & ElementOffset) const;
|
||||
|
||||
//! Returns true if the GID passed in belongs to the calling processor in this map, otherwise returns false.
|
||||
bool MyGID(int GID) const {return(LID(GID)!=-1);};
|
||||
|
||||
//! Returns true if the LID passed in belongs to the calling processor in this map, otherwise returns false.
|
||||
bool MyLID(int LID) const {return(GID(LID)!=BlockMapData_->IndexBase_-1);};
|
||||
|
||||
//!Returns the minimum global ID across the entire map.
|
||||
int MinAllGID() const {return(BlockMapData_->MinAllGID_);};
|
||||
|
||||
//! Returns the maximum global ID across the entire map.
|
||||
int MaxAllGID() const {return(BlockMapData_->MaxAllGID_);};
|
||||
|
||||
//! Returns the maximum global ID owned by this processor.
|
||||
int MinMyGID() const {return(BlockMapData_->MinMyGID_);};
|
||||
|
||||
//! Returns the maximum global ID owned by this processor.
|
||||
int MaxMyGID() const {return(BlockMapData_->MaxMyGID_);};
|
||||
|
||||
//! The minimum local index value on the calling processor.
|
||||
int MinLID() const {return(BlockMapData_->MinLID_);};
|
||||
|
||||
//! The maximum local index value on the calling processor.
|
||||
int MaxLID() const {return(BlockMapData_->MaxLID_);};
|
||||
//@}
|
||||
|
||||
//! @name Size and dimension accessor functions
|
||||
//@{
|
||||
//! Number of elements across all processors.
|
||||
int NumGlobalElements() const {return(BlockMapData_->NumGlobalElements_);};
|
||||
|
||||
//! Number of elements on the calling processor.
|
||||
int NumMyElements() const {return(BlockMapData_->NumMyElements_);};
|
||||
|
||||
//! Puts list of global elements on this processor into the user-provided array.
|
||||
int MyGlobalElements(int * MyGlobalElementList) const;
|
||||
|
||||
//! Returns the size of elements in the map; only valid if map has constant element size.
|
||||
int ElementSize() const {return(BlockMapData_->ElementSize_);};
|
||||
|
||||
//! Size of element for specified LID.
|
||||
int ElementSize(int LID) const;
|
||||
|
||||
//! Returns the requested entry in the FirstPointInElementList; see FirstPointInElementList() for details.
|
||||
/*! This function provides similar functionality to FirstPointInElementList(), but for simple maps may avoid
|
||||
the explicit construction of the FirstPointInElementList array. Returns -1 if LID is out-of-range.
|
||||
*/
|
||||
int FirstPointInElement(int LID) const;
|
||||
|
||||
//! Index base for this map.
|
||||
int IndexBase() const {return(BlockMapData_->IndexBase_);};
|
||||
|
||||
//! Number of global points for this map; equals the sum of all element sizes across all processors.
|
||||
int NumGlobalPoints() const {return(BlockMapData_->NumGlobalPoints_);};
|
||||
|
||||
//! Number of local points for this map; equals the sum of all element sizes on the calling processor.
|
||||
int NumMyPoints() const {return(BlockMapData_->NumMyPoints_);};
|
||||
|
||||
//! Minimum element size on the calling processor.
|
||||
int MinMyElementSize() const {return(BlockMapData_->MinMyElementSize_);};
|
||||
|
||||
//! Maximum element size on the calling processor.
|
||||
int MaxMyElementSize() const {return(BlockMapData_->MaxMyElementSize_);};
|
||||
|
||||
//! Minimum element size across all processors.
|
||||
int MinElementSize() const {return(BlockMapData_->MinElementSize_);};
|
||||
|
||||
//! Maximum element size across all processors.
|
||||
int MaxElementSize() const {return(BlockMapData_->MaxElementSize_);};
|
||||
//@}
|
||||
|
||||
//! @name Miscellaneous boolean tests
|
||||
//@{
|
||||
//! Returns true if map GIDs are 1-to-1.
|
||||
/*! Certain operations involving Epetra_BlockMap and Epetra_Map objects are well-defined only if
|
||||
the map GIDs are uniquely present in the map. In other words, if a GID occurs in the map, it occurs
|
||||
only once on a single processor and nowhere else. This boolean test returns true if this property
|
||||
is true, otherwise it returns false.
|
||||
*/
|
||||
bool UniqueGIDs() const {return(IsOneToOne());};
|
||||
|
||||
//! Returns true if map has constant element size.
|
||||
bool ConstantElementSize() const {return(BlockMapData_->ConstantElementSize_);};
|
||||
|
||||
//! Returns true if \e this and Map are identical maps
|
||||
bool SameAs(const Epetra_BlockMap & Map) const;
|
||||
|
||||
//! Returns true if \e this and Map have identical point-wise structure
|
||||
/*! If both maps have the same number of global points and the same point
|
||||
distribution across processors then this method returns true.
|
||||
*/
|
||||
bool PointSameAs(const Epetra_BlockMap & Map) const;
|
||||
|
||||
//! Returns true if the global ID space is contiguously divided (but not necessarily uniformly) across all processors.
|
||||
bool LinearMap() const {return(BlockMapData_->LinearMap_);};
|
||||
|
||||
//! Returns true if map is defined across more than one processor.
|
||||
bool DistributedGlobal() const {return(BlockMapData_->DistributedGlobal_);};
|
||||
//@}
|
||||
|
||||
//! @name Array accessor functions
|
||||
//@{
|
||||
|
||||
//! Pointer to internal array containing list of global IDs assigned to the calling processor.
|
||||
int * MyGlobalElements() const;
|
||||
|
||||
//! Pointer to internal array containing a mapping between the local elements and the first local point number in each element.
|
||||
/*! This array is a scan sum of the ElementSizeList such that the ith entry in FirstPointInElementList is the sum of the first
|
||||
i-1 entries of ElementSizeList().
|
||||
*/
|
||||
int * FirstPointInElementList() const;
|
||||
|
||||
//! List of the element sizes corresponding to the array MyGlobalElements().
|
||||
int * ElementSizeList() const;
|
||||
|
||||
//! For each local point, indicates the local element ID that the point belongs to.
|
||||
int * PointToElementList() const;
|
||||
|
||||
//! Same as ElementSizeList() except it fills the user array that is passed in.
|
||||
int ElementSizeList(int * ElementSizeList)const;
|
||||
|
||||
//! Same as FirstPointInElementList() except it fills the user array that is passed in.
|
||||
int FirstPointInElementList(int * FirstPointInElementList)const;
|
||||
|
||||
//! Same as PointToElementList() except it fills the user array that is passed in.
|
||||
int PointToElementList(int * PointToElementList) const;
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Miscellaneous
|
||||
//@{
|
||||
|
||||
//! Print object to an output stream
|
||||
virtual void Print(ostream & os) const;
|
||||
|
||||
//! Access function for Epetra_Comm communicator.
|
||||
const Epetra_Comm & Comm() const {return(*BlockMapData_->Comm_);}
|
||||
|
||||
bool IsOneToOne() const {return(BlockMapData_->OneToOne_);}
|
||||
|
||||
//! Assignment Operator
|
||||
Epetra_BlockMap & operator=(const Epetra_BlockMap & map);
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Expert Users and Developers Only
|
||||
//@{
|
||||
|
||||
//! Returns the reference count of BlockMapData.
|
||||
/*! (Intended for testing purposes.) */
|
||||
int ReferenceCount() const {return(BlockMapData_->ReferenceCount());}
|
||||
|
||||
//! Returns a pointer to the BlockMapData instance this BlockMap uses.
|
||||
/*! (Intended for developer use only for testing purposes.) */
|
||||
const Epetra_BlockMapData * DataPtr() const {return(BlockMapData_);}
|
||||
|
||||
//@}
|
||||
|
||||
private: // These need to be accessible to derived map classes.
|
||||
|
||||
void GlobalToLocalSetup();
|
||||
bool DetermineIsOneToOne();
|
||||
bool IsDistributedGlobal(int NumGlobalElements, int NumMyElements) const;
|
||||
void CheckValidNGE(int NumGlobalElements);
|
||||
void EndOfConstructorOps();
|
||||
void CleanupData();
|
||||
|
||||
Epetra_BlockMapData * BlockMapData_;
|
||||
|
||||
};
|
||||
|
||||
#endif /* EPETRA_BLOCKMAP_H */
|
||||
@@ -0,0 +1,105 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_BLOCKMAPDATA_H
|
||||
#define EPETRA_BLOCKMAPDATA_H
|
||||
|
||||
#include "Epetra_Data.h"
|
||||
#include "Epetra_IntSerialDenseVector.h"
|
||||
|
||||
class Epetra_Comm;
|
||||
class Epetra_Directory;
|
||||
class Epetra_HashTable;
|
||||
|
||||
//! Epetra_BlockMapData: The Epetra BlockMap Data Class.
|
||||
/*! The Epetra_BlockMapData class is an implementation detail of Epetra_BlockMap.
|
||||
It is reference-counted, and can be shared by multiple Epetra_BlockMap instances.
|
||||
It derives from Epetra_Data, and inherits reference-counting from it.
|
||||
*/
|
||||
|
||||
class Epetra_BlockMapData : public Epetra_Data {
|
||||
friend class Epetra_BlockMap;
|
||||
|
||||
private:
|
||||
|
||||
//! @name Constructor/Destructor Methods
|
||||
//@{
|
||||
|
||||
//! Epetra_BlockMapData Default Constructor.
|
||||
Epetra_BlockMapData(int NumGlobalElements, int ElementSize, int IndexBase, const Epetra_Comm & Comm);
|
||||
|
||||
//! Epetra_BlockMapData Destructor.
|
||||
~Epetra_BlockMapData();
|
||||
|
||||
//@}
|
||||
|
||||
const Epetra_Comm * Comm_;
|
||||
|
||||
Epetra_Directory* Directory_;
|
||||
|
||||
Epetra_IntSerialDenseVector LID_;
|
||||
Epetra_IntSerialDenseVector MyGlobalElements_;
|
||||
Epetra_IntSerialDenseVector FirstPointInElementList_;
|
||||
Epetra_IntSerialDenseVector ElementSizeList_;
|
||||
Epetra_IntSerialDenseVector PointToElementList_;
|
||||
|
||||
int NumGlobalElements_;
|
||||
int NumMyElements_;
|
||||
int IndexBase_;
|
||||
int ElementSize_;
|
||||
int MinMyElementSize_;
|
||||
int MaxMyElementSize_;
|
||||
int MinElementSize_;
|
||||
int MaxElementSize_;
|
||||
int MinAllGID_;
|
||||
int MaxAllGID_;
|
||||
int MinMyGID_;
|
||||
int MaxMyGID_;
|
||||
int MinLID_;
|
||||
int MaxLID_;
|
||||
int NumGlobalPoints_;
|
||||
int NumMyPoints_;
|
||||
|
||||
bool ConstantElementSize_;
|
||||
bool LinearMap_;
|
||||
bool DistributedGlobal_;
|
||||
bool OneToOne_;
|
||||
|
||||
int LastContiguousGID_;
|
||||
int LastContiguousGIDLoc_;
|
||||
Epetra_HashTable * LIDHash_;
|
||||
|
||||
// these are intentionally declared but not defined. See Epetra Developer's Guide for details.
|
||||
Epetra_BlockMapData(const Epetra_BlockMapData & BlockMapData);
|
||||
Epetra_BlockMapData& operator=(const Epetra_BlockMapData & BlockMapData);
|
||||
|
||||
};
|
||||
#endif /* EPETRA_BLOCKMAPDATA_H */
|
||||
@@ -0,0 +1,70 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_COMBINEMODE_H
|
||||
#define EPETRA_COMBINEMODE_H
|
||||
/*! \file Epetra_CombineMode.h
|
||||
\brief Epetra_Combine Mode enumerable type
|
||||
*/
|
||||
|
||||
/*! \enum Epetra_CombineMode
|
||||
If set to Add, components on the receiving processor will be added
|
||||
together. If set to Zero, off-processor components will be ignored.
|
||||
If set to Insert, off-processor components will replace existing
|
||||
components on the receiving processor. If set to InsertAdd, off-processor components
|
||||
will replace existing components, but multiple off-processor contributions will be added.
|
||||
If set to Average, off-processor components will be averaged with
|
||||
existing components on the receiving processor. (Recursive Binary Average)
|
||||
If set to AbsMax, magnitudes of off-processor components will be maxed
|
||||
with magnitudes of existing components of the receiving processor.
|
||||
{ V = Supported by Epetra_Vector and Epetra_MultiVector,
|
||||
M = Supported by Epetra_CrsMatrix and Epetra_VbrMatrix }
|
||||
*/
|
||||
|
||||
enum Epetra_CombineMode {Add, /*!< Components on the receiving processor
|
||||
will be added together. (V,M) */
|
||||
Zero, /*!< Off-processor components will be
|
||||
ignored. (V,M) */
|
||||
Insert, /*!< Off-processor components will
|
||||
be inserted into locations on
|
||||
receiving processor replacing existing values. (V,M) */
|
||||
InsertAdd, /*!< Off-processor components will
|
||||
be inserted into locations on
|
||||
receiving processor replacing existing values. (V,M) */
|
||||
Average,/*!< Off-processor components will be
|
||||
averaged with existing components
|
||||
on the receiving processor. (V) */
|
||||
AbsMax /*!< Magnitudes of Off-processor components will be
|
||||
maxed with magnitudes of existing components
|
||||
on the receiving processor. (V) */
|
||||
};
|
||||
|
||||
#endif // EPETRA_COMBINEMODE_H
|
||||
@@ -0,0 +1,366 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_COMM_H
|
||||
#define EPETRA_COMM_H
|
||||
|
||||
#include "Epetra_Object.h"
|
||||
|
||||
class Epetra_Distributor;
|
||||
class Epetra_Directory;
|
||||
class Epetra_BlockMap;
|
||||
|
||||
//! Epetra_Comm: The Epetra Communication Abstract Base Class.
|
||||
/*! The Epetra_Comm class is an interface that encapsulates the general
|
||||
information and services needed for other Epetra classes to run on a
|
||||
parallel computer. An Epetra_Comm object is required for building all
|
||||
Epetra Map objects, which in turn are required for all other Epetra
|
||||
classes.
|
||||
|
||||
Epetra_Comm has default implementations, via Epetra_SerialComm and
|
||||
Epetra_MpiComm, for both serial execution and MPI distributed memory
|
||||
execution. It is meant to insulate the user from the specifics of
|
||||
communication that are not required for normal manipulation of linear
|
||||
algebra objects. Most Epetra_Comm interfaces are similar to MPI
|
||||
interfaces, except that the type of data is not required as an argument
|
||||
since C++ can bind to the appropriate interface based on argument typing.
|
||||
|
||||
Any implementation of the Epetra_Comm interface is also responsible for
|
||||
generating an Epetra_Distributor and Epetra_Directory object.
|
||||
*/
|
||||
|
||||
class Epetra_Comm {
|
||||
|
||||
public:
|
||||
//! @name Constructor / Destructor
|
||||
//@{
|
||||
//! Epetra_Comm clone constructor.
|
||||
/*! The clone function will return a new heap-allocated Comm instance.
|
||||
It is the responsibility of the caller to ensure that this new instance
|
||||
is properly destroyed.
|
||||
*/
|
||||
virtual Epetra_Comm * Clone() const = 0;
|
||||
//! Epetra_Comm Destructor.
|
||||
virtual ~Epetra_Comm() {};
|
||||
//@}
|
||||
|
||||
//! @name Barrier Methods
|
||||
//@{
|
||||
//! Epetra_Comm Barrier function.
|
||||
/*! Each processor must wait at the point the barrier is called until all processors have arrived.
|
||||
*/
|
||||
virtual void Barrier() const = 0;
|
||||
//@}
|
||||
|
||||
//! @name Broadcast Methods
|
||||
//@{
|
||||
//! Epetra_Comm Broadcast function.
|
||||
/*! Take list of input values from the root processor and sends to all other processors.
|
||||
\param MyVals InOut
|
||||
On entry, the root processor contains the list of values. On exit,
|
||||
all processors will have the same list of values. Note that values must be
|
||||
allocated on all processor before the broadcast.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of Values.
|
||||
\param Root In
|
||||
On entry, contains the processor from which all processors will receive a copy of Values.
|
||||
*/
|
||||
|
||||
virtual int Broadcast(double * MyVals, int Count, int Root) const = 0;
|
||||
|
||||
//! Epetra_Comm Broadcast function.
|
||||
/*! Take list of input values from the root processor and sends to all other processors.
|
||||
\param MyVals InOut
|
||||
On entry, the root processor contains the list of values. On exit,
|
||||
all processors will have the same list of values. Note that values must be
|
||||
allocated on all processor before the broadcast.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of Values.
|
||||
\param Root In
|
||||
On entry, contains the processor from which all processors will receive a copy of Values.
|
||||
*/
|
||||
|
||||
virtual int Broadcast(int * MyVals, int Count, int Root) const = 0;
|
||||
|
||||
//! Epetra_Comm Broadcast function.
|
||||
/*! Take list of input values from the root processor and sends to all other processors.
|
||||
\param MyVals InOut
|
||||
On entry, the root processor contains the list of values. On exit,
|
||||
all processors will have the same list of values. Note that values must be
|
||||
allocated on all processor before the broadcast.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of Values.
|
||||
\param Root In
|
||||
On entry, contains the processor from which all processors will receive a copy of Values.
|
||||
*/
|
||||
|
||||
virtual int Broadcast(long * MyVals, int Count, int Root) const = 0;
|
||||
//@}
|
||||
|
||||
//! @name Gather Methods
|
||||
//@{
|
||||
//! Epetra_Comm All Gather function.
|
||||
/*! Take list of input values from all processors in the communicator and creates an ordered contiguous list of
|
||||
those values on each processor.
|
||||
\param MyVals In
|
||||
On entry, contains the list of values to be sent to all processors.
|
||||
\param AllVals Out
|
||||
On exit, contains the list of values from all processors. Must be of size NumProc*Count.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of MyVals.
|
||||
*/
|
||||
|
||||
virtual int GatherAll(double * MyVals, double * AllVals, int Count) const = 0;
|
||||
|
||||
//! Epetra_Comm All Gather function.
|
||||
/*! Take list of input values from all processors in the communicator and creates an ordered contiguous list of
|
||||
those values on each processor.
|
||||
\param MyVals In
|
||||
On entry, contains the list of values to be sent to all processors.
|
||||
\param AllVals Out
|
||||
On exit, contains the list of values from all processors. Must be of size NumProc*Count.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of MyVals.
|
||||
*/
|
||||
|
||||
virtual int GatherAll(int * MyVals, int * AllVals, int Count) const = 0;
|
||||
|
||||
//! Epetra_Comm All Gather function.
|
||||
/*! Take list of input values from all processors in the communicator and creates an ordered contiguous list of
|
||||
those values on each processor.
|
||||
\param MyVals In
|
||||
On entry, contains the list of values to be sent to all processors.
|
||||
\param AllVals Out
|
||||
On exit, contains the list of values from all processors. Must be of size NumProc*Count.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of MyVals.
|
||||
*/
|
||||
|
||||
virtual int GatherAll(long * MyVals, long * AllVals, int Count) const = 0;
|
||||
//@}
|
||||
|
||||
//! @name Sum Methods
|
||||
//@{
|
||||
//! Epetra_Comm Global Sum function.
|
||||
/*! Take list of input values from all processors in the communicator, computes the sum and returns the
|
||||
sum to all processors.
|
||||
\param PartialSums In
|
||||
On entry, contains the list of values, usually partial sums computed locally,
|
||||
to be summed across all processors.
|
||||
\param GlobalSums Out
|
||||
On exit, contains the list of values summed across all processors.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of values.
|
||||
*/
|
||||
|
||||
virtual int SumAll(double * PartialSums, double * GlobalSums, int Count) const = 0;
|
||||
|
||||
//! Epetra_Comm Global Sum function.
|
||||
/*! Take list of input values from all processors in the communicator, computes the sum and returns the
|
||||
sum to all processors.
|
||||
\param PartialSums In
|
||||
On entry, contains the list of values, usually partial sums computed locally,
|
||||
to be summed across all processors.
|
||||
\param GlobalSums Out
|
||||
On exit, contains the list of values summed across all processors.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of values.
|
||||
*/
|
||||
virtual int SumAll(int * PartialSums, int * GlobalSums, int Count) const = 0;
|
||||
|
||||
//! Epetra_Comm Global Sum function.
|
||||
/*! Take list of input values from all processors in the communicator, computes the sum and returns the
|
||||
sum to all processors.
|
||||
\param PartialSums In
|
||||
On entry, contains the list of values, usually partial sums computed locally,
|
||||
to be summed across all processors.
|
||||
\param GlobalSums Out
|
||||
On exit, contains the list of values summed across all processors.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of values.
|
||||
*/
|
||||
virtual int SumAll(long * PartialSums, long * GlobalSums, int Count) const = 0;
|
||||
//@}
|
||||
|
||||
//! @name Max/Min Methods
|
||||
//@{
|
||||
//! Epetra_Comm Global Max function.
|
||||
/*! Take list of input values from all processors in the communicator, computes the max and returns the
|
||||
max to all processors.
|
||||
\param PartialMaxs In
|
||||
On entry, contains the list of values, usually partial maxs computed locally;
|
||||
using these Partial Maxs, the max across all processors will be computed.
|
||||
\param GlobalMaxs Out
|
||||
On exit, contains the list of maxs computed across all processors.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of values.
|
||||
*/
|
||||
virtual int MaxAll(double * PartialMaxs, double * GlobalMaxs, int Count) const = 0;
|
||||
|
||||
//! Epetra_Comm Global Max function.
|
||||
/*! Take list of input values from all processors in the communicator, computes the max and returns the
|
||||
max to all processors.
|
||||
\param PartialMaxs In
|
||||
On entry, contains the list of values, usually partial maxs computed locally;
|
||||
using these Partial Maxs, the max across all processors will be computed.
|
||||
\param GlobalMaxs Out
|
||||
On exit, contains the list of maxs computed across all processors.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of values.
|
||||
*/
|
||||
virtual int MaxAll(int * PartialMaxs, int * GlobalMaxs, int Count) const = 0;
|
||||
|
||||
//! Epetra_Comm Global Max function.
|
||||
/*! Take list of input values from all processors in the communicator, computes the max and returns the
|
||||
max to all processors.
|
||||
\param PartialMaxs In
|
||||
On entry, contains the list of values, usually partial maxs computed locally;
|
||||
using these Partial Maxs, the max across all processors will be computed.
|
||||
\param GlobalMaxs Out
|
||||
On exit, contains the list of maxs computed across all processors.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of values.
|
||||
*/
|
||||
virtual int MaxAll(long * PartialMaxs, long * GlobalMaxs, int Count) const = 0;
|
||||
|
||||
//! Epetra_Comm Global Min function.
|
||||
/*! Take list of input values from all processors in the communicator, computes the min and returns the
|
||||
min to all processors.
|
||||
\param PartialMins In
|
||||
On entry, contains the list of values, usually partial mins computed locally;
|
||||
using these Partial Mins, the min across all processors will be computed.
|
||||
\param GlobalMins Out
|
||||
On exit, contains the list of mins computed across all processors.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of values.
|
||||
*/
|
||||
virtual int MinAll(double * PartialMins, double * GlobalMins, int Count) const = 0;
|
||||
|
||||
//! Epetra_Comm Global Min function.
|
||||
/*! Take list of input values from all processors in the communicator, computes the min and returns the
|
||||
min to all processors.
|
||||
\param PartialMins In
|
||||
On entry, contains the list of values, usually partial mins computed locally;
|
||||
using these Partial Mins, the min across all processors will be computed.
|
||||
\param GlobalMins Out
|
||||
On exit, contains the list of mins computed across all processors.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of values.
|
||||
*/
|
||||
virtual int MinAll(int * PartialMins, int * GlobalMins, int Count) const = 0;
|
||||
|
||||
//! Epetra_Comm Global Min function.
|
||||
/*! Take list of input values from all processors in the communicator, computes the min and returns the
|
||||
min to all processors.
|
||||
\param PartialMins In
|
||||
On entry, contains the list of values, usually partial mins computed locally;
|
||||
using these Partial Mins, the min across all processors will be computed.
|
||||
\param GlobalMins Out
|
||||
On exit, contains the list of mins computed across all processors.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of values.
|
||||
*/
|
||||
virtual int MinAll(long * PartialMins, long * GlobalMins, int Count) const = 0;
|
||||
//@}
|
||||
|
||||
//! @name Parallel Prefix Methods
|
||||
//@{
|
||||
//! Epetra_Comm Scan Sum function.
|
||||
/*! Take list of input values from all processors in the communicator, computes the scan sum and returns it
|
||||
to all processors such that processor i contains the sum of values from processor 0 up to and including
|
||||
processor i.
|
||||
\param MyVals In
|
||||
On entry, contains the list of values to be summed across all processors.
|
||||
\param ScanSums Out
|
||||
On exit, contains the list of values summed across processors 0 through i.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of values.
|
||||
*/
|
||||
virtual int ScanSum(double * MyVals, double * ScanSums, int Count) const = 0;
|
||||
|
||||
//! Epetra_Comm Scan Sum function.
|
||||
/*! Take list of input values from all processors in the communicator, computes the scan sum and returns it
|
||||
to all processors such that processor i contains the sum of values from processor 0 up to and including
|
||||
processor i.
|
||||
\param MyVals In
|
||||
On entry, contains the list of values to be summed across all processors.
|
||||
\param ScanSums Out
|
||||
On exit, contains the list of values summed across processors 0 through i.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of values.
|
||||
*/
|
||||
virtual int ScanSum(int * MyVals, int * ScanSums, int Count) const = 0;
|
||||
|
||||
//! Epetra_Comm Scan Sum function.
|
||||
/*! Take list of input values from all processors in the communicator, computes the scan sum and returns it
|
||||
to all processors such that processor i contains the sum of values from processor 0 up to and including
|
||||
processor i.
|
||||
\param MyVals In
|
||||
On entry, contains the list of values to be summed across all processors.
|
||||
\param ScanSums Out
|
||||
On exit, contains the list of values summed across processors 0 through i.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of values.
|
||||
*/
|
||||
virtual int ScanSum(long * MyVals, long * ScanSums, int Count) const = 0;
|
||||
//@}
|
||||
|
||||
//! @name Attribute Accessor Methods
|
||||
//@{
|
||||
|
||||
//! Return my process ID.
|
||||
/*! In MPI mode returns the rank of the calling process. In serial mode
|
||||
returns 0.
|
||||
*/
|
||||
virtual int MyPID() const = 0;
|
||||
|
||||
//! Returns total number of processes.
|
||||
/*! In MPI mode returns the size of the MPI communicator. In serial mode
|
||||
returns 1.
|
||||
*/
|
||||
virtual int NumProc() const = 0;
|
||||
//@}
|
||||
|
||||
//! @name Gather/Scatter and Directory Constructors
|
||||
//@{
|
||||
//! Create a distributor object.
|
||||
virtual Epetra_Distributor * CreateDistributor() const = 0;
|
||||
//! Create a directory object for the given Epetra_BlockMap.
|
||||
virtual Epetra_Directory * CreateDirectory(const Epetra_BlockMap & Map) const = 0;
|
||||
//@}
|
||||
|
||||
//! @name I/O methods
|
||||
//@{
|
||||
//! Print object to an output stream
|
||||
virtual void PrintInfo(ostream & os) const = 0;
|
||||
//@}
|
||||
};
|
||||
#endif /* EPETRA_COMM_H */
|
||||
@@ -0,0 +1,111 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_COMPOBJECT_H
|
||||
#define EPETRA_COMPOBJECT_H
|
||||
|
||||
//! Epetra_CompObject: Functionality and data that is common to all computational classes.
|
||||
|
||||
/*! The Epetra_CompObject is a base class for all Epetra computational objects. It provides the basic
|
||||
mechanisms and interface specifications for floating point operations using Epetra_Flops objects.
|
||||
|
||||
*/
|
||||
#include "Epetra_Object.h"
|
||||
#include "Epetra_Flops.h"
|
||||
//==========================================================================
|
||||
class Epetra_CompObject {
|
||||
|
||||
public:
|
||||
|
||||
//! @name Constructors/Destructor
|
||||
//@{
|
||||
//! Basic Epetra_CompObject constuctor.
|
||||
Epetra_CompObject();
|
||||
|
||||
//! Epetra_CompObject copy constructor.
|
||||
|
||||
Epetra_CompObject(const Epetra_CompObject& Source);
|
||||
|
||||
|
||||
//! Epetra_CompObject destructor.
|
||||
virtual ~Epetra_CompObject();
|
||||
//@}
|
||||
|
||||
//! @name Set/Get counter method
|
||||
//@{
|
||||
//! Set the internal Epetra_Flops() pointer.
|
||||
void SetFlopCounter(const Epetra_Flops & FlopCounter) {FlopCounter_= (Epetra_Flops *) &FlopCounter; return;}
|
||||
//! Set the internal Epetra_Flops() pointer to the flop counter of another Epetra_CompObject.
|
||||
void SetFlopCounter(const Epetra_CompObject & CompObject) {FlopCounter_= (Epetra_Flops *) (CompObject.GetFlopCounter()); return;}
|
||||
//! Set the internal Epetra_Flops() pointer to 0 (no flops counted).
|
||||
void UnsetFlopCounter() {FlopCounter_= 0; return;}
|
||||
//! Get the pointer to the Epetra_Flops() object associated with this object, returns 0 if none.
|
||||
Epetra_Flops * GetFlopCounter() const {return(FlopCounter_);}
|
||||
//@}
|
||||
|
||||
//! @name Set flop count methods
|
||||
//@{
|
||||
//! Resets the number of floating point operations to zero for \e this multi-vector.
|
||||
void ResetFlops() const {if (FlopCounter_!=0) FlopCounter_->ResetFlops(); return;}
|
||||
|
||||
//! Returns the number of floating point operations with \e this multi-vector.
|
||||
double Flops() const {if (FlopCounter_!=0) return(FlopCounter_->Flops()); else return(0.0);}
|
||||
//@}
|
||||
|
||||
//! @name Update flop count methods
|
||||
//@{
|
||||
//! Increment Flop count for \e this object
|
||||
void UpdateFlops(int Flops) const {if (FlopCounter_!=0) FlopCounter_->UpdateFlops(Flops); return;}
|
||||
|
||||
//! Increment Flop count for \e this object
|
||||
void UpdateFlops(long int Flops) const {if (FlopCounter_!=0) FlopCounter_->UpdateFlops(Flops); return;}
|
||||
|
||||
//! Increment Flop count for \e this object
|
||||
void UpdateFlops(double Flops) const {if (FlopCounter_!=0) FlopCounter_->UpdateFlops(Flops); return;}
|
||||
|
||||
//! Increment Flop count for \e this object
|
||||
void UpdateFlops(float Flops) const {if (FlopCounter_!=0) FlopCounter_->UpdateFlops(Flops); return;}
|
||||
//@}
|
||||
|
||||
Epetra_CompObject& operator=(const Epetra_CompObject& src)
|
||||
{
|
||||
FlopCounter_ = src.FlopCounter_;
|
||||
return(*this);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
Epetra_Flops * FlopCounter_;
|
||||
|
||||
};
|
||||
|
||||
#endif /* EPETRA_COMPOBJECT_H */
|
||||
@@ -0,0 +1,297 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_CONFIGDEFS_H
|
||||
#define EPETRA_CONFIGDEFS_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#define __cplusplus
|
||||
#endif
|
||||
|
||||
#define EPETRA_MAX(x,y) (( (x) > (y) ) ? x : y) /* max function */
|
||||
#define EPETRA_MIN(x,y) (( (x) < (y) ) ? x : y) /* min function */
|
||||
#define EPETRA_SGN(x) (((x) < 0.0) ? -1.0 : 1.0) /* sign function */
|
||||
|
||||
const double Epetra_MinDouble = 1.0E-100;
|
||||
const double Epetra_MaxDouble = 1.0E+100;
|
||||
const double Epetra_Overflow = 1.79E308; // Used to test if equilibration should be done.
|
||||
const double Epetra_Underflow = 2.23E-308;
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
||||
/*
|
||||
* The macros PACKAGE, PACKAGE_NAME, etc, get defined for each package and need to
|
||||
* be undef'd here to avoid warnings when this file is included from another package.
|
||||
* KL 11/25/02
|
||||
*/
|
||||
#ifdef PACKAGE
|
||||
#undef PACKAGE
|
||||
#endif
|
||||
|
||||
#ifdef PACKAGE_NAME
|
||||
#undef PACKAGE_NAME
|
||||
#endif
|
||||
|
||||
#ifdef PACKAGE_BUGREPORT
|
||||
#undef PACKAGE_BUGREPORT
|
||||
#endif
|
||||
|
||||
#ifdef PACKAGE_STRING
|
||||
#undef PACKAGE_STRING
|
||||
#endif
|
||||
|
||||
#ifdef PACKAGE_TARNAME
|
||||
#undef PACKAGE_TARNAME
|
||||
#endif
|
||||
|
||||
#ifdef PACKAGE_VERSION
|
||||
#undef PACKAGE_VERSION
|
||||
#endif
|
||||
|
||||
#ifdef VERSION
|
||||
#undef VERSION
|
||||
#endif
|
||||
|
||||
#include <Epetra_config.h>
|
||||
|
||||
#ifdef HAVE_MPI
|
||||
#ifndef EPETRA_MPI
|
||||
#define EPETRA_MPI
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CSTDLIB
|
||||
#include <cstdlib>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CSTDIO
|
||||
#include <cstdio>
|
||||
using std::sprintf;
|
||||
#endif
|
||||
#ifdef HAVE_STDIO_H
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CASSERT
|
||||
#include <cassert>
|
||||
#else
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING
|
||||
#include <string>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IOSTREAM
|
||||
#include <iostream>
|
||||
#else
|
||||
#include <iostream.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SSTREAM
|
||||
#include <sstream>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CMATH
|
||||
#include <cmath>
|
||||
using std::rand;
|
||||
#endif
|
||||
#ifdef HAVE_MATH_H
|
||||
#include <math.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IOMANIP
|
||||
#include <iomanip>
|
||||
#else
|
||||
#include <iomanip.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING
|
||||
using std::string;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IOSTREAM
|
||||
using std::istream;
|
||||
using std::ostream;
|
||||
using std::cerr;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::flush;
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
Must refine the following up to #else HAVE_CONFIG_H is not defined
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
#ifdef EPETRA_SIMULATE_BOOL
|
||||
#ifdef bool
|
||||
#undef bool
|
||||
#endif
|
||||
#ifdef true
|
||||
#undef true
|
||||
#endif
|
||||
#ifdef false
|
||||
#undef false
|
||||
#endif
|
||||
|
||||
#define bool int
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FORMAT_IO
|
||||
const bool Epetra_FormatStdout = false; // Set true if the ostream << operator should format output
|
||||
#else
|
||||
const bool Epetra_FormatStdout = true;
|
||||
#endif
|
||||
|
||||
// Define DefultTracebackMode (HAVE_WARNING_MESSAGES and HAVE_FATAL_MESSAGES can be defined
|
||||
// via the configure script command line)
|
||||
|
||||
#ifdef HAVE_WARNING_MESSAGES
|
||||
const int DefaultTracebackMode = 2;
|
||||
#elif defined HAVE_FATAL_MESSAGES
|
||||
const int DefaultTracebackMode = 1;
|
||||
#else
|
||||
const int DefaultTracebackMode = 0;
|
||||
#endif
|
||||
|
||||
#else /*HAVE_CONFIG_H is not defined*/
|
||||
|
||||
#ifndef __cplusplus
|
||||
#define __cplusplus
|
||||
#endif
|
||||
|
||||
#if defined(SGI) || defined(SGI64) || defined(SGI32) || defined(CPLANT)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
#include <math.h>
|
||||
#include <string>
|
||||
|
||||
using std::string;
|
||||
using std::istream;
|
||||
using std::ostream;
|
||||
using std::cerr;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::flush;
|
||||
|
||||
#else
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
|
||||
using std::string;
|
||||
using std::istream;
|
||||
using std::ostream;
|
||||
using std::cerr;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::flush;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef EPETRA_SIMULATE_BOOL
|
||||
#ifdef bool
|
||||
#undef bool
|
||||
#endif
|
||||
#ifdef true
|
||||
#undef true
|
||||
#endif
|
||||
#ifdef false
|
||||
#undef false
|
||||
#endif
|
||||
|
||||
#define bool int
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
#endif
|
||||
|
||||
const bool Epetra_FormatStdout = true; // Set true if the ostream << operator should format output
|
||||
const int DefaultTracebackMode = 1;
|
||||
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
|
||||
// Delete any previous definition of EPETRA_NO_ERROR_REPORTS
|
||||
|
||||
#ifdef EPETRA_CHK_ERR
|
||||
#undef EPETRA_CHK_ERR
|
||||
#endif
|
||||
#ifdef EPETRA_CHK_PTR
|
||||
#undef EPETRA_CHK_PTR
|
||||
#endif
|
||||
#ifdef EPETRA_CHK_REF
|
||||
#undef EPETRA_CHK_REF
|
||||
#endif
|
||||
|
||||
// Great little macro obtained from Alan Williams (modified for dynamic switching on/off)
|
||||
|
||||
#define EPETRA_CHK_ERR(a) { { int epetra_err = a; \
|
||||
if ((epetra_err < 0 && Epetra_Object::GetTracebackMode() > 0) || \
|
||||
(epetra_err > 0 && Epetra_Object::GetTracebackMode() > 1)) { \
|
||||
Epetra_Object::GetTracebackStream() << "Epetra ERROR " << epetra_err << ", " \
|
||||
<< __FILE__ << ", line " << __LINE__ << endl; }\
|
||||
if (epetra_err != 0) return(epetra_err); }\
|
||||
}
|
||||
|
||||
// Extension of same macro for pointer, returns zero if bad
|
||||
|
||||
#define EPETRA_CHK_PTR(a) { if (a == 0 && Epetra_Object::GetTracebackMode() > 0) { \
|
||||
Epetra_Object::GetTracebackStream() << "Epetra returning zero pointer " << ", " \
|
||||
<< __FILE__ << ", line " << __LINE__ << endl; } \
|
||||
return(a); \
|
||||
}
|
||||
// Extension of same macro for reference, returns a default reference
|
||||
|
||||
#define EPETRA_CHK_REF(a) { if (Epetra_Object::GetTracebackMode() > 0) {\
|
||||
Epetra_Object::GetTracebackStream() << "Epetra returning default reference " << ", " \
|
||||
<< __FILE__ << ", line " << __LINE__ << endl; } \
|
||||
return(a); \
|
||||
}
|
||||
|
||||
#endif /* EPETRA_CONFIGDEFS_H */
|
||||
@@ -0,0 +1,971 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_CRSGRAPH_H
|
||||
#define EPETRA_CRSGRAPH_H
|
||||
|
||||
#include "Epetra_DistObject.h"
|
||||
#include "Epetra_CrsGraphData.h"
|
||||
class Epetra_BlockMap;
|
||||
class Epetra_Util;
|
||||
class Epetra_Time;
|
||||
class Epetra_Import;
|
||||
class Epetra_Export;
|
||||
class Epetra_Distributor;
|
||||
class Epetra_RowMatrix;
|
||||
|
||||
//! Epetra_CrsGraph: A class for constructing and using sparse compressed row graphs.
|
||||
|
||||
/*! Epetra_CrsGraph enables the piecewise construction and use of sparse matrix graphs (the integer structure without
|
||||
values) where entries are intended for row access.
|
||||
|
||||
Epetra_CrsGraph is an attribute of all Epetra row-based matrix classes, defining their nonzero structure and also
|
||||
holding their Epetra_Map attributes.
|
||||
|
||||
<b>Constructing Epetra_CrsGraph objects</b>
|
||||
|
||||
Constructing Epetra_CrsGraph objects is a multi-step process. The basic steps are as follows:
|
||||
<ol>
|
||||
<li> Create Epetra_CrsGraph instance, including some initial storage, via constructor. In
|
||||
addition to the copy constructor, Epetra_CrsGraph has four different constructors. All four of these
|
||||
constructors have
|
||||
an argument, StaticProfile, which by default is set to false. If it is set to true, then the
|
||||
profile (the number of indices per row as defined by NumIndicesPerRow) will be rigidly enforced.
|
||||
Although this takes away flexibility, it allows a single array to be allocated for all indices.
|
||||
This decreases memory fragmentation and improves performance across many operations. A more detailed
|
||||
discussion of the StaticProfile option is found below.
|
||||
<ol>
|
||||
<li> User-provided row map, variable nonzero profile: This constructor is used to define the
|
||||
row distribution of the graph and specify a varying number of nonzero entries per row.
|
||||
It is best to use this constructor when the user will be inserting entries using global index
|
||||
values and wants every column index to be included in the graph. Note that in this case, the
|
||||
column map will be built for the user when FillComplete() is called. This constructor is also
|
||||
appropriate for when there is a large variation in the number of indices per row. If this is not
|
||||
the case, the next constructor may be more convenient to use.
|
||||
<li> User-provided row map, fixed nonzero profile: This constructor is used to define the
|
||||
row distribution of the graph and specify a fixed number of nonzero entries per row.
|
||||
It is best to use this constructor when the user will be inserting entries using global index
|
||||
values and wants every column index to be included in the graph. Note that in this case, the
|
||||
column map will be built for the user when FillComplete() is called. This constructor is also
|
||||
appropriate for when there is little or no variation in the number of indices per row.
|
||||
<li> User-provided row map, user-provided column map and variable nonzero profile:
|
||||
This constructor is used to define the
|
||||
row \e and \e column distribution of the graph, and specify a varying number of nonzero entries per row.
|
||||
It is best to use this constructor when the user will be inserting entries and already knows which columns
|
||||
of the matrix should be included on each processor. Note that in this case, the
|
||||
column map will \e not be built for the user when FillComplete() is called. Also, if the user attempts to
|
||||
insert a column index whose GID is not part of the column map on that process, the index will be
|
||||
discarded. This property can be used to "filter out" column entries that should be ignored.
|
||||
This constructor is also
|
||||
appropriate for when there is a large variation in the number of indices per row. If this is not
|
||||
the case, the next constructor may be more convenient to use.
|
||||
<li> User-provided row map, user-provided column map and fixed nonzero profile:
|
||||
This constructor is used to define the
|
||||
row \e and \e column distribution of the graph, and specify a fixed number of nonzero entries per row.
|
||||
It is best to use this constructor when the user will be inserting entries and already knows which columns
|
||||
of the matrix should be included on each processor. Note that in this case, the
|
||||
column map will \e not be built for the user when FillComplete() is called. Also, if the user attempts to
|
||||
insert a column index whose GID is not part of the column map on that process, the index will be
|
||||
discarded. This constructor is also
|
||||
appropriate for when there is little or no variation in the number of indices per row.
|
||||
</ol>
|
||||
<li> Enter row and column entry information via calls to the InsertGlobalIndices method.
|
||||
<li> Complete construction via FillComplete call, which performs the following tasks:
|
||||
<ol>
|
||||
<li>Transforms indices to local index space (after this, IndicesAreLocal()==true)
|
||||
<li>Sorts column-indices within each row
|
||||
<li>Compresses out any redundant indices within rows
|
||||
<li>Computes global data such as num-nonzeros, maximum row-lengths, etc.
|
||||
</ol>
|
||||
<li> (Optional) Optimize the graph storage via a call to OptimizeStorage.
|
||||
</ol>
|
||||
|
||||
<b> Performance Enhancement Issues </b>
|
||||
|
||||
The Epetra_CrsGraph class attempts to address four basic types of situations, depending on the user's primary concern:
|
||||
|
||||
<ol>
|
||||
<li> Simple, flexible construction over minimal memory use or control of column indices: In this case the user wants to provide only a row distribution
|
||||
of the graph and insert indices without worrying about memory allocation performance. This type of user is best
|
||||
served by the constructor that requires only a row map, and a fixed number of indices per row. In fact, setting NumIndicesPerRow=0
|
||||
is probably the best option.
|
||||
<li> Stronger control over memory allocation performance and use over flexibility and simplicity: In this case the user explicitly set
|
||||
StaticProfile to true and will provide values, either a single global int or an array of int's, for NumIndicesPerRow, such that
|
||||
the actual number of indices submitted to the graph will not exceed the estimates. Because we know that NumIndicesPerRow will not
|
||||
be exceeded, we can pre-allocate all of the storage for the graph as a single array. This is typically much more efficient.
|
||||
<li> Explicit control over column indices: In this case the user prescribes the column map. Given the column map, any index that is
|
||||
submitted for entry into the graph will be included \e only if they are present in the list of GIDs for the column map on the
|
||||
processor that submits the index. This feature allows the user to define a filter such that only certain columns will be kept. The
|
||||
user also prescribes the local ordering via this technique, since the ordering of GIDs in the column map imposes the local
|
||||
ordering.
|
||||
<li> Construction using local indices only: In some situations, users may want to build a graph using local index values only. In this
|
||||
case, the user must explicitly assign GIDs. This is done by prescribing the column map, in the same way as the previous situation.
|
||||
</ol>
|
||||
|
||||
Notes:
|
||||
<ul>
|
||||
<li>In all but the most advanced uses, users will typically \e not specify the column map. In other words, graph entries will be submitted using
|
||||
GIDs not LIDs and all entries that are submitted are intended to be inserted into the graph.
|
||||
|
||||
<li>If a user is not particularly worried about performance, or really needs the flexibility associated with the first situation, then there
|
||||
is no need to explicitly manage the NumIndicesPerRow values or set StaticProfile to true. In this case, it is best to set NumIndicesPerRow to
|
||||
zero.
|
||||
|
||||
<li> Users who are concerned about performance should carefully manage NumIndicesPerRow and set StaticProfile to true. This will give the best
|
||||
performance and use the least amount of memory.
|
||||
|
||||
<li> A compromise approach would be to not set StaticProfile to true, giving the user flexibility, but then calling OptimizeStorage() once FillComplete()
|
||||
has been called. This approach requires additional temporary memory because the graph will be copied into an efficient data structure and the old
|
||||
memory deleted. However, once the copy has been made, the resulting data structure is as efficient as when StaticProfile is used.
|
||||
</ul>
|
||||
|
||||
<b>Epetra_Map attributes</b>
|
||||
|
||||
Epetra_CrsGraph objects have four Epetra_Map attributes.
|
||||
|
||||
The Epetra_Map attributes can be obtained via these accessor methods:
|
||||
<ul>
|
||||
<li>RowMap() Describes the numbering and distribution of the rows of the graph. The row-map exists and is valid
|
||||
for the entire life of the graph, having been passed in as a constructor argument. The set of graph rows is defined
|
||||
by the row-map and may not be changed. Rows may not be inserted or deleted by the user. The only change that may be
|
||||
made is that the user can replace the row-map with a compatible row-map (which is the same except for re-numbering)
|
||||
by calling the ReplaceRowMap() method.
|
||||
<li>ColMap() Describes the set of column-indices that appear in the rows in each processor's portion of the graph.
|
||||
Unless provided by the user at construction time, a valid column-map doesn't exist until FillComplete() is called.
|
||||
<li>RangeMap() Describes the range of the matrix operator. e.g., for a matrix-vector product operation, the result
|
||||
vector's map must be compatible with the range-map of the matrix operator. The range-map is usually the same as
|
||||
the row-map. The range-map is set equal to the row-map at graph creation time, but may be specified by the user
|
||||
when FillComplete() is called.
|
||||
<li>DomainMap() Describes the domain of the matrix operator. The domain-map can be specified by the user when
|
||||
FillComplete() is called. Until then, it is set equal to the row-map.
|
||||
</ul>
|
||||
|
||||
It is important to note that while the row-map and the range-map are often the same, the column-map and the domain-map
|
||||
are almost never the same. The set of entries in a distributed column-map almost always form overlapping sets, with
|
||||
entries being associated with more than one processor. A domain-map, on the other hand, must be a 1-to-1 map, with
|
||||
entries being associated with only a single processor.
|
||||
|
||||
<b>Global versus Local indices</b>
|
||||
|
||||
After creation and before FillComplete() has been called, the column-indices of the graph are in
|
||||
the global space as received from the user. One of the tasks performed by FillComplete() is to
|
||||
transform the indices to a local index space. The query methods IndicesAreGlobal() and IndicesAreLocal()
|
||||
return true or false depending on whether this transformation has been performed or not.
|
||||
|
||||
Note the behavior of several graph methods:
|
||||
<ul>
|
||||
<li>InsertGlobalIndices() returns an error if IndicesAreLocal()==true or StorageOptimized()==true
|
||||
<li>InsertMyIndices() returns an error if IndicesAreGlobal()==true or StorageOptimized()==true
|
||||
<li>RemoveGlobalIndices() returns an error if IndicesAreLocal()==true or if graph was constructed in View mode
|
||||
<li>RemoveMyIndices() returns an error if IndicesAreGlobal()==true or if graph was constructed in View mode
|
||||
<li>ExtractGlobalRowCopy() works regardless of state of indices
|
||||
<li>ExtractMyRowCopy() returns an error if IndicesAreGlobal()==true
|
||||
<li>ExtractGlobalRowView() returns an error if IndicesAreLocal()==true
|
||||
<li>ExtractMyRowView() returns an error if IndicesAreGlobal()==true
|
||||
</ul>
|
||||
|
||||
Note that even after a graph is constructed, it is possible to add or remove entries. However,
|
||||
FillComplete must then be called again to restore the graph to a consistent state.
|
||||
|
||||
*/
|
||||
|
||||
class Epetra_CrsGraph: public Epetra_DistObject {
|
||||
|
||||
public:
|
||||
|
||||
//! @name Constructors/Destructor
|
||||
//@{
|
||||
//! Epetra_CrsGraph constuctor with variable number of indices per row.
|
||||
/*! Creates a Epetra_CrsGraph object and allocates storage.
|
||||
|
||||
\param CV - (In) A Epetra_DataAccess enumerated type set to Copy or View.
|
||||
\param RowMap - (In) An Epetra_BlockMap (or Epetra_Map or Epetra_LocalMap) listing the rows that this
|
||||
processor will contribute to.In
|
||||
\param NumIndicesPerRow - (In) An integer array of length NumMyRows
|
||||
such that NumIndicesPerRow[i] indicates the (approximate if StaticProfile=false) number of entries in the ith row.
|
||||
\param StaticProfile - (In) Optional argument that indicates whether or not NumIndicesPerRow should be interpreted as an exact
|
||||
count of nonzeros, or should be used as an approximation. By default this value is false, allowing the profile to be determined
|
||||
dynamically. If the user sets it to true, then the memory allocation for the Epetra_CrsGraph object will be done in one large
|
||||
block, saving on memory fragmentation and generally improving the performance of matrix multiplication and solve kernels.
|
||||
*/
|
||||
Epetra_CrsGraph(Epetra_DataAccess CV, const Epetra_BlockMap& RowMap, const int* NumIndicesPerRow, bool StaticProfile = false);
|
||||
|
||||
//! Epetra_CrsGraph constuctor with fixed number of indices per row.
|
||||
/*! Creates a Epetra_CrsGraph object and allocates storage.
|
||||
|
||||
\param CV - (In) A Epetra_DataAccess enumerated type set to Copy or View.
|
||||
\param RowMap - (In) An Epetra_BlockMap (or Epetra_Map or Epetra_LocalMap) listing the rows that this
|
||||
processor will contribute to.
|
||||
\param NumIndicesPerRow - (In) An integer that indicates the (approximate if StaticProfile=false) number of entries in the each row.
|
||||
Note that it is possible to use 0 for this value and let fill occur during the insertion phase.
|
||||
\param StaticProfile - (In) Optional argument that indicates whether or not NumIndicesPerRow should be interpreted as an exact
|
||||
count of nonzeros, or should be used as an approximation. By default this value is false, allowing the profile to be determined
|
||||
dynamically. If the user sets it to true, then the memory allocation for the Epetra_CrsGraph object will be done in one large
|
||||
block, saving on memory fragmentation and generally improving the performance of matrix multiplication and solve kernels.
|
||||
|
||||
*/
|
||||
Epetra_CrsGraph(Epetra_DataAccess CV, const Epetra_BlockMap& RowMap, int NumIndicesPerRow, bool StaticProfile = false);
|
||||
|
||||
//! Epetra_CrsGraph constuctor with variable number of indices per row.
|
||||
/*! Creates a Epetra_CrsGraph object and allocates storage.
|
||||
|
||||
\param CV - (In) A Epetra_DataAccess enumerated type set to Copy or View.
|
||||
\param RowMap - (In) An Epetra_BlockMap (or Epetra_Map or Epetra_LocalMap) listing the rows that this
|
||||
processor will contribute to.
|
||||
\param ColMap - (In) An Epetra_BlockMap (or Epetra_Map or Epetra_LocalMap) listing the columns that this
|
||||
processor will contribute to.
|
||||
\param NumIndicesPerRow - (In) An integer array of length NumMyRows
|
||||
such that NumIndicesPerRow[i] indicates the (approximate if StaticProfile=false) number of entries in the ith row.
|
||||
\param StaticProfile - (In) Optional argument that indicates whether or not NumIndicesPerRow should be interpreted as an exact
|
||||
count of nonzeros, or should be used as an approximation. By default this value is false, allowing the profile to be determined
|
||||
dynamically. If the user sets it to true, then the memory allocation for the Epetra_CrsGraph object will be done in one large
|
||||
block, saving on memory fragmentation and generally improving the performance of matrix multiplication and solve kernels.
|
||||
*/
|
||||
Epetra_CrsGraph(Epetra_DataAccess CV, const Epetra_BlockMap& RowMap,
|
||||
const Epetra_BlockMap& ColMap, const int* NumIndicesPerRow, bool StaticProfile = false);
|
||||
|
||||
//! Epetra_CrsGraph constuctor with fixed number of indices per row.
|
||||
/*! Creates a Epetra_CrsGraph object and allocates storage.
|
||||
|
||||
\param CV - (In) A Epetra_DataAccess enumerated type set to Copy or View.
|
||||
\param RowMap - (In) An Epetra_BlockMap (or Epetra_Map or Epetra_LocalMap) listing the rows that this
|
||||
processor will contribute to.
|
||||
\param ColMap - (In) An Epetra_BlockMap (or Epetra_Map or Epetra_LocalMap) listing the columns that this
|
||||
processor will contribute to.
|
||||
\param In
|
||||
NumIndicesPerRow - An integer that indicates the (approximate if StaticProfile=false) number of entries in the each row.
|
||||
Note that it is possible to use 0 for this value and let fill occur during the insertion phase.
|
||||
\param StaticProfile - (In) Optional argument that indicates whether or not NumIndicesPerRow should be interpreted as an exact
|
||||
count of nonzeros, or should be used as an approximation. By default this value is false, allowing the profile to be determined
|
||||
dynamically. If the user sets it to true, then the memory allocation for the Epetra_CrsGraph object will be done in one large
|
||||
block, saving on memory fragmentation and generally improving the performance of matrix multiplication and solve kernels.
|
||||
|
||||
*/
|
||||
Epetra_CrsGraph(Epetra_DataAccess CV, const Epetra_BlockMap& RowMap,
|
||||
const Epetra_BlockMap& ColMap, int NumIndicesPerRow, bool StaticProfile = false);
|
||||
|
||||
//! Copy constructor.
|
||||
/*! This will create a Level 1 deep copy. This Graph will share ownership
|
||||
of the CrsGraphData object with the right hand side Graph.
|
||||
*/
|
||||
Epetra_CrsGraph(const Epetra_CrsGraph& Graph);
|
||||
|
||||
//! Epetra_CrsGraph Destructor
|
||||
virtual ~Epetra_CrsGraph();
|
||||
//@}
|
||||
|
||||
//! @name Insertion/Removal methods
|
||||
//@{
|
||||
//! Enter a list of elements in a specified global row of the graph.
|
||||
/*!
|
||||
\param Row - (In) Global row number of indices.
|
||||
\param NumIndices - (In) Number of Indices.
|
||||
\param Indices - (In) Global column indices to insert.
|
||||
|
||||
\return Integer error code, set to 0 if successful. If the insertion requires
|
||||
that additional memory be allocated for the row, a positive error code of 1
|
||||
is returned. If the graph is a 'View'
|
||||
mode graph, then a positive warning code of 2 will be returned if the
|
||||
specified row already exists. Returns 1 if underlying graph data is shared
|
||||
by multiple graph instances.
|
||||
|
||||
\pre IndicesAreGlobal()==true, StorageOptimized()==false
|
||||
*/
|
||||
int InsertGlobalIndices(int GlobalRow, int NumIndices, int* Indices);
|
||||
|
||||
//! Remove a list of elements from a specified global row of the graph.
|
||||
/*!
|
||||
\param Row - (In) Global row number of indices.
|
||||
\param NumIndices - (In) Number of Indices.
|
||||
\param Indices - (In) Global column indices to remove.
|
||||
|
||||
\return Integer error code, set to 0 if successful. Returns 1 if data is shared.
|
||||
|
||||
\pre IndicesAreGlobal()==true, StorageOptimized()==false
|
||||
*/
|
||||
int RemoveGlobalIndices(int GlobalRow, int NumIndices, int* Indices);
|
||||
|
||||
//! Remove all indices from a specified global row of the graph.
|
||||
/*!
|
||||
\param Row - (In) Global row number of indices.
|
||||
|
||||
\return Integer error code, set to 0 if successful. Returns 1 if data is shared.
|
||||
|
||||
\pre IndicesAreGlobal()==true, StorageOptimized()==false
|
||||
*/
|
||||
int RemoveGlobalIndices(int Row);
|
||||
|
||||
|
||||
//! Enter a list of elements in a specified local row of the graph.
|
||||
/*!
|
||||
\param Row - (In) Local row number of indices.
|
||||
\param NumIndices - (In) Number of Indices.
|
||||
\param Indices - (In) Local column indices to insert.
|
||||
|
||||
\return Integer error code, set to 0 if successful. If the insertion requires
|
||||
that additional memory be allocated for the row, a positive error code of 1
|
||||
is returned. If one or more of the indices is ignored (due to not being
|
||||
contained in the column-map), then a positive warning code of 2 is returned.
|
||||
If the graph is a 'View' mode graph, then a positive warning code of 3 will
|
||||
be returned if the specified row already exists. Returns 1 if underlying
|
||||
graph data is shared by multiple graph instances.
|
||||
|
||||
\pre IndicesAreLocal()==true, StorageOptimized()==false
|
||||
*/
|
||||
int InsertMyIndices(int LocalRow, int NumIndices, int* Indices);
|
||||
|
||||
//! Remove a list of elements from a specified local row of the graph.
|
||||
/*!
|
||||
\param Row - (In) Local row number of indices.
|
||||
\param NumIndices - (In) Number of Indices.
|
||||
\param Indices - (In) Local column indices to remove.
|
||||
|
||||
\return Integer error code, set to 0 if successful. Returns 1 if data is shared.
|
||||
|
||||
\pre IndicesAreLocal()==true, StorageOptimized()==false
|
||||
*/
|
||||
int RemoveMyIndices(int LocalRow, int NumIndices, int* Indices);
|
||||
|
||||
//! Remove all indices from a specified local row of the graph.
|
||||
/*!
|
||||
\param Row - (In) Local row number of indices.
|
||||
|
||||
\return Integer error code, set to 0 if successful. Returns 1 if data is shared.
|
||||
|
||||
\pre IndicesAreLocal()==true, StorageOptimized()==false
|
||||
*/
|
||||
int RemoveMyIndices(int Row);
|
||||
//@}
|
||||
|
||||
//! @name Transformation methods
|
||||
//@{
|
||||
|
||||
//! Tranform to local index space. Perform other operations to allow optimal matrix operations.
|
||||
/*! This overloading of the FillComplete method assumes that the domain-map and range-map both equal
|
||||
the row-map, and simply calls FillComplete(RowMap(), RowMap()).
|
||||
\return Integer error code, set to 0 if successful. Returns 1 if data is shared (i.e., if the underlying graph-data
|
||||
object has a reference-count greater than 1).
|
||||
|
||||
\post IndicesAreLocal()==true, Filled()==true
|
||||
*/
|
||||
int FillComplete();
|
||||
|
||||
//! Transform to local index space using specified Domain/Range maps. Perform other operations to allow optimal matrix operations.
|
||||
/*! Performs this sequence of operations:
|
||||
<ol>
|
||||
<li>Transform indices to local index space
|
||||
<li>Sort column-indices within each row
|
||||
<li>Compress out any redundant indices within rows
|
||||
<li>Compute global data such as num-nonzeros, maximum row-lengths, etc.
|
||||
</ol>
|
||||
\return Integer error code, set to 0 if successful. Returns 1 if data is shared (i.e., if the underlying graph-data
|
||||
object has a reference-count greater than 1).
|
||||
|
||||
\post IndicesAreLocal()==true, Filled()==true
|
||||
*/
|
||||
int FillComplete(const Epetra_BlockMap& DomainMap, const Epetra_BlockMap& RangeMap);
|
||||
|
||||
//! Make consecutive row index sections contiguous, minimize internal storage used for constructing graph.
|
||||
/*! After construction and during initialization (when indices are being added via InsertGlobalIndices() etc.), the column-
|
||||
indices for each row are held in a separate piece of allocated memory. This method moves the column-indices for all rows
|
||||
into one large contiguous array and eliminates internal storage that is not needed after graph construction. Calling this
|
||||
method can have a significant impact on memory costs and machine performance.
|
||||
|
||||
If this object was constructed in View mode then this method can't make non-contiguous indices contiguous and will
|
||||
return a warning code of 1 if the viewed data isn't already contiguous.
|
||||
\return Integer error code, set to 0 if successful.
|
||||
|
||||
\pre Filled()==true.
|
||||
\pre If CV=View when the graph was constructed, then this method will be effective \only if the indices of the graph were already contiguous. In this case, the indices are left untouched and internal storage for the graph is minimized.
|
||||
|
||||
\post StorageOptimized()==true, if successful
|
||||
*/
|
||||
int OptimizeStorage();
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Extraction methods
|
||||
//@{
|
||||
|
||||
//! Extract a list of elements in a specified global row of the graph. Put into storage allocated by calling routine.
|
||||
/*!
|
||||
\param Row - (In) Global row number to get indices.
|
||||
\param LenOfIndices - (In) Length of Indices array.
|
||||
\param NumIndices - (Out) Number of Indices.
|
||||
\param Indices - (Out) Global column indices corresponding to values.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int ExtractGlobalRowCopy(int GlobalRow, int LenOfIndices, int& NumIndices, int* Indices) const;
|
||||
|
||||
//! Extract a list of elements in a specified local row of the graph. Put into storage allocated by calling routine.
|
||||
/*!
|
||||
\param Row - (In) Local row number to get indices.
|
||||
\param LenOfIndices - (In) Length of Indices array.
|
||||
\param NumIndices - (Out) Number of Indices.
|
||||
\param Indices - (Out) Local column indices corresponding to values.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
|
||||
\pre IndicesAreLocal()==true
|
||||
*/
|
||||
int ExtractMyRowCopy(int LocalRow, int LenOfIndices, int& NumIndices, int* Indices) const;
|
||||
|
||||
//! Get a view of the elements in a specified global row of the graph.
|
||||
/*!
|
||||
This function requires that the graph not be completed (FillComplete() was \e not called).
|
||||
\param Row - (In) Local row number to get indices.
|
||||
\param NumIndices - (Out) Number of Indices.
|
||||
\param Indices - (Out) Column indices corresponding to values.
|
||||
|
||||
\return Integer error code, set to 0 if successful. Returns -1 if invalid row. Returns -2 if graph is completed.
|
||||
|
||||
\pre IndicesAreLocal()==false
|
||||
*/
|
||||
int ExtractGlobalRowView(int GlobalRow, int& NumIndices, int*& Indices) const;
|
||||
|
||||
//! Get a view of the elements in a specified local row of the graph.
|
||||
/*!
|
||||
This function requires that the graph be completed FillComplete() was called).
|
||||
\param Row - (In) Local row number to get indices.
|
||||
\param NumIndices - (Out) Number of Indices.
|
||||
\param Indices - (Out) Column indices corresponding to values.
|
||||
|
||||
\return Integer error code, set to 0 if successful. Returns -1 if invalid row. Returns -2 if graph is not completed.
|
||||
|
||||
\pre IndicesAreLocal()==true
|
||||
*/
|
||||
int ExtractMyRowView(int LocalRow, int& NumIndices, int*& Indices) const;
|
||||
//@}
|
||||
|
||||
//! @name Graph Properties Query Methods
|
||||
//@{
|
||||
//! If FillComplete() has been called, this query returns true, otherwise it returns false.
|
||||
bool Filled() const {return(CrsGraphData_->Filled_);}
|
||||
|
||||
//! If OptimizeStorage() has been called, this query returns true, otherwise it returns false.
|
||||
bool StorageOptimized() const {return(CrsGraphData_->StorageOptimized_);}
|
||||
|
||||
//! If column indices are in global range, this query returns true, otherwise it returns false.
|
||||
bool IndicesAreGlobal() const {return(CrsGraphData_->IndicesAreGlobal_);}
|
||||
|
||||
//! If column indices are in local range, this query returns true, otherwise it returns false.
|
||||
bool IndicesAreLocal() const {return(CrsGraphData_->IndicesAreLocal_);}
|
||||
|
||||
//! If graph is lower triangular in local index space, this query returns true, otherwise it returns false.
|
||||
/*!
|
||||
\pre Filled()==true
|
||||
*/
|
||||
bool LowerTriangular() const {return(CrsGraphData_->LowerTriangular_);}
|
||||
|
||||
//! If graph is upper triangular in local index space, this query returns true, otherwise it returns false.
|
||||
/*!
|
||||
\pre Filled()==true
|
||||
*/
|
||||
bool UpperTriangular() const {return(CrsGraphData_->UpperTriangular_);}
|
||||
|
||||
//! If graph has no diagonal entries in global index space, this query returns true, otherwise it returns false.
|
||||
/*!
|
||||
\pre Filled()==true
|
||||
*/
|
||||
bool NoDiagonal() const {return(CrsGraphData_->NoDiagonal_);}
|
||||
|
||||
//! Returns true of GID is owned by the calling processor, otherwise it returns false.
|
||||
bool MyGlobalRow(int GID) const {return(RowMap().MyGID(GID));}
|
||||
|
||||
//! Returns true if we have a well-defined ColMap, and returns false otherwise.
|
||||
/*! \pre We have a well-defined ColMap if a) a ColMap was passed in at construction,
|
||||
or b) the MakeColMap function has been called. (Calling either of the FillComplete functions
|
||||
will result in MakeColMap being called.)
|
||||
*/
|
||||
bool HaveColMap() const {return(CrsGraphData_->HaveColMap_);}
|
||||
//@}
|
||||
|
||||
//! @name Atribute access functions
|
||||
//@{
|
||||
|
||||
//! Returns the number of matrix rows on this processor.
|
||||
int NumMyRows() const {return(CrsGraphData_->NumMyRows_);}
|
||||
|
||||
//! Returns the number of matrix rows in global matrix.
|
||||
int NumGlobalRows() const {return(CrsGraphData_->NumGlobalRows_);}
|
||||
|
||||
//! Returns the number of entries in the set of column-indices that appear on this processor.
|
||||
/*! The set of column-indices that appear on this processor is the union of column-indices that
|
||||
appear in all local rows. The size of this set isn't available until FillComplete() has been called.
|
||||
\pre Filled()==true
|
||||
*/
|
||||
int NumMyCols() const {return(CrsGraphData_->NumMyCols_);}
|
||||
|
||||
//! Returns the number of matrix columns in global matrix.
|
||||
/*!
|
||||
\pre Filled()==true
|
||||
*/
|
||||
int NumGlobalCols() const {return(CrsGraphData_->NumGlobalCols_);}
|
||||
|
||||
//! Returns the number of indices in the global graph.
|
||||
/*! Note that if the graph's maps are defined such that some nonzeros
|
||||
appear on more than one processor, then those nonzeros will be
|
||||
counted more than once. If the user wishes to assemble a graph from
|
||||
overlapping data, they can use Epetra_FECrsGraph.
|
||||
\pre Filled()==true
|
||||
*/
|
||||
int NumGlobalNonzeros() const {return(CrsGraphData_->NumGlobalNonzeros_);}
|
||||
|
||||
//! Returns the number of diagonal entries in the global graph, based on global row/column index comparisons.
|
||||
/*!
|
||||
\pre Filled()==true
|
||||
*/
|
||||
int NumGlobalDiagonals() const {return(CrsGraphData_->NumGlobalDiagonals_);}
|
||||
|
||||
//! Returns the number of diagonal entries in the local graph, based on global row/column index comparisons.
|
||||
/*!
|
||||
\pre Filled()==true
|
||||
*/
|
||||
int NumMyDiagonals() const {return(CrsGraphData_->NumMyDiagonals_);}
|
||||
|
||||
//! Returns the number of block matrix rows on this processor.
|
||||
int NumMyBlockRows() const {return(CrsGraphData_->NumMyBlockRows_);}
|
||||
|
||||
//! Returns the number of Block matrix rows in global matrix.
|
||||
int NumGlobalBlockRows() const {return(CrsGraphData_->NumGlobalBlockRows_);}
|
||||
|
||||
//! Returns the number of Block matrix columns on this processor.
|
||||
/*!
|
||||
\pre Filled()==true
|
||||
*/
|
||||
int NumMyBlockCols() const {return(CrsGraphData_->NumMyBlockCols_);}
|
||||
|
||||
//! Returns the number of Block matrix columns in global matrix.
|
||||
/*!
|
||||
\pre Filled()==true
|
||||
*/
|
||||
int NumGlobalBlockCols() const {return(CrsGraphData_->NumGlobalBlockCols_);}
|
||||
|
||||
//! Returns the number of Block diagonal entries in the local graph, based on global row/column index comparisons.
|
||||
/*!
|
||||
\pre Filled()==true
|
||||
*/
|
||||
int NumMyBlockDiagonals() const {return(CrsGraphData_->NumMyBlockDiagonals_);}
|
||||
|
||||
//! Returns the number of Block diagonal entries in the global graph, based on global row/column index comparisons.
|
||||
/*!
|
||||
\pre Filled()==true
|
||||
*/
|
||||
int NumGlobalBlockDiagonals() const {return(CrsGraphData_->NumGlobalBlockDiagonals_);}
|
||||
|
||||
//! Returns the number of entries in the global graph.
|
||||
/*!
|
||||
\pre Filled()==true
|
||||
*/
|
||||
int NumGlobalEntries() const {return(CrsGraphData_->NumGlobalEntries_);}
|
||||
|
||||
//! Returns the number of entries on this processor.
|
||||
/*!
|
||||
\pre Filled()==true
|
||||
*/
|
||||
int NumMyEntries() const {return(CrsGraphData_->NumMyEntries_);}
|
||||
//! Returns the max row dimension of block entries on the processor.
|
||||
/*!
|
||||
\pre Filled()==true
|
||||
*/
|
||||
int MaxRowDim() const {return(CrsGraphData_->MaxRowDim_);}
|
||||
|
||||
//! Returns the max row dimension of block entries across all processors.
|
||||
/*!
|
||||
\pre Filled()==true
|
||||
*/
|
||||
int GlobalMaxRowDim() const {return(CrsGraphData_->GlobalMaxRowDim_);}
|
||||
|
||||
//! Returns the max column dimension of block entries on the processor.
|
||||
/*!
|
||||
\pre Filled()==true
|
||||
*/
|
||||
int MaxColDim() const {return(CrsGraphData_->MaxColDim_);}
|
||||
|
||||
//! Returns the max column dimension of block entries across all processors.
|
||||
/*!
|
||||
\pre Filled()==true
|
||||
*/
|
||||
int GlobalMaxColDim() const {return(CrsGraphData_->GlobalMaxColDim_);}
|
||||
|
||||
//! Returns the number of indices in the local graph.
|
||||
/*!
|
||||
\pre Filled()==true
|
||||
*/
|
||||
int NumMyNonzeros() const {return(CrsGraphData_->NumMyNonzeros_);}
|
||||
|
||||
//! Returns the current number of nonzero entries in specified global row on this processor.
|
||||
int NumGlobalIndices(int Row) const;
|
||||
|
||||
//! Returns the allocated number of nonzero entries in specified global row on this processor.
|
||||
int NumAllocatedGlobalIndices(int Row) const;
|
||||
|
||||
//! Returns the maximum number of nonzero entries across all rows on this processor.
|
||||
/*!
|
||||
\pre Filled()==true
|
||||
*/
|
||||
int MaxNumIndices() const {return(CrsGraphData_->MaxNumIndices_);}
|
||||
|
||||
//! Returns the maximun number of nonzero entries across all rows across all processors.
|
||||
/*!
|
||||
\pre Filled()==true
|
||||
*/
|
||||
int GlobalMaxNumIndices() const {return(CrsGraphData_->GlobalMaxNumIndices_);}
|
||||
|
||||
//! Returns the maximum number of nonzero points across all rows on this processor.
|
||||
/*! For each entry in the graph, let i = the GRID of the entry and j = the CGID of the entry. Then
|
||||
the entry size is the product of the rowmap elementsize of i and the colmap elementsize of i.
|
||||
Let ki = sum of all entry sizes for the entries in the ith row.
|
||||
For example,
|
||||
if the ith block row had 5 block entries and the element size of each entry was 4-by-4, ki would be 80.
|
||||
Then this function returns the max over all ki for all row on this processor.
|
||||
|
||||
\pre Filled()==true
|
||||
*/
|
||||
int MaxNumNonzeros() const {return(CrsGraphData_->MaxNumNonzeros_);}
|
||||
|
||||
//! Returns the maximun number of nonzero points across all rows across all processors.
|
||||
/*! This function returns the max over all processor of MaxNumNonzeros().
|
||||
|
||||
\pre Filled()==true
|
||||
*/
|
||||
int GlobalMaxNumNonzeros() const {return(CrsGraphData_->GlobalMaxNumNonzeros_);}
|
||||
|
||||
//! Returns the current number of nonzero entries in specified local row on this processor.
|
||||
int NumMyIndices(int Row) const {if (Row<0 || Row >= NumMyRows()) return(0);
|
||||
if (StorageOptimized()) return(CrsGraphData_->IndexOffset_[Row+1] - CrsGraphData_->IndexOffset_[Row]);
|
||||
else return(CrsGraphData_->NumIndicesPerRow_[Row]);}
|
||||
|
||||
//! Returns the allocated number of nonzero entries in specified local row on this processor.
|
||||
int NumAllocatedMyIndices(int Row) const {if (Row<0 || Row >= NumMyRows()) return(0);
|
||||
if (StorageOptimized()) return(CrsGraphData_->IndexOffset_[Row+1] - CrsGraphData_->IndexOffset_[Row]);
|
||||
else return(CrsGraphData_->NumAllocatedIndicesPerRow_[Row]);}
|
||||
|
||||
//! Returns the index base for row and column indices for this graph.
|
||||
int IndexBase() const {return(CrsGraphData_->IndexBase_);}
|
||||
|
||||
//! Returns the RowMap associated with this graph.
|
||||
const Epetra_BlockMap& RowMap() const {return(Epetra_DistObject::Map());}
|
||||
|
||||
/** Replaces the current RowMap with the user-specified map object, but only
|
||||
if currentmap->PointSameAs(newmap) is true. This is a collective function.
|
||||
Returns 0 if map is replaced, -1 if not.
|
||||
|
||||
\pre RowMap().PointSameAs(newmap)==true
|
||||
*/
|
||||
int ReplaceRowMap(const Epetra_BlockMap& newmap);
|
||||
|
||||
/** Replaces the current ColMap with the user-specified map object, but only
|
||||
if currentmap->PointSameAs(newmap) is true. This is a collective function.
|
||||
Returns 0 if map is replaced, -1 if not.
|
||||
|
||||
\pre ColMap().PointSameAs(newmap)==true
|
||||
*/
|
||||
int ReplaceColMap(const Epetra_BlockMap& newmap);
|
||||
|
||||
//! Returns the Column Map associated with this graph.
|
||||
/*!
|
||||
\pre HaveColMap()==true
|
||||
*/
|
||||
const Epetra_BlockMap& ColMap() const {return(CrsGraphData_->ColMap_);}
|
||||
|
||||
//! Returns the DomainMap associated with this graph.
|
||||
/*!
|
||||
\pre Filled()==true
|
||||
*/
|
||||
const Epetra_BlockMap& DomainMap() const {return(CrsGraphData_->DomainMap_);}
|
||||
|
||||
//! Returns the RangeMap associated with this graph.
|
||||
/*!
|
||||
\pre Filled()==true
|
||||
*/
|
||||
const Epetra_BlockMap& RangeMap() const {return(CrsGraphData_->RangeMap_);}
|
||||
|
||||
//! Returns the Importer associated with this graph.
|
||||
const Epetra_Import* Importer() const {return(CrsGraphData_->Importer_);}
|
||||
|
||||
//! Returns the Exporter associated with this graph.
|
||||
const Epetra_Export* Exporter() const {return(CrsGraphData_->Exporter_);}
|
||||
|
||||
//! Returns a pointer to the Epetra_Comm communicator associated with this graph.
|
||||
const Epetra_Comm& Comm() const {return(Epetra_DistObject::Comm());}
|
||||
//@}
|
||||
|
||||
//! @name Local/Global ID methods
|
||||
//@{
|
||||
|
||||
//! Returns the local row index for given global row index, returns -1 if no local row for this global row.
|
||||
int LRID(int GRID) const {return(RowMap().LID(GRID));}
|
||||
|
||||
//! Returns the global row index for give local row index, returns IndexBase-1 if we don't have this local row.
|
||||
int GRID(int LRID) const {return(RowMap().GID(LRID));}
|
||||
|
||||
//! Returns the local column index for given global column index, returns -1 if no local column for this global column.
|
||||
/*!
|
||||
\pre HaveColMap()==true (If HaveColMap()==false, returns -1)
|
||||
*/
|
||||
int LCID(int GCID) const
|
||||
{
|
||||
return( CrsGraphData_->HaveColMap_ ? ColMap().LID(GCID) : -1 );
|
||||
}
|
||||
|
||||
//! Returns the global column index for give local column index, returns IndexBase-1 if we don't have this local column.
|
||||
/*!
|
||||
\pre HaveColMap()==true (If HaveColMap()==false, returns -1)
|
||||
*/
|
||||
int GCID(int LCID) const
|
||||
{
|
||||
return( CrsGraphData_->HaveColMap_ ? ColMap().GID(LCID) : -1 );
|
||||
}
|
||||
|
||||
//! Returns true if the GRID passed in belongs to the calling processor in this map, otherwise returns false.
|
||||
bool MyGRID(int GRID) const {return(LRID(GRID) != -1);}
|
||||
|
||||
//! Returns true if the LRID passed in belongs to the calling processor in this map, otherwise returns false.
|
||||
bool MyLRID(int LRID) const {return(GRID(LRID) != IndexBase() - 1);}
|
||||
|
||||
//! Returns true if the GCID passed in belongs to the calling processor in this map, otherwise returns false.
|
||||
/*!
|
||||
\pre HaveColMap()==true (If HaveColMap()==false, returns -1)
|
||||
*/
|
||||
bool MyGCID(int GCID) const {return(LCID(GCID) != -1);}
|
||||
|
||||
//! Returns true if the LRID passed in belongs to the calling processor in this map, otherwise returns false.
|
||||
/*!
|
||||
\pre HaveColMap()==true (If HaveColMap()==false, returns -1)
|
||||
*/
|
||||
bool MyLCID(int LCID) const {return(GCID(LCID) != IndexBase() - 1);}
|
||||
//@}
|
||||
|
||||
//! @name Inlined Operator Methods
|
||||
//@{
|
||||
|
||||
//! Inlined bracket operator for fast access to data. (Const and Non-const versions)
|
||||
/*! No error checking and dangerous for optimization purposes.
|
||||
\param Loc (In) - Local row.
|
||||
|
||||
\return reference to pointer to locally indexed Loc row in matrix.
|
||||
*/
|
||||
|
||||
inline int* operator[]( int Loc ) {
|
||||
if (StorageOptimized()){ return(CrsGraphData_->All_Indices_.Values() + CrsGraphData_->IndexOffset_[Loc]);}
|
||||
else return(CrsGraphData_->Indices_[Loc]); }
|
||||
|
||||
inline int* operator[]( int Loc ) const {
|
||||
if (StorageOptimized()) { return(CrsGraphData_->All_Indices_.Values() +CrsGraphData_->IndexOffset_[Loc]);}
|
||||
else return(CrsGraphData_->Indices_[Loc]); }
|
||||
|
||||
//@}
|
||||
|
||||
//! Assignment operator
|
||||
/*! This will do a Level 1 deep copy. It will share ownership of the CrsGraphData
|
||||
with the right hand side Graph.
|
||||
*/
|
||||
Epetra_CrsGraph& operator = (const Epetra_CrsGraph& Source);
|
||||
|
||||
//! @name I/O Methods
|
||||
//@{
|
||||
|
||||
//! Print method
|
||||
virtual void Print(ostream& os) const;
|
||||
|
||||
void PrintGraphData(ostream& os) const {CrsGraphData_->Print(os);}
|
||||
void PrintGraphData(ostream& os, int level) const {CrsGraphData_->Print(os, level);}
|
||||
//@}
|
||||
|
||||
//! @name Deprecated methods: These methods still work, but will be removed in a future version
|
||||
//@{
|
||||
|
||||
//! Use ColMap() instead.
|
||||
const Epetra_BlockMap& ImportMap() const {return(CrsGraphData_->ColMap_);}
|
||||
|
||||
//! Use FillComplete() instead.
|
||||
int TransformToLocal();
|
||||
|
||||
//! Use FillComplete(const Epetra_BlockMap& DomainMap, const Epetra_BlockMap& RangeMap) instead.
|
||||
int TransformToLocal(const Epetra_BlockMap* DomainMap, const Epetra_BlockMap* RangeMap);
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Expert Users and Developers Only
|
||||
//@{
|
||||
|
||||
//! Returns the reference count of CrsGraphData.
|
||||
/*! (Intended for testing purposes.) */
|
||||
int ReferenceCount() const {return(CrsGraphData_->ReferenceCount());}
|
||||
|
||||
//! Returns a pointer to the CrsGraphData instance this CrsGraph uses.
|
||||
/*! (Intended for developer use only for testing purposes.) */
|
||||
const Epetra_CrsGraphData* DataPtr() const {return(CrsGraphData_);}
|
||||
|
||||
//@}
|
||||
|
||||
// functions listed in protected are the ones used by CrsMatrix and VbrMatrix.
|
||||
// functions listed in private are the ones that are really private.
|
||||
// (just pretend CrsMatrix and VbrMatrix derive from CrsGraph to understand the distinction.)
|
||||
friend class Epetra_CrsMatrix;
|
||||
friend class Epetra_VbrMatrix;
|
||||
friend class Epetra_FECrsGraph;
|
||||
friend class Epetra_FECrsMatrix;
|
||||
friend class Epetra_FEVbrMatrix;
|
||||
friend class Epetra_OffsetIndex;
|
||||
|
||||
protected:
|
||||
int *All_Indices() const {
|
||||
if (!StorageOptimized()) throw ReportError("This method: int *All_Indices() cannot be called when StorageOptimized()==false", -1);
|
||||
else return(CrsGraphData_->All_Indices_.Values());}
|
||||
int *IndexOffset() const {
|
||||
if (!StorageOptimized()) throw ReportError("This method: int *IndexOffset() cannot be called when StorageOptimized()==false", -1);
|
||||
else return(CrsGraphData_->IndexOffset_.Values());}
|
||||
int* NumIndicesPerRow() const {
|
||||
if (StorageOptimized()) throw ReportError("This method: int* NumIndicesPerRow() cannot be called when StorageOptimized()==true", -1);
|
||||
else return(CrsGraphData_->NumIndicesPerRow_.Values());}
|
||||
int* NumAllocatedIndicesPerRow() const {
|
||||
if (StorageOptimized()) throw ReportError("This method: int* NumAllocatedIndicesPerRow() cannot be called when StorageOptimized()==true", -1);
|
||||
else return(CrsGraphData_->NumAllocatedIndicesPerRow_.Values());}
|
||||
int** Indices() const {
|
||||
if (StorageOptimized()) throw ReportError("This method: int** Indices() cannot be called when StorageOptimized()==true", -1);
|
||||
else return(CrsGraphData_->Indices_);}
|
||||
int* Indices(int LocalRow) const {
|
||||
if (StorageOptimized()) return(CrsGraphData_->All_Indices_.Values()+CrsGraphData_->IndexOffset_[LocalRow]);
|
||||
else return(CrsGraphData_->Indices_[LocalRow]);}
|
||||
// If column indices are stored in one long array (via a call to OptimizeStorage),
|
||||
// IndicesAreContiguous returns true, otherwise it returns false.
|
||||
bool IndicesAreContiguous() const {return(CrsGraphData_->IndicesAreContiguous_);}
|
||||
bool StaticProfile() const {return(CrsGraphData_->StaticProfile_);}
|
||||
bool GlobalConstantsComputed() const;
|
||||
bool FindGlobalIndexLoc(int LocalRow, int Index, int Start, int& Loc) const;
|
||||
bool FindGlobalIndexLoc(int NumIndices, const int* Indices, int Index, int Start, int& Loc) const;
|
||||
bool FindMyIndexLoc(int LocalRow, int Index, int Start, int& Loc) const;
|
||||
bool FindMyIndexLoc(int NumIndices, const int* Indices, int Index, int Start, int& Loc) const;
|
||||
int InsertIndices(int Row, int NumIndices, int* Indices);
|
||||
int MakeIndicesLocal(const Epetra_BlockMap& DomainMap, const Epetra_BlockMap& RangeMap);
|
||||
void SetIndicesAreLocal(bool Flag) {CrsGraphData_->IndicesAreLocal_ = Flag;}
|
||||
void SetIndicesAreGlobal(bool Flag) {CrsGraphData_->IndicesAreGlobal_ = Flag;}
|
||||
void SetSorted(bool Flag) {CrsGraphData_->Sorted_ = Flag;}
|
||||
|
||||
//! Sort column indices, row-by-row, in ascending order.
|
||||
/*!
|
||||
\return Integer error code, set to 0 if successful. Returns 1 if data is shared.
|
||||
*/
|
||||
int SortIndices();
|
||||
|
||||
//! If SortIndices() has been called, this query returns true, otherwise it returns false.
|
||||
bool Sorted() const {return(CrsGraphData_->Sorted_);}
|
||||
|
||||
//! Removes any redundant column indices in the rows of the graph.
|
||||
/*!
|
||||
\return Integer error code, set to 0 if successful. Returns 1 if data is shared.
|
||||
*/
|
||||
int RemoveRedundantIndices();
|
||||
|
||||
//! If RemoveRedundantIndices() has been called, this query returns true, otherwise it returns false.
|
||||
bool NoRedundancies() const {return(CrsGraphData_->NoRedundancies_);}
|
||||
|
||||
private:
|
||||
void SetGlobalConstantsComputed(bool Flag) {CrsGraphData_->GlobalConstantsComputed_ = Flag;}
|
||||
void SetIndicesAreContiguous(bool Flag) {CrsGraphData_->IndicesAreContiguous_ = Flag;}
|
||||
void SetNoRedundancies(bool Flag) {CrsGraphData_->NoRedundancies_ = Flag;}
|
||||
void ComputeIndexState();
|
||||
int MakeColMap(const Epetra_BlockMap& DomainMap, const Epetra_BlockMap& RangeMap);
|
||||
int Allocate(const int* NumIndicesPerRow, int Inc, bool StaticProfile);
|
||||
//int ReAllocate();
|
||||
int ComputeGlobalConstants();
|
||||
void SetFilled(bool Flag) {CrsGraphData_->Filled_ = Flag;}
|
||||
bool Allocated() const {return(CrsGraphData_->Allocated_);}
|
||||
void SetAllocated(bool Flag) {CrsGraphData_->Allocated_ = Flag;}
|
||||
|
||||
int CheckSizes(const Epetra_SrcDistObject& A);
|
||||
|
||||
int CopyAndPermute(const Epetra_SrcDistObject& Source,
|
||||
int NumSameIDs,
|
||||
int NumPermuteIDs,
|
||||
int* PermuteToLIDs,
|
||||
int* PermuteFromLIDs,
|
||||
const Epetra_OffsetIndex * Indexor);
|
||||
int CopyAndPermuteRowMatrix(const Epetra_RowMatrix& A,
|
||||
int NumSameIDs,
|
||||
int NumPermuteIDs,
|
||||
int* PermuteToLIDs,
|
||||
int* PermuteFromLIDs,
|
||||
const Epetra_OffsetIndex * Indexor);
|
||||
int CopyAndPermuteCrsGraph(const Epetra_CrsGraph& A,
|
||||
int NumSameIDs,
|
||||
int NumPermuteIDs,
|
||||
int* PermuteToLIDs,
|
||||
int* PermuteFromLIDs,
|
||||
const Epetra_OffsetIndex * Indexor);
|
||||
|
||||
int PackAndPrepare(const Epetra_SrcDistObject& Source,
|
||||
int NumExportIDs,
|
||||
int* ExportLIDs,
|
||||
int& LenExports,
|
||||
char*& Exports,
|
||||
int& SizeOfPacket,
|
||||
int * Sizes,
|
||||
bool & VarSizes,
|
||||
Epetra_Distributor& Distor);
|
||||
int PackAndPrepareCrsGraph(const Epetra_CrsGraph& A,
|
||||
int NumExportIDs,
|
||||
int* ExportLIDs,
|
||||
int& LenExports,
|
||||
char*& Exports,
|
||||
int& SizeOfPacket,
|
||||
int* Sizes,
|
||||
bool& VarSizes,
|
||||
Epetra_Distributor& Distor);
|
||||
int PackAndPrepareRowMatrix(const Epetra_RowMatrix& A,
|
||||
int NumExportIDs,
|
||||
int* ExportLIDs,
|
||||
int& LenExports,
|
||||
char*& Exports,
|
||||
int& SizeOfPacket,
|
||||
int* Sizes,
|
||||
bool& VarSizes,
|
||||
Epetra_Distributor& Distor);
|
||||
|
||||
int UnpackAndCombine(const Epetra_SrcDistObject& Source,
|
||||
int NumImportIDs,
|
||||
int* ImportLIDs,
|
||||
int LenImports,
|
||||
char* Imports,
|
||||
int& SizeOfPacket,
|
||||
Epetra_Distributor& Distor,
|
||||
Epetra_CombineMode CombineMode,
|
||||
const Epetra_OffsetIndex * Indexor);
|
||||
|
||||
void CleanupData();
|
||||
|
||||
Epetra_CrsGraphData* CrsGraphData_;
|
||||
|
||||
};
|
||||
#endif /* EPETRA_CRSGRAPH_H */
|
||||
@@ -0,0 +1,156 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_CRSGRAPHDATA_H
|
||||
#define EPETRA_CRSGRAPHDATA_H
|
||||
|
||||
#include "Epetra_Data.h"
|
||||
#include "Epetra_DataAccess.h"
|
||||
#include "Epetra_BlockMap.h"
|
||||
#include "Epetra_IntSerialDenseVector.h"
|
||||
class Epetra_Import;
|
||||
class Epetra_Export;
|
||||
|
||||
//! Epetra_CrsGraphData: The Epetra CrsGraph Data Class.
|
||||
/*! The Epetra_CrsGraphData class is an implementation detail of Epetra_CrsGraph.
|
||||
It is reference-counted, and can be shared by multiple Epetra_CrsGraph instances.
|
||||
It derives from Epetra_Data, and inherits reference-counting from it.
|
||||
*/
|
||||
|
||||
class Epetra_CrsGraphData : public Epetra_Data {
|
||||
friend class Epetra_CrsGraph;
|
||||
|
||||
private:
|
||||
|
||||
//! @name Constructor/Destructor Methods
|
||||
//@{
|
||||
|
||||
//! Epetra_CrsGraphData Default Constructor.
|
||||
Epetra_CrsGraphData(Epetra_DataAccess CV, const Epetra_BlockMap& RowMap, bool StaticProfile);
|
||||
|
||||
//! Epetra_CrsGraphData Constructor (user provided ColMap).
|
||||
Epetra_CrsGraphData(Epetra_DataAccess CV, const Epetra_BlockMap& RowMap, const Epetra_BlockMap& ColMap, bool StaticProfile);
|
||||
|
||||
//! Epetra_CrsGraphData copy constructor (not defined).
|
||||
Epetra_CrsGraphData(const Epetra_CrsGraphData& CrsGraphData);
|
||||
|
||||
//! Epetra_CrsGraphData Destructor.
|
||||
~Epetra_CrsGraphData();
|
||||
|
||||
//@}
|
||||
|
||||
//! Outputs state of almost all data members. (primarily used for testing purposes).
|
||||
/*! Output level: Uses same scheme as chmod. 4-bit = BlockMaps, 2-bit = Indices, 1-bit = Everything else.
|
||||
Default paramenter sets it to 3, which is everything but the BlockMaps. Commonly used options:
|
||||
1 = Everything except the BlockMaps & Indices_
|
||||
2 = Just Indices_
|
||||
3 = Everything except the BlockMaps
|
||||
*/
|
||||
void Print(ostream& os, int level = 3) const;
|
||||
|
||||
//! Epetra_CrsGraphData assignment operator (not defined)
|
||||
Epetra_CrsGraphData& operator=(const Epetra_CrsGraphData& CrsGraphData);
|
||||
|
||||
//! @name Helper methods called in CrsGraph. Mainly memory allocations and deallocations.
|
||||
//@{
|
||||
|
||||
//! called by FillComplete (and TransformToLocal)
|
||||
int MakeImportExport();
|
||||
|
||||
//! called by PackAndPrepare
|
||||
int ReAllocateAndCast(char*& UserPtr, int& Length, const int IntPacketSizeTimesNumTrans);
|
||||
|
||||
//@}
|
||||
|
||||
// Defined by CrsGraph::FillComplete and related
|
||||
Epetra_BlockMap RowMap_;
|
||||
Epetra_BlockMap ColMap_;
|
||||
Epetra_BlockMap DomainMap_;
|
||||
Epetra_BlockMap RangeMap_;
|
||||
|
||||
const Epetra_Import* Importer_;
|
||||
const Epetra_Export* Exporter_;
|
||||
|
||||
bool HaveColMap_;
|
||||
bool Filled_;
|
||||
bool Allocated_;
|
||||
bool Sorted_;
|
||||
bool StorageOptimized_;
|
||||
bool NoRedundancies_;
|
||||
bool IndicesAreGlobal_;
|
||||
bool IndicesAreLocal_;
|
||||
bool IndicesAreContiguous_;
|
||||
bool LowerTriangular_;
|
||||
bool UpperTriangular_;
|
||||
bool NoDiagonal_;
|
||||
bool GlobalConstantsComputed_;
|
||||
bool StaticProfile_;
|
||||
|
||||
int IndexBase_;
|
||||
|
||||
int NumGlobalEntries_;
|
||||
int NumGlobalBlockRows_;
|
||||
int NumGlobalBlockCols_;
|
||||
int NumGlobalBlockDiagonals_;
|
||||
int NumMyEntries_;
|
||||
int NumMyBlockRows_;
|
||||
int NumMyBlockCols_;
|
||||
int NumMyBlockDiagonals_;
|
||||
|
||||
int MaxRowDim_;
|
||||
int MaxColDim_;
|
||||
int GlobalMaxRowDim_;
|
||||
int GlobalMaxColDim_;
|
||||
int MaxNumNonzeros_;
|
||||
int GlobalMaxNumNonzeros_;
|
||||
|
||||
int NumGlobalNonzeros_;
|
||||
int NumGlobalRows_;
|
||||
int NumGlobalCols_;
|
||||
int NumGlobalDiagonals_;
|
||||
int NumMyNonzeros_;
|
||||
int NumMyRows_;
|
||||
int NumMyCols_;
|
||||
int NumMyDiagonals_;
|
||||
|
||||
int MaxNumIndices_;
|
||||
int GlobalMaxNumIndices_;
|
||||
|
||||
int** Indices_;
|
||||
Epetra_IntSerialDenseVector NumAllocatedIndicesPerRow_;
|
||||
Epetra_IntSerialDenseVector NumIndicesPerRow_;
|
||||
Epetra_IntSerialDenseVector IndexOffset_;
|
||||
Epetra_IntSerialDenseVector All_Indices_;
|
||||
Epetra_DataAccess CV_;
|
||||
|
||||
};
|
||||
|
||||
#endif /* EPETRA_CRSGRAPHDATA_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,303 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_CRSSINGLETONFILTER_H
|
||||
#define EPETRA_CRSSINGLETONFILTER_H
|
||||
|
||||
#include "Epetra_Object.h"
|
||||
#include "Epetra_CrsMatrix.h"
|
||||
#include "Epetra_MapColoring.h"
|
||||
#include "Epetra_SerialDenseVector.h"
|
||||
class Epetra_LinearProblem;
|
||||
class Epetra_Map;
|
||||
class Epetra_MultiVector;
|
||||
class Epetra_Import;
|
||||
class Epetra_Export;
|
||||
class Epetra_IntVector;
|
||||
|
||||
//! Epetra_CrsSingletonFilter: A class for explicitly eliminating matrix rows and columns.
|
||||
|
||||
/*! The Epetra_CrsSingletonFilter class takes an existing Epetra_LinearProblem object, analyzes
|
||||
it structure and explicitly eliminates singleton rows and columns from the matrix and appropriately
|
||||
modifies the RHS and LHS of the linear problem. The result of this process is a reduced system of equations
|
||||
that is itself an Epetra_LinearProblem object. The reduced system can then be solved using any solver that
|
||||
is understands an Epetra_LinearProblem. The solution for the full system is obtained by calling ComputeFullSolution().
|
||||
|
||||
Singleton rows are defined to be rows that have a single nonzero entry in the matrix. The equation associated with
|
||||
this row can be explicitly eliminated because it involved only one variable. For example if row i has a single nonzero
|
||||
value in column j, call it A(i,j), we can explicitly solve for x(j) = b(i)/A(i,j), where b(i) is the ith entry of the RHS
|
||||
and x(j) is the jth entry of the LHS.
|
||||
|
||||
Singleton columns are defined to be columns that have a single nonzero entry in the matrix. The variable associated
|
||||
with this column is fully dependent, meaning that the solution for all other variables does not depend on it. If this
|
||||
entry is A(i,j) then the ith row and jth column can be removed from the system and x(j) can be solved after the solution
|
||||
for all other variables is determined.
|
||||
|
||||
By removing singleton rows and columns, we can often produce a reduced system that is smaller and far less dense, and in
|
||||
general having better numerical properties.
|
||||
|
||||
The basic procedure for using this class is as follows:
|
||||
<ol>
|
||||
<li> Construct full problem: Construct and Epetra_LinearProblem containing the "full" matrix, RHS and LHS. This is
|
||||
done outside of Epetra_CrsSingletonFilter class.
|
||||
Presumably, you have some reason to believe that this system may contain singletons.
|
||||
<li> Construct an Epetra_CrsSingletonFilter instance: Constructor needs no arguments.
|
||||
<li> Analyze matrix: Invoke the Analyze() method, passing in the Epetra_RowMatrix object from your full linear
|
||||
problem mentioned in the first step above.
|
||||
<li> Go/No Go decision to construct reduced problem:
|
||||
Query the results of the Analyze method using the SingletonsDetected() method. This method
|
||||
returns "true" if there were singletons found in the matrix. You can also query any of the other methods
|
||||
in the Filter Statistics section to determine if you want to proceed with the construction of the reduced system.
|
||||
<li> Construct reduced problem:
|
||||
If, in the previous step, you determine that you want to proceed with the construction of the reduced problem,
|
||||
you should next call the ConstructReducedProblem() method, passing in the full linear problem object from the first
|
||||
step. This method will use the information from the Analyze() method to construct a reduce problem that has
|
||||
explicitly eliminated the singleton rows, solved for the corresponding LHS values and updated the RHS. This
|
||||
step will also remove singleton columns from the reduced system. Once the solution of the reduced problem is
|
||||
is computed (via any solver that understands an Epetra_LinearProblem), you should call the ComputeFullSolution()
|
||||
method to compute the LHS values assocaited with the singleton columns.
|
||||
<li> Solve reduced problem: Obtain a pointer to the reduced problem using the ReducedProblem() method.
|
||||
Using the solver of your choice, solve the reduced system.
|
||||
<li> Compute solution to full problem: Once the solution the reduced problem is determined, the ComputeFullSolution()
|
||||
method will place the reduced solution values into the appropriate locations of the full solution LHS and then
|
||||
compute the values associated with column singletons. At this point, you have a complete solution to the original
|
||||
full problem.
|
||||
<li> Solve a subsequent full problem that differs from the original problem only in values: It is often the case that the
|
||||
structure of a problem will be the same for a sequence of linear problems. In this case, the UpdateReducedProblem()
|
||||
method can be useful. After going through the above process one time, if you have a linear problem that is structural
|
||||
\e identical to the previous problem, you can minimize memory and time costs by using the UpdateReducedProblem()
|
||||
method, passing in the subsequent problem. Once you have called the UpdateReducedProblem() method, you can then
|
||||
solve the reduce problem problem as you wish, and then compute the full solution as before. The pointer generated
|
||||
by ReducedProblem() will not change when UpdateReducedProblem() is called.
|
||||
</ol>
|
||||
*/
|
||||
|
||||
class Epetra_CrsSingletonFilter {
|
||||
|
||||
public:
|
||||
|
||||
//! @name Constructors/Destructor
|
||||
//@{
|
||||
//! Epetra_CrsSingletonFilter default constructor.
|
||||
Epetra_CrsSingletonFilter();
|
||||
|
||||
//! Epetra_CrsSingletonFilter Destructor
|
||||
virtual ~Epetra_CrsSingletonFilter();
|
||||
//@}
|
||||
//! @name Analyze methods
|
||||
//@{
|
||||
//! Analyze the input matrix, removing row/column pairs that have singletons.
|
||||
/*! Analyzes the user's input matrix to determine rows and columns that should be explicitly
|
||||
eliminated to create the reduced system. Look for rows and columns that have single entries.
|
||||
These rows/columns
|
||||
can easily be removed from the problem.
|
||||
The results of calling this method are two MapColoring objects accessible via RowMapColors() and
|
||||
ColMapColors() accessor methods. All rows/columns that would be eliminated in the reduced system
|
||||
have a color of 1 in the corresponding RowMapColors/ColMapColors object. All kept rows/cols have a
|
||||
color of 0.
|
||||
*/
|
||||
int Analyze(Epetra_RowMatrix * FullMatrix);
|
||||
|
||||
//! Returns true if singletons were detected in this matrix (must be called after Analyze() to be effective).
|
||||
bool SingletonsDetected() const {if (!AnalysisDone_) return(false); else return(RowMapColors_->MaxNumColors()>1);};
|
||||
//@}
|
||||
|
||||
//! @name Reduce methods
|
||||
//@{
|
||||
//! Return a reduced linear problem based on results of Analyze().
|
||||
/*! Creates a new Epetra_LinearProblem object based on the results of the Analyze phase. A pointer
|
||||
to the reduced problem is obtained via a call to ReducedProblem().
|
||||
|
||||
\return Error code, set to 0 if no error.
|
||||
*/
|
||||
int ConstructReducedProblem(Epetra_LinearProblem * Problem);
|
||||
|
||||
//! Update a reduced linear problem using new values.
|
||||
/*! Updates an existing Epetra_LinearProblem object using new matrix, LHS and RHS values. The matrix
|
||||
structure must be \e identical to the matrix that was used to construct the original reduced problem.
|
||||
|
||||
\return Error code, set to 0 if no error.
|
||||
*/
|
||||
int UpdateReducedProblem(Epetra_LinearProblem * Problem);
|
||||
|
||||
//@}
|
||||
//! @name Methods to construct Full System Solution
|
||||
//@{
|
||||
//! Compute a solution for the full problem using the solution of the reduced problem, put in LHS of FullProblem().
|
||||
/*! After solving the reduced linear system, this method can be called to compute the
|
||||
solution to the original problem, assuming the solution for the reduced system is valid. The solution of the
|
||||
unreduced, original problem will be in the LHS of the original Epetra_LinearProblem.
|
||||
|
||||
*/
|
||||
int ComputeFullSolution();
|
||||
//@}
|
||||
//! @name Filter Statistics
|
||||
//@{
|
||||
//! Return number of rows that contain a single entry, returns -1 if Analysis not performed yet.
|
||||
int NumRowSingletons() const {return(NumGlobalRowSingletons_);};
|
||||
|
||||
//! Return number of columns that contain a single entry that are \e not associated with singleton row, returns -1 if Analysis not performed yet.
|
||||
int NumColSingletons() const {return(NumGlobalColSingletons_);};
|
||||
|
||||
//! Return total number of singletons detected, returns -1 if Analysis not performed yet.
|
||||
/*! Return total number of singletons detected across all processors. This method will not return a
|
||||
valid result until after the Analyze() method is called. The dimension of the reduced system can
|
||||
be computed by subtracting this number from dimension of full system.
|
||||
\warning This method returns -1 if Analyze() method has not been called.
|
||||
*/
|
||||
int NumSingletons() const {return(NumColSingletons()+NumRowSingletons());};
|
||||
|
||||
//! Returns ratio of reduced system to full system dimensions, returns -1.0 if reduced problem not constructed.
|
||||
double RatioOfDimensions() const {return(RatioOfDimensions_);};
|
||||
|
||||
//! Returns ratio of reduced system to full system nonzero count, returns -1.0 if reduced problem not constructed.
|
||||
double RatioOfNonzeros() const {return(RatioOfNonzeros_);};
|
||||
|
||||
//@}
|
||||
//! @name Attribute Access Methods
|
||||
//@{
|
||||
|
||||
//! Returns pointer to the original unreduced Epetra_LinearProblem.
|
||||
Epetra_LinearProblem * FullProblem() const {return(FullProblem_);};
|
||||
|
||||
//! Returns pointer to the derived reduced Epetra_LinearProblem.
|
||||
Epetra_LinearProblem * ReducedProblem() const {return(ReducedProblem_);};
|
||||
|
||||
//! Returns pointer to Epetra_CrsMatrix from full problem.
|
||||
Epetra_RowMatrix * FullMatrix() const {return(FullMatrix_);};
|
||||
|
||||
//! Returns pointer to Epetra_CrsMatrix from full problem.
|
||||
Epetra_CrsMatrix * ReducedMatrix() const {return(ReducedMatrix_);};
|
||||
|
||||
//! Returns pointer to Epetra_MapColoring object: color 0 rows are part of reduced system.
|
||||
Epetra_MapColoring * RowMapColors() const {return(RowMapColors_);};
|
||||
|
||||
//! Returns pointer to Epetra_MapColoring object: color 0 columns are part of reduced system.
|
||||
Epetra_MapColoring * ColMapColors() const {return(ColMapColors_);};
|
||||
|
||||
//! Returns pointer to Epetra_Map describing the reduced system row distribution.
|
||||
Epetra_Map * ReducedMatrixRowMap() const {return(ReducedMatrixRowMap_);};
|
||||
|
||||
//! Returns pointer to Epetra_Map describing the reduced system column distribution.
|
||||
Epetra_Map * ReducedMatrixColMap() const {return(ReducedMatrixColMap_);};
|
||||
|
||||
//! Returns pointer to Epetra_Map describing the domain map for the reduced system.
|
||||
Epetra_Map * ReducedMatrixDomainMap() const {return(ReducedMatrixDomainMap_);};
|
||||
|
||||
//! Returns pointer to Epetra_Map describing the range map for the reduced system.
|
||||
Epetra_Map * ReducedMatrixRangeMap() const {return(ReducedMatrixRangeMap_);};
|
||||
//@}
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
// This pointer will be zero if full matrix is not a CrsMatrix.
|
||||
Epetra_CrsMatrix * FullCrsMatrix() const {return(FullCrsMatrix_);};
|
||||
|
||||
const Epetra_Map & FullMatrixRowMap() const {return(FullMatrix()->RowMatrixRowMap());};
|
||||
const Epetra_Map & FullMatrixColMap() const {return(FullMatrix()->RowMatrixColMap());};
|
||||
const Epetra_Map & FullMatrixDomainMap() const {return((FullMatrix()->OperatorDomainMap()));};
|
||||
const Epetra_Map & FullMatrixRangeMap() const {return((FullMatrix()->OperatorRangeMap()));};
|
||||
void InitializeDefaults();
|
||||
int ComputeEliminateMaps();
|
||||
int Setup(Epetra_LinearProblem * Problem);
|
||||
int InitFullMatrixAccess();
|
||||
int GetRow(int Row, int & NumIndices, int * & Indices);
|
||||
int GetRowGCIDs(int Row, int & NumIndices, double * & Values, int * & GlobalIndices);
|
||||
int GetRow(int Row, int & NumIndices, double * & Values, int * & Indices);
|
||||
int CreatePostSolveArrays(const Epetra_IntVector & RowIDs,
|
||||
const Epetra_MapColoring & RowMapColors,
|
||||
const Epetra_IntVector & ColProfiles,
|
||||
const Epetra_IntVector & NewColProfiles,
|
||||
const Epetra_IntVector & ColHasRowWithSingleton);
|
||||
|
||||
int ConstructRedistributeExporter(Epetra_Map * SourceMap, Epetra_Map * TargetMap,
|
||||
Epetra_Export * & RedistributeExporter,
|
||||
Epetra_Map * & RedistributeMap);
|
||||
|
||||
Epetra_LinearProblem * FullProblem_;
|
||||
Epetra_LinearProblem * ReducedProblem_;
|
||||
Epetra_RowMatrix * FullMatrix_;
|
||||
Epetra_CrsMatrix * FullCrsMatrix_;
|
||||
Epetra_CrsMatrix * ReducedMatrix_;
|
||||
Epetra_MultiVector * ReducedRHS_;
|
||||
Epetra_MultiVector * ReducedLHS_;
|
||||
|
||||
Epetra_Map * ReducedMatrixRowMap_;
|
||||
Epetra_Map * ReducedMatrixColMap_;
|
||||
Epetra_Map * ReducedMatrixDomainMap_;
|
||||
Epetra_Map * ReducedMatrixRangeMap_;
|
||||
Epetra_Map * OrigReducedMatrixDomainMap_;
|
||||
Epetra_Import * Full2ReducedRHSImporter_;
|
||||
Epetra_Import * Full2ReducedLHSImporter_;
|
||||
Epetra_Export * RedistributeDomainExporter_;
|
||||
|
||||
int * ColSingletonRowLIDs_;
|
||||
int * ColSingletonColLIDs_;
|
||||
int * ColSingletonPivotLIDs_;
|
||||
double * ColSingletonPivots_;
|
||||
|
||||
|
||||
int AbsoluteThreshold_;
|
||||
double RelativeThreshold_;
|
||||
|
||||
int NumMyRowSingletons_;
|
||||
int NumMyColSingletons_;
|
||||
int NumGlobalRowSingletons_;
|
||||
int NumGlobalColSingletons_;
|
||||
double RatioOfDimensions_;
|
||||
double RatioOfNonzeros_;
|
||||
|
||||
bool HaveReducedProblem_;
|
||||
bool UserDefinedEliminateMaps_;
|
||||
bool AnalysisDone_;
|
||||
bool SymmetricElimination_;
|
||||
|
||||
Epetra_MultiVector * tempExportX_;
|
||||
Epetra_MultiVector * tempX_;
|
||||
Epetra_MultiVector * tempB_;
|
||||
Epetra_MultiVector * RedistributeReducedLHS_;
|
||||
int * Indices_;
|
||||
Epetra_SerialDenseVector Values_;
|
||||
|
||||
Epetra_MapColoring * RowMapColors_;
|
||||
Epetra_MapColoring * ColMapColors_;
|
||||
bool FullMatrixIsCrsMatrix_;
|
||||
int MaxNumMyEntries_;
|
||||
|
||||
|
||||
private:
|
||||
//! Copy constructor (defined as private so it is unavailable to user).
|
||||
Epetra_CrsSingletonFilter(const Epetra_CrsSingletonFilter & Problem);
|
||||
Epetra_CrsSingletonFilter & operator=(const Epetra_CrsSingletonFilter & Problem);
|
||||
};
|
||||
#endif /* EPETRA_CRSSINGLETONFILTER_H */
|
||||
@@ -0,0 +1,94 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_DATA_H
|
||||
#define EPETRA_DATA_H
|
||||
|
||||
//! Epetra_Data: The Epetra Base Data Class.
|
||||
/*! The Epetra_Data class is a base class for all Epetra Data Classes.
|
||||
It provides a mechanism so that one data object can be shared by multiple
|
||||
class instances. However, it is meant only to be used internally by
|
||||
another Epetra class. It does not provide smart pointer like capabilities.
|
||||
Incrementing and decrementing the reference count, and deleting the
|
||||
data class instance (if necessary), are duties of the Epetra class
|
||||
utilizing Epetra_Data.
|
||||
|
||||
All of Epetra_Data's methods are protected. This is because Epetra_Data
|
||||
should never be used directly. Rather, a class that derives from
|
||||
Epetra_Data should be used instead. For example, Epetra_MpiCommData or
|
||||
Epetra_BlockMapData.
|
||||
|
||||
DEVELOPER NOTES:
|
||||
(1) Any class that inherits from Epetra_Data may need to define an
|
||||
assignment operator, if it adds pointers. Epetra_Data doesn't have any,
|
||||
and so the default (compiler-generated) assignment operator is good enough.
|
||||
(2) The behavior of a derived class is left up to the
|
||||
implementer(s) of that class. As such, it cannot be assumed that
|
||||
just because a class inherits from Epetra_Data, that it supports copy
|
||||
construction or assignment, or that it will perform as expected.
|
||||
*/
|
||||
|
||||
class Epetra_Data {
|
||||
protected:
|
||||
//! @name Constructor/Destructor Methods
|
||||
//@{
|
||||
|
||||
//! Epetra_Data Serial Constructor.
|
||||
Epetra_Data();
|
||||
|
||||
//! Epetra_Data Copy Constructor.
|
||||
/*! Reference count will be set to 1 on new instance.*/
|
||||
Epetra_Data(const Epetra_Data & Data);
|
||||
|
||||
//! Epetra_Data Destructor.
|
||||
virtual ~Epetra_Data();
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Reference-Counting Methods
|
||||
//@{
|
||||
|
||||
//! Increment reference count
|
||||
void IncrementReferenceCount();
|
||||
|
||||
//! Decrement reference count
|
||||
void DecrementReferenceCount();
|
||||
|
||||
//! Get reference count
|
||||
int ReferenceCount() const;
|
||||
|
||||
//@}
|
||||
|
||||
int ReferenceCount_;
|
||||
|
||||
};
|
||||
|
||||
#endif /* EPETRA_DATA_H */
|
||||
@@ -0,0 +1,49 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_DATAACCESS_H
|
||||
#define EPETRA_DATAACCESS_H
|
||||
/*! \file Epetra_DataAccess.h
|
||||
\brief Epetra_DataAccess Mode enumerable type
|
||||
*/
|
||||
|
||||
/*! \enum Epetra_DataAccess
|
||||
If set to Copy, user data will be copied at construction.
|
||||
If set to View, user data will be encapsulated and used throughout
|
||||
the life of the object.
|
||||
*/
|
||||
enum Epetra_DataAccess {Copy, /*!< User data will be copied at
|
||||
construction. */
|
||||
View /*!< User data will be encapsulated and
|
||||
used throughout the life of the object. */
|
||||
};
|
||||
|
||||
#endif // EPETRA_DATAACCESS_H
|
||||
@@ -0,0 +1,99 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_DIRECTORY_H
|
||||
#define EPETRA_DIRECTORY_H
|
||||
|
||||
class Epetra_BlockMap; // Compiler needs forward reference
|
||||
class Epetra_Map;
|
||||
|
||||
//! Epetra_Directory: This class is a pure virtual class whose interface allows Epetra_Map and Epetr_BlockMap objects to reference non-local elements.
|
||||
|
||||
/*! For Epetra_BlockMap objects, a Epetra_Directory object must be created by a call to
|
||||
the Epetra_Comm CreateDirectory method. The Directory is needed to allow referencing
|
||||
of non-local elements.
|
||||
|
||||
*/
|
||||
class Epetra_Directory {
|
||||
|
||||
public:
|
||||
|
||||
//! @name Constructors/Destructor
|
||||
//@{
|
||||
//! Epetra_Directory destructor.
|
||||
virtual ~Epetra_Directory(){}
|
||||
//@}
|
||||
|
||||
//! @name Query method
|
||||
//@{
|
||||
//! GetDirectoryEntries : Returns proc and local id info for non-local map entries
|
||||
/*! Given a list of Global Entry IDs, this function returns the list of
|
||||
processor IDs and local IDs on the owning processor that correspond
|
||||
to the list of entries. If LocalEntries is 0, then local IDs are
|
||||
not returned. If EntrySizes is nonzero, it will contain a list of corresponding
|
||||
element sizes for the requested global entries.
|
||||
\param In
|
||||
NumEntries - Number of Global IDs being passed in.
|
||||
\param In
|
||||
GlobalEntries - List of Global IDs being passed in.
|
||||
\param InOut
|
||||
Procs - User allocated array of length at least NumEntries. On return contains list of processors
|
||||
owning the Global IDs in question.
|
||||
\param InOut
|
||||
LocalEntries - User allocated array of length at least NumEntries. On return contains the local ID of
|
||||
the global on the owning processor. If LocalEntries is zero, no local ID information is returned.
|
||||
\param InOut
|
||||
EntrySizes - User allocated array of length at least NumEntries. On return contains the size of the
|
||||
object associated with this global ID. If LocalEntries is zero, no size information is returned.
|
||||
|
||||
\param In
|
||||
high_rank_sharing_procs Optional argument, defaults to true. If any GIDs appear on multiple
|
||||
processors (referred to as "sharing procs"), this specifies whether the lowest-rank proc or the
|
||||
highest-rank proc is chosen as the "owner".
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual int GetDirectoryEntries( const Epetra_BlockMap& Map,
|
||||
const int NumEntries,
|
||||
const int * GlobalEntries,
|
||||
int * Procs,
|
||||
int * LocalEntries,
|
||||
int * EntrySizes,
|
||||
bool high_rank_sharing_procs=false) const = 0;
|
||||
|
||||
//!GIDsAllUniquelyOwned: returns true if all GIDs appear on just one processor.
|
||||
/*! If any GIDs are owned by multiple processors, returns false.
|
||||
*/
|
||||
virtual bool GIDsAllUniquelyOwned() const = 0;
|
||||
//@}
|
||||
};
|
||||
|
||||
#endif /* EPETRA_DIRECTORY_H */
|
||||
@@ -0,0 +1,270 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_DISTOBJECT_H
|
||||
#define EPETRA_DISTOBJECT_H
|
||||
#include "Epetra_Object.h"
|
||||
#include "Epetra_SrcDistObject.h"
|
||||
#include "Epetra_BlockMap.h"
|
||||
class Epetra_Comm;
|
||||
class Epetra_Import;
|
||||
class Epetra_Export;
|
||||
class Epetra_Distributor;
|
||||
class Epetra_OffsetIndex;
|
||||
|
||||
//! Epetra_DistObject: A class for constructing and using dense multi-vectors, vectors and matrices in parallel.
|
||||
|
||||
/*! The Epetra_DistObject is a base class for all Epetra distributed global objects. It provides the basic
|
||||
mechanisms and interface specifications for importing and exporting operations using Epetra_Import and
|
||||
Epetra_Export objects.
|
||||
|
||||
<b> Distributed Global vs. Replicated Local.</b>
|
||||
|
||||
<ul>
|
||||
<li> Distributed Global objects - In most instances, a distributed object will be partitioned
|
||||
across multiple memory images associated with multiple processors. In this case, there is
|
||||
a unique copy of each element and elements are spread across all processors specified by
|
||||
the Epetra_Comm communicator.
|
||||
<li> Replicated Local Objects - Some algorithms use objects that are too small to
|
||||
be distributed across all processors, the Hessenberg matrix in a GMRES
|
||||
computation. In other cases, such as with block iterative methods, block dot product
|
||||
functions produce small
|
||||
dense matrices that are required by all processors. Replicated local objectss handle
|
||||
these types of situation.
|
||||
</ul>
|
||||
|
||||
*/
|
||||
|
||||
//==========================================================================
|
||||
class Epetra_DistObject: public Epetra_Object, public virtual Epetra_SrcDistObject {
|
||||
|
||||
public:
|
||||
//! @name Constructors/Destructor
|
||||
//@{
|
||||
//! Basic Epetra_DistObject constuctor.
|
||||
/*! Creates a Epetra_DistObject object.
|
||||
|
||||
\param In
|
||||
Map - A Epetra_LocalMap, Epetra_Map or Epetra_BlockMap.
|
||||
|
||||
\warning Note that, because Epetra_LocalMap
|
||||
derives from Epetra_Map and Epetra_Map derives from Epetra_BlockMap, this constructor works
|
||||
for all three types of Epetra map classes.
|
||||
|
||||
\return Pointer to a Epetra_DistObject.
|
||||
|
||||
*/
|
||||
Epetra_DistObject(const Epetra_BlockMap& Map);
|
||||
|
||||
/*! Creates a Epetra_DistObject object.
|
||||
|
||||
\param In
|
||||
Map - A Epetra_LocalMap, Epetra_Map or Epetra_BlockMap.
|
||||
|
||||
\warning Note that, because Epetra_LocalMap
|
||||
derives from Epetra_Map and Epetra_Map derives from Epetra_BlockMap, this constructor works
|
||||
for all three types of Epetra map classes.
|
||||
\param In
|
||||
Label - An identifier for this object. By default, set to the name of the object class.
|
||||
|
||||
\return Pointer to a Epetra_DistObject.
|
||||
|
||||
*/
|
||||
Epetra_DistObject(const Epetra_BlockMap& Map, const char* const Label);
|
||||
|
||||
//! Epetra_DistObject copy constructor.
|
||||
|
||||
Epetra_DistObject(const Epetra_DistObject& Source);
|
||||
|
||||
|
||||
//! Epetra_DistObject destructor.
|
||||
virtual ~Epetra_DistObject();
|
||||
//@}
|
||||
|
||||
//! @name Import/Export Methods
|
||||
//@{
|
||||
|
||||
//! Imports an Epetra_DistObject using the Epetra_Import object.
|
||||
/*!
|
||||
\param In
|
||||
Source - Distributed object that will be imported into the "\e this" object.
|
||||
\param In
|
||||
Importer - A Epetra_Import object specifying the communication required.
|
||||
|
||||
\param In
|
||||
CombineMode - A Epetra_CombineMode enumerated type specifying how results should be combined on the
|
||||
receiving processor.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int Import(const Epetra_SrcDistObject& A, const Epetra_Import& Importer, Epetra_CombineMode CombineMode, const Epetra_OffsetIndex * Indexor = 0);
|
||||
|
||||
//! Imports an Epetra_DistObject using the Epetra_Export object.
|
||||
/*!
|
||||
\param In
|
||||
Source - Distributed object that will be imported into the "\e this" object.
|
||||
\param In
|
||||
Exporter - A Epetra_Export object specifying the communication required.
|
||||
|
||||
\param In
|
||||
CombineMode - A Epetra_CombineMode enumerated type specifying how results should be combined on the
|
||||
receiving processor.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int Import(const Epetra_SrcDistObject& A, const Epetra_Export& Exporter, Epetra_CombineMode CombineMode, const Epetra_OffsetIndex * Indexor = 0);
|
||||
|
||||
//! Exports an Epetra_DistObject using the Epetra_Import object.
|
||||
/*!
|
||||
\param In
|
||||
Source - Distributed object that will be exported to the "\e this" object.
|
||||
\param In
|
||||
Importer - A Epetra_Import object specifying the communication required.
|
||||
|
||||
\param In
|
||||
CombineMode - A Epetra_CombineMode enumerated type specifying how results should be combined on the
|
||||
receiving processor.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int Export(const Epetra_SrcDistObject& A, const Epetra_Import & Importer, Epetra_CombineMode CombineMode, const Epetra_OffsetIndex * Indexor = 0);
|
||||
|
||||
//! Exports an Epetra_DistObject using the Epetra_Export object.
|
||||
/*!
|
||||
\param In
|
||||
Source - Distributed object that will be exported to the "\e this" multivector.
|
||||
\param In
|
||||
Exporter - A Epetra_Export object specifying the communication required.
|
||||
|
||||
\param In
|
||||
CombineMode - A Epetra_CombineMode enumerated type specifying how results should be combined on the
|
||||
receiving processor.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int Export(const Epetra_SrcDistObject& A, const Epetra_Export& Exporter, Epetra_CombineMode CombineMode, const Epetra_OffsetIndex * Indexor = 0);
|
||||
//@}
|
||||
|
||||
//! @name Attribute accessor methods
|
||||
//@{
|
||||
//! Returns the address of the Epetra_BlockMap for this multi-vector.
|
||||
const Epetra_BlockMap& Map() const {return(Map_);};
|
||||
|
||||
//! Returns the address of the Epetra_Comm for this multi-vector.
|
||||
const Epetra_Comm& Comm() const {return(*Comm_);};
|
||||
|
||||
//! Returns true if this multi-vector is distributed global, i.e., not local replicated.
|
||||
bool DistributedGlobal() const {return(DistributedGlobal_);};
|
||||
//@}
|
||||
|
||||
//! @name Miscellaneous
|
||||
//@{
|
||||
//! Print method
|
||||
virtual void Print(ostream& os) const;
|
||||
//@}
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
//! @name Internal utilities
|
||||
//@{
|
||||
//! Perform actual transfer (redistribution) of data across memory images, using Epetra_Distributor object.
|
||||
virtual int DoTransfer(const Epetra_SrcDistObject& A,
|
||||
Epetra_CombineMode CombineMode,
|
||||
int NumSameIDs,
|
||||
int NumPermuteIDs,
|
||||
int NumRemoteIDs,
|
||||
int NumExportIDs,
|
||||
int* PermuteToLIDs,
|
||||
int* PermuteFromLIDs,
|
||||
int* RemoteLIDs,
|
||||
int* ExportLIDs,
|
||||
int& LenExports,
|
||||
char*& Exports,
|
||||
int& LenImports,
|
||||
char*& Imports,
|
||||
Epetra_Distributor& Distor,
|
||||
bool DoReverse,
|
||||
const Epetra_OffsetIndex * Indexor );
|
||||
//@}
|
||||
|
||||
// These methods must be implemented by derived class
|
||||
|
||||
//! @name Virtual methods to be implemented by derived class
|
||||
//@{
|
||||
//! Allows the source and target (\e this) objects to be compared for compatibility, return nonzero if not.
|
||||
virtual int CheckSizes(const Epetra_SrcDistObject& Source) = 0;
|
||||
//! Perform ID copies and permutations that are on processor.
|
||||
virtual int CopyAndPermute(const Epetra_SrcDistObject& Source,
|
||||
int NumSameIDs,
|
||||
int NumPermuteIDs,
|
||||
int * PermuteToLIDs,
|
||||
int * PermuteFromLIDs,
|
||||
const Epetra_OffsetIndex * Indexor) = 0;
|
||||
|
||||
//! Perform any packing or preparation required for call to DoTransfer().
|
||||
virtual int PackAndPrepare(const Epetra_SrcDistObject& Source,
|
||||
int NumExportIDs,
|
||||
int* ExportLIDs,
|
||||
int& LenExports,
|
||||
char*& Exports,
|
||||
int& SizeOfPacket,
|
||||
int* Sizes,
|
||||
bool & VarSizes,
|
||||
Epetra_Distributor& Distor) = 0;
|
||||
|
||||
//! Perform any unpacking and combining after call to DoTransfer().
|
||||
virtual int UnpackAndCombine(const Epetra_SrcDistObject& Source,
|
||||
int NumImportIDs,
|
||||
int* ImportLIDs,
|
||||
int LenImports,
|
||||
char* Imports,
|
||||
int& SizeOfPacket,
|
||||
Epetra_Distributor& Distor,
|
||||
Epetra_CombineMode CombineMode,
|
||||
const Epetra_OffsetIndex * Indexor) = 0;
|
||||
|
||||
//@}
|
||||
Epetra_BlockMap Map_;
|
||||
const Epetra_Comm* Comm_;
|
||||
bool DistributedGlobal_;
|
||||
char* Exports_;
|
||||
char* Imports_;
|
||||
int LenExports_;
|
||||
int LenImports_;
|
||||
int *Sizes_;
|
||||
|
||||
private:
|
||||
Epetra_DistObject& operator=(const Epetra_DistObject& src);
|
||||
|
||||
};
|
||||
|
||||
#endif /* EPETRA_DISTOBJECT_H */
|
||||
@@ -0,0 +1,177 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_DISTRIBUTOR_H
|
||||
#define EPETRA_DISTRIBUTOR_H
|
||||
|
||||
//! Epetra_Distributor: The Epetra Gather/Scatter Setup Base Class.
|
||||
/*! The Epetra_Distributor class is an interface that encapsulates the general
|
||||
information and services needed for other Epetra classes to perform gather/scatter
|
||||
operations on a parallel computer.
|
||||
An Epetra_Distributor object is actually produced by calling a method in the Epetra_Comm class.
|
||||
|
||||
Epetra_Distributor has default implementations, via Epetra_SerialDistributor and
|
||||
Epetra_MpiDistributor, for both serial execution and MPI
|
||||
distributed memory execution. It is meant to insulate the user from
|
||||
the specifics of communication that are not required for normal
|
||||
manipulation of linear algebra objects..
|
||||
*/
|
||||
|
||||
#include "Epetra_Object.h"
|
||||
class Epetra_Distributor {
|
||||
|
||||
public:
|
||||
//! @name Constructor and Destructor
|
||||
//@{
|
||||
//! Epetra_Distributor clone constructor.
|
||||
virtual Epetra_Distributor * Clone() = 0;
|
||||
//! Epetra_Distributor Destructor.
|
||||
virtual ~Epetra_Distributor(){};
|
||||
//@}
|
||||
|
||||
|
||||
//! @name Gather/Scatter Constructors
|
||||
//@{
|
||||
//! Create Distributor object using list of process IDs to which we export
|
||||
/*! Take a list of Process IDs and construct a plan for efficiently scattering to these processes.
|
||||
Return the number of IDs being sent to me.
|
||||
\param NumExportIDs In
|
||||
Number of IDs that need to be sent from this processor.
|
||||
\param ExportPIDs In
|
||||
List of processors that will get the exported IDs.
|
||||
\param Deterministic In
|
||||
No op.
|
||||
\param NumRemoteIDs Out
|
||||
Number of IDs this processor will be receiving.
|
||||
*/
|
||||
virtual int CreateFromSends( const int & NumExportIDs,
|
||||
const int * ExportPIDs,
|
||||
bool Deterministic,
|
||||
int & NumRemoteIDs ) = 0;
|
||||
|
||||
//! Create Distributor object using list of Remote global IDs and corresponding PIDs
|
||||
/*! Take a list of global IDs and construct a plan for efficiently scattering to these processes.
|
||||
Return the number and list of IDs being sent by me.
|
||||
\param NumRemoteIDs In
|
||||
Number of IDs this processor will be receiving.
|
||||
\param RemoteGIDs In
|
||||
List of IDs that this processor wants.
|
||||
\param RemotePIDs In
|
||||
List of processors that will send the remote IDs.
|
||||
\param Deterministic In
|
||||
No op.
|
||||
\param NumExportIDs Out
|
||||
Number of IDs that need to be sent from this processor.
|
||||
\param ExportPIDs Out
|
||||
List of processors that will get the exported IDs.
|
||||
*/
|
||||
virtual int CreateFromRecvs( const int & NumRemoteIDs,
|
||||
const int * RemoteGIDs,
|
||||
const int * RemotePIDs,
|
||||
bool Deterministic,
|
||||
int & NumExportIDs,
|
||||
int *& ExportGIDs,
|
||||
int *& ExportPIDs) = 0;
|
||||
//@}
|
||||
|
||||
//! @name Execute Gather/Scatter Operations (Constant size objects)
|
||||
//@{
|
||||
|
||||
//! Execute plan on buffer of export objects in a single step
|
||||
virtual int Do( char * export_objs,
|
||||
int obj_size,
|
||||
int & len_import_objs,
|
||||
char *& import_objs) = 0;
|
||||
|
||||
//! Execute reverse of plan on buffer of export objects in a single step
|
||||
virtual int DoReverse( char * export_objs,
|
||||
int obj_size,
|
||||
int & len_import_objs,
|
||||
char *& import_objs ) = 0;
|
||||
|
||||
//! Post buffer of export objects (can do other local work before executing Waits)
|
||||
virtual int DoPosts( char * export_objs,
|
||||
int obj_size,
|
||||
int & len_import_objs,
|
||||
char *& import_objs ) = 0;
|
||||
|
||||
//! Wait on a set of posts
|
||||
virtual int DoWaits() = 0;
|
||||
|
||||
//! Do reverse post of buffer of export objects (can do other local work before executing Waits)
|
||||
virtual int DoReversePosts( char * export_objs,
|
||||
int obj_size,
|
||||
int & len_import_objs,
|
||||
char *& import_objs) = 0;
|
||||
|
||||
//! Wait on a reverse set of posts
|
||||
virtual int DoReverseWaits() = 0;
|
||||
//@}
|
||||
|
||||
//! @name Execute Gather/Scatter Operations (Non-constant size objects)
|
||||
//@{
|
||||
|
||||
//! Execute plan on buffer of export objects in a single step (object size may vary)
|
||||
virtual int Do( char * export_objs,
|
||||
int obj_size,
|
||||
int *& sizes,
|
||||
int & len_import_objs,
|
||||
char *& import_objs) = 0;
|
||||
|
||||
//! Execute reverse of plan on buffer of export objects in a single step (object size may vary)
|
||||
virtual int DoReverse( char * export_objs,
|
||||
int obj_size,
|
||||
int *& sizes,
|
||||
int & len_import_objs,
|
||||
char *& import_objs) = 0;
|
||||
|
||||
//! Post buffer of export objects (can do other local work before executing Waits)
|
||||
virtual int DoPosts( char * export_objs,
|
||||
int obj_size,
|
||||
int *& sizes,
|
||||
int & len_import_objs,
|
||||
char *& import_objs) = 0;
|
||||
|
||||
//! Do reverse post of buffer of export objects (can do other local work before executing Waits)
|
||||
virtual int DoReversePosts( char * export_objs,
|
||||
int obj_size,
|
||||
int *& sizes,
|
||||
int & len_import_objs,
|
||||
char *& import_objs) = 0;
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Print object to an output stream
|
||||
//@{
|
||||
virtual void Print(ostream & os) const = 0;
|
||||
//@}
|
||||
};
|
||||
#endif /* EPETRA_DISTRIBUTOR_H */
|
||||
@@ -0,0 +1,300 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_EXPORT_H
|
||||
#define EPETRA_EXPORT_H
|
||||
|
||||
#include "Epetra_Object.h"
|
||||
#include "Epetra_BlockMap.h"
|
||||
|
||||
class Epetra_Distributor;
|
||||
|
||||
//! Epetra_Export: This class builds an export object for efficient exporting of off-processor elements.
|
||||
|
||||
/*! Epetra_Export is used to construct a communication plan that can be called repeatedly by computational
|
||||
classes such the Epetra matrix, vector and multivector classes to efficiently send data to a target processor.
|
||||
|
||||
This class currently has one constructor, taking two Epetra_Map or Epetra_BlockMap objects. The
|
||||
first map specifies the global IDs that are owned by the calling processor. The second map specifies
|
||||
the global IDs of elements that we want to export to later.
|
||||
*/
|
||||
|
||||
class Epetra_Export: public Epetra_Object {
|
||||
|
||||
public:
|
||||
|
||||
//! Constructs a Epetra_Export object from the source and target maps.
|
||||
/*! This constructor builds an Epetra_Export object by comparing the GID lists of the source and
|
||||
target maps.
|
||||
\param SourceMap (In) Map containing the GIDs from which data should be exported from each processor to
|
||||
the target map whenever an export operation is performed using this exporter.
|
||||
\param TargetMap (In) Map containing the GIDs that should be used for exporting data.
|
||||
|
||||
\warning Note that the TargetMap \e must have GIDs uniquely owned, each GID of the target map can occur only once.
|
||||
|
||||
Builds an export object that will transfer objects built with SourceMap to objects built with TargetMap.
|
||||
|
||||
A Epetra_Export object categorizes the elements of the target map into three sets as follows:
|
||||
<ol>
|
||||
<li> All elements in the target map that have the same GID as the corresponding element of the source map,
|
||||
starting with the first
|
||||
element in the target map, going up to the first element that is different from the source map. The number of
|
||||
these IDs is returned by NumSameIDs().
|
||||
<li> All elements that are local to the processor, but are not part of the first set of elements. These elements
|
||||
have GIDs that are owned by the calling processor, but at least the first element of this list is permuted.
|
||||
Even if subsequent elements are not permuted, they are included in this list. The number of permuted elements
|
||||
is returned by NumPermutedIDs(). The list of elements (local IDs) in the source map that are permuted can be
|
||||
found in the list PermuteFromLIDs(). The list of elements (local IDs) in the target map that are the new locations
|
||||
of the source elements can be found in the list PermuteToLIDs().
|
||||
<li> All remaining elements of the target map correspond to global IDs that are owned by remote processors. The number
|
||||
of these elements is returned by NumRemoteIDs() and the list of these is returned by RemoteLIDs().
|
||||
</ol>
|
||||
|
||||
Given the above information, the Epetra_Export constructor builds a list of elements that must be communicated to other
|
||||
processors as a result of export requests. The number of exported elements (where multiple sends of the same element
|
||||
to different processors is counted) is returned by NumExportIDs(). The local IDs to be sent are returned by the list
|
||||
ExportLIDs(). The processors to which each of the elements will be sent in returned in a list of the same length by
|
||||
ExportPIDs().
|
||||
|
||||
The total number of elements that will be sent by the calling processor is returned by NumSend(). The total number of
|
||||
elements that will be received is returned by NumRecv().
|
||||
|
||||
|
||||
The following example illustrates the basic concepts.
|
||||
|
||||
Assume we have 3 processors and 9 global elements with each processor owning 3 elements as follows
|
||||
\verbatim
|
||||
PE 0 Elements | PE 1 Elements | PE 2 Elements
|
||||
0 1 2 3 4 5 6 7 8
|
||||
\endverbatim
|
||||
|
||||
The above layout essentially defines the target map argument of the export object.
|
||||
|
||||
This could correspond to a 9-entry forcing vector with the first three entries on PE 0, and so on.
|
||||
Suppose that the entries of this forcing vector are computed by integrating over linear "hat" functions:
|
||||
|
||||
\verbatim
|
||||
^ ^ ^ ^ ^ ^ ^ ^ ^
|
||||
\/ \/ \/ \/ \/ \/ \/ \/
|
||||
/\ /\ /\ /\ /\ /\ /\ /\
|
||||
+--+--+--+--+--+--+--+--+
|
||||
0 1 2 3 4 5 6 7 8
|
||||
|
||||
|
||||
\endverbatim
|
||||
|
||||
In this case, PE 0 will make contributions to entries 0 through 3, PE 1 will make contributions to entries 2 through
|
||||
6 and PE 2 will make contributions to entries 5 through 8. A convenient way to compute these contributions is to create
|
||||
a forcing vector with replicated entries for the shared contributions. Specifically the following SourceMap works for
|
||||
this scenario:
|
||||
|
||||
\verbatim
|
||||
|
||||
PE 0 Elements | PE 1 Elements | PE 2 Elements
|
||||
0 1 2 3 2 3 4 5 6 5 6 7 8
|
||||
\endverbatim
|
||||
|
||||
A vector constructed using this SourceMap can be used to collect each processor's contributions to the forcing vector.
|
||||
Note that the ordering of the elements on each processor is not unique, but has been chosen for illustration.
|
||||
|
||||
With these two maps passed into the Epetra_Export constructor, we get the following attribute definitions:
|
||||
|
||||
On PE 0:
|
||||
|
||||
\verbatim
|
||||
NumSameIDs = 3
|
||||
|
||||
NumPermuteIDs = 0
|
||||
PermuteToLIDs = 0
|
||||
PermuteFromLIDs = 0
|
||||
|
||||
NumRemoteIDs = 1
|
||||
RemoteLIDs = [2]
|
||||
|
||||
NumExportIDs = 1
|
||||
ExportLIDs = [3]
|
||||
ExportPIDs = [1]
|
||||
|
||||
NumSend = 1
|
||||
NumRecv = 1
|
||||
|
||||
\endverbatim
|
||||
|
||||
On PE 1:
|
||||
|
||||
\verbatim
|
||||
NumSameIDs = 0
|
||||
|
||||
NumPermuteIDs = 3
|
||||
PermuteToLIDs = [0, 1, 2]
|
||||
PermuteFromLIDs = [1, 2, 3]
|
||||
|
||||
NumRemoteIDs = 2
|
||||
RemoteLIDs = [0, 2]
|
||||
|
||||
NumExportIDs = 2
|
||||
ExportLIDs = [0, 4]
|
||||
ExportPIDs = [0, 2]
|
||||
|
||||
NumSend = 2
|
||||
NumRecv = 2
|
||||
|
||||
\endverbatim
|
||||
|
||||
On PE 2:
|
||||
|
||||
\verbatim
|
||||
NumSameIDs = 0
|
||||
|
||||
NumPermuteIDs = 3
|
||||
PermuteToLIDs = [0, 1, 2]
|
||||
PermuteFromLIDs = [1, 2, 3]
|
||||
|
||||
NumRemoteIDs = 1
|
||||
RemoteLIDs = [0]
|
||||
|
||||
NumExportIDs = 1
|
||||
ExportLIDs = [0]
|
||||
ExportPIDs = [1]
|
||||
|
||||
NumSend = 1
|
||||
NumRecv = 1
|
||||
|
||||
\endverbatim
|
||||
|
||||
|
||||
<b> Using Epetra_Export Objects </b>
|
||||
|
||||
Once a Epetra_Export object has been constructed, it can be used by any of the Epetra classes that support distributed global
|
||||
objects, namely Epetra_Vector, Epetra_MultiVector, Epetra_CrsGraph, Epetra_CrsMatrix and Epetra_VbrMatrix.
|
||||
All of these classes have Export and Export methods that will fill new objects whose distribution is described by
|
||||
the target map, taking elements from the source object whose distribution is described by the source map. Details of usage
|
||||
for each class is given in the appropriate class documentation.
|
||||
|
||||
In the above example, if x_integrate is constructed using the SourceMap and then filled with local contributions, and x_force
|
||||
is constructed using the target map, the following operation will fill x_force with the combined results of x_integrate:
|
||||
\verbatim
|
||||
x_force.Export(x_integrate, exporter, Add);
|
||||
\endverbatim
|
||||
The third argument above tells the export operation to add results that come from multiple processors for the same GID.
|
||||
|
||||
Epetra_Export objects can also be used by Import operations to perform the reverse operation. For example, if x_force in the
|
||||
above example had boundary conditions that should be sent to processors that share a boundary element, the following operation
|
||||
would send replicated values to x_integrate:
|
||||
\verbatim
|
||||
x_integrate.Import(x_force, exporter, Insert);
|
||||
\endverbatim
|
||||
At the end of this operation, x_integrate would have replicated values from x_force of entries 2 and 3 on PEs 0 and 1,
|
||||
and entries 5 and 6 on PEs 1 and 2.
|
||||
|
||||
*/
|
||||
Epetra_Export( const Epetra_BlockMap & SourceMap, const Epetra_BlockMap & TargetMap );
|
||||
|
||||
//! Epetra_Export copy constructor.
|
||||
Epetra_Export(const Epetra_Export& Exporter);
|
||||
|
||||
//! Epetra_Export destructor.
|
||||
|
||||
virtual ~Epetra_Export(void);
|
||||
//! Returns the number of elements that are identical between the source and target maps, up to the first different ID
|
||||
int NumSameIDs() const {return(NumSameIDs_);};
|
||||
|
||||
//! Returns the number of elements that are local to the calling processor, but not part of the first NumSameIDs() elements.
|
||||
int NumPermuteIDs() const {return(NumPermuteIDs_);};
|
||||
|
||||
//! List of elements in the source map that are permuted.
|
||||
int * PermuteFromLIDs () const {return(PermuteFromLIDs_);};
|
||||
//! List of elements in the target map that are permuted.
|
||||
int * PermuteToLIDs () const {return(PermuteToLIDs_);};
|
||||
|
||||
//! Returns the number of elements that are not on the calling processor.
|
||||
int NumRemoteIDs() const {return(NumRemoteIDs_);};
|
||||
|
||||
//! List of elements in the target map that are coming from other processors.
|
||||
int * RemoteLIDs() const {return(RemoteLIDs_);};
|
||||
|
||||
//! Returns the number of elements that must be sent by the calling processor to other processors.
|
||||
int NumExportIDs () const {return(NumExportIDs_);};
|
||||
|
||||
//! List of elements that will be sent to other processors.
|
||||
int * ExportLIDs () const {return(ExportLIDs_);};
|
||||
|
||||
//! List of processors to which elements will be sent, ExportLIDs() [i] will be sent to processor ExportPIDs() [i].
|
||||
int * ExportPIDs () const {return(ExportPIDs_);};
|
||||
|
||||
//! Total number of elements to be sent.
|
||||
int NumSend() const {return(NumSend_);};
|
||||
|
||||
//! Total number of elements to be received.
|
||||
int NumRecv() const {return(NumRecv_);};
|
||||
|
||||
//! Returns the SourceMap used to construct this exporter
|
||||
const Epetra_BlockMap & SourceMap() const {return(SourceMap_);};
|
||||
|
||||
//! Returns the TargetMap used to construct this exporter
|
||||
const Epetra_BlockMap & TargetMap() const {return(TargetMap_);};
|
||||
|
||||
Epetra_Distributor & Distributor() const {return(*Distor_);};
|
||||
|
||||
//! @name Print object to an output stream
|
||||
//@{
|
||||
virtual void Print(ostream & os) const;
|
||||
//@}
|
||||
protected:
|
||||
|
||||
friend class Epetra_BlockMap;
|
||||
|
||||
private:
|
||||
Epetra_Export& operator=(const Epetra_Export& src);
|
||||
|
||||
Epetra_BlockMap TargetMap_;
|
||||
Epetra_BlockMap SourceMap_;
|
||||
|
||||
int NumSameIDs_;
|
||||
int NumPermuteIDs_;
|
||||
int * PermuteToLIDs_;
|
||||
int * PermuteFromLIDs_;
|
||||
int NumRemoteIDs_;
|
||||
int * RemoteLIDs_;
|
||||
|
||||
int NumExportIDs_;
|
||||
int * ExportLIDs_;
|
||||
int * ExportPIDs_;
|
||||
|
||||
int NumSend_;
|
||||
int NumRecv_;
|
||||
|
||||
Epetra_Distributor * Distor_;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif /* EPETRA_EXPORT_H */
|
||||
@@ -0,0 +1,176 @@
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_FECRSGRAPH_H
|
||||
#define EPETRA_FECRSGRAPH_H
|
||||
|
||||
#include "Epetra_Map.h"
|
||||
#include "Epetra_CrsGraph.h"
|
||||
|
||||
/**
|
||||
Epetra Finite-Element CrsGraph. This class provides the ability to insert
|
||||
indices into a matrix-graph, where the indices represent dense submatrices
|
||||
such as element-stiffnesses that might arise from a finite-element
|
||||
application.
|
||||
|
||||
In a parallel setting, indices may be submitted on the local processor
|
||||
for rows that do not reside in the local portion of the row-map. After
|
||||
all indices have been submitted, the GlobalAssemble method gathers all
|
||||
non-local graph rows to the appropriate 'owning' processors (an owning
|
||||
processor is a processor which has the row in its row-map).
|
||||
*/
|
||||
class Epetra_FECrsGraph : public Epetra_CrsGraph {
|
||||
public:
|
||||
|
||||
/** Constructor */
|
||||
Epetra_FECrsGraph(Epetra_DataAccess CV,
|
||||
const Epetra_BlockMap& RowMap,
|
||||
int* NumIndicesPerRow,
|
||||
bool ignoreNonLocalEntries=false);
|
||||
|
||||
/** Constructor */
|
||||
Epetra_FECrsGraph(Epetra_DataAccess CV,
|
||||
const Epetra_BlockMap& RowMap,
|
||||
int NumIndicesPerRow,
|
||||
bool ignoreNonLocalEntries=false);
|
||||
|
||||
/** Constructor */
|
||||
Epetra_FECrsGraph(Epetra_DataAccess CV,
|
||||
const Epetra_BlockMap& RowMap,
|
||||
const Epetra_BlockMap& ColMap,
|
||||
int* NumIndicesPerRow,
|
||||
bool ignoreNonLocalEntries=false);
|
||||
|
||||
/** Constructor */
|
||||
Epetra_FECrsGraph(Epetra_DataAccess CV,
|
||||
const Epetra_BlockMap& RowMap,
|
||||
const Epetra_BlockMap& ColMap,
|
||||
int NumIndicesPerRow,
|
||||
bool ignoreNonLocalEntries=false);
|
||||
|
||||
/** Constructor */
|
||||
Epetra_FECrsGraph(const Epetra_FECrsGraph& Graph);
|
||||
|
||||
/** Destructor */
|
||||
virtual ~Epetra_FECrsGraph();
|
||||
|
||||
//Let the compiler know we intend to overload the base-class function
|
||||
//InsertGlobalIndices rather than hide it.
|
||||
using Epetra_CrsGraph::InsertGlobalIndices;
|
||||
|
||||
/** Insert a rectangular, dense 'submatrix' of entries (matrix nonzero
|
||||
positions) into the graph.
|
||||
|
||||
@param numRows Number of rows in the submatrix.
|
||||
@param rows List of row-numbers for the submatrix.
|
||||
@param numCols Number of columns in the submatrix.
|
||||
@param cols List of column-indices that will be used for each row in
|
||||
the 'rows' list.
|
||||
*/
|
||||
int InsertGlobalIndices(int numRows, const int* rows,
|
||||
int numCols, const int* cols);
|
||||
|
||||
/** Gather any overlapping/shared data into the non-overlapping partitioning
|
||||
defined by the Map that was passed to this matrix at construction time.
|
||||
Data imported from other processors is stored on the owning processor
|
||||
with a "sumInto" or accumulate operation.
|
||||
This is a collective method -- every processor must enter it before any
|
||||
will complete it.
|
||||
|
||||
***NOTE***: When GlobalAssemble() calls FillComplete(), it passes the
|
||||
arguments 'DomainMap()' and 'RangeMap()', which are the map attributes
|
||||
held by the base-class CrsMatrix and its graph. If a rectangular matrix
|
||||
is being assembled, the domain-map and range-map must be specified by
|
||||
calling the other overloading of this method. Otherwise, GlobalAssemble()
|
||||
has no way of knowing what these maps should really be.
|
||||
|
||||
|
||||
@param callFillComplete option argument, defaults to true.
|
||||
Determines whether GlobalAssemble() internally calls the
|
||||
FillComplete() method on this matrix.
|
||||
|
||||
@return error-code 0 if successful, non-zero if some error occurs
|
||||
*/
|
||||
int GlobalAssemble(bool callFillComplete=true);
|
||||
|
||||
/** Gather any overlapping/shared data into the non-overlapping partitioning
|
||||
defined by the Map that was passed to this matrix at construction time.
|
||||
Data imported from other processors is stored on the owning processor
|
||||
with a "sumInto" or accumulate operation.
|
||||
This is a collective method -- every processor must enter it before any
|
||||
will complete it.
|
||||
|
||||
***NOTE***: When GlobalAssemble() (the other overloading of this method)
|
||||
calls FillComplete(), it passes the arguments 'DomainMap()' and
|
||||
'RangeMap()', which are the map attributes already held by the base-class
|
||||
CrsMatrix and its graph. If a rectangular matrix is being assembled, the
|
||||
domain-map and range-map must be specified. Otherwise, GlobalAssemble()
|
||||
has no way of knowing what these maps should really be.
|
||||
|
||||
|
||||
@param domain_map user-supplied domain map for this matrix
|
||||
|
||||
@param range_map user-supplied range map for this matrix
|
||||
|
||||
@param callFillComplete option argument, defaults to true.
|
||||
Determines whether GlobalAssemble() internally calls the
|
||||
FillComplete() method on this matrix.
|
||||
|
||||
@return error-code 0 if successful, non-zero if some error occurs
|
||||
*/
|
||||
int GlobalAssemble(const Epetra_Map& domain_map,
|
||||
const Epetra_Map& range_map,
|
||||
bool callFillComplete=true);
|
||||
|
||||
private:
|
||||
void DeleteMemory();
|
||||
int InsertNonlocalRow(int row, int offset);
|
||||
int InputNonlocalIndices(int row,
|
||||
int numCols,
|
||||
const int* cols);
|
||||
int InputNonlocalIndex(int rowoffset,
|
||||
int col);
|
||||
|
||||
int myFirstRow_;
|
||||
int myNumRows_;
|
||||
bool ignoreNonLocalEntries_;
|
||||
|
||||
int numNonlocalRows_;
|
||||
int* nonlocalRows_;
|
||||
int* nonlocalRowLengths_;
|
||||
int* nonlocalRowAllocLengths_;
|
||||
int** nonlocalCols_;
|
||||
|
||||
Epetra_FECrsGraph & operator=(const Epetra_FECrsGraph& Graph);
|
||||
|
||||
|
||||
};//class Epetra_FECrsGraph
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,581 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_FECRSMATRIX_H
|
||||
#define EPETRA_FECRSMATRIX_H
|
||||
|
||||
#include <Epetra_CrsMatrix.h>
|
||||
class Epetra_Map;
|
||||
class Epetra_IntSerialDenseVector;
|
||||
class Epetra_SerialDenseMatrix;
|
||||
|
||||
/** Epetra Finite-Element CrsMatrix. This class provides the ability to
|
||||
input finite-element style sub-matrix data, including sub-matrices with
|
||||
non-local rows (which could correspond to shared finite-element nodes for
|
||||
example). This class inherits Epetra_CrsMatrix, and so all Epetra_CrsMatrix
|
||||
functionality is also available.
|
||||
|
||||
It is intended that this class will be used as follows:
|
||||
<ul>
|
||||
<li> Construct with either a map or graph that describes a (non-overlapping)
|
||||
data distribution.
|
||||
<li> Input data, including non-local data, using the methods
|
||||
InsertGlobalValues(), SumIntoGlobalValues() and/or ReplaceGlobalValues().
|
||||
<li> Call the method GlobalAssemble(), which gathers all non-local data
|
||||
onto the owning processors as determined by the map provided at
|
||||
construction. Users should note that the GlobalAssemble() method has an
|
||||
optional argument which determines whether GlobalAssemble() in turn calls
|
||||
FillComplete() after the data-exchange has occurred. If not explicitly
|
||||
supplied, this argument defaults to true.
|
||||
***NOTE***: When GlobalAssemble() calls FillComplete(), it passes the
|
||||
arguments 'DomainMap()' and 'RangeMap()', which are the map attributes
|
||||
held by the base-class CrsMatrix and its graph. If a rectangular matrix
|
||||
is being assembled, the correct domain-map and range-map must be passed to
|
||||
GlobalAssemble (there are two overloadings of this method) -- otherwise, it
|
||||
has no way of knowing what these maps should really be.
|
||||
</ul>
|
||||
|
||||
Sub-matrix data, which is assumed to be a rectangular 'table' of
|
||||
coefficients accompanied by 'scatter-indices', can be provided in three
|
||||
forms:
|
||||
<ul>
|
||||
<li>Fortran-style packed 1-D array.
|
||||
<li>C-style double-pointer, or list-of-rows.
|
||||
<li>Epetra_SerialDenseMatrix object.
|
||||
</ul>
|
||||
In all cases, a "format" parameter specifies whether the data is laid out
|
||||
in row-major or column-major order (i.e., whether coefficients for a row
|
||||
lie contiguously or whether coefficients for a column lie contiguously).
|
||||
See the documentation for the methods SumIntoGlobalValues() and
|
||||
ReplaceGlobalValues().
|
||||
|
||||
Important notes:
|
||||
<ol>
|
||||
<li> Since Epetra_FECrsMatrix inherits Epetra_CrsMatrix, the semantics of
|
||||
the Insert/SumInto/Replace methods are the same as they are on
|
||||
Epetra_CrsMatrix, which is:
|
||||
<ul>
|
||||
<li>InsertGlobalValues() inserts values into the matrix only if the graph
|
||||
has not yet been finalized (FillComplete() has not yet been called). For
|
||||
non-local values, the call to InsertGlobalValues() may succeed but the
|
||||
GlobalAssemble() method may then fail because the non-local data is not
|
||||
actually inserted in the underlying matrix until GlobalAssemble() is called.
|
||||
<li>SumIntoGlobalValues() and ReplaceGlobalValues() only work for values
|
||||
that already exist in the matrix. In other words, these methods can not be
|
||||
used to put new values into the matrix.
|
||||
</ul>
|
||||
</ol>
|
||||
*/
|
||||
class Epetra_FECrsMatrix : public Epetra_CrsMatrix {
|
||||
public:
|
||||
/** Constructor. */
|
||||
Epetra_FECrsMatrix(Epetra_DataAccess CV,
|
||||
const Epetra_Map& RowMap,
|
||||
int* NumEntriesPerRow,
|
||||
bool ignoreNonLocalEntries=false);
|
||||
|
||||
/** Constructor. */
|
||||
Epetra_FECrsMatrix(Epetra_DataAccess CV,
|
||||
const Epetra_Map& RowMap,
|
||||
int NumEntriesPerRow,
|
||||
bool ignoreNonLocalEntries=false);
|
||||
|
||||
/** Constructor. */
|
||||
Epetra_FECrsMatrix(Epetra_DataAccess CV,
|
||||
const Epetra_Map& RowMap,
|
||||
const Epetra_Map& ColMap,
|
||||
int* NumEntriesPerRow,
|
||||
bool ignoreNonLocalEntries=false);
|
||||
|
||||
/** Constructor. */
|
||||
Epetra_FECrsMatrix(Epetra_DataAccess CV,
|
||||
const Epetra_Map& RowMap,
|
||||
const Epetra_Map& ColMap,
|
||||
int NumEntriesPerRow,
|
||||
bool ignoreNonLocalEntries=false);
|
||||
|
||||
/** Constructor. */
|
||||
Epetra_FECrsMatrix(Epetra_DataAccess CV,
|
||||
const Epetra_CrsGraph& Graph,
|
||||
bool ignoreNonLocalEntries=false);
|
||||
|
||||
/** Copy Constructor. */
|
||||
Epetra_FECrsMatrix(const Epetra_FECrsMatrix& src);
|
||||
|
||||
/** Destructor. */
|
||||
virtual ~Epetra_FECrsMatrix();
|
||||
|
||||
/** Assignment operator */
|
||||
Epetra_FECrsMatrix& operator=(const Epetra_FECrsMatrix& src);
|
||||
|
||||
enum { ROW_MAJOR = 0, COLUMN_MAJOR = 3 };
|
||||
|
||||
//Let the compiler know we intend to overload the following base-class
|
||||
//functions, rather than hide them.
|
||||
using Epetra_CrsMatrix::SumIntoGlobalValues;
|
||||
using Epetra_CrsMatrix::InsertGlobalValues;
|
||||
using Epetra_CrsMatrix::ReplaceGlobalValues;
|
||||
|
||||
/** Sum a Fortran-style table (single-dimensional packed-list) of
|
||||
coefficients into the matrix, adding them to any coefficients that
|
||||
may already exist at the specified row/column locations.
|
||||
|
||||
@param numIndices Number of rows (and columns) in the sub-matrix.
|
||||
@param indices List of scatter-indices (rows and columns) for the
|
||||
sub-matrix.
|
||||
@param values List, length numIndices*numIndices. Square sub-matrix of
|
||||
coefficients, packed in a 1-D array. Data is packed either contiguously
|
||||
by row or by column, specified by the final parameter 'format'.
|
||||
@param format Specifies whether the data in 'values' is packed in
|
||||
column-major or row-major order. Valid values are
|
||||
Epetra_FECrsMatrix::ROW_MAJOR or Epetra_FECrsMatrix::COLUMN_MAJOR. This
|
||||
is an optional parameter, default value is COLUMN_MAJOR.
|
||||
*/
|
||||
int SumIntoGlobalValues(int numIndices, const int* indices,
|
||||
const double* values,
|
||||
int format=Epetra_FECrsMatrix::COLUMN_MAJOR);
|
||||
|
||||
/** Sum a Fortran-style table (single-dimensional packed-list) of
|
||||
coefficients into the matrix, adding them to any coefficients that
|
||||
may already exist at the specified row/column locations.
|
||||
|
||||
@param numRows Number of rows in the sub-matrix.
|
||||
@param rows List of row-numbers (scatter-indices) for the sub-matrix.
|
||||
@param numCols Number of columns in the sub-matrix.
|
||||
@param cols List of column-numbers (scatter-indices) for the sub-matrix.
|
||||
@param values List, length numRows*numCols. Rectangular sub-matrix of
|
||||
coefficients, packed in a 1-D array. Data is packed either contiguously
|
||||
by row or by column, specified by the final parameter 'format'.
|
||||
@param format Specifies whether the data in 'values' is packed in
|
||||
column-major or row-major order. Valid values are
|
||||
Epetra_FECrsMatrix::ROW_MAJOR or Epetra_FECrsMatrix::COLUMN_MAJOR. This
|
||||
is an optional parameter, default value is COLUMN_MAJOR.
|
||||
*/
|
||||
int SumIntoGlobalValues(int numRows, const int* rows,
|
||||
int numCols, const int* cols,
|
||||
const double* values,
|
||||
int format=Epetra_FECrsMatrix::COLUMN_MAJOR);
|
||||
|
||||
/** Sum C-style table (double-pointer, or list of lists) of coefficients
|
||||
into the matrix, adding them to any coefficients that
|
||||
may already exist at the specified row/column locations.
|
||||
|
||||
@param numIndices Number of rows (and columns) in the sub-matrix.
|
||||
@param indices List of scatter-indices (rows and columns) for the
|
||||
sub-matrix.
|
||||
@param values Square sub-matrix of coefficients, provided in a 2-D
|
||||
array, or double-pointer.
|
||||
@param format Specifies whether the data in 'values' is packed in
|
||||
column-major or row-major order. Valid values are
|
||||
Epetra_FECrsMatrix::ROW_MAJOR or Epetra_FECrsMatrix::COLUMN_MAJOR. This
|
||||
is an optional parameter, default value is ROW_MAJOR.
|
||||
*/
|
||||
int SumIntoGlobalValues(int numIndices, const int* indices,
|
||||
const double* const* values,
|
||||
int format=Epetra_FECrsMatrix::ROW_MAJOR);
|
||||
|
||||
/** Sum C-style table (double-pointer, or list of lists) of coefficients
|
||||
into the matrix, adding them to any coefficients that
|
||||
may already exist at the specified row/column locations.
|
||||
|
||||
@param numRows Number of rows in the sub-matrix.
|
||||
@param rows List of row-numbers (scatter-indices) for the sub-matrix.
|
||||
@param numCols Number of columns in the sub-matrix.
|
||||
@param cols List of column-numbers (scatter-indices) for the sub-matrix.
|
||||
@param values Rectangular sub-matrix of coefficients, provided in a 2-D
|
||||
array, or double-pointer.
|
||||
@param format Specifies whether the data in 'values' is packed in
|
||||
column-major or row-major order. Valid values are
|
||||
Epetra_FECrsMatrix::ROW_MAJOR or Epetra_FECrsMatrix::COLUMN_MAJOR. This
|
||||
is an optional parameter, default value is ROW_MAJOR.
|
||||
*/
|
||||
int SumIntoGlobalValues(int numRows, const int* rows,
|
||||
int numCols, const int* cols,
|
||||
const double* const* values,
|
||||
int format=Epetra_FECrsMatrix::ROW_MAJOR);
|
||||
|
||||
/** Insert a Fortran-style table (single-dimensional packed-list) of
|
||||
coefficients into the matrix.
|
||||
|
||||
@param numIndices Number of rows (and columns) in the sub-matrix.
|
||||
@param indices List of scatter-indices (rows and columns) for the
|
||||
sub-matrix.
|
||||
@param values List, length numIndices*numIndices. Square sub-matrix of
|
||||
coefficients, packed in a 1-D array. Data is packed either contiguously
|
||||
by row or by column, specified by the final parameter 'format'.
|
||||
@param format Specifies whether the data in 'values' is packed in
|
||||
column-major or row-major order. Valid values are
|
||||
Epetra_FECrsMatrix::ROW_MAJOR or Epetra_FECrsMatrix::COLUMN_MAJOR. This
|
||||
is an optional parameter, default value is COLUMN_MAJOR.
|
||||
*/
|
||||
int InsertGlobalValues(int numIndices, const int* indices,
|
||||
const double* values,
|
||||
int format=Epetra_FECrsMatrix::COLUMN_MAJOR);
|
||||
|
||||
/** Insert a Fortran-style table (single-dimensional packed-list) of
|
||||
coefficients into the matrix.
|
||||
|
||||
@param numRows Number of rows in the sub-matrix.
|
||||
@param rows List of row-numbers (scatter-indices) for the sub-matrix.
|
||||
@param numCols Number of columns in the sub-matrix.
|
||||
@param cols List of column-numbers (scatter-indices) for the sub-matrix.
|
||||
@param values List, length numRows*numCols. Rectangular sub-matrix of
|
||||
coefficients, packed in a 1-D array. Data is packed either contiguously
|
||||
by row or by column, specified by the final parameter 'format'.
|
||||
@param format Specifies whether the data in 'values' is packed in
|
||||
column-major or row-major order. Valid values are
|
||||
Epetra_FECrsMatrix::ROW_MAJOR or Epetra_FECrsMatrix::COLUMN_MAJOR. This
|
||||
is an optional parameter, default value is COLUMN_MAJOR.
|
||||
*/
|
||||
int InsertGlobalValues(int numRows, const int* rows,
|
||||
int numCols, const int* cols,
|
||||
const double* values,
|
||||
int format=Epetra_FECrsMatrix::COLUMN_MAJOR);
|
||||
|
||||
/** Insert a C-style table (double-pointer, or list of lists) of coefficients
|
||||
into the matrix.
|
||||
|
||||
@param numIndices Number of rows (and columns) in the sub-matrix.
|
||||
@param indices List of scatter-indices (rows and columns) for the
|
||||
sub-matrix.
|
||||
@param values Square sub-matrix of coefficients, provided in a 2-D
|
||||
array, or double-pointer.
|
||||
@param format Specifies whether the data in 'values' is packed in
|
||||
column-major or row-major order. Valid values are
|
||||
Epetra_FECrsMatrix::ROW_MAJOR or Epetra_FECrsMatrix::COLUMN_MAJOR. This
|
||||
is an optional parameter, default value is ROW_MAJOR.
|
||||
*/
|
||||
int InsertGlobalValues(int numIndices, const int* indices,
|
||||
const double* const* values,
|
||||
int format=Epetra_FECrsMatrix::ROW_MAJOR);
|
||||
|
||||
/** Insert a C-style table (double-pointer, or list of lists) of coefficients
|
||||
into the matrix.
|
||||
|
||||
@param numRows Number of rows in the sub-matrix.
|
||||
@param rows List of row-numbers (scatter-indices) for the sub-matrix.
|
||||
@param numCols Number of columns in the sub-matrix.
|
||||
@param cols List of column-numbers (scatter-indices) for the sub-matrix.
|
||||
@param values Rectangular sub-matrix of coefficients, provided in a 2-D
|
||||
array, or double-pointer.
|
||||
@param format Specifies whether the data in 'values' is packed in
|
||||
column-major or row-major order. Valid values are
|
||||
Epetra_FECrsMatrix::ROW_MAJOR or Epetra_FECrsMatrix::COLUMN_MAJOR. This
|
||||
is an optional parameter, default value is ROW_MAJOR.
|
||||
*/
|
||||
int InsertGlobalValues(int numRows, const int* rows,
|
||||
int numCols, const int* cols,
|
||||
const double* const* values,
|
||||
int format=Epetra_FECrsMatrix::ROW_MAJOR);
|
||||
|
||||
/** Copy a Fortran-style table (single-dimensional packed-list) of
|
||||
coefficients into the matrix, replacing any coefficients that
|
||||
may already exist at the specified row/column locations.
|
||||
|
||||
@param numIndices Number of rows (and columns) in the sub-matrix.
|
||||
@param indices List of scatter-indices (rows and columns) for the
|
||||
sub-matrix.
|
||||
@param values List, length numIndices*numIndices. Square sub-matrix of
|
||||
coefficients, packed in a 1-D array. Data is packed either contiguously
|
||||
by row or by column, specified by the final parameter 'format'.
|
||||
@param format Specifies whether the data in 'values' is packed in
|
||||
column-major or row-major order. Valid values are
|
||||
Epetra_FECrsMatrix::ROW_MAJOR or Epetra_FECrsMatrix::COLUMN_MAJOR. This
|
||||
is an optional parameter, default value is COLUMN_MAJOR.
|
||||
*/
|
||||
int ReplaceGlobalValues(int numIndices, const int* indices,
|
||||
const double* values,
|
||||
int format=Epetra_FECrsMatrix::COLUMN_MAJOR);
|
||||
|
||||
/** Copy Fortran-style table (single-dimensional packed-list) of coefficients
|
||||
into the matrix, replacing any coefficients that
|
||||
may already exist at the specified row/column locations.
|
||||
|
||||
@param numRows Number of rows in the sub-matrix.
|
||||
@param rows List of row-numbers (scatter-indices) for the sub-matrix.
|
||||
@param numCols Number of columns in the sub-matrix.
|
||||
@param cols List, of column-numbers
|
||||
(scatter-indices) for the sub-matrix.
|
||||
@param values List, length numRows*numCols. Rectangular sub-matrix of
|
||||
coefficients, packed in a 1-D array. Data is packed either contiguously
|
||||
by row or by column, specified by the final parameter 'format'.
|
||||
@param format Specifies whether the data in 'values' is packed in
|
||||
column-major or row-major order. Valid values are
|
||||
Epetra_FECrsMatrix::ROW_MAJOR or Epetra_FECrsMatrix::COLUMN_MAJOR. This
|
||||
is an optional parameter, default value is COLUMN_MAJOR.
|
||||
*/
|
||||
int ReplaceGlobalValues(int numRows, const int* rows,
|
||||
int numCols, const int* cols,
|
||||
const double* values,
|
||||
int format=Epetra_FECrsMatrix::COLUMN_MAJOR);
|
||||
|
||||
/** Copy C-style table (double-pointer, or list of lists) of coefficients
|
||||
into the matrix, replacing any coefficients that
|
||||
may already exist at the specified row/column locations.
|
||||
|
||||
@param numIndices Number of rows (and columns) in the sub-matrix.
|
||||
@param indices List of scatter-indices (rows and columns) for the
|
||||
sub-matrix.
|
||||
@param values Square sub-matrix of coefficients, provided in a 2-D
|
||||
array, or double-pointer.
|
||||
@param format Specifies whether the data in 'values' is packed in
|
||||
column-major or row-major order. Valid values are
|
||||
Epetra_FECrsMatrix::ROW_MAJOR or Epetra_FECrsMatrix::COLUMN_MAJOR. This
|
||||
is an optional parameter, default value is ROW_MAJOR.
|
||||
*/
|
||||
int ReplaceGlobalValues(int numIndices, const int* indices,
|
||||
const double* const* values,
|
||||
int format=Epetra_FECrsMatrix::ROW_MAJOR);
|
||||
|
||||
/** Copy C-style table (double-pointer, or list of lists) of coefficients
|
||||
into the matrix, replacing any coefficients that
|
||||
may already exist at the specified row/column locations.
|
||||
|
||||
@param numRows Number of rows in the sub-matrix.
|
||||
@param rows List of row-numbers (scatter-indices) for the sub-matrix.
|
||||
@param numCols Number of columns in the sub-matrix.
|
||||
@param cols List of column-numbers (scatter-indices) for the sub-matrix.
|
||||
@param values Rectangular sub-matrix of coefficients, provided in a 2-D
|
||||
array, or double-pointer.
|
||||
@param format Specifies whether the data in 'values' is packed in
|
||||
column-major or row-major order. Valid values are
|
||||
Epetra_FECrsMatrix::ROW_MAJOR or Epetra_FECrsMatrix::COLUMN_MAJOR. This
|
||||
is an optional parameter, default value is ROW_MAJOR.
|
||||
*/
|
||||
int ReplaceGlobalValues(int numRows, const int* rows,
|
||||
int numCols, const int* cols,
|
||||
const double* const* values,
|
||||
int format=Epetra_FECrsMatrix::ROW_MAJOR);
|
||||
|
||||
/** Sum a square structurally-symmetric sub-matrix into the global matrix.
|
||||
For non-square sub-matrices, see the other overloading of this method.
|
||||
|
||||
@param indices List of scatter-indices. indices.Length() must be the same
|
||||
as values.M() and values.N().
|
||||
|
||||
@param values Sub-matrix of coefficients. Must be square.
|
||||
|
||||
@param format Optional format specifier, defaults to COLUMN_MAJOR.
|
||||
*/
|
||||
int SumIntoGlobalValues(const Epetra_IntSerialDenseVector& indices,
|
||||
const Epetra_SerialDenseMatrix& values,
|
||||
int format=Epetra_FECrsMatrix::COLUMN_MAJOR);
|
||||
|
||||
/** Sum a general sub-matrix into the global matrix.
|
||||
For square structurally-symmetric sub-matrices, see the other
|
||||
overloading of this method.
|
||||
|
||||
@param rows List of row-indices. rows.Length() must be the same
|
||||
as values.M().
|
||||
|
||||
@param cols List of column-indices. cols.Length() must be the same
|
||||
as values.N().
|
||||
|
||||
@param values Sub-matrix of coefficients.
|
||||
|
||||
@param format Optional format specifier, defaults to COLUMN_MAJOR.
|
||||
*/
|
||||
int SumIntoGlobalValues(const Epetra_IntSerialDenseVector& rows,
|
||||
const Epetra_IntSerialDenseVector& cols,
|
||||
const Epetra_SerialDenseMatrix& values,
|
||||
int format=Epetra_FECrsMatrix::COLUMN_MAJOR);
|
||||
|
||||
/** Insert a square structurally-symmetric sub-matrix into the global matrix.
|
||||
For non-square sub-matrices, see the other overloading of this method.
|
||||
|
||||
@param indices List of scatter-indices. indices.Length() must be the same
|
||||
as values.M() and values.N().
|
||||
|
||||
@param values Sub-matrix of coefficients. Must be square.
|
||||
|
||||
@param format Optional format specifier, defaults to COLUMN_MAJOR.
|
||||
*/
|
||||
int InsertGlobalValues(const Epetra_IntSerialDenseVector& indices,
|
||||
const Epetra_SerialDenseMatrix& values,
|
||||
int format=Epetra_FECrsMatrix::COLUMN_MAJOR);
|
||||
|
||||
/** Insert a general sub-matrix into the global matrix.
|
||||
For square structurally-symmetric sub-matrices, see the other
|
||||
overloading of this method.
|
||||
|
||||
@param rows List of row-indices. rows.Length() must be the same
|
||||
as values.M().
|
||||
|
||||
@param cols List of column-indices. cols.Length() must be the same
|
||||
as values.N().
|
||||
|
||||
@param values Sub-matrix of coefficients.
|
||||
|
||||
@param format Optional format specifier, defaults to COLUMN_MAJOR.
|
||||
*/
|
||||
int InsertGlobalValues(const Epetra_IntSerialDenseVector& rows,
|
||||
const Epetra_IntSerialDenseVector& cols,
|
||||
const Epetra_SerialDenseMatrix& values,
|
||||
int format=Epetra_FECrsMatrix::COLUMN_MAJOR);
|
||||
|
||||
/** Use a square structurally-symmetric sub-matrix to replace existing
|
||||
values in the global matrix.
|
||||
For non-square sub-matrices, see the other overloading of this method.
|
||||
|
||||
@param indices List of scatter-indices. indices.Length() must be the same
|
||||
as values.M() and values.N().
|
||||
|
||||
@param values Sub-matrix of coefficients. Must be square.
|
||||
|
||||
@param format Optional format specifier, defaults to COLUMN_MAJOR.
|
||||
*/
|
||||
int ReplaceGlobalValues(const Epetra_IntSerialDenseVector& indices,
|
||||
const Epetra_SerialDenseMatrix& values,
|
||||
int format=Epetra_FECrsMatrix::COLUMN_MAJOR);
|
||||
|
||||
/** Use a general sub-matrix to replace existing values.
|
||||
For square structurally-symmetric sub-matrices, see the other
|
||||
overloading of this method.
|
||||
|
||||
@param rows List of row-indices. rows.Length() must be the same
|
||||
as values.M().
|
||||
|
||||
@param cols List of column-indices. cols.Length() must be the same
|
||||
as values.N().
|
||||
|
||||
@param values Sub-matrix of coefficients.
|
||||
|
||||
@param format Optional format specifier, defaults to COLUMN_MAJOR.
|
||||
*/
|
||||
int ReplaceGlobalValues(const Epetra_IntSerialDenseVector& rows,
|
||||
const Epetra_IntSerialDenseVector& cols,
|
||||
const Epetra_SerialDenseMatrix& values,
|
||||
int format=Epetra_FECrsMatrix::COLUMN_MAJOR);
|
||||
|
||||
/** Gather any overlapping/shared data into the non-overlapping partitioning
|
||||
defined by the Map that was passed to this matrix at construction time.
|
||||
Data imported from other processors is stored on the owning processor
|
||||
with a "sumInto" or accumulate operation.
|
||||
This is a collective method -- every processor must enter it before any
|
||||
will complete it.
|
||||
|
||||
***NOTE***: When GlobalAssemble() calls FillComplete(), it passes the
|
||||
arguments 'DomainMap()' and 'RangeMap()', which are the map attributes
|
||||
held by the base-class CrsMatrix and its graph. If a rectangular matrix
|
||||
is being assembled, the domain-map and range-map must be specified by
|
||||
calling the other overloading of this method. Otherwise, GlobalAssemble()
|
||||
has no way of knowing what these maps should really be.
|
||||
|
||||
|
||||
@param callFillComplete option argument, defaults to true.
|
||||
Determines whether GlobalAssemble() internally calls the
|
||||
FillComplete() method on this matrix.
|
||||
|
||||
@return error-code 0 if successful, non-zero if some error occurs
|
||||
*/
|
||||
int GlobalAssemble(bool callFillComplete=true);
|
||||
|
||||
/** Gather any overlapping/shared data into the non-overlapping partitioning
|
||||
defined by the Map that was passed to this matrix at construction time.
|
||||
Data imported from other processors is stored on the owning processor
|
||||
with a "sumInto" or accumulate operation.
|
||||
This is a collective method -- every processor must enter it before any
|
||||
will complete it.
|
||||
|
||||
***NOTE***: When GlobalAssemble() (the other overloading of this method)
|
||||
calls FillComplete(), it passes the arguments 'DomainMap()' and
|
||||
'RangeMap()', which are the map attributes already held by the base-class
|
||||
CrsMatrix and its graph. If a rectangular matrix is being assembled, the
|
||||
domain-map and range-map must be specified. Otherwise, GlobalAssemble()
|
||||
has no way of knowing what these maps should really be.
|
||||
|
||||
|
||||
@param domain_map user-supplied domain map for this matrix
|
||||
|
||||
@param range_map user-supplied range map for this matrix
|
||||
|
||||
@param callFillComplete option argument, defaults to true.
|
||||
Determines whether GlobalAssemble() internally calls the
|
||||
FillComplete() method on this matrix.
|
||||
|
||||
@return error-code 0 if successful, non-zero if some error occurs
|
||||
*/
|
||||
int GlobalAssemble(const Epetra_Map& domain_map,
|
||||
const Epetra_Map& range_map,
|
||||
bool callFillComplete=true);
|
||||
|
||||
/** Set whether or not non-local data values should be ignored. By default,
|
||||
non-local data values are NOT ignored.
|
||||
*/
|
||||
void setIgnoreNonLocalEntries(bool flag) {
|
||||
ignoreNonLocalEntries_ = flag;
|
||||
}
|
||||
|
||||
private:
|
||||
void DeleteMemory();
|
||||
|
||||
enum {SUMINTO = 0, REPLACE = 1, INSERT = 2};
|
||||
|
||||
int InputGlobalValues(int numRows, const int* rows,
|
||||
int numCols, const int* cols,
|
||||
const double* const* values,
|
||||
int format,
|
||||
int mode);
|
||||
|
||||
int InputGlobalValues(int numRows, const int* rows,
|
||||
int numCols, const int* cols,
|
||||
const double* values,
|
||||
int format,
|
||||
int mode);
|
||||
|
||||
int InputNonlocalGlobalValues(int row,
|
||||
int numCols, const int* cols,
|
||||
const double* values,
|
||||
int mode);
|
||||
|
||||
int InsertNonlocalRow(int row, int offset);
|
||||
|
||||
int InputNonlocalValue(int rowoffset,
|
||||
int col, double value,
|
||||
int mode);
|
||||
|
||||
int myFirstRow_;
|
||||
int myNumRows_;
|
||||
|
||||
bool ignoreNonLocalEntries_;
|
||||
|
||||
int numNonlocalRows_;
|
||||
int* nonlocalRows_;
|
||||
int* nonlocalRowLengths_;
|
||||
int* nonlocalRowAllocLengths_;
|
||||
int** nonlocalCols_;
|
||||
double** nonlocalCoefs_;
|
||||
|
||||
double* workData_;
|
||||
int workDataLength_;
|
||||
};//class Epetra_FECrsMatrix
|
||||
|
||||
#endif /* EPETRA_FECRSMATRIX_H */
|
||||
@@ -0,0 +1,276 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_FEVBRMATRIX_H
|
||||
#define EPETRA_FEVBRMATRIX_H
|
||||
|
||||
#include <Epetra_VbrMatrix.h>
|
||||
#include <Epetra_SerialDenseMatrix.h>
|
||||
|
||||
/** Epetra Finite-Element VbrMatrix. This class provides the ability to
|
||||
input finite-element style sub-matrix data, including sub-matrices with
|
||||
non-local rows (which could correspond to shared finite-element nodes for
|
||||
example). This class inherits Epetra_VbrMatrix, and so all Epetra_VbrMatrix
|
||||
functionality is also available.
|
||||
*/
|
||||
|
||||
class Epetra_FEVbrMatrix: public Epetra_VbrMatrix {
|
||||
public:
|
||||
|
||||
//! @name Constructors/Destructor
|
||||
//@{
|
||||
//! Epetra_FEVbrMatrix constuctor with variable number of indices per row.
|
||||
/*! Creates a Epetra_FEVbrMatrix object and allocates storage.
|
||||
|
||||
\param In
|
||||
CV - A Epetra_DataAccess enumerated type set to Copy or View.
|
||||
\param In
|
||||
RowMap - A Epetra_BlockMap listing the block rows that this processor
|
||||
will contribute to.
|
||||
\param In
|
||||
NumBlockEntriesPerRow - An integer array of length NumRows
|
||||
such that NumBlockEntriesPerRow[i] indicates the (approximate)
|
||||
number of Block entries in the ith row.
|
||||
*/
|
||||
Epetra_FEVbrMatrix(Epetra_DataAccess CV,
|
||||
const Epetra_BlockMap& RowMap,
|
||||
int *NumBlockEntriesPerRow,
|
||||
bool ignoreNonLocalEntries=false);
|
||||
|
||||
//! Epetra_FEVbrMatrix constuctor with fixed number of indices per row.
|
||||
/*! Creates a Epetra_FEVbrMatrix object and allocates storage.
|
||||
|
||||
\param In
|
||||
CV - A Epetra_DataAccess enumerated type set to Copy or View.
|
||||
\param In
|
||||
RowMap - An Epetra_BlockMap listing the block rows that this
|
||||
processor will contribute to.
|
||||
\param In
|
||||
NumBlockEntriesPerRow - An integer that indicates the (approximate)
|
||||
number of Block entries in the each Block row.
|
||||
Note that it is possible to use 0 for this value and let fill occur
|
||||
during the insertion phase.
|
||||
*/
|
||||
Epetra_FEVbrMatrix(Epetra_DataAccess CV,
|
||||
const Epetra_BlockMap& RowMap,
|
||||
int NumBlockEntriesPerRow,
|
||||
bool ignoreNonLocalEntries=false);
|
||||
|
||||
//! Epetra_FEVbrMatrix constuctor with variable number of indices per row.
|
||||
/*! Creates a Epetra_FEVbrMatrix object and allocates storage.
|
||||
|
||||
\param In
|
||||
CV - A Epetra_DataAccess enumerated type set to Copy or View.
|
||||
\param In
|
||||
RowMap - A Epetra_BlockMap listing the block rows that this processor
|
||||
will contribute to.
|
||||
\param In
|
||||
ColMap - A Epetra_BlockMap listing the block columns to be contained
|
||||
on this processor.
|
||||
\param In
|
||||
NumBlockEntriesPerRow - An integer array of length NumRows
|
||||
such that NumBlockEntriesPerRow[i] indicates the (approximate)
|
||||
number of Block entries in the ith row.
|
||||
*/
|
||||
Epetra_FEVbrMatrix(Epetra_DataAccess CV,
|
||||
const Epetra_BlockMap& RowMap,
|
||||
const Epetra_BlockMap& ColMap,
|
||||
int *NumBlockEntriesPerRow,
|
||||
bool ignoreNonLocalEntries=false);
|
||||
|
||||
//! Epetra_FEVbrMatrix constuctor with fixed number of indices per row.
|
||||
/*! Creates a Epetra_FEVbrMatrix object and allocates storage.
|
||||
|
||||
\param In
|
||||
CV - A Epetra_DataAccess enumerated type set to Copy or View.
|
||||
\param In
|
||||
RowMap - An Epetra_BlockMap listing the block rows that this
|
||||
processor will contribute to.
|
||||
\param In
|
||||
ColMap - An Epetra_BlockMap listing the block columns to be contained
|
||||
on this processor.
|
||||
\param In
|
||||
NumBlockEntriesPerRow - An integer that indicates the (approximate)
|
||||
number of Block entries in the each Block row.
|
||||
Note that it is possible to use 0 for this value and let fill occur
|
||||
during the insertion phase.
|
||||
*/
|
||||
Epetra_FEVbrMatrix(Epetra_DataAccess CV,
|
||||
const Epetra_BlockMap& RowMap,
|
||||
const Epetra_BlockMap& ColMap,
|
||||
int NumBlockEntriesPerRow,
|
||||
bool ignoreNonLocalEntries=false);
|
||||
|
||||
/** Constructor with pre-constructed Graph.
|
||||
*/
|
||||
Epetra_FEVbrMatrix(Epetra_DataAccess CV,
|
||||
const Epetra_CrsGraph& Graph,
|
||||
bool ignoreNonLocalEntries=false);
|
||||
|
||||
/** Copy Constructor. */
|
||||
Epetra_FEVbrMatrix(const Epetra_FEVbrMatrix& src);
|
||||
|
||||
//! Epetra_VbrMatrix Destructor
|
||||
virtual ~Epetra_FEVbrMatrix();
|
||||
//@}
|
||||
|
||||
//! @name Insertion/Replace/SumInto methods
|
||||
//@{
|
||||
|
||||
Epetra_FEVbrMatrix& operator=(const Epetra_FEVbrMatrix& src);
|
||||
|
||||
//! Initialize all values in graph of the matrix with constant value.
|
||||
/*!
|
||||
\param In
|
||||
ScalarConstant - Value to use.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int PutScalar(double ScalarConstant);
|
||||
|
||||
//! Initiate insertion of a list of elements in a given global row of the matrix, values are inserted via SubmitEntry().
|
||||
/*!
|
||||
\param In
|
||||
BlockRow - Block Row number (in global coordinates) to put elements.
|
||||
\param In
|
||||
NumBlockEntries - Number of entries.
|
||||
\param In
|
||||
Indices - Global column indices corresponding to values.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int BeginInsertGlobalValues(int BlockRow, int NumBlockEntries, int * BlockIndices);
|
||||
|
||||
//! Initiate replacement of current values with this list of entries for a given global row of the matrix, values are replaced via SubmitEntry()
|
||||
/*!
|
||||
\param In
|
||||
Row - Block Row number (in global coordinates) to put elements.
|
||||
\param In
|
||||
NumBlockEntries - Number of entries.
|
||||
\param In
|
||||
Indices - Global column indices corresponding to values.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int BeginReplaceGlobalValues(int BlockRow, int NumBlockEntries, int *BlockIndices);
|
||||
|
||||
//! Initiate summing into current values with this list of entries for a given global row of the matrix, values are replaced via SubmitEntry()
|
||||
/*!
|
||||
\param In
|
||||
Row - Block Row number (in global coordinates) to put elements.
|
||||
\param In
|
||||
NumBlockEntries - Number of entries.
|
||||
\param In
|
||||
Indices - Global column indices corresponding to values.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int BeginSumIntoGlobalValues(int BlockRow, int NumBlockEntries, int *BlockIndices);
|
||||
|
||||
//Let the compiler know we intend to overload the base-class function
|
||||
//SubmitBlockEntry rather than hide it.
|
||||
using Epetra_VbrMatrix::SubmitBlockEntry;
|
||||
|
||||
//! Submit a block entry to the indicated block row and column specified in the Begin routine.
|
||||
/* Submit a block entry that will recorded in the block row that was initiated by one of the
|
||||
Begin routines listed above. Once a one of the following routines: BeginInsertGlobalValues(),
|
||||
BeginInsertMyValues(), BeginReplaceGlobalValues(), BeginReplaceMyValues(), BeginSumIntoGlobalValues(),
|
||||
BeginSumIntoMyValues(), you \e must call SubmitBlockEntry() NumBlockEntries times to register the values
|
||||
corresponding to the block indices passed in to the Begin routine. If the Epetra_VbrMatrix constuctor
|
||||
was called in Copy mode, the values will be copied. However, no copying will be done until the EndSubmitEntries()
|
||||
function is call to complete submission of the current block row. If the constructor was called in View mode, all
|
||||
block entries passed via SubmitBlockEntry() will not be copied, but a pointer will be set to point to the argument Values
|
||||
that was passed in by the user.
|
||||
|
||||
For performance reasons, SubmitBlockEntry() does minimal processing of data. Any processing that can be
|
||||
delayed is performed in EndSubmitEntries().
|
||||
|
||||
\param In
|
||||
Values - The starting address of the values.
|
||||
\param In
|
||||
LDA - The stride between successive columns of Values.
|
||||
\param In
|
||||
NumRows - The number of rows passed in.
|
||||
\param In
|
||||
NumCols - The number of columns passed in.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int SubmitBlockEntry(double *Values, int LDA, int NumRows, int NumCols);
|
||||
|
||||
//! Completes processing of all data passed in for the current block row.
|
||||
/*! This function completes the processing of all block entries submitted via SubmitBlockEntry().
|
||||
It also checks to make sure that SubmitBlockEntry was called the correct number of times as
|
||||
specified by the Begin routine that initiated the entry process.
|
||||
*/
|
||||
|
||||
int EndSubmitEntries();
|
||||
|
||||
int GlobalAssemble(bool callFillComplete=true);
|
||||
|
||||
private:
|
||||
int SetupForNonlocalSubmits(int BlockRow,
|
||||
int NumBlockEntries,
|
||||
int * BlockIndices,
|
||||
bool IndicesAreLocal,
|
||||
Epetra_CombineMode SubmitMode);
|
||||
|
||||
int InputNonlocalBlockEntry(double *Values, int LDA,
|
||||
int NumRows, int NumCols);
|
||||
|
||||
int InsertNonlocalRow(int row, int offset, int numCols);
|
||||
|
||||
void destroyNonlocalData();
|
||||
|
||||
bool ignoreNonLocalEntries_;
|
||||
|
||||
int numNonlocalBlockRows_;
|
||||
int* nonlocalBlockRows_;
|
||||
int* nonlocalBlockRowLengths_;
|
||||
int* nonlocalBlockRowAllocLengths_;
|
||||
int** nonlocalBlockCols_;
|
||||
|
||||
//Triple-pointers are gross, but we need one here. We want a 2-D table of
|
||||
//pointer-to-matrix objects. If we only use a double-pointer, it would be
|
||||
//too hard to change the lengths of the rows of the table.
|
||||
|
||||
Epetra_SerialDenseMatrix*** nonlocalCoefs_;
|
||||
|
||||
//Following the approach Mike uses in Epetra_VbrMatrix, we need some state
|
||||
//variables to keep track of block-entry submits.
|
||||
int curRowOffset_;
|
||||
int curColOffset_;
|
||||
int curNumCols_;
|
||||
int* curCols_;
|
||||
int curMode_;
|
||||
};
|
||||
|
||||
#endif /* EPETRA_FEVBRMATRIX_H */
|
||||
@@ -0,0 +1,167 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_FEVECTOR_H
|
||||
#define EPETRA_FEVECTOR_H
|
||||
|
||||
#include <Epetra_CombineMode.h>
|
||||
#include <Epetra_Map.h>
|
||||
#include <Epetra_MultiVector.h>
|
||||
class Epetra_IntSerialDenseVector;
|
||||
class Epetra_SerialDenseVector;
|
||||
|
||||
/** Epetra Finite-Element Vector. This class inherits Epetra_MultiVector
|
||||
and thus provides all Epetra_MultiVector functionality, with one
|
||||
restriction: currently an Epetra_FEVector only has 1 internal vector.
|
||||
|
||||
The added functionality provided by Epetra_FEVector is the ability to
|
||||
perform finite-element style vector assembly. It accepts sub-vector
|
||||
contributions, such as those that would come from element-load vectors, etc.,
|
||||
and these sub-vectors need not be wholly locally owned. In other words, the
|
||||
user can assemble overlapping data (e.g., corresponding to shared
|
||||
finite-element nodes). When the user is finished assembling their vector
|
||||
data, they then call the method Epetra_FEVector::GlobalAssemble() which
|
||||
gathers the overlapping data (all non-local data that was input on each
|
||||
processor) into the data-distribution specified by the map that the
|
||||
Epetra_FEVector is constructed with.
|
||||
|
||||
Note: At the current time (Sept 6, 2002) the methods in this implementation
|
||||
assume that there is only 1 point associated with each map element. This
|
||||
limitation will be removed in the near future.
|
||||
*/
|
||||
|
||||
class Epetra_FEVector : public Epetra_MultiVector {
|
||||
public:
|
||||
/** Constructor that requires a map specifying a non-overlapping
|
||||
data layout. The methods SumIntoGlobalValues() and
|
||||
ReplaceGlobalValues() will accept any global IDs, and GlobalAssemble()
|
||||
will move any non-local data onto the appropriate owning processors.
|
||||
*/
|
||||
Epetra_FEVector(const Epetra_BlockMap& Map,
|
||||
bool ignoreNonLocalEntries=false);
|
||||
|
||||
/** Copy constructor. */
|
||||
Epetra_FEVector(const Epetra_FEVector& source);
|
||||
|
||||
/** Destructor */
|
||||
virtual ~Epetra_FEVector();
|
||||
|
||||
/** Accumulate values into the vector, adding them to any values that
|
||||
already exist for the specified indices.
|
||||
*/
|
||||
int SumIntoGlobalValues(int numIDs, const int* GIDs, const double* values);
|
||||
|
||||
/** Accumulate values into the vector, adding them to any values that
|
||||
already exist for the specified GIDs.
|
||||
|
||||
@param GIDs List of global ids. Must be the same length as the
|
||||
accompanying list of values.
|
||||
|
||||
@param values List of coefficient values. Must be the same length as
|
||||
the accompanying list of GIDs.
|
||||
*/
|
||||
int SumIntoGlobalValues(const Epetra_IntSerialDenseVector& GIDs,
|
||||
const Epetra_SerialDenseVector& values);
|
||||
|
||||
/** Copy values into the vector overwriting any values that already exist
|
||||
for the specified indices.
|
||||
*/
|
||||
int ReplaceGlobalValues(int numIDs, const int* GIDs, const double* values);
|
||||
|
||||
/** Copy values into the vector, replacing any values that
|
||||
already exist for the specified GIDs.
|
||||
|
||||
@param GIDs List of global ids. Must be the same length as the
|
||||
accompanying list of values.
|
||||
|
||||
@param values List of coefficient values. Must be the same length as
|
||||
the accompanying list of GIDs.
|
||||
*/
|
||||
int ReplaceGlobalValues(const Epetra_IntSerialDenseVector& GIDs,
|
||||
const Epetra_SerialDenseVector& values);
|
||||
|
||||
int SumIntoGlobalValues(int numIDs, const int* GIDs,
|
||||
const int* numValuesPerID,
|
||||
const double* values);
|
||||
|
||||
int ReplaceGlobalValues(int numIDs, const int* GIDs,
|
||||
const int* numValuesPerID,
|
||||
const double* values);
|
||||
|
||||
/** Gather any overlapping/shared data into the non-overlapping partitioning
|
||||
defined by the Map that was passed to this vector at construction time.
|
||||
Data imported from other processors is stored on the owning processor
|
||||
with a "sumInto" or accumulate operation.
|
||||
This is a collective method -- every processor must enter it before any
|
||||
will complete it.
|
||||
*/
|
||||
int GlobalAssemble(Epetra_CombineMode mode = Add);
|
||||
|
||||
/** Set whether or not non-local data values should be ignored.
|
||||
*/
|
||||
void setIgnoreNonLocalEntries(bool flag) {
|
||||
ignoreNonLocalEntries_ = flag;
|
||||
}
|
||||
|
||||
Epetra_FEVector& operator=(const Epetra_FEVector& source);
|
||||
|
||||
private:
|
||||
int inputValues(int numIDs,
|
||||
const int* GIDs, const double* values,
|
||||
bool accumulate);
|
||||
|
||||
int inputValues(int numIDs,
|
||||
const int* GIDs, const int* numValuesPerID,
|
||||
const double* values,
|
||||
bool accumulate);
|
||||
|
||||
int inputNonlocalValue(int GID, double value, bool accumulate);
|
||||
|
||||
int inputNonlocalValues(int GID, int numValues, const double* values,
|
||||
bool accumulate);
|
||||
|
||||
void destroyNonlocalData();
|
||||
|
||||
int myFirstID_;
|
||||
int myNumIDs_;
|
||||
double* myCoefs_;
|
||||
|
||||
int* nonlocalIDs_;
|
||||
int* nonlocalElementSize_;
|
||||
int numNonlocalIDs_;
|
||||
int allocatedNonlocalLength_;
|
||||
double** nonlocalCoefs_;
|
||||
|
||||
bool ignoreNonLocalEntries_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_FLOPS_H
|
||||
#define EPETRA_FLOPS_H
|
||||
|
||||
//! Epetra_Flops: The Epetra Floating Point Operations Class.
|
||||
/*! The Epetra_Flops class provides basic support and consistent interfaces
|
||||
for counting and reporting floating point operations performed in
|
||||
the Epetra computational classes. All classes based on the Epetra_CompObject
|
||||
can count flops by the user creating an Epetra_Flops object and calling the SetFlopCounter()
|
||||
method for an Epetra_CompObject.
|
||||
|
||||
*/
|
||||
|
||||
class Epetra_Flops {
|
||||
|
||||
public:
|
||||
//! Epetra_Flops Constructor.
|
||||
/*! Creates a Epetra_Flops instance. This instance can be queried for
|
||||
the number of floating point operations performed for the associated
|
||||
\e this object.
|
||||
*/
|
||||
Epetra_Flops(void);
|
||||
|
||||
//! Epetra_Flops Copy Constructor.
|
||||
/*! Makes an exact copy of an existing Epetra_Flops instance.
|
||||
*/
|
||||
Epetra_Flops(const Epetra_Flops& Flops);
|
||||
|
||||
//! Returns the number of floating point operations with \e this object and resets the count.
|
||||
double Flops() const {double tmp = Flops_; Flops_ = 0.0; return(tmp);};
|
||||
|
||||
//! Resets the number of floating point operations to zero for \e this multi-vector.
|
||||
void ResetFlops() {Flops_=0.0;};
|
||||
|
||||
//! Epetra_Flops Destructor.
|
||||
/*! Completely deletes a Epetra_Flops object.
|
||||
*/
|
||||
virtual ~Epetra_Flops(void);
|
||||
|
||||
Epetra_Flops& operator=(const Epetra_Flops& src)
|
||||
{
|
||||
Flops_ = src.Flops_;
|
||||
return(*this);
|
||||
}
|
||||
|
||||
friend class Epetra_CompObject;
|
||||
|
||||
protected:
|
||||
mutable double Flops_;
|
||||
//! Increment Flop count for \e this object from an int
|
||||
void UpdateFlops(int Flops) const {Flops_ += (double) Flops;};
|
||||
//! Increment Flop count for \e this object from a long int
|
||||
void UpdateFlops(long int Flops) const {Flops_ += (double) Flops;};
|
||||
//! Increment Flop count for \e this object from a double
|
||||
void UpdateFlops(double Flops) const {Flops_ += Flops;};
|
||||
//! Increment Flop count for \e this object from a float
|
||||
void UpdateFlops(float Flops) const {Flops_ +=(double) Flops;};
|
||||
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif /* EPETRA_FLOPS_H */
|
||||
@@ -0,0 +1,131 @@
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef Epetra_HashTable_H_
|
||||
#define Epetra_HashTable_H_
|
||||
|
||||
#include "Epetra_Object.h"
|
||||
|
||||
class Epetra_HashTable : public Epetra_Object
|
||||
{
|
||||
struct Node
|
||||
{
|
||||
int Key;
|
||||
int Value;
|
||||
Node * Ptr;
|
||||
|
||||
Node( const int key = 0, const int value = 0, Node * ptr = 0 )
|
||||
: Key(key), Value(value), Ptr(ptr) {}
|
||||
|
||||
private:
|
||||
Node(const Node& src)
|
||||
: Key(src.Key), Value(src.Value), Ptr(src.Ptr) {}
|
||||
|
||||
Node& operator=(const Node& src)
|
||||
{ Key = src.Key; Value = src.Value; Ptr = src.Ptr; return(*this); }
|
||||
};
|
||||
|
||||
Node ** Container_;
|
||||
int Size_;
|
||||
unsigned int Seed_;
|
||||
|
||||
int Func( const int key ) { return (Seed_ ^ key)%Size_; }
|
||||
|
||||
public:
|
||||
|
||||
Epetra_HashTable( const int size, const unsigned int seed = (2654435761U) )
|
||||
: Container_(NULL),
|
||||
Size_(size),
|
||||
Seed_(seed)
|
||||
{
|
||||
if (size<=0)
|
||||
throw ReportError( "Bad Hash Table Size: " + toString(size), -1 );
|
||||
|
||||
Container_ = new Node * [size];
|
||||
for( int i = 0; i < size; ++i ) Container_[i] = 0;
|
||||
}
|
||||
|
||||
Epetra_HashTable( const Epetra_HashTable & obj )
|
||||
: Container_(NULL),
|
||||
Size_(obj.Size_),
|
||||
Seed_(obj.Seed_)
|
||||
{
|
||||
Container_ = new Node * [Size_];
|
||||
for( int i = 0; i < Size_; ++i ) Container_[i] = 0;
|
||||
for( int i = 0; i < Size_; ++i )
|
||||
{
|
||||
Node * ptr = obj.Container_[i];
|
||||
while( ptr ) { Add( ptr->Key, ptr->Value ); ptr = ptr->Ptr; }
|
||||
}
|
||||
}
|
||||
|
||||
~Epetra_HashTable()
|
||||
{
|
||||
Node * ptr1;
|
||||
Node * ptr2;
|
||||
for( int i = 0; i < Size_; ++i )
|
||||
{
|
||||
ptr1 = Container_[i];
|
||||
while( ptr1 ) { ptr2 = ptr1; ptr1 = ptr1->Ptr; delete ptr2; }
|
||||
}
|
||||
|
||||
delete [] Container_;
|
||||
}
|
||||
|
||||
void Add( const int key, const int value )
|
||||
{
|
||||
int v = Func(key);
|
||||
Node * n1 = Container_[v];
|
||||
Container_[v] = new Node(key,value,n1);
|
||||
}
|
||||
|
||||
int Get( const int key )
|
||||
{
|
||||
Node * n = Container_[ Func(key) ];
|
||||
while( n && (n->Key != key) ) n = n->Ptr;
|
||||
if( n ) return n->Value;
|
||||
else return -1;
|
||||
}
|
||||
|
||||
private:
|
||||
Epetra_HashTable& operator=(const Epetra_HashTable& src)
|
||||
{
|
||||
(void)src;
|
||||
//not currently supported
|
||||
bool throw_error = true;
|
||||
if (throw_error) {
|
||||
throw ReportError("Epetra_HashTable::operator= not supported.",-1);
|
||||
}
|
||||
return(*this);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,308 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_IMPORT_H
|
||||
#define EPETRA_IMPORT_H
|
||||
|
||||
#include "Epetra_Object.h"
|
||||
#include "Epetra_BlockMap.h"
|
||||
class Epetra_Distributor;
|
||||
|
||||
//! Epetra_Import: This class builds an import object for efficient importing of off-processor elements.
|
||||
|
||||
/*! Epetra_Import is used to construct a communication plan that can be called repeatedly by computational
|
||||
classes such the Epetra matrix, vector and multivector classes to efficiently obtain off-processor
|
||||
elements.
|
||||
|
||||
This class currently has one constructor, taking two Epetra_Map or Epetra_BlockMap objects.
|
||||
The first map specifies the global IDs of elements that we want to import later. The
|
||||
second map specifies the global IDs that are owned by the calling processor.
|
||||
*/
|
||||
|
||||
class Epetra_Import: public Epetra_Object {
|
||||
|
||||
public:
|
||||
|
||||
//! Constructs a Epetra_Import object from the source and target maps.
|
||||
/*! This constructor builds an Epetra_Import object by comparing the GID lists of the source and
|
||||
target maps.
|
||||
\param TargetMap (In) Map containing the GIDs from which data should be imported to each processor from
|
||||
the source map whenever an import operation is performed using this importer.
|
||||
\param SourceMap (In) Map containing the GIDs that should be used for importing data.
|
||||
|
||||
\warning Note that the SourceMap \e must have GIDs uniquely owned, each GID of the source map can occur only once.
|
||||
|
||||
|
||||
Builds an import object that will transfer objects built with SourceMap to objects built with TargetMap.
|
||||
|
||||
A Epetra_Import object categorizes the elements of the target map into three sets as follows:
|
||||
<ol>
|
||||
<li> All elements in the target map that have the same GID as the corresponding element of the source map,
|
||||
starting with the first
|
||||
element in the target map, going up to the first element that is different from the source map. The number of
|
||||
these IDs is returned by NumSameIDs().
|
||||
<li> All elements that are local to the processor, but are not part of the first set of elements. These elements
|
||||
have GIDs that are owned by the calling processor, but at least the first element of this list is permuted.
|
||||
Even if subsequent elements are not permuted, they are included in this list. The number of permuted elements
|
||||
is returned by NumPermutedIDs(). The list of elements (local IDs) in the source map that are permuted can be
|
||||
found in the list PermuteFromLIDs(). The list of elements (local IDs) in the target map that are the new locations
|
||||
of the source elements can be found in the list PermuteToLIDs().
|
||||
<li> All remaining elements of the target map correspond to global IDs that are owned by remote processors. The number
|
||||
of these elements is returned by NumRemoteIDs() and the list of these is returned by RemoteLIDs().
|
||||
</ol>
|
||||
|
||||
Given the above information, the Epetra_Import constructor builds a list of elements that must be communicated to other
|
||||
processors as a result of import requests. The number of exported elements (where multiple sends of the same element
|
||||
to different processors is counted) is returned by NumExportIDs(). The local IDs to be sent are returned by the list
|
||||
ExportLIDs(). The processors to which each of the elements will be sent in returned in a list of the same length by
|
||||
ExportPIDs().
|
||||
|
||||
The total number of elements that will be sent by the calling processor is returned by NumSend(). The total number of
|
||||
elements that will be received is returned by NumRecv().
|
||||
|
||||
|
||||
The following example illustrates the basic concepts.
|
||||
|
||||
Assume we have 3 processors and 9 global elements with each processor owning 3 elements as follows
|
||||
\verbatim
|
||||
PE 0 Elements | PE 1 Elements | PE 2 Elements
|
||||
0 1 2 3 4 5 6 7 8
|
||||
\endverbatim
|
||||
|
||||
The above layout essentially defines the source map argument of the import object.
|
||||
|
||||
This could correspond to a 9 by 9 matrix with the first three rows on PE 0, and so on. Suppose that this matrix
|
||||
is periodic tridiagonal having the following sparsity pattern:
|
||||
|
||||
\verbatim
|
||||
|
||||
PE 0 Rows:
|
||||
|
||||
X X 0 0 0 0 0 0 X
|
||||
X X X 0 0 0 0 0 0
|
||||
0 X X X 0 0 0 0 0
|
||||
|
||||
PE 1 Rows:
|
||||
|
||||
0 0 X X X 0 0 0 0
|
||||
0 0 0 X X X 0 0 0
|
||||
0 0 0 0 X X X 0 0
|
||||
|
||||
PE 2 Rows:
|
||||
|
||||
0 0 0 0 0 X X X 0
|
||||
0 0 0 0 0 0 X X X
|
||||
X 0 0 0 0 0 0 X X
|
||||
|
||||
\endverbatim
|
||||
|
||||
To perform a matrix vector multiplication operation y = A*x (assuming that x has the same distribution as the
|
||||
rows of the matrix A) each processor will need to import elements of x that
|
||||
are not local. To do this, we build a target map on each processor as follows:
|
||||
\verbatim
|
||||
PE 0 Elements | PE 1 Elements | PE 2 Elements
|
||||
0 1 2 3 8 2 3 4 5 6 0 5 6 7 8
|
||||
\endverbatim
|
||||
|
||||
The above list is the elements that will be needed to perform the matrix vector multiplication locally on each processor.
|
||||
Note that the ordering of the elements on each processor is not unique, but has been chosen for illustration.
|
||||
|
||||
With these two maps passed into the Epetra_Import constructor, we get the following attribute definitions:
|
||||
|
||||
On PE 0:
|
||||
|
||||
\verbatim
|
||||
NumSameIDs = 3
|
||||
|
||||
NumPermuteIDs = 0
|
||||
PermuteToLIDs = 0
|
||||
PermuteFromLIDs = 0
|
||||
|
||||
NumRemoteIDs = 2
|
||||
RemoteLIDs = [3, 4]
|
||||
|
||||
NumExportIDs = 2
|
||||
ExportLIDs = [0, 2]
|
||||
ExportPIDs = [1, 2]
|
||||
|
||||
NumSend = 2
|
||||
NumRecv = 2
|
||||
|
||||
\endverbatim
|
||||
|
||||
On PE 1:
|
||||
|
||||
\verbatim
|
||||
NumSameIDs = 0
|
||||
|
||||
NumPermuteIDs = 3
|
||||
PermuteToLIDs = [0, 1, 2]
|
||||
PermuteFromLIDs = [1, 2, 3]
|
||||
|
||||
NumRemoteIDs = 2
|
||||
RemoteLIDs = [0, 4]
|
||||
|
||||
NumExportIDs = 2
|
||||
ExportLIDs = [0, 2]
|
||||
ExportPIDs = [0, 2]
|
||||
|
||||
NumSend = 2
|
||||
NumRecv = 2
|
||||
|
||||
\endverbatim
|
||||
|
||||
On PE 2:
|
||||
|
||||
\verbatim
|
||||
NumSameIDs = 0
|
||||
|
||||
NumPermuteIDs = 3
|
||||
PermuteToLIDs = [0, 1, 2]
|
||||
PermuteFromLIDs = [2, 3, 4]
|
||||
|
||||
NumRemoteIDs = 2
|
||||
RemoteLIDs = [0, 1]
|
||||
|
||||
NumExportIDs = 2
|
||||
ExportLIDs = [0, 2]
|
||||
ExportPIDs = [0, 1]
|
||||
|
||||
NumSend = 2
|
||||
NumRecv = 2
|
||||
|
||||
\endverbatim
|
||||
|
||||
|
||||
<b> Using Epetra_Import Objects </b>
|
||||
|
||||
Once a Epetra_Import object has been constructed, it can be used by any of the Epetra classes that support distributed global
|
||||
objects, namely Epetra_Vector, Epetra_MultiVector, Epetra_CrsGraph, Epetra_CrsMatrix and Epetra_VbrMatrix.
|
||||
All of these classes have Import and Export methods that will fill new objects whose distribution is described by
|
||||
the target map, taking elements from the source object whose distribution is described by the source map. Details of usage
|
||||
for each class is given in the appropriate class documentation.
|
||||
|
||||
Note that the reverse operation, an export, using this importer is also possible and appropriate in some instances.
|
||||
For example, if we compute y = A^Tx, the transpose matrix-multiplication operation, then we can use the importer we constructed
|
||||
in the above example to do an export operation to y, adding the contributions that come from multiple processors.
|
||||
|
||||
*/
|
||||
|
||||
Epetra_Import( const Epetra_BlockMap & TargetMap, const Epetra_BlockMap & SourceMap );
|
||||
|
||||
//! Epetra_Import copy constructor.
|
||||
Epetra_Import(const Epetra_Import& Importer);
|
||||
|
||||
//! Epetra_Import destructor.
|
||||
|
||||
virtual ~Epetra_Import(void);
|
||||
//! Returns the number of elements that are identical between the source and target maps, up to the first different ID
|
||||
int NumSameIDs() const {return(NumSameIDs_);};
|
||||
|
||||
//! Returns the number of elements that are local to the calling processor, but not part of the first NumSameIDs() elements.
|
||||
int NumPermuteIDs() const {return(NumPermuteIDs_);};
|
||||
|
||||
//! List of elements in the source map that are permuted.
|
||||
int * PermuteFromLIDs () const {return(PermuteFromLIDs_);};
|
||||
//! List of elements in the target map that are permuted.
|
||||
int * PermuteToLIDs () const {return(PermuteToLIDs_);};
|
||||
|
||||
//! Returns the number of elements that are not on the calling processor.
|
||||
int NumRemoteIDs() const {return(NumRemoteIDs_);};
|
||||
|
||||
//! List of elements in the target map that are coming from other processors.
|
||||
int * RemoteLIDs() const {return(RemoteLIDs_);};
|
||||
|
||||
//! Returns the number of elements that must be sent by the calling processor to other processors.
|
||||
int NumExportIDs () const {return(NumExportIDs_);};
|
||||
|
||||
//! List of elements that will be sent to other processors.
|
||||
int * ExportLIDs () const {return(ExportLIDs_);};
|
||||
|
||||
//! List of processors to which elements will be sent, ExportLIDs() [i] will be sent to processor ExportPIDs() [i].
|
||||
int * ExportPIDs () const {return(ExportPIDs_);};
|
||||
|
||||
//! Total number of elements to be sent.
|
||||
int NumSend() const {return(NumSend_);};
|
||||
|
||||
//! Total number of elements to be received.
|
||||
int NumRecv() const {return(NumRecv_);};
|
||||
|
||||
//! Returns the SourceMap used to construct this importer
|
||||
const Epetra_BlockMap & SourceMap() const {return(SourceMap_);};
|
||||
|
||||
//! Returns the TargetMap used to construct this importer
|
||||
const Epetra_BlockMap & TargetMap() const {return(TargetMap_);};
|
||||
|
||||
Epetra_Distributor & Distributor() const {return(*Distor_);};
|
||||
|
||||
//! @name Print object to an output stream
|
||||
//@{
|
||||
virtual void Print(ostream & os) const;
|
||||
//@}
|
||||
protected:
|
||||
|
||||
friend class Epetra_BlockMap;
|
||||
|
||||
private:
|
||||
Epetra_Import& operator=(const Epetra_Import& src)
|
||||
{
|
||||
(void)src;
|
||||
//not currently supported
|
||||
bool throw_error = true;
|
||||
if (throw_error) {
|
||||
throw ReportError("Epetra_Import::operator= not supported.",-1);
|
||||
}
|
||||
return(*this);
|
||||
}
|
||||
|
||||
Epetra_BlockMap TargetMap_;
|
||||
Epetra_BlockMap SourceMap_;
|
||||
|
||||
int NumSameIDs_;
|
||||
int NumPermuteIDs_;
|
||||
int * PermuteToLIDs_;
|
||||
int * PermuteFromLIDs_;
|
||||
int NumRemoteIDs_;
|
||||
int * RemoteLIDs_;
|
||||
|
||||
int NumExportIDs_;
|
||||
int * ExportLIDs_;
|
||||
int * ExportPIDs_;
|
||||
|
||||
int NumSend_;
|
||||
int NumRecv_;
|
||||
|
||||
Epetra_Distributor * Distor_;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif /* EPETRA_IMPORT_H */
|
||||
@@ -0,0 +1,395 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_INTSERIALDENSEMATRIX_H
|
||||
#define EPETRA_INTSERIALDENSEMATRIX_H
|
||||
|
||||
#include "Epetra_Object.h"
|
||||
|
||||
//! Epetra_IntSerialDenseMatrix: A class for constructing and using general dense integer matrices.
|
||||
|
||||
/*! The Epetra_IntSerialDenseMatrix class enables the construction and use of integer-valued, general
|
||||
dense matrices.
|
||||
|
||||
The Epetra_IntSerialDenseMatrix class is intended to provide very basic support for dense rectangular matrices.
|
||||
|
||||
|
||||
<b>Constructing Epetra_IntSerialDenseMatrix Objects</b>
|
||||
|
||||
There are four Epetra_IntSerialDenseMatrix constructors. The first constructs a zero-sized object which should be made
|
||||
to appropriate length using the Shape() or Reshape() functions and then filled with the [] or () operators.
|
||||
The second constructs an object sized to the dimensions specified, which should be filled with the [] or () operators.
|
||||
The third is a constructor that accepts user
|
||||
data as a 2D array, and the fourth is a copy constructor. The third constructor has
|
||||
two data access modes (specified by the Epetra_DataAccess argument):
|
||||
<ol>
|
||||
<li> Copy mode - Allocates memory and makes a copy of the user-provided data. In this case, the
|
||||
user data is not needed after construction.
|
||||
<li> View mode - Creates a "view" of the user data. In this case, the
|
||||
user data is required to remain intact for the life of the object.
|
||||
</ol>
|
||||
|
||||
\warning View mode is \e extremely dangerous from a data hiding perspective.
|
||||
Therefore, we strongly encourage users to develop code using Copy mode first and
|
||||
only use the View mode in a secondary optimization phase.
|
||||
|
||||
Epetra_IntSerialDenseMatrix constructors will throw an exception if an error occurrs.
|
||||
These exceptions will alway be negative integer values as follows:
|
||||
<ol>
|
||||
<li> -1 Invalid dimension specified.
|
||||
<li> -2 Shape returned non-zero.
|
||||
<li> -3 Null pointer specified for user's data.
|
||||
<li> -99 Internal Epetra_IntSerialDenseMatrix error. Contact developer.
|
||||
</ol>
|
||||
|
||||
Other Epetra_IntSerialDenseMatrix functions that do not return an integer error code
|
||||
(such as operators () and [] ) will throw an exception if an error occurrs.
|
||||
These exceptions will be integer values as follows:
|
||||
<ol>
|
||||
<li> -1 Invalid row specified.
|
||||
<li> -2 Invalid column specified.
|
||||
<li> -5 Invalid assignment (type mismatch).
|
||||
<li> -99 Internal Epetra_IntSerialDenseMatrix error. Contact developer.
|
||||
</ol>
|
||||
|
||||
|
||||
b<b>Extracting Data from Epetra_IntSerialDenseMatrix Objects</b>
|
||||
|
||||
Once a Epetra_IntSerialDenseMatrix is constructed, it is possible to view the data via access functions.
|
||||
|
||||
\warning Use of these access functions cam be \e extremely dangerous from a data hiding perspective.
|
||||
|
||||
|
||||
<b>Vector and Utility Functions</b>
|
||||
|
||||
Once a Epetra_IntSerialDenseMatrix is constructed, several mathematical functions can be applied to
|
||||
the object. Specifically:
|
||||
<ul>
|
||||
<li> Multiplication.
|
||||
<li> Norms.
|
||||
</ul>
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//=========================================================================
|
||||
class Epetra_IntSerialDenseMatrix : public Epetra_Object {
|
||||
|
||||
public:
|
||||
|
||||
//! @name Constructor/Destructor Methods
|
||||
//@{
|
||||
//! Default constructor; defines a zero size object.
|
||||
/*!
|
||||
Epetra_IntSerialDenseMatrix objects defined by the default constructor should be sized with the
|
||||
Shape() or Reshape functions.
|
||||
Values should be defined by using the [] or () operators.
|
||||
*/
|
||||
Epetra_IntSerialDenseMatrix();
|
||||
|
||||
//! Shaped constructor; defines a variable-sized object
|
||||
/*!
|
||||
\param In
|
||||
NumRows - Number of rows in object.
|
||||
\param In
|
||||
NumCols - Number of columns in object.
|
||||
|
||||
Epetra_SerialDenseMatrix objects defined by the shaped constructor are already shaped to the
|
||||
dimensions given as a parameters. All values are initialized to 0. Calling this constructor
|
||||
is equivalent to using the default constructor, and then calling the Shape function on it.
|
||||
Values should be defined by using the [] or () operators.
|
||||
*/
|
||||
Epetra_IntSerialDenseMatrix(int NumRows, int NumCols);
|
||||
|
||||
//! Set object values from two-dimensional array.
|
||||
/*!
|
||||
\param In
|
||||
Epetra_DataAccess - Enumerated type set to Copy or View.
|
||||
\param In
|
||||
A - Pointer to an array of integer numbers. The first vector starts at A.
|
||||
The second vector starts at A+LDA, the third at A+2*LDA, and so on.
|
||||
\param In
|
||||
LDA - The "Leading Dimension", or stride between vectors in memory.
|
||||
\param In
|
||||
NumRows - Number of rows in object.
|
||||
\param In
|
||||
NumCols - Number of columns in object.
|
||||
|
||||
See Detailed Description section for further discussion.
|
||||
*/
|
||||
Epetra_IntSerialDenseMatrix(Epetra_DataAccess CV, int* A, int LDA, int NumRows, int NumCols);
|
||||
|
||||
//! Epetra_IntSerialDenseMatrix copy constructor.
|
||||
/*!
|
||||
This matrix will take on the data access mode of the Source matrix.
|
||||
*/
|
||||
Epetra_IntSerialDenseMatrix(const Epetra_IntSerialDenseMatrix& Source);
|
||||
|
||||
//! Epetra_IntSerialDenseMatrix destructor.
|
||||
virtual ~Epetra_IntSerialDenseMatrix ();
|
||||
//@}
|
||||
|
||||
//! @name Shaping/sizing Methods
|
||||
//@{
|
||||
//! Set dimensions of a Epetra_IntSerialDenseMatrix object; init values to zero.
|
||||
/*!
|
||||
\param In
|
||||
NumRows - Number of rows in object.
|
||||
\param In
|
||||
NumCols - Number of columns in object.
|
||||
|
||||
Allows user to define the dimensions of a Epetra_IntSerialDenseMatrix at any point. This function can
|
||||
be called at any point after construction. Any values that were previously in this object are
|
||||
destroyed and the resized matrix starts off with all zero values.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int Shape(int NumRows, int NumCols);
|
||||
|
||||
//! Reshape a Epetra_IntSerialDenseMatrix object.
|
||||
/*!
|
||||
\param In
|
||||
NumRows - Number of rows in object.
|
||||
\param In
|
||||
NumCols - Number of columns in object.
|
||||
|
||||
Allows user to define the dimensions of a Epetra_IntSerialDenseMatrix at any point. This function can
|
||||
be called at any point after construction. Any values that were previously in this object are
|
||||
copied into the new shape. If the new shape is smaller than the original, the upper left portion
|
||||
of the original matrix (the principal submatrix) is copied to the new matrix.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int Reshape(int NumRows, int NumCols);
|
||||
//@}
|
||||
|
||||
//! @name Data Accessor methods
|
||||
//@{
|
||||
|
||||
//! Computes the 1-Norm of the \e this matrix.
|
||||
/*!
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual int OneNorm();
|
||||
|
||||
//! Computes the Infinity-Norm of the \e this matrix.
|
||||
virtual int InfNorm();
|
||||
|
||||
//! Copy from one matrix to another.
|
||||
/*!
|
||||
The operator= allows one to copy the values from one existing IntSerialDenseMatrix to another.
|
||||
The left hand side matrix will take on the data access mode of the right hand side matrix.
|
||||
|
||||
\return Values of the left hand side matrix are modified by the values of the right hand side matrix.
|
||||
*/
|
||||
Epetra_IntSerialDenseMatrix& operator = (const Epetra_IntSerialDenseMatrix& Source);
|
||||
|
||||
//! Comparison operator.
|
||||
/*! operator== compares two Epetra_IntSerialDenseMatrix objects, returns false if sizes are different,
|
||||
or if any coefficients differ.
|
||||
*/
|
||||
bool operator==(const Epetra_IntSerialDenseMatrix& rhs) const;
|
||||
|
||||
//! Inequality operator
|
||||
/*! operator!= simply returns the negation of operator==.
|
||||
*/
|
||||
bool operator!=(const Epetra_IntSerialDenseMatrix& rhs) const
|
||||
{ return !(*this == rhs); }
|
||||
|
||||
//! Element access function.
|
||||
/*!
|
||||
The parentheses operator returns the element in the ith row and jth column if A(i,j) is
|
||||
specified, the expression A[j][i] (note that i and j are reversed) will return the same element.
|
||||
Thus, A(i,j) = A[j][i] for all valid i and j.
|
||||
|
||||
\return Element from the specified row and column.
|
||||
|
||||
\warning No bounds checking is done unless Epetra is compiled with HAVE_EPETRA_ARRAY_BOUNDS_CHECK.
|
||||
*/
|
||||
int& operator () (int RowIndex, int ColIndex);
|
||||
|
||||
//! Element access function.
|
||||
/*!
|
||||
The parentheses operator returns the element in the ith row and jth column if A(i,j) is
|
||||
specified, the expression A[j][i] (note that i and j are reversed) will return the same element.
|
||||
Thus, A(i,j) = A[j][i] for all valid i and j.
|
||||
|
||||
\return Element from the specified row and column.
|
||||
|
||||
\warning No bounds checking is done unless Epetra is compiled with HAVE_EPETRA_ARRAY_BOUNDS_CHECK.
|
||||
*/
|
||||
const int& operator () (int RowIndex, int ColIndex) const;
|
||||
|
||||
//! Column access function.
|
||||
/*!
|
||||
The parentheses operator returns the element in the ith row and jth column if A(i,j) is
|
||||
specified, the expression A[j][i] (note that i and j are reversed) will return the same element.
|
||||
Thus, A(i,j) = A[j][i] for all valid i and j.
|
||||
|
||||
\return Pointer to address of specified column.
|
||||
|
||||
\warning No bounds checking can be done for the index i in the expression A[j][i].
|
||||
\warning No bounds checking is done unless Epetra is compiled with HAVE_EPETRA_ARRAY_BOUNDS_CHECK.
|
||||
*/
|
||||
int* operator [] (int ColIndex);
|
||||
|
||||
//! Column access function.
|
||||
/*!
|
||||
The parentheses operator returns the element in the ith row and jth column if A(i,j) is
|
||||
specified, the expression A[j][i] (note that i and j are reversed) will return the same element.
|
||||
Thus, A(i,j) = A[j][i] for all valid i and j.
|
||||
|
||||
\return Pointer to address of specified column.
|
||||
|
||||
\warning No bounds checking can be done for the index i in the expression A[j][i].
|
||||
\warning No bounds checking is done unless Epetra is compiled with HAVE_EPETRA_ARRAY_BOUNDS_CHECK.
|
||||
*/
|
||||
const int* operator [] (int ColIndex) const;
|
||||
|
||||
//! Set matrix values to random numbers.
|
||||
/*!
|
||||
IntSerialDenseMatrix uses the random number generator provided by Epetra_Util.
|
||||
The matrix values will be set to random values on the interval (0, 2^31 - 1).
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int Random();
|
||||
|
||||
//! Returns row dimension of system.
|
||||
int M() const {return(M_);};
|
||||
|
||||
//! Returns column dimension of system.
|
||||
int N() const {return(N_);};
|
||||
|
||||
//! Returns const pointer to the \e this matrix.
|
||||
const int* A() const {return(A_);};
|
||||
|
||||
//! Returns pointer to the \e this matrix.
|
||||
int* A() {return(A_);};
|
||||
|
||||
//! Returns the leading dimension of the \e this matrix.
|
||||
int LDA() const {return(LDA_);};
|
||||
|
||||
//! Returns the data access mode of the \e this matrix.
|
||||
Epetra_DataAccess CV() const {return(CV_);};
|
||||
//@}
|
||||
|
||||
//! @name I/O methods
|
||||
//@{
|
||||
//! Print service methods; defines behavior of ostream << operator.
|
||||
virtual void Print(ostream& os) const;
|
||||
//@}
|
||||
|
||||
//! @name Expert-only unsupported methods
|
||||
//@{
|
||||
|
||||
//! Reset an existing IntSerialDenseMatrix to point to another Matrix.
|
||||
/*! Allows an existing IntSerialDenseMatrix to become a View of another
|
||||
matrix's data, regardless of the DataAccess mode of the Source matrix.
|
||||
It is assumed that the Source matrix is an independent matrix, and
|
||||
no checking is done to verify this.
|
||||
|
||||
This is used by Epetra_CrsGraph in the OptimizeStorage method. It is used so that
|
||||
an existing (Copy) matrix can be converted to a View. This frees up
|
||||
memory that CrsGraph no longer needs.
|
||||
|
||||
@param Source The IntSerialDenseMatrix this will become a view of.
|
||||
|
||||
\return Integer error code, set to 0 if successful, and set to -1
|
||||
if a type mismatch occured.
|
||||
|
||||
\warning This method is extremely dangerous and should only be used by experts.
|
||||
*/
|
||||
|
||||
int MakeViewOf(const Epetra_IntSerialDenseMatrix& Source);
|
||||
//@}
|
||||
|
||||
protected:
|
||||
|
||||
void CopyMat(int* Source, int Source_LDA, int NumRows, int NumCols, int* Target, int Target_LDA);
|
||||
void CleanupData();
|
||||
|
||||
Epetra_DataAccess CV_;
|
||||
bool A_Copied_;
|
||||
int M_;
|
||||
int N_;
|
||||
int LDA_;
|
||||
int* A_;
|
||||
|
||||
};
|
||||
|
||||
// inlined definitions of op() and op[]
|
||||
//=========================================================================
|
||||
inline int& Epetra_IntSerialDenseMatrix::operator () (int RowIndex, int ColIndex) {
|
||||
#ifdef HAVE_EPETRA_ARRAY_BOUNDS_CHECK
|
||||
if(RowIndex >= M_ || RowIndex < 0)
|
||||
throw ReportError("Row index = " + toString(RowIndex) +
|
||||
" Out of Range 0 - " + toString(M_-1),-1);
|
||||
if(ColIndex >= N_ || ColIndex < 0)
|
||||
throw ReportError("Column index = " + toString(ColIndex) +
|
||||
" Out of Range 0 - " + toString(N_-1),-2);
|
||||
#endif
|
||||
return(A_[ColIndex*LDA_ + RowIndex]);
|
||||
}
|
||||
//=========================================================================
|
||||
inline const int& Epetra_IntSerialDenseMatrix::operator () (int RowIndex, int ColIndex) const {
|
||||
#ifdef HAVE_EPETRA_ARRAY_BOUNDS_CHECK
|
||||
if(RowIndex >= M_ || RowIndex < 0)
|
||||
throw ReportError("Row index = " + toString(RowIndex) +
|
||||
" Out of Range 0 - " + toString(M_-1),-1);
|
||||
if(ColIndex >= N_ || ColIndex < 0)
|
||||
throw ReportError("Column index = " + toString(ColIndex) +
|
||||
" Out of Range 0 - " + toString(N_-1),-2);
|
||||
#endif
|
||||
return(A_[ColIndex * LDA_ + RowIndex]);
|
||||
}
|
||||
//=========================================================================
|
||||
inline int* Epetra_IntSerialDenseMatrix::operator [] (int ColIndex) {
|
||||
#ifdef HAVE_EPETRA_ARRAY_BOUNDS_CHECK
|
||||
if(ColIndex >= N_ || ColIndex < 0)
|
||||
throw ReportError("Column index = " + toString(ColIndex) +
|
||||
" Out of Range 0 - " + toString(N_-1),-2);
|
||||
#endif
|
||||
return(A_+ ColIndex * LDA_);
|
||||
}
|
||||
//=========================================================================
|
||||
inline const int* Epetra_IntSerialDenseMatrix::operator [] (int ColIndex) const {
|
||||
#ifdef HAVE_EPETRA_ARRAY_BOUNDS_CHECK
|
||||
if(ColIndex >= N_ || ColIndex < 0)
|
||||
throw ReportError("Column index = " + toString(ColIndex) +
|
||||
" Out of Range 0 - " + toString(N_-1),-2);
|
||||
#endif
|
||||
return(A_ + ColIndex * LDA_);
|
||||
}
|
||||
//=========================================================================
|
||||
|
||||
#endif /* EPETRA_INTSERIALDENSEMATRIX_H */
|
||||
@@ -0,0 +1,289 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_INTSERIALDENSEVECTOR_H
|
||||
#define EPETRA_INTSERIALDENSEVECTOR_H
|
||||
|
||||
#include "Epetra_Object.h"
|
||||
#include "Epetra_IntSerialDenseMatrix.h"
|
||||
|
||||
//! Epetra_IntSerialDenseVector: A class for constructing and using dense vectors.
|
||||
|
||||
/*! The Epetra_IntSerialDenseVector class enables the construction and use of integer-valued,
|
||||
dense vectors. It derives from the Epetra_IntSerialDenseMatrix class.
|
||||
|
||||
The Epetra_IntSerialDenseVector class is intended to provide convenient vector notation but derives all signficant
|
||||
functionality from Epetra_IntSerialDenseMatrix.
|
||||
|
||||
<b>Constructing Epetra_IntSerialDenseVector Objects</b>
|
||||
|
||||
There are three Epetra_IntSerialDenseVector constructors. The first constructs a zero-length object which should be made
|
||||
to appropriate length using the Size() or Resize() functions and then filled with the [] or () operators.
|
||||
The second constructs an object sized to the dimension specified, which should be filled with the [] or () operators.
|
||||
The third is a constructor that accepts user
|
||||
data as a 1D array, and the fourth is a copy constructor. The third constructor has
|
||||
two data access modes (specified by the Epetra_DataAccess argument):
|
||||
<ol>
|
||||
<li> Copy mode - Allocates memory and makes a copy of the user-provided data. In this case, the
|
||||
user data is not needed after construction.
|
||||
<li> View mode - Creates a "view" of the user data. In this case, the
|
||||
user data is required to remain intact for the life of the object.
|
||||
</ol>
|
||||
|
||||
\warning View mode is \e extremely dangerous from a data hiding perspective.
|
||||
Therefore, we strongly encourage users to develop code using Copy mode first and
|
||||
only use the View mode in a secondary optimization phase.
|
||||
|
||||
<b>Extracting Data from Epetra_IntSerialDenseVector Objects</b>
|
||||
|
||||
Once a Epetra_IntSerialDenseVector is constructed, it is possible to view the data via access functions.
|
||||
|
||||
\warning Use of these access functions cam be \e extremely dangerous from a data hiding perspective.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//=========================================================================
|
||||
class Epetra_IntSerialDenseVector : public Epetra_IntSerialDenseMatrix{
|
||||
|
||||
public:
|
||||
|
||||
//! Default constructor; defines a zero size object.
|
||||
/*!
|
||||
Epetra_IntSerialDenseVector objects defined by the default constructor should be sized with the
|
||||
Size() or Resize functions.
|
||||
Values should be defined by using the [] or () operators.
|
||||
*/
|
||||
Epetra_IntSerialDenseVector();
|
||||
|
||||
//! Sized constructor; defines a variable-sized object
|
||||
/*!
|
||||
\param In
|
||||
Length - Length of vector.
|
||||
|
||||
Epetra_IntSerialDenseVector objects defined by the sized constructor are already sized to the
|
||||
dimension given as a parameter. All values are initialized to 0. Calling this constructor
|
||||
is equivalent to using the default constructor, and then calling the Size function on it.
|
||||
Values should be defined by using the [] or () operators.
|
||||
*/
|
||||
Epetra_IntSerialDenseVector(int Length);
|
||||
|
||||
//! Set object values from one-dimensional array.
|
||||
/*!
|
||||
\param In
|
||||
Epetra_DataAccess - Enumerated type set to Copy or View.
|
||||
\param In
|
||||
Values - Pointer to an array of integer numbers containing the values.
|
||||
\param In
|
||||
Length - Length of vector.
|
||||
|
||||
See Detailed Description section for further discussion.
|
||||
*/
|
||||
Epetra_IntSerialDenseVector(Epetra_DataAccess CV, int* Values, int Length);
|
||||
|
||||
//! Epetra_IntSerialDenseVector copy constructor.
|
||||
|
||||
Epetra_IntSerialDenseVector(const Epetra_IntSerialDenseVector& Source);
|
||||
|
||||
//! Set length of a Epetra_IntSerialDenseVector object; init values to zero.
|
||||
/*!
|
||||
\param In
|
||||
Length - Length of vector object.
|
||||
|
||||
Allows user to define the dimension of a Epetra_IntSerialDenseVector. This function can
|
||||
be called at any point after construction. Any values that were previously in this object are
|
||||
destroyed and the resized vector starts off with all zero values.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int Size(int Length) {return(Epetra_IntSerialDenseMatrix::Shape(Length, 1));};
|
||||
|
||||
//! Resize a Epetra_IntSerialDenseVector object.
|
||||
/*!
|
||||
\param In
|
||||
Length - Length of vector object.
|
||||
|
||||
Allows user to define the dimension of a Epetra_IntSerialDenseVector. This function can
|
||||
be called at any point after construction. Any values that were previously in this object are
|
||||
copied into the new size. If the new shape is smaller than the original, the first Length values
|
||||
are copied to the new vector.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int Resize(int Length) {return(Epetra_IntSerialDenseMatrix::Reshape(Length, 1));};
|
||||
|
||||
//! Epetra_IntSerialDenseVector destructor.
|
||||
virtual ~Epetra_IntSerialDenseVector ();
|
||||
|
||||
//bring the base-class operator() into the current scope, in order to tell the
|
||||
//compiler that we intend to overload it, rather than hide it.
|
||||
using Epetra_IntSerialDenseMatrix::operator();
|
||||
|
||||
//! Element access function.
|
||||
/*!
|
||||
Returns the specified element of the vector.
|
||||
\return Specified element in vector.
|
||||
|
||||
\warning No bounds checking is done unless Epetra is compiled with HAVE_EPETRA_ARRAY_BOUNDS_CHECK.
|
||||
*/
|
||||
int& operator () (int Index);
|
||||
|
||||
//! Element access function.
|
||||
/*!
|
||||
Returns the specified element of the vector.
|
||||
\return Specified element in vector.
|
||||
|
||||
\warning No bounds checking is done unless Epetra is compiled with HAVE_EPETRA_ARRAY_BOUNDS_CHECK.
|
||||
*/
|
||||
const int& operator () (int Index) const;
|
||||
|
||||
//! Element access function.
|
||||
/*!
|
||||
Returns the specified element of the vector.
|
||||
\return Specified element in vector.
|
||||
|
||||
\warning No bounds checking is done unless Epetra is compiled with HAVE_EPETRA_ARRAY_BOUNDS_CHECK.
|
||||
*/
|
||||
int& operator [] (int Index);
|
||||
|
||||
//! Element access function.
|
||||
/*!
|
||||
Returns the specified element of the vector.
|
||||
\return Specified element in vector.
|
||||
|
||||
\warning No bounds checking is done unless Epetra is compiled with HAVE_EPETRA_ARRAY_BOUNDS_CHECK.
|
||||
*/
|
||||
const int& operator [] (int Index) const;
|
||||
|
||||
//! Set vector values to random numbers.
|
||||
/*!
|
||||
IntSerialDenseVector uses the random number generator provided by Epetra_Util.
|
||||
The vector values will be set to random values on the interval (0, 2^31 - 1).
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int Random();
|
||||
|
||||
//! Returns length of vector.
|
||||
int Length() const {return(M_);};
|
||||
|
||||
//! Returns pointer to the values in vector.
|
||||
int* Values() {return(A_);};
|
||||
|
||||
//! Returns const pointer to the values in vector.
|
||||
const int* Values() const {return(A_);};
|
||||
|
||||
//! Returns the data access mode of the \e this vector.
|
||||
Epetra_DataAccess CV() const {return(CV_);};
|
||||
|
||||
//! Copy from one vector to another.
|
||||
/*!
|
||||
The operator= allows one to copy the values from one existing IntSerialDenseVector to another.
|
||||
The left hand side vector will take on the data access mode of the right hand side vector.
|
||||
|
||||
\return Values of the left hand side vector are modified by the values of the right hand side vector.
|
||||
*/
|
||||
Epetra_IntSerialDenseVector& operator = (const Epetra_IntSerialDenseVector& Source);
|
||||
|
||||
//! @name I/O methods
|
||||
//@{
|
||||
//! Print service methods; defines behavior of ostream << operator.
|
||||
virtual void Print(ostream& os) const;
|
||||
//@}
|
||||
|
||||
//! @name Expert-only unsupported methods
|
||||
//@{
|
||||
|
||||
//Bring the base-class MakeViewOf method into the current scope so that the
|
||||
//compiler knows we intend to overload it, rather than hide it.
|
||||
using Epetra_IntSerialDenseMatrix::MakeViewOf;
|
||||
|
||||
//! Reset an existing IntSerialDenseVector to point to another Vector.
|
||||
/*! Allows an existing IntSerialDenseVector to become a View of another
|
||||
vector's data, regardless of the DataAccess mode of the Source vector.
|
||||
It is assumed that the Source vector is an independent vector, and
|
||||
no checking is done to verify this.
|
||||
|
||||
This is used by Epetra_CrsGraph in the OptimizeStorage method. It is used
|
||||
so that an existing (Copy) vector can be converted to a View. This frees up
|
||||
memory that CrsGraph no longer needs.
|
||||
|
||||
@param Source The IntSerialDenseVector this will become a view of.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
|
||||
\warning This method is extremely dangerous and should only be used by experts.
|
||||
*/
|
||||
|
||||
int MakeViewOf(const Epetra_IntSerialDenseVector& Source);
|
||||
//@}
|
||||
};
|
||||
|
||||
// inlined definitions of op() and op[]
|
||||
//=========================================================================
|
||||
inline int& Epetra_IntSerialDenseVector::operator() (int Index) {
|
||||
#ifdef HAVE_EPETRA_ARRAY_BOUNDS_CHECK
|
||||
if(Index >= M_ || Index < 0)
|
||||
throw ReportError("Index = " + toString(Index) +
|
||||
" Out of Range 0 - " + toString(M_-1),-1);
|
||||
#endif
|
||||
return(A_[Index]);
|
||||
}
|
||||
//=========================================================================
|
||||
inline const int& Epetra_IntSerialDenseVector::operator() (int Index) const {
|
||||
#ifdef HAVE_EPETRA_ARRAY_BOUNDS_CHECK
|
||||
if(Index >= M_ || Index < 0)
|
||||
throw ReportError("Index = " + toString(Index) +
|
||||
" Out of Range 0 - " + toString(M_-1),-1);
|
||||
#endif
|
||||
return(A_[Index]);
|
||||
}
|
||||
//=========================================================================
|
||||
inline int& Epetra_IntSerialDenseVector::operator [] (int Index) {
|
||||
#ifdef HAVE_EPETRA_ARRAY_BOUNDS_CHECK
|
||||
if(Index >= M_ || Index < 0)
|
||||
throw ReportError("Index = " + toString(Index) +
|
||||
" Out of Range 0 - " + toString(M_-1),-1);
|
||||
#endif
|
||||
return(A_[Index]);
|
||||
}
|
||||
//=========================================================================
|
||||
inline const int& Epetra_IntSerialDenseVector::operator [] (int Index) const {
|
||||
#ifdef HAVE_EPETRA_ARRAY_BOUNDS_CHECK
|
||||
if(Index >= M_ || Index < 0)
|
||||
throw ReportError("Index = " + toString(Index) +
|
||||
" Out of Range 0 - " + toString(M_-1),-1);
|
||||
#endif
|
||||
return(A_[Index]);
|
||||
}
|
||||
//=========================================================================
|
||||
|
||||
#endif /* EPETRA_INTSERIALDENSEVECTOR_H */
|
||||
@@ -0,0 +1,291 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_INTVECTOR_H
|
||||
#define EPETRA_INTVECTOR_H
|
||||
|
||||
#include "Epetra_DistObject.h"
|
||||
#include "Epetra_BlockMap.h"
|
||||
#include "Epetra_Distributor.h"
|
||||
class Epetra_Map;
|
||||
|
||||
//! Epetra_IntVector: A class for constructing and using dense integer vectors on a parallel computer.
|
||||
|
||||
/*! The Epetra_IntVector class enables the construction and use of integer
|
||||
dense vectors in a distributed memory environment. The distribution of the dense
|
||||
vector is determined in part by a Epetra_Comm object and a Epetra_Map (or Epetra_LocalMap
|
||||
or Epetra_BlockMap).
|
||||
|
||||
|
||||
<b> Distributed Global vs. Replicated Local</b>
|
||||
<ul>
|
||||
<li> Distributed Global Vectors - In most instances, a multi-vector will be partitioned
|
||||
across multiple memory images associated with multiple processors. In this case, there is
|
||||
a unique copy of each element and elements are spread across all processors specified by
|
||||
the Epetra_Comm communicator.
|
||||
<li> Replicated Local Vectors - Some algorithms use vectors that are too small to
|
||||
be distributed across all processors. Replicated local vectors handle
|
||||
these types of situation.
|
||||
</ul>
|
||||
|
||||
<b>Constructing Epetra_IntVectors</b>
|
||||
|
||||
There are four Epetra_IntVector constructors. The first is a basic constructor that allocates
|
||||
space and sets all values to zero, the second is a
|
||||
copy constructor. The third and fourth constructors work with user data. These constructors have
|
||||
two data access modes:
|
||||
<ol>
|
||||
<li> Copy mode - Allocates memory and makes a copy of the user-provided data. In this case, the
|
||||
user data is not needed after construction.
|
||||
<li> View mode - Creates a "view" of the user data. In this case, the
|
||||
user data is required to remain intact for the life of the vector.
|
||||
</ol>
|
||||
|
||||
\warning View mode is \e extremely dangerous from a data hiding perspective.
|
||||
Therefore, we strongly encourage users to develop code using Copy mode first and
|
||||
only use the View mode in a secondary optimization phase.
|
||||
|
||||
All Epetra_IntVector constructors require a map argument that describes the layout of elements
|
||||
on the parallel machine. Specifically,
|
||||
\c map is a Epetra_Map, Epetra_LocalMap or Epetra_BlockMap object describing the desired
|
||||
memory layout for the vector.
|
||||
|
||||
There are four different Epetra_IntVector constructors:
|
||||
<ul>
|
||||
<li> Basic - All values are zero.
|
||||
<li> Copy - Copy an existing vector.
|
||||
<li> Copy from or make view of user int array.
|
||||
</ul>
|
||||
|
||||
<b>Extracting Data from Epetra_IntVectors</b>
|
||||
|
||||
Once a Epetra_IntVector is constructed, it is possible to extract a copy of the values or create
|
||||
a view of them.
|
||||
|
||||
\warning ExtractView functions are \e extremely dangerous from a data hiding perspective.
|
||||
For both ExtractView fuctions, there is a corresponding ExtractCopy function. We
|
||||
strongly encourage users to develop code using ExtractCopy functions first and
|
||||
only use the ExtractView functions in a secondary optimization phase.
|
||||
|
||||
There are two Extract functions:
|
||||
<ul>
|
||||
<li> ExtractCopy - Copy values into a user-provided array.
|
||||
<li> ExtractView - Set user-provided array to point to Epetra_IntVector data.
|
||||
</ul>
|
||||
|
||||
|
||||
\warning A Epetra_Map, Epetra_LocalMap or Epetra_BlockMap object is required for all
|
||||
Epetra_IntVector constructors.
|
||||
|
||||
*/
|
||||
|
||||
//=========================================================================
|
||||
class Epetra_IntVector : public Epetra_DistObject {
|
||||
|
||||
public:
|
||||
|
||||
//! @name Constructors/destructors
|
||||
//@{
|
||||
//! Basic Epetra_IntVector constuctor.
|
||||
/*! Creates a Epetra_IntVector object and, by default, fills with zero values.
|
||||
|
||||
\param In
|
||||
Map - A Epetra_LocalMap, Epetra_Map or Epetra_BlockMap.
|
||||
|
||||
\warning Note that, because Epetra_LocalMap
|
||||
derives from Epetra_Map and Epetra_Map derives from Epetra_BlockMap, this constructor works
|
||||
for all three types of Epetra map classes.
|
||||
\param In
|
||||
zeroOut - If <tt>true</tt> then the allocated memory will be zeroed
|
||||
out initialy. If <tt>false</tt> then this memory will not
|
||||
be touched which can be significantly faster.
|
||||
|
||||
\return Pointer to a Epetra_IntVector.
|
||||
|
||||
*/
|
||||
Epetra_IntVector(const Epetra_BlockMap& Map, bool zeroOut = true);
|
||||
|
||||
//! Epetra_IntVector copy constructor.
|
||||
|
||||
Epetra_IntVector(const Epetra_IntVector& Source);
|
||||
|
||||
//! Set vector values from user array.
|
||||
/*!
|
||||
\param In
|
||||
Epetra_DataAccess - Enumerated type set to Copy or View.
|
||||
\param In
|
||||
Map - A Epetra_LocalMap, Epetra_Map or Epetra_BlockMap.
|
||||
\param In
|
||||
V - Pointer to an array of integer numbers..
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
|
||||
See Detailed Description section for further discussion.
|
||||
*/
|
||||
Epetra_IntVector(Epetra_DataAccess CV, const Epetra_BlockMap& Map, int *V);
|
||||
|
||||
//! Epetra_IntVector destructor.
|
||||
virtual ~Epetra_IntVector ();
|
||||
//@}
|
||||
|
||||
|
||||
//! @name Post-construction modification methods
|
||||
//@{
|
||||
//! Set all elements of the vector to Value
|
||||
int PutValue(int Value);
|
||||
//@}
|
||||
|
||||
|
||||
//! @name Extraction methods
|
||||
//@{
|
||||
|
||||
|
||||
//! Put vector values into user-provided array.
|
||||
/*!
|
||||
\param Out
|
||||
V - Pointer to memory space that will contain the vector values.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int ExtractCopy(int *V) const;
|
||||
|
||||
//! Set user-provided address of V.
|
||||
/*!
|
||||
\param Out
|
||||
V - Address of a pointer to that will be set to point to the values of the vector.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int ExtractView(int **V) const;
|
||||
//@}
|
||||
|
||||
//! @name Mathematical methods
|
||||
//@{
|
||||
//! Find maximum value
|
||||
/*!
|
||||
\return Maximum value across all processors.
|
||||
*/
|
||||
int MaxValue();
|
||||
|
||||
//! Find minimum value
|
||||
/*!
|
||||
\return Minimum value across all processors.
|
||||
*/
|
||||
int MinValue();
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Overloaded operators
|
||||
//@{
|
||||
|
||||
//! = Operator.
|
||||
/*!
|
||||
\param In
|
||||
A - Epetra_IntVector to copy.
|
||||
|
||||
\return Epetra_IntVector.
|
||||
*/
|
||||
Epetra_IntVector& operator = (const Epetra_IntVector& Source);
|
||||
|
||||
//! Element access function.
|
||||
/*!
|
||||
\return V[Index].
|
||||
*/
|
||||
int& operator [] (int index) { return Values_[index]; }
|
||||
//! Element access function.
|
||||
/*!
|
||||
\return V[Index].
|
||||
*/
|
||||
const int& operator [] (int index) const { return Values_[index]; }
|
||||
//@}
|
||||
|
||||
//! @name Attribute access functions
|
||||
//@{
|
||||
|
||||
//! Returns a pointer to an array containing the values of this vector.
|
||||
int * Values() const {return(Values_);};
|
||||
|
||||
//! Returns the local vector length on the calling processor of vectors in the multi-vector.
|
||||
int MyLength() const {return(Map().NumMyPoints());};
|
||||
|
||||
//! Returns the global vector length of vectors in the multi-vector.
|
||||
int GlobalLength() const {return(Map().NumGlobalPoints());};
|
||||
//@}
|
||||
|
||||
//! @name I/O methods
|
||||
//@{
|
||||
|
||||
//! Print method
|
||||
virtual void Print(ostream & os) const;
|
||||
//@}
|
||||
private:
|
||||
|
||||
int AllocateForCopy();
|
||||
int DoCopy(int * V);
|
||||
int AllocateForView();
|
||||
int DoView(int * V);
|
||||
|
||||
// Routines to implement Epetra_DistObject virtual methods
|
||||
int CheckSizes(const Epetra_SrcDistObject& A);
|
||||
|
||||
int CopyAndPermute(const Epetra_SrcDistObject & Source,
|
||||
int NumSameIDs,
|
||||
int NumPermuteIDs,
|
||||
int * PermuteToLIDs,
|
||||
int * PermuteFromLIDs,
|
||||
const Epetra_OffsetIndex * Indexor);
|
||||
|
||||
int PackAndPrepare(const Epetra_SrcDistObject & Source,
|
||||
int NumExportIDs,
|
||||
int * ExportLIDs,
|
||||
int & LenExports,
|
||||
char * & Exports,
|
||||
int & SizeOfPacket,
|
||||
int * Sizes,
|
||||
bool& VarSizes,
|
||||
Epetra_Distributor & Distor);
|
||||
|
||||
int UnpackAndCombine(const Epetra_SrcDistObject & Source,
|
||||
int NumImportIDs,
|
||||
int * ImportLIDs,
|
||||
int LenImports,
|
||||
char * Imports,
|
||||
int & SizeOfPacket,
|
||||
Epetra_Distributor & Distor,
|
||||
Epetra_CombineMode CombineMode,
|
||||
const Epetra_OffsetIndex * Indexor);
|
||||
|
||||
int * Values_;
|
||||
bool UserAllocated_;
|
||||
bool Allocated_;
|
||||
};
|
||||
|
||||
#endif /* EPETRA_INTVECTOR_H */
|
||||
@@ -0,0 +1,155 @@
|
||||
|
||||
/*@HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Epetra: Linear Algebra Services Package
|
||||
// Copyright (2001) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
//@HEADER
|
||||
*/
|
||||
|
||||
#ifndef EPETRA_INVOPERATOR_H
|
||||
#define EPETRA_INVOPERATOR_H
|
||||
|
||||
class Epetra_MultiVector;
|
||||
class Epetra_BlockMap;
|
||||
class Epetra_Comm;
|
||||
#include <string>
|
||||
#include "Epetra_Operator.h"
|
||||
|
||||
//! Epetra_InvOperator: An implementation of the Epetra_Operator class that reverses the role of Apply() and ApplyInverse() methods.
|
||||
/*! The Epetra_InvOperator class implements Epetra_Operator using another pre-constructed Epetra_Operator object.
|
||||
Once constructed, an Epetra_InvOperator can be used as the inverse of the input operator
|
||||
object as long as the appropriate Apply and ApplyInverse methods are implemented in the original Epetra_Operator object.
|
||||
*/
|
||||
|
||||
class Epetra_InvOperator: public virtual Epetra_Operator {
|
||||
|
||||
public:
|
||||
|
||||
//! @name Constructor
|
||||
//@{
|
||||
//! Uses an Epetra_Operator instance to implement the Epetra_Operator interface.
|
||||
/*! Facilitates the use of an Epetra_Operator instance as an inverse operator.
|
||||
\param In - A fully-constructed Epetra_Operator object.
|
||||
*/
|
||||
Epetra_InvOperator(Epetra_Operator * operatorIn) {
|
||||
operator_ = operatorIn;
|
||||
Label_ = "Inverse of " + string(operatorIn->Label());
|
||||
return;
|
||||
}
|
||||
//! Destructor
|
||||
virtual ~Epetra_InvOperator(){}
|
||||
//@}
|
||||
|
||||
//! @name Atribute set methods
|
||||
//@{
|
||||
|
||||
//! If set true, transpose of this operator will be applied.
|
||||
/*! This flag allows the transpose of the given operator to be used implicitly. Setting this flag
|
||||
affects only the Apply() and ApplyInverse() methods. If the implementation of this interface
|
||||
does not support transpose use, this method should return a value of -1.
|
||||
|
||||
\param In
|
||||
UseTranspose - If true, multiply by the transpose of operator, otherwise just use operator.
|
||||
|
||||
\warning - This method has no effect and returns -1 as error code.
|
||||
*/
|
||||
int SetUseTranspose(bool UseTranspose){EPETRA_CHK_ERR(operator_->SetUseTranspose(UseTranspose)); return(0);}
|
||||
//@}
|
||||
|
||||
//! @name Mathematical functions
|
||||
//@{
|
||||
|
||||
//! Returns the result of a Epetra_InvOperator applied to a Epetra_MultiVector X in Y.
|
||||
/*!
|
||||
\param In
|
||||
X - A Epetra_MultiVector of dimension NumVectors to multiply with matrix.
|
||||
\param Out
|
||||
Y -A Epetra_MultiVector of dimension NumVectors containing result.
|
||||
|
||||
\warning - This method has no effect and returns -1 as error code.
|
||||
*/
|
||||
int Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const {EPETRA_CHK_ERR(operator_->ApplyInverse(X,Y)); return(0);}
|
||||
|
||||
//! Returns the result of a Epetra_InvOperator inverse applied to an Epetra_MultiVector X in Y.
|
||||
/*!
|
||||
\param In
|
||||
X - A Epetra_MultiVector of dimension NumVectors to solve for.
|
||||
\param Out
|
||||
Y -A Epetra_MultiVector of dimension NumVectors containing result.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int ApplyInverse(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const{EPETRA_CHK_ERR(operator_->Apply(X,Y)); return(0);}
|
||||
|
||||
//! Returns the infinity norm of the global matrix.
|
||||
/* Returns the quantity \f$ \| A \|_\infty\f$ such that
|
||||
\f[\| A \|_\infty = \max_{1\lei\lem} \sum_{j=1}^n |a_{ij}| \f].
|
||||
|
||||
\warning This method must not be called unless HasNormInf() returns true.
|
||||
*/
|
||||
double NormInf() const {return(operator_->NormInf());}
|
||||
|
||||
//! @name Atribute access functions
|
||||
//@{
|
||||
|
||||
//! Returns a character string describing the operator
|
||||
const char * Label() const {return(Label_.c_str());}
|
||||
|
||||
//! Returns a pointer to the Epetra_Operator operator object that was used to create this Epetra_InvOperator object.
|
||||
Epetra_Operator * Operator() const {return(operator_);}
|
||||
|
||||
|
||||
//! Returns the current UseTranspose setting.
|
||||
bool UseTranspose() const {return(operator_->UseTranspose());}
|
||||
|
||||
//! Returns true if the \e this object can provide an approximate Inf-norm, false otherwise.
|
||||
bool HasNormInf() const {return(operator_->HasNormInf());};
|
||||
|
||||
//! Returns a pointer to the Epetra_Comm communicator associated with this operator.
|
||||
const Epetra_Comm & Comm() const {return(operator_->Comm());}
|
||||
|
||||
//! Returns the Epetra_BlockMap object associated with the domain of this matrix operator.
|
||||
const Epetra_Map & OperatorDomainMap() const
|
||||
{
|
||||
if (!UseTranspose()) return(operator_->OperatorRangeMap());
|
||||
else return(operator_->OperatorDomainMap());
|
||||
}
|
||||
|
||||
//! Returns the Epetra_BlockMap object associated with the range of this matrix operator.
|
||||
const Epetra_Map & OperatorRangeMap() const
|
||||
{
|
||||
if (!UseTranspose()) return(operator_->OperatorDomainMap());
|
||||
else return(operator_->OperatorRangeMap());
|
||||
}
|
||||
//@}
|
||||
|
||||
protected:
|
||||
|
||||
Epetra_Operator * operator_;
|
||||
string Label_;
|
||||
};
|
||||
|
||||
#endif /* EPETRA_INVOPERATOR_H */
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_JADMATRIX_H
|
||||
#define EPETRA_JADMATRIX_H
|
||||
|
||||
#include "Epetra_BasicRowMatrix.h"
|
||||
#include "Epetra_Map.h"
|
||||
#include "Epetra_Comm.h"
|
||||
#include "Epetra_SerialDenseVector.h"
|
||||
#include "Epetra_IntSerialDenseVector.h"
|
||||
|
||||
|
||||
class Epetra_Vector;
|
||||
class Epetra_MultiVector;
|
||||
class Epetra_Import;
|
||||
class Epetra_Export;
|
||||
|
||||
//! Epetra_JadMatrix: A class for constructing matrix objects optimized for common kernels.
|
||||
|
||||
/*! The Epetra_JadMatrix class takes an existing Epetra_RowMatrix ojbect, analyzes it and
|
||||
builds a jagged diagonal equivalent of it. Once constructed, it is also possible to
|
||||
update the values of the matrix with values from another Epetra_RowMatrix that has
|
||||
the identical structure.
|
||||
|
||||
*/
|
||||
|
||||
class Epetra_JadMatrix: public Epetra_BasicRowMatrix {
|
||||
|
||||
public:
|
||||
|
||||
//! @name Constructors/Destructor
|
||||
//@{
|
||||
//! Epetra_JadMatrix constuctor.
|
||||
/* The constructor for this class requires a fully constructed instance of an Epetra_RowMatrix
|
||||
object.
|
||||
\param Matrix (In) An existing Epetra_RowMatrix.
|
||||
\pre Matrix must have Matrix.Filled()==true.
|
||||
*/
|
||||
Epetra_JadMatrix(const Epetra_RowMatrix & Matrix);
|
||||
|
||||
//! Epetra_JadMatrix Destructor
|
||||
virtual ~Epetra_JadMatrix();
|
||||
//@}
|
||||
|
||||
//! @name Post-construction modifications
|
||||
//@{
|
||||
//! Update values using a matrix with identical structure.
|
||||
/* Updates the values only using a matrix that has exactly the same structure as
|
||||
the matrix used to construct this Epetra_JadMatrix object. Once the constructor
|
||||
is called, the Matrix argument is no longer needed.
|
||||
\param Matrix (In) An existing Epetra_RowMatrix with \e identical structure to
|
||||
the matrix used to create this Epetra_JadMatrix.
|
||||
\param CheckStructure (In) Optional argument, by default is false. If set to true,
|
||||
the method will check to see if the structure of Matrix is compatible with
|
||||
the structure of matrix used to create this Epetra_JadMatrix. Performing
|
||||
this check has signficant overhead, so it should only be turned on for debugging.
|
||||
\pre Matrix must have Matrix.Filled()==true.
|
||||
*/
|
||||
int UpdateValues(const Epetra_RowMatrix & Matrix, bool CheckStructure = false);
|
||||
//@}
|
||||
|
||||
//! @name Methods required for implementing Epetra_BasicRowMatrix
|
||||
//@{
|
||||
|
||||
//! Returns a copy of the specified local row in user-provided arrays.
|
||||
/*!
|
||||
\param MyRow (In) - Local row to extract.
|
||||
\param Length (In) - Length of Values and Indices.
|
||||
\param NumEntries (Out) - Number of nonzero entries extracted.
|
||||
\param Values (Out) - Extracted values for this row.
|
||||
\param Indices (Out) - Extracted global column indices for the corresponding values.
|
||||
|
||||
\return Integer error code, set to 0 if successful, set to -1 if MyRow not valid, -2 if Length is too short (NumEntries will have required length).
|
||||
*/
|
||||
int ExtractMyRowCopy(int MyRow, int Length, int & NumEntries, double *Values, int * Indices) const;
|
||||
|
||||
//! Returns a reference to the ith entry in the matrix, along with its row and column index.
|
||||
/*!
|
||||
\param CurEntry (In) - Local entry to extract.
|
||||
\param Value (Out) - Extracted reference to current values.
|
||||
\param RowIndex (Out) - Row index for current entry.
|
||||
\param ColIndex (Out) - Column index for current entry.
|
||||
|
||||
\return Integer error code, set to 0 if successful, set to -1 if CurEntry not valid.
|
||||
*/
|
||||
int ExtractMyEntryView(int CurEntry, double * &Value, int & RowIndex, int & ColIndex) {
|
||||
if (CurEntry>=NumMyNonzeros_) EPETRA_CHK_ERR(-1);
|
||||
Value = &Values_[CurEntry];
|
||||
ColIndex = Indices_[CurEntry];
|
||||
for (int j=0; j<NumJaggedDiagonals_; j++) if (CurEntry<IndexOffset_[j+1]) {RowIndex = RowPerm_[CurEntry-IndexOffset_[j]]; break;}
|
||||
return(0);
|
||||
}
|
||||
|
||||
//! Returns a const reference to the ith entry in the matrix, along with its row and column index.
|
||||
/*!
|
||||
\param CurEntry (In) - Local entry to extract.
|
||||
\param Value (Out) - Extracted reference to current values.
|
||||
\param RowIndex (Out) - Row index for current entry.
|
||||
\param ColIndex (Out) - Column index for current entry.
|
||||
|
||||
\return Integer error code, set to 0 if successful, set to -1 if CurEntry not valid.
|
||||
*/
|
||||
int ExtractMyEntryView(int CurEntry, double const * & Value, int & RowIndex, int & ColIndex) const {
|
||||
if (CurEntry>=NumMyNonzeros_) EPETRA_CHK_ERR(-1);
|
||||
Value = &Values_[CurEntry];
|
||||
ColIndex = Indices_[CurEntry];
|
||||
for (int j=0; j<NumJaggedDiagonals_; j++) if (CurEntry<IndexOffset_[j+1]) RowIndex = RowPerm_[CurEntry-IndexOffset_[j]];
|
||||
return(0);
|
||||
}
|
||||
|
||||
//! Return the current number of values stored for the specified local row.
|
||||
/*! Similar to NumMyEntries() except NumEntries is returned as an argument
|
||||
and error checking is done on the input value MyRow.
|
||||
\param MyRow - (In) Local row.
|
||||
\param NumEntries - (Out) Number of nonzero values.
|
||||
|
||||
\return Integer error code, set to 0 if successful, set to -1 if MyRow not valid.
|
||||
\pre None.
|
||||
\post Unchanged.
|
||||
*/
|
||||
int NumMyRowEntries(int MyRow, int & NumEntries) const;
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Computational methods
|
||||
//@{
|
||||
|
||||
//! Returns the result of a Epetra_JadMatrix multiplied by a Epetra_MultiVector X in Y.
|
||||
/*!
|
||||
\param In
|
||||
TransA -If true, multiply by the transpose of matrix, otherwise just use matrix.
|
||||
\param In
|
||||
X - A Epetra_MultiVector of dimension NumVectors to multiply with matrix.
|
||||
\param Out
|
||||
Y -A Epetra_MultiVector of dimension NumVectorscontaining result.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int Multiply(bool TransA, const Epetra_MultiVector& X, Epetra_MultiVector& Y) const;
|
||||
|
||||
//! Returns the result of a Epetra_JadMatrix solve with a Epetra_MultiVector X in Y (not implemented).
|
||||
/*!
|
||||
\param In
|
||||
Upper -If true, solve Ux = y, otherwise solve Lx = y.
|
||||
\param In
|
||||
Trans -If true, solve transpose problem.
|
||||
\param In
|
||||
UnitDiagonal -If true, assume diagonal is unit (whether it's stored or not).
|
||||
\param In
|
||||
X - A Epetra_MultiVector of dimension NumVectors to solve for.
|
||||
\param Out
|
||||
Y -A Epetra_MultiVector of dimension NumVectors containing result.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int Solve(bool Upper, bool Trans, bool UnitDiagonal,
|
||||
const Epetra_MultiVector& X,
|
||||
Epetra_MultiVector& Y) const
|
||||
{
|
||||
(void)Upper;
|
||||
(void)Trans;
|
||||
(void)UnitDiagonal;
|
||||
(void)X;
|
||||
(void)Y;
|
||||
return(-1);
|
||||
}
|
||||
//@}
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
void GeneralMV(bool TransA, double * x, double * y) const;
|
||||
void GeneralMM(bool TransA, double ** X, int LDX, double ** Y, int LDY, int NumVectors) const;
|
||||
void GeneralMM3RHS(bool TransA, double ** X, int LDX, double ** Y, int LDY, int NumVectors) const;
|
||||
void GeneralMM2RHS(bool TransA, double * x, int ldx, double * y, int ldy) const;
|
||||
void Allocate(const Epetra_RowMatrix & Matrix);
|
||||
|
||||
Epetra_SerialDenseVector Values_;
|
||||
Epetra_IntSerialDenseVector Indices_;
|
||||
Epetra_IntSerialDenseVector IndexOffset_;
|
||||
Epetra_IntSerialDenseVector Profile_;
|
||||
Epetra_IntSerialDenseVector RowPerm_;
|
||||
Epetra_IntSerialDenseVector InvRowPerm_;
|
||||
int NumJaggedDiagonals_;
|
||||
|
||||
};
|
||||
#endif /* EPETRA_JADMATRIX_H */
|
||||
@@ -0,0 +1,402 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_LAPACK_H
|
||||
#define EPETRA_LAPACK_H
|
||||
|
||||
//! Epetra_LAPACK: The Epetra LAPACK Wrapper Class.
|
||||
/*! The Epetra_LAPACK class is a wrapper that encapsulates LAPACK
|
||||
(Linear Algebra Package). LAPACK provides portable, high-
|
||||
performance implementations of linear, eigen, SVD, etc solvers.
|
||||
|
||||
The standard LAPACK interface is Fortran-specific. Unfortunately, the
|
||||
interface between C++ and Fortran is not standard across all computer
|
||||
platforms. The Epetra_LAPACK class provides C++ wrappers for the LAPACK
|
||||
kernels in order to insulate the rest of Epetra from the details of C++ to Fortran
|
||||
translation.
|
||||
A Epetra_LAPACK object is essentially nothing, but allows access to the LAPACK wrapper
|
||||
functions.
|
||||
|
||||
Epetra_LAPACK is a serial interface only. This is appropriate since the standard
|
||||
LAPACK are only specified for serial execution (or shared memory parallel).
|
||||
*/
|
||||
|
||||
#include "Epetra_Object.h"
|
||||
|
||||
class Epetra_LAPACK {
|
||||
|
||||
public:
|
||||
//! @name Constructors/destructors
|
||||
//@{
|
||||
//! Epetra_LAPACK Constructor.
|
||||
/*! Builds an instance of a serial LAPACK object.
|
||||
*/
|
||||
Epetra_LAPACK(void);
|
||||
|
||||
|
||||
//! Epetra_LAPACK Copy Constructor.
|
||||
/*! Makes an exact copy of an existing Epetra_LAPACK instance.
|
||||
*/
|
||||
Epetra_LAPACK(const Epetra_LAPACK& LAPACK);
|
||||
|
||||
//! Epetra_LAPACK Destructor.
|
||||
virtual ~Epetra_LAPACK(void);
|
||||
//@}
|
||||
|
||||
|
||||
//! @name Symmetric Positive Definite linear system routines
|
||||
//@{
|
||||
|
||||
//! Epetra_LAPACK factorization for positive definite matrix (SPOTRF)
|
||||
void POTRF( const char UPLO, const int N, float * A, const int LDA, int * INFO) const;
|
||||
//! Epetra_LAPACK factorization for positive definite matrix (DPOTRF)
|
||||
void POTRF( const char UPLO, const int N, double * A, const int LDA, int * INFO) const;
|
||||
|
||||
//! Epetra_LAPACK solve (after factorization) for positive definite matrix (SPOTRS)
|
||||
void POTRS( const char UPLO, const int N, const int NRHS, const float * A, const int LDA, float * X, const int LDX, int * INFO) const;
|
||||
//! Epetra_LAPACK solve (after factorization) for positive definite matrix (DPOTRS)
|
||||
void POTRS( const char UPLO, const int N, const int NRHS, const double * A, const int LDA, double * X, const int LDX, int * INFO) const;
|
||||
|
||||
//! Epetra_LAPACK inversion for positive definite matrix (SPOTRI)
|
||||
void POTRI( const char UPLO, const int N, float * A, const int LDA, int * INFO) const;
|
||||
//! Epetra_LAPACK inversion for positive definite matrix (DPOTRI)
|
||||
void POTRI( const char UPLO, const int N, double * A, const int LDA, int * INFO) const;
|
||||
|
||||
//! Epetra_LAPACK condition number estimator for positive definite matrix (SPOCON)
|
||||
void POCON( const char UPLO, const int N, const float * A, const int LDA, const float ANORM,
|
||||
float * RCOND, float * WORK, int * IWORK, int * INFO) const;
|
||||
//! Epetra_LAPACK condition number estimator for positive definite matrix (DPOCON)
|
||||
void POCON( const char UPLO, const int N, const double * A, const int LDA, const double ANORM,
|
||||
double * RCOND, double * WORK, int * IWORK, int * INFO) const;
|
||||
|
||||
//! Epetra_LAPACK factor and solve for positive definite matrix (SPOSV)
|
||||
void POSV( const char UPLO, const int N, const int NRHS, float * A, const int LDA, float * X, const int LDX, int * INFO) const;
|
||||
//! Epetra_LAPACK factor and solve for positive definite matrix (DPOSV)
|
||||
void POSV( const char UPLO, const int N, const int NRHS, double * A, const int LDA, double * X, const int LDX, int * INFO) const;
|
||||
|
||||
//! Epetra_LAPACK equilibration for positive definite matrix (SPOEQU)
|
||||
void POEQU(const int N, const float * A, const int LDA, float * S, float * SCOND, float * AMAX, int * INFO) const;
|
||||
//! Epetra_LAPACK equilibration for positive definite matrix (DPOEQU)
|
||||
void POEQU(const int N, const double * A, const int LDA, double * S, double * SCOND, double * AMAX, int * INFO) const;
|
||||
|
||||
//! Epetra_LAPACK solve driver for positive definite matrix (SPOSVX)
|
||||
void PORFS(const char UPLO, const int N, const int NRHS, const float * A, const int LDA, const float * AF, const int LDAF,
|
||||
const float * B, const int LDB, float * X, const int LDX,
|
||||
float * FERR, float * BERR, float * WORK, int * IWORK, int * INFO) const;
|
||||
//! Epetra_LAPACK solve driver for positive definite matrix (DPOSVX)
|
||||
void PORFS(const char UPLO, const int N, const int NRHS, const double * A, const int LDA, const double * AF, const int LDAF,
|
||||
const double * B, const int LDB, double * X, const int LDX,
|
||||
double * FERR, double * BERR, double * WORK, int * IWORK, int * INFO) const;
|
||||
|
||||
//! Epetra_LAPACK solve driver for positive definite matrix (SPOSVX)
|
||||
void POSVX(const char FACT, const char UPLO, const int N, const int NRHS, float * A, const int LDA, float * AF, const int LDAF,
|
||||
const char EQUED, float * S, float * B, const int LDB, float * X, const int LDX, float * RCOND,
|
||||
float * FERR, float * BERR, float * WORK, int * IWORK, int * INFO) const;
|
||||
//! Epetra_LAPACK solve driver for positive definite matrix (DPOSVX)
|
||||
void POSVX(const char FACT, const char UPLO, const int N, const int NRHS, double * A, const int LDA, double * AF, const int LDAF,
|
||||
const char EQUED, double * S, double * B, const int LDB, double * X, const int LDX, double * RCOND,
|
||||
double * FERR, double * BERR, double * WORK, int * IWORK, int * INFO) const;
|
||||
//@}
|
||||
|
||||
//! @name General linear system routines
|
||||
//@{
|
||||
|
||||
//! Epetra_LAPACK simple driver to solve least-squares systems
|
||||
void GELS( const char TRANS, const int M, const int N, const int NRHS, double* A, const int LDA,
|
||||
double* B, const int LDB, double* WORK, const int LWORK, int * INFO) const;
|
||||
//! Epetra_LAPACK factorization for general matrix (SGETRF)
|
||||
void GETRF( const int M, const int N, float * A, const int LDA, int * IPIV, int * INFO) const;
|
||||
//! Epetra_LAPACK factorization for general matrix (DGETRF)
|
||||
void GETRF( const int M, const int N, double * A, const int LDA, int * IPIV, int * INFO) const;
|
||||
|
||||
//! Epetra_LAPACK QR factorization for general matrix (SGEQRF)
|
||||
void GEQRF( const int M, const int N, float * A, const int LDA, float * TAU, float * WORK, const int lwork, int * INFO) const;
|
||||
//! Epetra_LAPACK factorization for general matrix (DGEQRF)
|
||||
void GEQRF( const int M, const int N, double * A, const int LDA, double * TAU, double * WORK, const int lwork, int * INFO) const;
|
||||
|
||||
//! Epetra_LAPACK solve (after factorization) for general matrix (SGETRS)
|
||||
void GETRS( const char TRANS, const int N, const int NRHS, const float * A, const int LDA, const int * IPIV, float * X, const int LDX, int * INFO) const;
|
||||
//! Epetra_LAPACK solve (after factorization) for general matrix (DGETRS)
|
||||
void GETRS( const char TRANS, const int N, const int NRHS, const double * A, const int LDA, const int * IPIV, double * X, const int LDX, int * INFO) const;
|
||||
|
||||
//! Epetra_LAPACK inversion for general matrix (SGETRI)
|
||||
void GETRI( const int N, float * A, const int LDA, int * IPIV, float * WORK, const int * LWORK, int * INFO) const;
|
||||
//! Epetra_LAPACK inversion for general matrix (DGETRI)
|
||||
void GETRI( const int N, double * A, const int LDA, int * IPIV, double * WORK, const int * LWORK, int * INFO) const;
|
||||
|
||||
//! Epetra_LAPACK condition number estimator for general matrix (SGECON)
|
||||
void GECON( const char NORM, const int N, const float * A, const int LDA, const float ANORM,
|
||||
float * RCOND, float * WORK, int * IWORK, int * INFO) const;
|
||||
//! Epetra_LAPACK condition number estimator for general matrix (DGECON)
|
||||
void GECON( const char NORM, const int N, const double * A, const int LDA, const double ANORM,
|
||||
double * RCOND, double * WORK, int * IWORK, int * INFO) const;
|
||||
|
||||
//! Epetra_LAPACK factor and solve for general matrix (SGESV)
|
||||
void GESV( const int N, const int NRHS, float * A, const int LDA, int * IPIV, float * X, const int LDX, int * INFO) const;
|
||||
//! Epetra_LAPACK factor and solve for general matrix (DGESV)
|
||||
void GESV( const int N, const int NRHS, double * A, const int LDA, int * IPIV, double * X, const int LDX, int * INFO) const;
|
||||
|
||||
//! Epetra_LAPACK equilibration for general matrix (SGEEQU)
|
||||
void GEEQU(const int M, const int N, const float * A, const int LDA, float * R, float * C, float * ROWCND, float * COLCND, float * AMAX, int * INFO) const;
|
||||
//! Epetra_LAPACK equilibration for general matrix (DGEEQU)
|
||||
void GEEQU(const int M, const int N, const double * A, const int LDA, double * R, double * C, double * ROWCND, double * COLCND, double * AMAX, int * INFO) const;
|
||||
|
||||
//! Epetra_LAPACK Refine solution (GERFS)
|
||||
void GERFS(const char TRANS, const int N, const int NRHS, const float * A, const int LDA, const float * AF, const int LDAF,
|
||||
const int * IPIV, const float * B, const int LDB, float * X, const int LDX,
|
||||
float * FERR, float * BERR, float * WORK, int * IWORK, int * INFO) const;
|
||||
//! Epetra_LAPACK Refine solution (GERFS)
|
||||
void GERFS(const char TRANS, const int N, const int NRHS, const double * A, const int LDA, const double * AF, const int LDAF,
|
||||
const int * IPIV, const double * B, const int LDB, double * X, const int LDX,
|
||||
double * FERR, double * BERR, double * WORK, int * IWORK, int * INFO) const;
|
||||
|
||||
//! Epetra_LAPACK solve driver for general matrix (SGESVX)
|
||||
void GESVX(const char FACT, const char TRANS, const int N, const int NRHS, float * A, const int LDA, float * AF, const int LDAF, int * IPIV,
|
||||
const char EQUED, float * R, float * C, float * B, const int LDB, float * X, const int LDX, float * RCOND,
|
||||
float * FERR, float * BERR, float * WORK, int * IWORK, int * INFO) const;
|
||||
//! Epetra_LAPACK solve driver for general matrix (DGESVX)
|
||||
void GESVX(const char FACT, const char TRANS, const int N, const int NRHS, double * A, const int LDA, double * AF, const int LDAF, int * IPIV,
|
||||
const char EQUED, double * R, double * C, double * B, const int LDB, double * X, const int LDX, double * RCOND,
|
||||
double * FERR, double * BERR, double * WORK, int * IWORK, int * INFO) const;
|
||||
|
||||
|
||||
//! Epetra_LAPACK wrapper for reduction to Hessenberg form (SGEHRD)
|
||||
void GEHRD(const int N, const int ILO, const int IHI, float * A, const int LDA, float * TAU, float * WORK, const int LWORK, int * INFO) const;
|
||||
//! Epetra_LAPACK wrapper for reduction to Hessenberg form (DGEHRD)
|
||||
void GEHRD(const int N, const int ILO, const int IHI, double * A, const int LDA, double * TAU, double * WORK, const int LWORK, int * INFO) const;
|
||||
//@}
|
||||
|
||||
//! @name Hessenberg routines
|
||||
//@{
|
||||
//! Epetra_LAPACK wrapper for computing the eigenvalues of a real upper Hessenberg matrix (SHSEQR)
|
||||
void HSEQR( const char JOB, const char COMPZ, const int N, const int ILO, const int IHI, float * H, const int LDH, float * WR, float * WI,
|
||||
float * Z, const int LDZ, float * WORK, const int LWORK, int * INFO) const;
|
||||
//! Epetra_LAPACK wrapper for computing the eigenvalues of a real upper Hessenberg matrix (DHSEQR)
|
||||
void HSEQR( const char JOB, const char COMPZ, const int N, const int ILO, const int IHI, double * H, const int LDH, double * WR, double * WI,
|
||||
double * Z, const int LDZ, double * WORK, const int LWORK, int * INFO) const;
|
||||
//@}
|
||||
|
||||
//! @name Orthogonal matrix routines
|
||||
//@{
|
||||
//! Epetra_LAPACK wrapper for generating a m x n real matrix Q with orthonormal columns, defined as the product of k elementary reflectors. (SORGQR)
|
||||
void ORGQR( const int M, const int N, const int K, float * A, const int LDA, float * TAU, float * WORK, const int LWORK, int * INFO) const;
|
||||
//! Epetra_LAPACK wrapper for generating a m x n real matrix Q with orthonormal columns, defined as the product of k elementary reflectors. (DORGQR)
|
||||
void ORGQR( const int M, const int N, const int K, double * A, const int LDA, double * TAU, double * WORK, const int LWORK, int * INFO) const;
|
||||
|
||||
//! Epetra_LAPACK wrapper for generating a real orthogonal matrix Q defined by elementary reflectors. (SORGHR)
|
||||
void ORGHR( const int N, const int ILO, const int IHI, float * A, const int LDA, float * TAU, float * WORK, const int LWORK, int * INFO) const;
|
||||
//! Epetra_LAPACK wrapper for generating a real orthogonal matrix Q defined by elementary reflectors. (DORGHR)
|
||||
void ORGHR( const int N, const int ILO, const int IHI, double * A, const int LDA, double * TAU, double * WORK, const int LWORK, int * INFO) const;
|
||||
|
||||
//! Epetra_LAPACK wrapper for applying an orthogonal matrix in-place (SORMHR)
|
||||
void ORMHR( const char SIDE, const char TRANS, const int M, const int N, const int ILO, const int IHI, const float * A, const int LDA,
|
||||
const float * TAU, float * C,
|
||||
const int LDC, float * WORK, const int LWORK, int * INFO) const;
|
||||
//! Epetra_LAPACK wrapper for applying an orthogonal matrix in-place (DORMHR)
|
||||
void ORMHR( const char SIDE, const char TRANS, const int M, const int N, const int ILO, const int IHI, const double * A, const int LDA,
|
||||
const double * TAU, double * C,
|
||||
const int LDC, double * WORK, const int LWORK, int * INFO) const;
|
||||
//! Epetra_LAPACK for forming the triangular factor of a product of elementary Householder reflectors (SLARFT).
|
||||
void LARFT( const char DIRECT, const char STOREV, const int N, const int K, double * V, const int LDV, double * TAU, double * T, const int LDT) const;
|
||||
//! Epetra_LAPACK for forming the triangular factor of a product of elementary Householder reflectors (DLARFT).
|
||||
void LARFT( const char DIRECT, const char STOREV, const int N, const int K, float * V, const int LDV, float * TAU, float * T, const int LDT) const;
|
||||
//@}
|
||||
|
||||
//! @name Triangular matrix routines
|
||||
//@{
|
||||
|
||||
//! Epetra_LAPACK wrapper for computing eigenvectors of a quasi-triangular/triagnular matrix (STREVC)
|
||||
/*! \warning HOWMNY = 'S" is not supported.
|
||||
*/
|
||||
void TREVC( const char SIDE, const char HOWMNY, int * SELECT, const int N, const float * T, const int LDT, float *VL, const int LDVL,
|
||||
float * VR, const int LDVR, const int MM, int * M, float * WORK, int * INFO) const;
|
||||
//! Epetra_LAPACK wrapper for computing eigenvectors of a quasi-triangular/triagnular matrix (DTREVC)
|
||||
/*! \warning HOWMNY = 'S" is not supported.
|
||||
*/
|
||||
void TREVC( const char SIDE, const char HOWMNY, int * SELECT, const int N, const double * T, const int LDT, double *VL, const int LDVL,
|
||||
double * VR, const int LDVR, const int MM, int *M, double * WORK, int * INFO) const;
|
||||
|
||||
//! Epetra_LAPACK wrapper for reordering the real-Schur/Schur factorization of a matrix (STREXC)
|
||||
void TREXC( const char COMPQ, const int N, float * T, const int LDT, float * Q, const int LDQ, int IFST, int ILST,
|
||||
float * WORK, int * INFO) const;
|
||||
//! Epetra_LAPACK wrapper for reordering the real-Schur/Schur factorization of a matrix (DTREXC)
|
||||
void TREXC( const char COMPQ, const int N, double * T, const int LDT, double * Q, const int LDQ, int IFST, int ILST,
|
||||
double * WORK, int * INFO) const;
|
||||
//@}
|
||||
|
||||
//! @name Singular Value Decomposition matrix routines
|
||||
//@{
|
||||
|
||||
//! Epetra_LAPACK wrapper for computing the singular value decomposition (SGESVD)
|
||||
void GESVD( const char JOBU, const char JOBVT, const int M, const int N, float * A, const int LDA, float * S, float * U,
|
||||
const int LDU, float * VT, const int LDVT, float * WORK, const int * LWORK, int * INFO) const;
|
||||
//! Epetra_LAPACK wrapper for computing the singular value decomposition (DGESVD)
|
||||
void GESVD( const char JOBU, const char JOBVT, const int M, const int N, double * A, const int LDA, double * S, double * U,
|
||||
const int LDU, double * VT, const int LDVT, double * WORK, const int * LWORK, int * INFO) const;
|
||||
|
||||
//! Epetra_LAPACK wrapper to compute the generalized singular value decomposition (GSVD) of an M-by-N real matrix A and P-by-N real matrix B
|
||||
void GGSVD(const char JOBU, const char JOBV, const char JOBQ, const int M, const int N, const int P, int * K, int * L, double* A, const int LDA, double* B, const int LDB,
|
||||
double* ALPHA, double* BETA, double* U, const int LDU, double* V, const int LDV, double* Q, const int LDQ, double* WORK, int* IWORK,
|
||||
int* INFO) const;
|
||||
//! Epetra_LAPACK wrapper to compute the generalized singular value decomposition (GSVD) of an M-by-N real matrix A and P-by-N real matrix B
|
||||
void GGSVD(const char JOBU, const char JOBV, const char JOBQ, const int M, const int N, const int P, int * K, int * L, float* A, const int LDA, float* B, const int LDB,
|
||||
float* ALPHA, float* BETA, float* U, const int LDU, float* V, const int LDV, float* Q, const int LDQ, float* WORK, int* IWORK,
|
||||
int* INFO) const;
|
||||
//@}
|
||||
|
||||
//! @name Eigenvalue/Eigenvector routines
|
||||
//@{
|
||||
//! Epetra_LAPACK wrapper to compute for an N-by-N real nonsymmetric matrix A, the eigenvalues and, optionally, the left and/or right eigenvectors
|
||||
void GEEV(const char JOBVL, const char JOBVR, const int N, double* A, const int LDA, double* WR, double* WI,
|
||||
double* VL, const int LDVL, double* VR, const int LDVR, double* WORK, const int LWORK, int* INFO) const;
|
||||
//! Epetra_LAPACK wrapper to compute for an N-by-N real nonsymmetric matrix A, the eigenvalues and, optionally, the left and/or right eigenvectors
|
||||
void GEEV(const char JOBVL, const char JOBVR, const int N, float* A, const int LDA, float* WR, float* WI,
|
||||
float* VL, const int LDVL, float* VR, const int LDVR, float* WORK, const int LWORK, int* INFO) const;
|
||||
|
||||
//! Epetra_LAPACK wrapper to compute all the eigenvalues and, optionally, eigenvectors of a real symmetric matrix A in packed storage
|
||||
void SPEV(const char JOBZ, const char UPLO, const int N, double* AP, double* W, double* Z, int LDZ, double* WORK, int* INFO) const;
|
||||
//! Epetra_LAPACK wrapper to compute all the eigenvalues and, optionally, eigenvectors of a real symmetric matrix A in packed storage
|
||||
void SPEV(const char JOBZ, const char UPLO, const int N, float* AP, float* W, float* Z, int LDZ, float* WORK, int* INFO) const;
|
||||
|
||||
//! Epetra_LAPACK wrapper to compute all the eigenvalues and, optionally, the eigenvectors of a real generalized symmetric-definite eigenproblem, of the form A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x
|
||||
void SPGV(const int ITYPE, const char JOBZ, const char UPLO, const int N, double* AP, double* BP, double* W, double* Z, const int LDZ, double* WORK, int* INFO) const;
|
||||
//! Epetra_LAPACK wrapper to compute all the eigenvalues and, optionally, the eigenvectors of a real generalized symmetric-definite eigenproblem, of the form A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x
|
||||
void SPGV(const int ITYPE, const char JOBZ, const char UPLO, const int N, float* AP, float* BP, float* W, float* Z, const int LDZ, float* WORK, int* INFO) const;
|
||||
|
||||
//! Epetra_LAPACK wrapper to compute all eigenvalues and, optionally, eigenvectors of a real symmetric matrix A
|
||||
void SYEV(const char JOBZ, const char UPLO, const int N, double* A, const int LDA, double* W, double* WORK, const int LWORK, int* INFO) const;
|
||||
//! Epetra_LAPACK wrapper to compute all eigenvalues and, optionally, eigenvectors of a real symmetric matrix A
|
||||
void SYEV(const char JOBZ, const char UPLO, const int N, float* A, const int LDA, float* W, float* WORK, const int LWORK, int* INFO) const;
|
||||
|
||||
//! Epetra_LAPACK wrapper to compute all eigenvalues and, optionally, eigenvectors of a real symmetric matrix A
|
||||
void SYEVD(const char JOBZ, const char UPLO, const int N, double* A, const int LDA, double* W,
|
||||
double* WORK, const int LWORK, int* IWORK, const int LIWORK, int* INFO) const;
|
||||
//! Epetra_LAPACK wrapper to compute all eigenvalues and, optionally, eigenvectors of a real symmetric matrix A
|
||||
void SYEVD(const char JOBZ, const char UPLO, const int N, float* A, const int LDA, float* W,
|
||||
float* WORK, const int LWORK, int* IWORK, const int LIWORK, int* INFO) const;
|
||||
|
||||
//! Epetra_LAPACK wrapper to compute selected eigenvalues and, optionally, eigenvectors of a real symmetric matrix A
|
||||
void SYEVX(const char JOBZ, const char RANGE, const char UPLO, const int N, double* A, const int LDA,
|
||||
const double* VL, const double* VU, const int* IL, const int* IU,
|
||||
const double ABSTOL, int * M, double* W, double* Z, const int LDZ, double* WORK,
|
||||
const int LWORK, int* IWORK, int* IFAIL,
|
||||
int* INFO) const;
|
||||
//! Epetra_LAPACK wrapper to compute selected eigenvalues and, optionally, eigenvectors of a real symmetric matrix A
|
||||
void SYEVX(const char JOBZ, const char RANGE, const char UPLO, const int N, float* A, const int LDA,
|
||||
const float* VL, const float* VU, const int* IL, const int* IU,
|
||||
const float ABSTOL, int * M, float* W, float* Z, const int LDZ, float* WORK,
|
||||
const int LWORK, int* IWORK, int* IFAIL,
|
||||
int* INFO) const;
|
||||
|
||||
//! Epetra_LAPACK wrapper to compute all the eigenvalues, and optionally, the eigenvectors of a real generalized symmetric-definite eigenproblem, of the form A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x
|
||||
void SYGV(const int ITYPE, const char JOBZ, const char UPLO, const int N, double* A, const int LDA, double* B,
|
||||
const int LDB, double* W, double* WORK, const int LWORK, int* INFO) const;
|
||||
//! Epetra_LAPACK wrapper to compute all the eigenvalues, and optionally, the eigenvectors of a real generalized symmetric-definite eigenproblem, of the form A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x
|
||||
void SYGV(const int ITYPE, const char JOBZ, const char UPLO, const int N, float* A, const int LDA, float* B,
|
||||
const int LDB, float* W, float* WORK, const int LWORK, int* INFO) const;
|
||||
|
||||
//! Epetra_LAPACK wrapper to compute selected eigenvalues, and optionally, eigenvectors of a real generalized symmetric-definite eigenproblem, of the form A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x
|
||||
void SYGVX(const int ITYPE, const char JOBZ, const char RANGE, const char UPLO, const int N,
|
||||
double* A, const int LDA, double* B, const int LDB, const double* VL, const double* VU,
|
||||
const int* IL, const int* IU, const double ABSTOL, int* M, double* W, double* Z,
|
||||
const int LDZ, double* WORK, const int LWORK, int* IWORK,
|
||||
int* IFAIL, int* INFO) const;
|
||||
//! Epetra_LAPACK wrapper to compute selected eigenvalues, and optionally, eigenvectors of a real generalized symmetric-definite eigenproblem, of the form A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x
|
||||
void SYGVX(const int ITYPE, const char JOBZ, const char RANGE, const char UPLO, const int N,
|
||||
float* A, const int LDA, float* B, const int LDB, const float* VL, const float* VU,
|
||||
const int* IL, const int* IU, const float ABSTOL, int* M, float* W, float* Z,
|
||||
const int LDZ, float* WORK, const int LWORK, int* IWORK,
|
||||
int* IFAIL, int* INFO) const;
|
||||
|
||||
//! Epetra_LAPACK wrapper to compute selected eigenvalues and, optionally, eigenvectors of a real symmetric matrix T
|
||||
void SYEVR(const char JOBZ, const char RANGE, const char UPLO, const int N, double* A, const int LDA, const double* VL, const double* VU, const int *IL, const int *IU,
|
||||
const double ABSTOL, int* M, double* W, double* Z, const int LDZ, int* ISUPPZ, double* WORK, const int LWORK, int* IWORK,
|
||||
const int LIWORK, int* INFO) const;
|
||||
//! Epetra_LAPACK wrapper to compute selected eigenvalues and, optionally, eigenvectors of a real symmetric matrix T
|
||||
void SYEVR(const char JOBZ, const char RANGE, const char UPLO, const int N, float* A, const int LDA,
|
||||
const float* VL, const float* VU, const int *IL, const int *IU,
|
||||
const float ABSTOL, int* M, float* W, float* Z, const int LDZ, int* ISUPPZ,
|
||||
float* WORK, const int LWORK, int* IWORK,
|
||||
const int LIWORK, int* INFO) const;
|
||||
|
||||
//! Epetra_LAPACK wrapper to compute for an N-by-N real nonsymmetric matrix A, the eigenvalues and, optionally, the left and/or right eigenvectors
|
||||
void GEEVX(const char BALANC, const char JOBVL, const char JOBVR, const char SENSE, const int N, double* A, const int LDA, double* WR, double* WI, double* VL,
|
||||
const int LDVL, double* VR, const int LDVR, int* ILO, int* IHI, double* SCALE, double* ABNRM, double* RCONDE,
|
||||
double* RCONDV, double* WORK, const int LWORK, int* IWORK, int* INFO) const;
|
||||
//! Epetra_LAPACK wrapper to compute for an N-by-N real nonsymmetric matrix A, the eigenvalues and, optionally, the left and/or right eigenvectors
|
||||
void GEEVX(const char BALANC, const char JOBVL, const char JOBVR, const char SENSE, const int N, float* A, const int LDA, float* WR, float* WI, float* VL,
|
||||
const int LDVL, float* VR, const int LDVR, int* ILO, int* IHI, float* SCALE, float* ABNRM, float* RCONDE,
|
||||
float* RCONDV, float* WORK, const int LWORK, int* IWORK, int* INFO) const;
|
||||
|
||||
//! Epetra_LAPACK wrapper to compute the singular value decomposition (SVD) of a real M-by-N matrix A, optionally computing the left and right singular vectors
|
||||
void GESDD(const char JOBZ, const int M, const int N, double* A, const int LDA, double* S, double* U, const int LDU, double* VT, const int LDVT, double* WORK,
|
||||
const int LWORK, int* IWORK, int* INFO) const;
|
||||
//! Epetra_LAPACK wrapper to
|
||||
void GESDD(const char JOBZ, const int M, const int N, float* A, const int LDA, float* S, float* U, const int LDU, float* VT, const int LDVT, float* WORK,
|
||||
const int LWORK, int* IWORK, int* INFO) const;
|
||||
//! Epetra_LAPACK wrapper to compute for a pair of N-by-N real nonsymmetric matrices (A,B) the generalized eigenvalues, and optionally, the left and/or right generalized eigenvectors.
|
||||
|
||||
void GGEV(const char JOBVL, const char JOBVR, const int N, double* A, const int LDA, double* B, const int LDB, double* ALPHAR, double* ALPHAI,
|
||||
double* BETA, double* VL, const int LDVL, double* VR, const int LDVR, double* WORK, const int LWORK, int* INFO) const;
|
||||
//! Epetra_LAPACK wrapper to compute for a pair of N-by-N real nonsymmetric matrices (A,B) the generalized eigenvalues, and optionally, the left and/or right generalized eigenvectors.
|
||||
void GGEV(const char JOBVL, const char JOBVR, const int N, float* A, const int LDA, float* B, const int LDB, float* ALPHAR, float* ALPHAI,
|
||||
float* BETA, float* VL, const int LDVL, float* VR, const int LDVR, float* WORK, const int LWORK, int* INFO) const;
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Linear Least Squares
|
||||
//@{
|
||||
//! Epetra_LAPACK wrapper to solve the linear equality-constrained least squares (LSE) problem
|
||||
void GGLSE(const int M, const int N, const int P, double* A, const int LDA, double* B, const int LDB,
|
||||
double* C, double* D, double* X, double* WORK, const int LWORK, int* INFO) const;
|
||||
//! Epetra_LAPACK wrapper to solve the linear equality-constrained least squares (LSE) problem
|
||||
void GGLSE(const int M, const int N, const int P, float* A, const int LDA, float* B, const int LDB,
|
||||
float* C, float* D, float* X, float* WORK, const int LWORK, int* INFO) const;
|
||||
//@}
|
||||
|
||||
//! @name Machine characteristics routines
|
||||
//@{
|
||||
//! Epetra_LAPACK wrapper for DLAMCH routine. On out, T holds machine double precision floating point characteristics. This information is returned by the Lapack routine.
|
||||
void LAMCH ( const char CMACH, float & T) const;
|
||||
//! Epetra_LAPACK wrapper for SLAMCH routine. On out, T holds machine single precision floating point characteristics. This information is returned by the Lapack routine.
|
||||
void LAMCH ( const char CMACH, double & T) const;
|
||||
//@}
|
||||
|
||||
};
|
||||
|
||||
// Epetra_LAPACK constructor
|
||||
inline Epetra_LAPACK::Epetra_LAPACK(void){}
|
||||
// Epetra_LAPACK constructor
|
||||
inline Epetra_LAPACK::Epetra_LAPACK(const Epetra_LAPACK& LAPACK){(void)LAPACK;}
|
||||
// Epetra_LAPACK destructor
|
||||
inline Epetra_LAPACK::~Epetra_LAPACK(){}
|
||||
|
||||
#endif /* EPETRA_LAPACK_H */
|
||||
@@ -0,0 +1,458 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_LAPACK_WRAPPERS_H
|
||||
#define EPETRA_LAPACK_WRAPPERS_H
|
||||
|
||||
#include "Epetra_ConfigDefs.h"
|
||||
#if defined(CRAY_T3X) || defined(INTEL_CXML) || defined(INTEL_MKL)
|
||||
|
||||
#ifdef CRAY_T3X
|
||||
|
||||
#include "fortran.h"
|
||||
#define Epetra_fcd fcd
|
||||
#define PREFIX
|
||||
|
||||
/* CRAY Single precision is used like everyone else's double precision */
|
||||
#define DGECON_F77 SGECON
|
||||
#define DGEEQU_F77 SGEEQU
|
||||
#define DGEEV_F77 SGEEV
|
||||
#define DGEEVX_F77 SGEEVX
|
||||
#define DGEHRD_F77 SGEHRD
|
||||
#define DGELS_F77 SGELS
|
||||
#define DGELSS_F77 SGELSS
|
||||
#define DGEQPF_F77 SGEQPF
|
||||
#define DGERFS_F77 SGERFS
|
||||
#define DGESDD_F77 SGESDD
|
||||
#define DGESVD_F77 SGESVD
|
||||
#define DGESV_F77 SGESV
|
||||
#define DGESVX_F77 SGESVX
|
||||
#define DGETRF_F77 SGETRF
|
||||
#define DGEQRF_F77 SGEQRF
|
||||
#define DGETRI_F77 SGETRI
|
||||
#define DGETRS_F77 SGETRS
|
||||
#define DGGEV_F77 SGGEV
|
||||
#define DGGLSE_F77 SGGLSE
|
||||
#define DGGSVD_F77 SGGSVD
|
||||
#define DHSEQR_F77 SHSEQR
|
||||
#define DLAIC1_F77 SLAIC1
|
||||
#define DLAMCH_F77 SLAMCH
|
||||
#define DLARFT_F77 SLARFT
|
||||
#define DLASWP_F77 SLASWP
|
||||
#define DORGQR_F77 SORGQR
|
||||
#define DORGHR_F77 SORGHR
|
||||
#define DORMHR_F77 SORMHR
|
||||
#define DPOCON_F77 SPOCON
|
||||
#define DPOEQU_F77 SPOEQU
|
||||
#define DPORFS_F77 SPORFS
|
||||
#define DPOSV_F77 SPOSV
|
||||
#define DPOSVX_F77 SPOSVX
|
||||
#define DPOTRF_F77 SPOTRF
|
||||
#define DPOTRI_F77 SPOTRI
|
||||
#define DPOTRS_F77 SPOTRS
|
||||
#define DSPEV_F77 SSPEV
|
||||
#define DSPGV_F77 SSPGV
|
||||
#define DSTEV_F77 SSTEV
|
||||
#define DSYEVD_F77 SSYEVD
|
||||
#define DSYEV_F77 SSYEV
|
||||
#define DSYEVR_F77 SSYEVR
|
||||
#define DSYEVX_F77 SSYEVX
|
||||
#define DSYGV_F77 SSYGV
|
||||
#define DSYGVX_F77 SSYGVX
|
||||
#define DTREVC_F77 STREVC
|
||||
#define DTREXC_F77 STREXC
|
||||
/* Done with T3X double precision */
|
||||
#endif
|
||||
|
||||
#if defined(INTEL_CXML)
|
||||
|
||||
#define Epetra_fcd const char *, const unsigned int
|
||||
#define PREFIX __stdcall
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(INTEL_MKL)
|
||||
|
||||
#define Epetra_fcd const char *
|
||||
#define PREFIX
|
||||
|
||||
#endif
|
||||
|
||||
/* The remainder of this block is for T3X, CXML and MKL */
|
||||
|
||||
#ifdef F77_FUNC
|
||||
#undef F77_FUNC
|
||||
#endif
|
||||
|
||||
#define F77_FUNC(lcase,UCASE) UCASE
|
||||
|
||||
#else
|
||||
/* Not defined(CRAY_T3X) || defined(INTEL_CXML) || defined(INTEL_MKL) */
|
||||
|
||||
#define Epetra_fcd const char *
|
||||
#define PREFIX
|
||||
|
||||
/* Use autoconf's definition of F77_FUNC
|
||||
unless using old make system */
|
||||
|
||||
#ifndef HAVE_CONFIG_H
|
||||
|
||||
#ifdef F77_FUNC
|
||||
#undef F77_FUNC
|
||||
#endif
|
||||
|
||||
#ifdef TRILINOS_HAVE_NO_FORTRAN_UNDERSCORE
|
||||
#define F77_FUNC(lcase,UCASE) lcase
|
||||
#else /* TRILINOS_HAVE_NO_FORTRAN_UNDERSCORE not defined*/
|
||||
#define F77_FUNC(lcase,UCASE) lcase ## _
|
||||
#endif /* TRILINOS_HAVE_NO_FORTRAN_UNDERSCORE */
|
||||
|
||||
#endif /* !HAVE_CONFIG_H */
|
||||
#endif /* defined(CRAY_T3X) || defined(INTEL_CXML) || defined(INTEL_MKL) */
|
||||
|
||||
#ifndef CRAY_T3X
|
||||
|
||||
#define DGECON_F77 F77_FUNC(dgecon,DGECON)
|
||||
#define DGEEQU_F77 F77_FUNC(dgeequ,DGEEQU)
|
||||
#define DGEEV_F77 F77_FUNC(dgeev,DGEEV)
|
||||
#define DGEEVX_F77 F77_FUNC(dgeevx,DGEEVX)
|
||||
#define DGEHRD_F77 F77_FUNC(dgehrd,DGEHRD)
|
||||
#define DGELS_F77 F77_FUNC(dgels,DGELS)
|
||||
#define DGELSS_F77 F77_FUNC(dgelss,DGELSS)
|
||||
#define DGEQPF_F77 F77_FUNC(dgeqpf,DGEQPF)
|
||||
#define DGERFS_F77 F77_FUNC(dgerfs,DGERFS)
|
||||
#define DGESDD_F77 F77_FUNC(dgesdd,DGESDD)
|
||||
#define DGESVD_F77 F77_FUNC(dgesvd,DGESVD)
|
||||
#define DGESV_F77 F77_FUNC(dgesv,DGESV)
|
||||
#define DGESVX_F77 F77_FUNC(dgesvx,DGESVX)
|
||||
#define DGETRF_F77 F77_FUNC(dgetrf,DGETRF)
|
||||
#define DGEQRF_F77 F77_FUNC(dgeqrf,DGEQRF)
|
||||
#define DGETRI_F77 F77_FUNC(dgetri,DGETRI)
|
||||
#define DGETRS_F77 F77_FUNC(dgetrs,DGETRS)
|
||||
#define DGGEV_F77 F77_FUNC(dggev,DGGEV)
|
||||
#define DGGLSE_F77 F77_FUNC(dgglse,DGGLSE)
|
||||
#define DGGSVD_F77 F77_FUNC(dggsvd,DGGSVD)
|
||||
#define DHSEQR_F77 F77_FUNC(dhseqr,DHSEQR)
|
||||
#define DLAIC1_F77 F77_FUNC(dlaic1,DLAIC1)
|
||||
#define DLAMCH_F77 F77_FUNC(dlamch,DLAMCH)
|
||||
#define DLARFT_F77 F77_FUNC(dlarft,DLARFT)
|
||||
#define DLASWP_F77 F77_FUNC(dlaswp,DLASWP)
|
||||
#define DORGQR_F77 F77_FUNC(dorgqr,DORGQR)
|
||||
#define DORGHR_F77 F77_FUNC(dorghr,DORGHR)
|
||||
#define DORMHR_F77 F77_FUNC(dormhr,DORMHR)
|
||||
#define DPOCON_F77 F77_FUNC(dpocon,DPOCON)
|
||||
#define DPOEQU_F77 F77_FUNC(dpoequ,DPOEQU)
|
||||
#define DPORFS_F77 F77_FUNC(dporfs,DPORFS)
|
||||
#define DPOSV_F77 F77_FUNC(dposv,DPOSV)
|
||||
#define DPOSVX_F77 F77_FUNC(dposvx,DPOSVX)
|
||||
#define DPOTRF_F77 F77_FUNC(dpotrf,DPOTRF)
|
||||
#define DPOTRI_F77 F77_FUNC(dpotri,DPOTRI)
|
||||
#define DPOTRS_F77 F77_FUNC(dpotrs,DPOTRS)
|
||||
#define DSPEV_F77 F77_FUNC(dspev,DSPEV)
|
||||
#define DSPGV_F77 F77_FUNC(dspgv,DSPGV)
|
||||
#define DSTEV_F77 F77_FUNC(dstev,DSTEV)
|
||||
#define DSYEVD_F77 F77_FUNC(dsyevd,DSYEVD)
|
||||
#define DSYEV_F77 F77_FUNC(dsyev,DSYEV)
|
||||
#define DSYEVR_F77 F77_FUNC(dsyevr,DSYEVR)
|
||||
#define DSYEVX_F77 F77_FUNC(dsyevx,DSYEVX)
|
||||
#define DSYGV_F77 F77_FUNC(dsygv,DSYGV)
|
||||
#define DSYGVX_F77 F77_FUNC(dsygvx,DSYGVX)
|
||||
#define DTREVC_F77 F77_FUNC(dtrevc,DTREVC)
|
||||
#define DTREXC_F77 F77_FUNC(dtrexc,DTREXC)
|
||||
|
||||
/* End of defines for double precision when not on a T3X */
|
||||
|
||||
#endif
|
||||
|
||||
/* The following defines are good for all platforms */
|
||||
|
||||
#define SGECON_F77 F77_FUNC(sgecon,SGECON)
|
||||
#define SGEEQU_F77 F77_FUNC(sgeequ,SGEEQU)
|
||||
#define SGEEV_F77 F77_FUNC(sgeev,SGEEV)
|
||||
#define SGEEVX_F77 F77_FUNC(sgeevx,SGEEVX)
|
||||
#define SGEHRD_F77 F77_FUNC(sgehrd,SGEHRD)
|
||||
#define SGELS_F77 F77_FUNC(sgels,SGELS)
|
||||
#define SGELSS_F77 F77_FUNC(sgelss,SGELSS)
|
||||
#define SGEQPF_F77 F77_FUNC(sgeqpf,SGEQPF)
|
||||
#define SGERFS_F77 F77_FUNC(sgerfs,SGERFS)
|
||||
#define SGESDD_F77 F77_FUNC(sgesdd,SGESDD)
|
||||
#define SGESVD_F77 F77_FUNC(sgesvd,SGESVD)
|
||||
#define SGESV_F77 F77_FUNC(sgesv,SGESV)
|
||||
#define SGESVX_F77 F77_FUNC(sgesvx,SGESVX)
|
||||
#define SGETRF_F77 F77_FUNC(sgetrf,SGETRF)
|
||||
#define SGEQRF_F77 F77_FUNC(sgeqrf,SGEQRF)
|
||||
#define SGETRI_F77 F77_FUNC(sgetri,SGETRI)
|
||||
#define SGETRS_F77 F77_FUNC(sgetrs,SGETRS)
|
||||
#define SGGEV_F77 F77_FUNC(sggev,SGGEV)
|
||||
#define SGGLSE_F77 F77_FUNC(sgglse,SGGLSE)
|
||||
#define SGGSVD_F77 F77_FUNC(sggsvd,SGGSVD)
|
||||
#define SHSEQR_F77 F77_FUNC(shseqr,SHSEQR)
|
||||
#define SLAMCH_F77 F77_FUNC(slamch,SLAMCH)
|
||||
#define SLARFT_F77 F77_FUNC(slarft,SLARFT)
|
||||
#define SORGQR_F77 F77_FUNC(sorgqr,SORGQR)
|
||||
#define SORGHR_F77 F77_FUNC(sorghr,SORGHR)
|
||||
#define SORMHR_F77 F77_FUNC(sormhr,SORMHR)
|
||||
#define SPOCON_F77 F77_FUNC(spocon,SPOCON)
|
||||
#define SPOEQU_F77 F77_FUNC(spoequ,SPOEQU)
|
||||
#define SPORFS_F77 F77_FUNC(sporfs,SPORFS)
|
||||
#define SPOSV_F77 F77_FUNC(sposv,SPOSV)
|
||||
#define SPOSVX_F77 F77_FUNC(sposvx,SPOSVX)
|
||||
#define SPOTRF_F77 F77_FUNC(spotrf,SPOTRF)
|
||||
#define SPOTRI_F77 F77_FUNC(spotri,SPOTRI)
|
||||
#define SPOTRS_F77 F77_FUNC(spotrs,SPOTRS)
|
||||
#define SSPEV_F77 F77_FUNC(sspev,SSPEV)
|
||||
#define SSPGV_F77 F77_FUNC(sspgv,SSPGV)
|
||||
#define SSTEV_F77 F77_FUNC(sstev,SSTEV)
|
||||
#define SSYEVD_F77 F77_FUNC(ssyevd,SSYEVD)
|
||||
#define SSYEV_F77 F77_FUNC(ssyev,SSYEV)
|
||||
#define SSYEVR_F77 F77_FUNC(ssyevr,SSYEVR)
|
||||
#define SSYEVX_F77 F77_FUNC(ssyevx,SSYEVX)
|
||||
#define SSYGV_F77 F77_FUNC(ssygv,SSYGV)
|
||||
#define SSYGVX_F77 F77_FUNC(ssygvx,SSYGVX)
|
||||
#define STREVC_F77 F77_FUNC(strevc,STREVC)
|
||||
#define STREXC_F77 F77_FUNC(strexc,STREXC)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
void PREFIX DGECON_F77(Epetra_fcd norm, const int* n, const double* a, const int* lda, const double *anorm, double * rcond,
|
||||
double * work, int * iwork, int* info);
|
||||
void PREFIX DGEEQU_F77(const int* m, const int* n, const double* a, const int* lda, double * r, double * c, double * rowcnd,
|
||||
double * colcnd, double * amax, int* info);
|
||||
void PREFIX DGEEV_F77(Epetra_fcd, Epetra_fcd, const int* n, double* a, const int* lda, double* wr, double* wi,
|
||||
double* vl, const int* ldvl,
|
||||
double* vr, const int* ldvr, double* work, const int* lwork, int* info);
|
||||
void PREFIX DGEEVX_F77(Epetra_fcd, Epetra_fcd, Epetra_fcd, Epetra_fcd, const int * n, double * a, const int * lda,
|
||||
double * wr, double * wi, double * vl, const int * ldvl, double * vr, const int * ldvr,
|
||||
int * ilo, int * ihi, double * scale, double * abnrm, double * rconde, double * rcondv,
|
||||
double * work, const int * lwork, int * iwork, int * info);
|
||||
void PREFIX DGEHRD_F77(const int * n, const int * ilo, const int * ihi, double * A, const int * lda, double * tau, double * work,
|
||||
const int * lwork, int * info);
|
||||
void PREFIX DGELS_F77(Epetra_fcd ch, const int* m, const int* n, const int* nrhs, double* a, const int* lda, double* b, const int* ldb,
|
||||
double* work, const int* lwork, int* info);
|
||||
void PREFIX DGELSS_F77(const int * m, const int * n, const int * nrhs, double * a, const int * lda, double * b, const int * ldb,
|
||||
double * s, const double * rcond, int * rank, double * work, const int * lwork, int * info);
|
||||
void PREFIX DGEQPF_F77(const int * m, const int * n, double * a, const int * lda, int * jpvt, double * tau, double * work, int * info);
|
||||
void PREFIX DGERFS_F77(Epetra_fcd, const int * n, const int * nrhs, const double * a, const int * lda, const double * af, const int * ldaf,
|
||||
const int*ipiv, const double * b, const int * ldb, double * x, const int * ldx, double * ferr, double * berr,
|
||||
double * work, int * iwork, int * info);
|
||||
|
||||
void PREFIX DGESDD_F77(Epetra_fcd, const int * m, const int * n, double * a, const int * lda, double * s, double * u,
|
||||
const int * ldu, double * vt, const int * ldvt, double * work, const int * lwork, int * iwork, int * info);
|
||||
|
||||
void PREFIX DGESVD_F77(Epetra_fcd, Epetra_fcd, const int* m, const int* n, double* a, const int* lda, double* s, double* u,
|
||||
const int* ldu, double* vt, const int* ldvt, double* work, const int* lwork, int* info);
|
||||
void PREFIX DGESV_F77(const int * n, const int * nrhs, double* a, const int* lda, int*ipiv, double*x , const int* ldx, int* info);
|
||||
void PREFIX DGESVX_F77(Epetra_fcd, Epetra_fcd, const int * n, const int * nrhs, double * a, const int * lda, double * af,
|
||||
const int * ldaf, int*ipiv, Epetra_fcd, double * r, double *c, double * b, const int * ldb,
|
||||
double * x, const int * ldx, double * rcond, double * ferr, double * berr, double *
|
||||
work, int * iwork, int * info);
|
||||
void PREFIX DGETRF_F77(const int* m, const int* n, double* a, const int* lda, int* ipiv, int* info);
|
||||
void PREFIX DGEQRF_F77(const int* m, const int* n, double* a, const int* lda, double* tau, double* work, const int* lwork, int* info);
|
||||
void PREFIX DGETRI_F77(const int* n, double* a, const int* lda, int*ipiv, double * work , const int* lwork, int* info);
|
||||
void PREFIX DGETRS_F77(Epetra_fcd, const int* n, const int* nrhs, const double* a, const int* lda, const int* ipiv, double* x ,
|
||||
const int* ldx, int* info);
|
||||
void PREFIX DGGEV_F77(Epetra_fcd, Epetra_fcd, const int * n, double * a, const int * lda, double * b, const int * ldb,
|
||||
double * alphar, double * alphai, double * beta, double * vl, const int * ldvl,
|
||||
double * vr, const int * ldvr, double * work, const int * lwork, int * info);
|
||||
void PREFIX DGGLSE_F77(const int * m, const int * n, const int * p, double * a, const int * lda, double * b, const int * ldb,
|
||||
double * c, double * d, double * x, double * work, const int * lwork, int * info);
|
||||
void PREFIX DGGSVD_F77(Epetra_fcd, Epetra_fcd, Epetra_fcd, const int * m, const int * n, const int * p, int * k, int * l,
|
||||
double * a, const int * lda, double * b, const int * ldb, double * alpha, double * beta,
|
||||
double * u, const int * ldu, double * v, const int * ldv, double * q, const int * ldq, double * work,
|
||||
int * iwork, int * info);
|
||||
void PREFIX DHSEQR_F77(Epetra_fcd job, Epetra_fcd, const int * n, const int * ilo, const int * ihi, double * h, const int * ldh,
|
||||
double * wr, double * wi, double * z, const int * ldz, double * work, const int * lwork, int * info);
|
||||
double PREFIX DLAMCH_F77(Epetra_fcd);
|
||||
void PREFIX DLARFT_F77(Epetra_fcd direct, Epetra_fcd storev, const int * n, const int * k, double * v, const int * ldv, double * tau, double * t, const int * ldt );
|
||||
void PREFIX DORGQR_F77(const int * m, const int * n, const int * k, double * a, const int * lda, const double * tau, double * work,
|
||||
const int * lwork, int * info);
|
||||
void PREFIX DORGHR_F77(const int * n, const int * ilo, const int * ihi, double * a, const int * lda, const double * tau, double * work,
|
||||
const int * lwork, int * info);
|
||||
void PREFIX DORMHR_F77(Epetra_fcd, Epetra_fcd, const int * m, const int * n, const int * ilo, const int * ihi, const double * a,
|
||||
const int * lda, const double * tau, double * c, const int * ldc, double * work, const int * lwork, int * info);
|
||||
void PREFIX DPOCON_F77(Epetra_fcd, const int* n, const double* a, const int* lda, const double * anorm, double * rcond,
|
||||
double * work, int * iwork, int* info);
|
||||
void PREFIX DPOEQU_F77(const int* n, const double* a, const int* lda, double * s, double * scond, double * amax, int* info);
|
||||
void PREFIX DPORFS_F77(Epetra_fcd, const int * n, const int * nrhs, const double * a, const int * lda, const double * af, const int * ldaf,
|
||||
const double * b, const int * ldb, double * x, const int * ldx, double * ferr, double * berr,
|
||||
double * work, int * iwork, int * info);
|
||||
void PREFIX DPOSV_F77(Epetra_fcd, const int * n, const int * nrhs, const double* a, const int* lda, double*x , const int* ldx, int* info);
|
||||
void PREFIX DPOSVX_F77(Epetra_fcd, Epetra_fcd, const int * n, const int * nrhs, double * a, const int * lda, double * af,
|
||||
const int * ldaf, Epetra_fcd, double * s, double * b, const int * ldb, double * x,
|
||||
const int * ldx, double * rcond, double * ferr, double * berr, double * work,
|
||||
int * iwork, int * info);
|
||||
void PREFIX DPOTRF_F77(Epetra_fcd, const int* n, double* a, const int* lda, int* info);
|
||||
void PREFIX DPOTRI_F77(Epetra_fcd, const int* n, double* a, const int* lda, int* info);
|
||||
void PREFIX DPOTRS_F77(Epetra_fcd, const int * n, const int * nrhs, const double* a, const int* lda, double*x ,
|
||||
const int* ldx, int* info);
|
||||
void PREFIX DSPEV_F77( Epetra_fcd, Epetra_fcd,const int * n, double * ap, double * w, double * z,
|
||||
const int * ldz, double * work, int * info);
|
||||
void PREFIX DSPGV_F77(const int * itype, Epetra_fcd, Epetra_fcd, const int * n, double * ap, double * bp,
|
||||
double * w, double * z, const int * ldz, double * work, int * info);
|
||||
void PREFIX DSTEV_F77(Epetra_fcd jobz, const int * n, double * d, double * e, double * z, const int * ldz,
|
||||
double * work, int * info);
|
||||
void PREFIX DSYEVD_F77(Epetra_fcd, Epetra_fcd, const int * n, double * a, const int * lda, double * w,
|
||||
double * work, const int * lwork, int * iwork, const int * liwork,int * info);
|
||||
void PREFIX DSYEV_F77(Epetra_fcd, Epetra_fcd, const int * n, double * a, const int * lda, double * w,
|
||||
double * work, const int * lwork, int * info);
|
||||
void PREFIX DSYEVR_F77(Epetra_fcd, Epetra_fcd, Epetra_fcd, const int * n, double * a, const int * lda,
|
||||
const double * vl, const double * vu, const int * il, const int * iu, const
|
||||
double * abstol, int * m,
|
||||
double * w, double * z, const int * ldz, int * isuppz, double * work,
|
||||
const int * lwork, int * iwork, const int * liwork, int * info);
|
||||
void PREFIX DSYEVX_F77(Epetra_fcd, Epetra_fcd, Epetra_fcd, const int * n, double * a, const int * lda,
|
||||
const double * vl, const double * vu, const int * il, const int * iu, const double * abstol, int * m,
|
||||
double * w, double * z, const int * ldz, double * work, const int * lwork, int * iwork,
|
||||
int * ifail, int * info);
|
||||
void PREFIX DSYGV_F77(const int * itype, Epetra_fcd, Epetra_fcd, const int * n, double * a, const int * lda,
|
||||
double * b, const int * ldb, double * w, double * work, const int * lwork, int * info);
|
||||
void PREFIX DSYGVX_F77(const int * itype, Epetra_fcd, Epetra_fcd, Epetra_fcd, const int * n, double * a,
|
||||
const int * lda, double * b, const int * ldb, const double * vl, const double * vu, const int * il,
|
||||
const int * iu, const double * abstol, int * m, double * w, double * z, const int * ldz,
|
||||
double * work, const int * lwork, int * iwork, int * ifail, int * info);
|
||||
void PREFIX DTREVC_F77(Epetra_fcd, Epetra_fcd, int * select, const int * n, const double * t, const int * ldt,
|
||||
double *vl, const int * ldvl, double * vr, const int * ldvr, const int * mm, int * m,
|
||||
double * work, int * info);
|
||||
void PREFIX DTREXC_F77(Epetra_fcd, const int * n, double * t, const int * ldt, double * q, const int * ldq,
|
||||
int * ifst, int * ilst, double * work, int * info);
|
||||
|
||||
|
||||
void PREFIX SGECON_F77(Epetra_fcd norm, const int* n, const float* a, const int* lda, const float *anorm, float * rcond,
|
||||
float * work, int * iwork, int* info);
|
||||
void PREFIX SGEEQU_F77(const int* m, const int* n, const float* a, const int* lda, float * r, float * c, float * rowcnd,
|
||||
float * colcnd, float * amax, int* info);
|
||||
void PREFIX SGEEV_F77(Epetra_fcd, Epetra_fcd, const int* n, float* a, const int* lda, float* wr, float* wi,
|
||||
float* vl, const int* ldvl,
|
||||
float* vr, const int* ldvr, float* work, const int* lwork, int* info);
|
||||
void PREFIX SGEEVX_F77(Epetra_fcd, Epetra_fcd, Epetra_fcd, Epetra_fcd, const int * n, float * a, const int * lda,
|
||||
float * wr, float * wi, float * vl, const int * ldvl, float * vr, const int * ldvr,
|
||||
int * ilo, int * ihi, float * scale, float * abnrm, float * rconde, float * rcondv,
|
||||
float * work, const int * lwork, int * iwork, int * info);
|
||||
void PREFIX SGEHRD_F77(const int * n, const int * ilo, const int * ihi, float * A, const int * lda, float * tau, float * work,
|
||||
const int * lwork, int * info);
|
||||
void PREFIX SGELS_F77(Epetra_fcd ch, const int* m, const int* n, const int* nrhs, float* a, const int* lda, float* b, const int* ldb,
|
||||
float* work, const int* lwork, int* info);
|
||||
void PREFIX SGELSS_F77(const int * m, const int * n, const int * nrhs, float * a, const int * lda, float * b, const int * ldb,
|
||||
float * s, const float * rcond, int * rank, float * work, const int * lwork, int * info);
|
||||
void PREFIX SGEQPF_F77(const int * m, const int * n, float * a, const int * lda, int * jpvt, float * tau, float * work, int * info);
|
||||
void PREFIX SGERFS_F77(Epetra_fcd, const int * n, const int * nrhs, const float * a, const int * lda, const float * af, const int * ldaf,
|
||||
const int*ipiv, const float * b, const int * ldb, float * x, const int * ldx, float * ferr, float * berr,
|
||||
float * work, int * iwork, int * info);
|
||||
|
||||
void PREFIX SGESDD_F77(Epetra_fcd, const int * m, const int * n, float * a, const int * lda, float * s, float * u,
|
||||
const int * ldu, float * vt, const int * ldvt, float * work, const int * lwork, int * iwork, int * info);
|
||||
|
||||
void PREFIX SGESVD_F77(Epetra_fcd, Epetra_fcd, const int* m, const int* n, float* a, const int* lda, float* s, float* u,
|
||||
const int* ldu, float* vt, const int* ldvt, float* work, const int* lwork, int* info);
|
||||
void PREFIX SGESV_F77(const int * n, const int * nrhs, float* a, const int* lda, int*ipiv, float*x , const int* ldx, int* info);
|
||||
void PREFIX SGESVX_F77(Epetra_fcd, Epetra_fcd, const int * n, const int * nrhs, float * a, const int * lda, float * af,
|
||||
const int * ldaf, int*ipiv, Epetra_fcd, float * r, float *c, float * b, const int * ldb,
|
||||
float * x, const int * ldx, float * rcond, float * ferr, float * berr, float *
|
||||
work, int * iwork, int * info);
|
||||
void PREFIX SGETRF_F77(const int* m, const int* n, float* a, const int* lda, int* ipiv, int* info);
|
||||
void PREFIX SGEQRF_F77(const int* m, const int* n, float* a, const int* lda, float* tau, float* work, const int* lwork, int* info);
|
||||
void PREFIX SGETRI_F77(const int* n, float* a, const int* lda, int*ipiv, float * work , const int* lwork, int* info);
|
||||
void PREFIX SGETRS_F77(Epetra_fcd, const int* n, const int* nrhs, const float* a, const int* lda, const int* ipiv, float* x ,
|
||||
const int* ldx, int* info);
|
||||
void PREFIX SGGEV_F77(Epetra_fcd, Epetra_fcd, const int * n, float * a, const int * lda, float * b, const int * ldb,
|
||||
float * alphar, float * alphai, float * beta, float * vl, const int * ldvl,
|
||||
float * vr, const int * ldvr, float * work, const int * lwork, int * info);
|
||||
void PREFIX SGGLSE_F77(const int * m, const int * n, const int * p, float * a, const int * lda, float * b, const int * ldb,
|
||||
float * c, float * d, float * x, float * work, const int * lwork, int * info);
|
||||
void PREFIX SGGSVD_F77(Epetra_fcd, Epetra_fcd, Epetra_fcd, const int * m, const int * n, const int * p, int * k, int * l,
|
||||
float * a, const int * lda, float * b, const int * ldb, float * alpha, float * beta,
|
||||
float * u, const int * ldu, float * v, const int * ldv, float * q, const int * ldq, float * work,
|
||||
int * iwork, int * info);
|
||||
void PREFIX SHSEQR_F77(Epetra_fcd job, Epetra_fcd, const int * n, const int * ilo, const int * ihi, float * h, const int * ldh,
|
||||
float * wr, float * wi, float * z, const int * ldz, float * work, const int * lwork, int * info);
|
||||
float PREFIX SLAMCH_F77(Epetra_fcd);
|
||||
void PREFIX SLARFT_F77(Epetra_fcd direct, Epetra_fcd storev, const int * n, const int * k, float * v, const int * ldv, float * tau, float * t, const int * ldt );
|
||||
void PREFIX SORGQR_F77(const int * m, const int * n, const int * k, float * a, const int * lda, const float * tau, float * work,
|
||||
const int * lwork, int * info);
|
||||
void PREFIX SORGHR_F77(const int * n, const int * ilo, const int * ihi, float * a, const int * lda, const float * tau, float * work,
|
||||
const int * lwork, int * info);
|
||||
void PREFIX SORMHR_F77(Epetra_fcd, Epetra_fcd, const int * m, const int * n, const int * ilo, const int * ihi, const float * a,
|
||||
const int * lda, const float * tau, float * c, const int * ldc, float * work, const int * lwork, int * info);
|
||||
void PREFIX SPOCON_F77(Epetra_fcd, const int* n, const float* a, const int* lda, const float * anorm, float * rcond,
|
||||
float * work, int * iwork, int* info);
|
||||
void PREFIX SPOEQU_F77(const int* n, const float* a, const int* lda, float * s, float * scond, float * amax, int* info);
|
||||
void PREFIX SPORFS_F77(Epetra_fcd, const int * n, const int * nrhs, const float * a, const int * lda, const float * af, const int * ldaf,
|
||||
const float * b, const int * ldb, float * x, const int * ldx, float * ferr, float * berr,
|
||||
float * work, int * iwork, int * info);
|
||||
void PREFIX SPOSV_F77(Epetra_fcd, const int * n, const int * nrhs, const float* a, const int* lda, float*x , const int* ldx, int* info);
|
||||
void PREFIX SPOSVX_F77(Epetra_fcd, Epetra_fcd, const int * n, const int * nrhs, float * a, const int * lda, float * af,
|
||||
const int * ldaf, Epetra_fcd, float * s, float * b, const int * ldb, float * x,
|
||||
const int * ldx, float * rcond, float * ferr, float * berr, float * work,
|
||||
int * iwork, int * info);
|
||||
void PREFIX SPOTRF_F77(Epetra_fcd, const int* n, float* a, const int* lda, int* info);
|
||||
void PREFIX SPOTRI_F77(Epetra_fcd, const int* n, float* a, const int* lda, int* info);
|
||||
void PREFIX SPOTRS_F77(Epetra_fcd, const int * n, const int * nrhs, const float* a, const int* lda, float*x ,
|
||||
const int* ldx, int* info);
|
||||
void PREFIX SSPEV_F77( Epetra_fcd, Epetra_fcd,const int * n, float * ap, float * w, float * z,
|
||||
const int * ldz, float * work, int * info);
|
||||
void PREFIX SSPGV_F77(const int * itype, Epetra_fcd, Epetra_fcd, const int * n, float * ap, float * bp,
|
||||
float * w, float * z, const int * ldz, float * work, int * info);
|
||||
void PREFIX SSTEV_F77(Epetra_fcd jobz, const int * n, float * d, float * e, float * z, const int * ldz,
|
||||
float * work, int * info);
|
||||
void PREFIX SSYEVD_F77(Epetra_fcd, Epetra_fcd, const int * n, float * a, const int * lda, float * w,
|
||||
float * work, const int * lwork, int * iwork, const int * liwork, int * info);
|
||||
void PREFIX SSYEV_F77(Epetra_fcd, Epetra_fcd, const int * n, float * a, const int * lda, float * w,
|
||||
float * work, const int * lwork, int * info);
|
||||
void PREFIX SSYEVR_F77(Epetra_fcd, Epetra_fcd, Epetra_fcd, const int * n, float * a, const int * lda,
|
||||
const float * vl, const float * vu, const int * il, const int * iu, const
|
||||
float * abstol, int * m,
|
||||
float * w, float * z, const int * ldz, int * isuppz, float * work,
|
||||
const int * lwork, int * iwork, const int * liwork, int * info);
|
||||
void PREFIX SSYEVX_F77(Epetra_fcd, Epetra_fcd, Epetra_fcd, const int * n, float * a, const int * lda,
|
||||
const float * vl, const float * vu, const int * il, const int * iu, const float * abstol, int * m,
|
||||
float * w, float * z, const int * ldz, float * work, const int * lwork, int * iwork,
|
||||
int * ifail, int * info);
|
||||
void PREFIX SSYGV_F77(const int * itype, Epetra_fcd, Epetra_fcd, const int * n, float * a, const int * lda,
|
||||
float * b, const int * ldb, float * w, float * work, const int * lwork, int * info);
|
||||
void PREFIX SSYGVX_F77(const int * itype, Epetra_fcd, Epetra_fcd, Epetra_fcd, const int * n, float * a,
|
||||
const int * lda, float * b, const int * ldb, const float * vl, const float * vu, const int * il,
|
||||
const int * iu, const float * abstol, int * m, float * w, float * z, const int * ldz,
|
||||
float * work, const int * lwork, int * iwork, int * ifail, int * info);
|
||||
void PREFIX STREVC_F77(Epetra_fcd, Epetra_fcd, int * select, const int * n, const float * t, const int * ldt,
|
||||
float *vl, const int * ldvl, float * vr, const int * ldvr, const int * mm, int * m,
|
||||
float * work, int * info);
|
||||
void PREFIX STREXC_F77(Epetra_fcd, const int * n, float * t, const int * ldt, float * q, const int * ldq,
|
||||
int * ifst, int * ilst, float * work, int * info);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* EPETRA_LAPACK_WRAPPERS_H */
|
||||
@@ -0,0 +1,190 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_LINEARPROBLEM_H
|
||||
#define EPETRA_LINEARPROBLEM_H
|
||||
|
||||
#include "Epetra_RowMatrix.h"
|
||||
#include "Epetra_Operator.h"
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
enum ProblemDifficultyLevel {easy, moderate, hard, unsure};
|
||||
#endif
|
||||
|
||||
//! Epetra_LinearProblem: The Epetra Linear Problem Class.
|
||||
/*! The Epetra_LinearProblem class is a wrapper that encapsulates the
|
||||
general information needed for solving a linear system of equations.
|
||||
Currently it accepts a Epetra matrix, initial guess and RHS and
|
||||
returns the solution.
|
||||
the elapsed time for each calling processor.
|
||||
*/
|
||||
|
||||
|
||||
class Epetra_LinearProblem {
|
||||
|
||||
public:
|
||||
//! @name Constructors/Destructor
|
||||
//@{
|
||||
//! Epetra_LinearProblem Default Constructor.
|
||||
/*! Creates an empty Epetra_LinearProblem instance. The operator A, left-hand-side X
|
||||
and right-hand-side B must be set use the SetOperator(), SetLHS() and SetRHS()
|
||||
methods respectively.
|
||||
*/
|
||||
Epetra_LinearProblem(void);
|
||||
|
||||
//! Epetra_LinearProblem Constructor to pass in an operator as a matrix.
|
||||
/*! Creates a Epetra_LinearProblem instance where the operator is passed in as a matrix.
|
||||
*/
|
||||
Epetra_LinearProblem(Epetra_RowMatrix * A, Epetra_MultiVector * X,
|
||||
Epetra_MultiVector * B);
|
||||
|
||||
//! Epetra_LinearProblem Constructor to pass in a basic Epetra_Operator.
|
||||
/*! Creates a Epetra_LinearProblem instance for the case where an operator is not necessarily a matrix.
|
||||
*/
|
||||
Epetra_LinearProblem(Epetra_Operator * A, Epetra_MultiVector * X,
|
||||
Epetra_MultiVector * B);
|
||||
//! Epetra_LinearProblem Copy Constructor.
|
||||
/*! Makes copy of an existing Epetra_LinearProblem instance.
|
||||
*/
|
||||
Epetra_LinearProblem(const Epetra_LinearProblem& Problem);
|
||||
|
||||
//! Epetra_LinearProblem Destructor.
|
||||
/*! Completely deletes a Epetra_LinearProblem object.
|
||||
*/
|
||||
virtual ~Epetra_LinearProblem(void);
|
||||
//@}
|
||||
|
||||
//! @name Integrity check method
|
||||
//@{
|
||||
|
||||
//! Check input parameters for existence and size consistency.
|
||||
/*! Returns 0 if all input parameters are valid. Returns +1 if operator is not a matrix.
|
||||
This is not necessarily an error, but no scaling can be done if the user passes in an
|
||||
Epetra_Operator that is not an Epetra_Matrix
|
||||
*/
|
||||
int CheckInput() const;
|
||||
//@}
|
||||
|
||||
//! @name Set methods
|
||||
//@{
|
||||
|
||||
void AssertSymmetric(){OperatorSymmetric_ = true;};
|
||||
#ifdef DOXYGEN_SHOULD_SKIP_THIS
|
||||
enum ProblemDifficultyLevel {easy, moderate, hard, unsure};
|
||||
#endif
|
||||
//! Set problem difficulty level.
|
||||
/*! Sets Aztec options and parameters based on a definition of easy moderate or hard problem.
|
||||
Relieves the user from explicitly setting a large number of individual parameter values.
|
||||
This function can be used in conjunction with the SetOptions() and SetParams() functions.
|
||||
*/
|
||||
void SetPDL(ProblemDifficultyLevel PDL) {PDL_ = PDL;};
|
||||
|
||||
//! Set Operator A of linear problem AX = B using an Epetra_RowMatrix.
|
||||
/*! Sets a pointer to a Epetra_RowMatrix. No copy of the operator is made.
|
||||
*/
|
||||
void SetOperator(Epetra_RowMatrix * A)
|
||||
{ A_ = A; Operator_ = A; }
|
||||
|
||||
//! Set Operator A of linear problem AX = B using an Epetra_Operator.
|
||||
/*! Sets a pointer to a Epetra_Operator. No copy of the operator is made.
|
||||
*/
|
||||
void SetOperator(Epetra_Operator * A)
|
||||
{ A_ = dynamic_cast<Epetra_RowMatrix *>(A); Operator_ = A; }
|
||||
|
||||
//! Set left-hand-side X of linear problem AX = B.
|
||||
/*! Sets a pointer to a Epetra_MultiVector. No copy of the object is made.
|
||||
*/
|
||||
void SetLHS(Epetra_MultiVector * X) {X_ = X;}
|
||||
|
||||
//! Set right-hand-side B of linear problem AX = B.
|
||||
/*! Sets a pointer to a Epetra_MultiVector. No copy of the object is made.
|
||||
*/
|
||||
void SetRHS(Epetra_MultiVector * B) {B_ = B;}
|
||||
//@}
|
||||
|
||||
//! @name Computational methods
|
||||
//@{
|
||||
//! Perform left scaling of a linear problem.
|
||||
/*! Applies the scaling vector D to the left side of the matrix A() and
|
||||
to the right hand side B(). Note that the operator must be an Epetra_RowMatrix,
|
||||
not just an Epetra_Operator (the base class of Epetra_RowMatrix).
|
||||
\param In
|
||||
D - Vector containing scaling values. D[i] will be applied
|
||||
to the ith row of A() and B().
|
||||
\return Integer error code, set to 0 if successful. Return -1 if operator is not a matrix.
|
||||
*/
|
||||
int LeftScale(const Epetra_Vector & D);
|
||||
|
||||
//! Perform right scaling of a linear problem.
|
||||
/*! Applies the scaling vector D to the right side of the matrix A().
|
||||
Apply the inverse of D to the initial guess. Note that the operator must be an Epetra_RowMatrix,
|
||||
not just an Epetra_Operator (the base class of Epetra_RowMatrix).
|
||||
\param In
|
||||
D - Vector containing scaling values. D[i] will be applied
|
||||
to the ith row of A(). 1/D[i] will be applied to the
|
||||
ith row of B().
|
||||
\return Integer error code, set to 0 if successful. Return -1 if operator is not a matrix.
|
||||
*/
|
||||
int RightScale(const Epetra_Vector & D);
|
||||
//@}
|
||||
|
||||
//! @name Accessor methods
|
||||
//@{
|
||||
//! Get a pointer to the operator A.
|
||||
Epetra_Operator * GetOperator() const {return(Operator_);};
|
||||
//! Get a pointer to the matrix A.
|
||||
Epetra_RowMatrix * GetMatrix() const {return(A_);};
|
||||
//! Get a pointer to the left-hand-side X.
|
||||
Epetra_MultiVector * GetLHS() const {return(X_);};
|
||||
//! Get a pointer to the right-hand-side B.
|
||||
Epetra_MultiVector * GetRHS() const {return(B_);};
|
||||
//! Get problem difficulty level.
|
||||
ProblemDifficultyLevel GetPDL() const {return(PDL_);};
|
||||
//! Get operator symmetry bool.
|
||||
bool IsOperatorSymmetric() const {return(OperatorSymmetric_);};
|
||||
//@}
|
||||
|
||||
private:
|
||||
|
||||
Epetra_Operator * Operator_;
|
||||
Epetra_RowMatrix * A_;
|
||||
Epetra_MultiVector * X_;
|
||||
Epetra_MultiVector * B_;
|
||||
|
||||
bool OperatorSymmetric_;
|
||||
ProblemDifficultyLevel PDL_;
|
||||
bool LeftScaled_;
|
||||
bool RightScaled_;
|
||||
Epetra_Vector * LeftScaleVector_;
|
||||
Epetra_Vector * RightScaleVector_;
|
||||
Epetra_LinearProblem & operator=(const Epetra_LinearProblem& Problem);
|
||||
};
|
||||
|
||||
#endif /* EPETRA_LINEARPROBLEM_H */
|
||||
@@ -0,0 +1,115 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_LOCALMAP_H
|
||||
#define EPETRA_LOCALMAP_H
|
||||
|
||||
//! Epetra_LocalMap: A class for replicating vectors and matrices across multiple processors.
|
||||
|
||||
/*! Small matrix and vector objects are often replicated on distributed memory
|
||||
parallel machines. The Epetra_LocalMap class allows construction of these replicated
|
||||
local objects and keeps information that describes
|
||||
this distribution.
|
||||
|
||||
Epetra_LocalMap allows the storage and retrieval of the following information.
|
||||
Once a Epetra_Map is constructed any of the following attributes can
|
||||
be obtained
|
||||
by calling a query function that has the name as the attribute, e.g. to get the
|
||||
value of NumGlobalPoints, you can call a function NumGlobalElements().
|
||||
For attributes that
|
||||
are lists, the query functions return the list values in a user allocated array.
|
||||
|
||||
|
||||
<ul>
|
||||
<li> NumMyElements - The number of elements owned by the calling processor.
|
||||
<li> IndexBase - The base integer value for indexed array references. Typically this is 0
|
||||
for C/C++ and 1 for Fortran, but it can be set to any integer value.
|
||||
<li> Comm - The Epetra_Comm communicator. This communicator can in turn be queried for
|
||||
processor rank and size information.
|
||||
</ul>
|
||||
|
||||
The Epetra_LocalMap class is actually a derived class of Epetra_Map. Epetra_Map is in turn derived
|
||||
from Epetra_BlockMap. As such, Epetra_LocalMap has full access to all the functions in these other
|
||||
map classes.
|
||||
|
||||
In particular, the following function allows a boolean test:
|
||||
|
||||
<ul>
|
||||
<li> DistributedGlobal() - Returns false for a Epetra_LocalMap object.
|
||||
</ul>
|
||||
|
||||
\warning A Epetra_Comm object is required for all Epetra_LocalMap constructors.
|
||||
|
||||
\internal In the current implementation, Epetra_Map is the base class for Epetra_LocalMap.
|
||||
|
||||
*/
|
||||
#include "Epetra_Map.h"
|
||||
|
||||
class Epetra_LocalMap : public Epetra_Map {
|
||||
|
||||
public:
|
||||
//! Epetra_LocalMap constructor for a user-defined replicate distribution of elements.
|
||||
/*! Creates a map that puts NumMyElements on the calling processor. Each processor should
|
||||
pass in the same value for NumMyElements.
|
||||
|
||||
\param In
|
||||
NumMyElements - Number of elements owned by the calling processor.
|
||||
|
||||
\param In
|
||||
IndexBase - Minimum index value used for arrays that use this map. Typically 0 for
|
||||
C/C++ and 1 for Fortran.
|
||||
|
||||
\param In
|
||||
Comm - Epetra_Comm communicator containing information on the number of
|
||||
processors.
|
||||
|
||||
\return Pointer to a Epetra_Map object.
|
||||
|
||||
*/
|
||||
Epetra_LocalMap(int NumMyElements, int IndexBase, const Epetra_Comm& Comm);
|
||||
|
||||
//! Epetra_LocalMap copy constructor.
|
||||
|
||||
Epetra_LocalMap(const Epetra_LocalMap& map);
|
||||
|
||||
//! Epetra_LocalMap destructor.
|
||||
|
||||
virtual ~Epetra_LocalMap();
|
||||
|
||||
//! Assignment Operator
|
||||
Epetra_LocalMap & operator=(const Epetra_LocalMap & map);
|
||||
|
||||
private:
|
||||
|
||||
int CheckInput();
|
||||
|
||||
};
|
||||
#endif /* EPETRA_LOCALMAP_H */
|
||||
@@ -0,0 +1,214 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_MAP_H
|
||||
#define EPETRA_MAP_H
|
||||
|
||||
//! Epetra_Map: A class for partitioning vectors and matrices.
|
||||
|
||||
/*! It is often the case that multiple matrix and vector objects have an identical distribution
|
||||
of elements on a parallel machine. The Epetra_Map class keep information that describes
|
||||
this distribution for matrices and vectors.
|
||||
|
||||
Epetra_Map allows the storage and retrieval of the following information. Depending on the
|
||||
constructor that is used, some of the information is defined by the user and some is
|
||||
determined by the constructor. Once a Epetra_Map is constructed any of the following attributes can
|
||||
be obtained
|
||||
by calling a query function that has the name as the attribute, e.g. to get the
|
||||
value of NumGlobalElements, you can call a function NumGlobalElements(). For attributes that
|
||||
are lists, the query functions return the list values in a user allocated array.
|
||||
|
||||
<ul>
|
||||
<li> NumGlobalElements - The total number of elements across all processors. If this parameter and
|
||||
NumMyElements are both passed into the constructor, one of the three cases will apply:
|
||||
<ol>
|
||||
<li> If NumGlobalElements = NumMyElements (and not equal to zero)
|
||||
the map is defined to be a local replicated
|
||||
map. In this case, objects constructed using this map will be identically replicated across
|
||||
all processors in the communicator.
|
||||
<li> If NumGlobalElements = -1 and NumMyElements is passed in then NumGlobalElements will
|
||||
be computed as the sum of NumMyElements across all processors.
|
||||
<li> If neither of the above is true, NumGlobalElements will be checked against the sum of
|
||||
NumMyElements across all processors. An error is issued if the comparison is not equal.
|
||||
</ol>
|
||||
<li> NumMyElements - The number of elements owned by the calling processor.
|
||||
<li> MyGlobalElements - A list of length NumMyElements that contains the global element IDs
|
||||
of the elements owned by the calling processor.
|
||||
<li> IndexBase - The base integer value for indexed array references. Typically this is 0
|
||||
for C/C++ and 1 for Fortran, but it can be set to any integer value.
|
||||
<li> Comm - The Epetra_Comm communicator. This communicator can in turn be queried for
|
||||
processor rank and size information.
|
||||
</ul>
|
||||
|
||||
|
||||
In addition to the information above that is passed in to or created by the Epetra_Map constructor,
|
||||
the following attributes are computed and available via query to the user using the same scheme
|
||||
as above, e.g., use NumGlobalPoints() to get the value of NumGlobalPoints.
|
||||
|
||||
<ul>
|
||||
<li> NumGlobalPoints - The total number of points across all processors.
|
||||
<li> NumMyPoints - The number of points on the calling processor.
|
||||
<li> MinAllGID - The minimum global index value across all processors.
|
||||
<li> MaxAllGID - The maximum global index value across all processors.
|
||||
<li> MinMyGID - The minimum global index value on the calling processor.
|
||||
<li> MaxMyGID - The maximum global index value on the calling processor.
|
||||
<li> MinLID - The minimum local index value on the calling processor.
|
||||
<li> MaxLID - The maximum local index value on the calling processor.
|
||||
</ul>
|
||||
|
||||
The following functions allow boolean tests for certain properties.
|
||||
|
||||
<ul>
|
||||
<li> LinearMap() - Returns true if the elements are distributed linear across processors, i.e.,
|
||||
processor 0 gets the first n/p elements, processor 1 gets the next n/p elements, etc. where
|
||||
n is the number of elements and p is the number of processors.
|
||||
<li> DistributedGlobal() - Returns true if the element space of the map spans more than one processor.
|
||||
This will be true in most cases, but will be false in serial cases and for objects
|
||||
that are created via the derived Epetra_LocalMap class.
|
||||
</ul>
|
||||
|
||||
\warning An Epetra_Comm object is required for all Epetra_Map constructors.
|
||||
|
||||
\note In the current implementation, Epetra_BlockMap is the base class for Epetra_Map.
|
||||
|
||||
*/
|
||||
|
||||
#include "Epetra_BlockMap.h"
|
||||
|
||||
class Epetra_Map : public Epetra_BlockMap {
|
||||
|
||||
public:
|
||||
|
||||
//! Epetra_Map constructor for a Epetra-defined uniform linear distribution of elements.
|
||||
/*! Creates a map that distributes NumGlobalElements elements evenly across all processors in the
|
||||
Epetra_Comm communicator. If NumGlobalElements does not divide exactly into the number of processors,
|
||||
the first processors in the communicator get one extra element until the remainder is gone.
|
||||
|
||||
\param In
|
||||
NumGlobalElements - Number of elements to distribute.
|
||||
|
||||
\param In
|
||||
IndexBase - Minimum index value used for arrays that use this map. Typically 0 for
|
||||
C/C++ and 1 for Fortran.
|
||||
|
||||
\param In
|
||||
Comm - Epetra_Comm communicator containing information on the number of
|
||||
processors.
|
||||
|
||||
\return Pointer to a Epetra_Map object.
|
||||
|
||||
*/
|
||||
Epetra_Map(int NumGlobalElements, int IndexBase, const Epetra_Comm& Comm);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//! Epetra_Map constructor for a user-defined linear distribution of elements.
|
||||
/*! Creates a map that puts NumMyElements on the calling processor. If
|
||||
NumGlobalElements=-1, the number of global elements will be
|
||||
the computed sum of NumMyElements across all processors in the
|
||||
Epetra_Comm communicator.
|
||||
|
||||
\param In
|
||||
NumGlobalElements - Number of elements to distribute. Must be
|
||||
either -1 or equal to the computed sum of NumMyElements across all
|
||||
processors in the Epetra_Comm communicator.
|
||||
|
||||
\param In
|
||||
NumMyElements - Number of elements owned by the calling processor.
|
||||
|
||||
\param In
|
||||
IndexBase - Minimum index value used for arrays that use this map. Typically 0 for
|
||||
C/C++ and 1 for Fortran.
|
||||
|
||||
\param In
|
||||
Comm - Epetra_Comm communicator containing information on the number of
|
||||
processors.
|
||||
|
||||
\return Pointer to a Epetra_Map object.
|
||||
|
||||
*/
|
||||
Epetra_Map(int NumGlobalElements, int NumMyElements, int IndexBase, const Epetra_Comm& Comm);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//! Epetra_Map constructor for a user-defined arbitrary distribution of elements.
|
||||
/*! Creates a map that puts NumMyElements on the calling processor. The indices of the elements
|
||||
are determined from the list MyGlobalElements. If
|
||||
NumGlobalElements=-1, the number of global elements will be
|
||||
the computed sum of NumMyElements across all processors in the
|
||||
Epetra_Comm communicator.
|
||||
|
||||
\param In
|
||||
NumGlobalElements - Number of elements to distribute. Must be
|
||||
either -1 or equal to the computed sum of NumMyElements across all
|
||||
processors in the Epetra_Comm communicator.
|
||||
|
||||
\param In
|
||||
NumMyElements - Number of elements owned by the calling processor.
|
||||
|
||||
\param In
|
||||
MyGlobalElements - Integer array of length NumMyElements. The ith entry contains the
|
||||
global index value of the ith element on this processor. Index values are not required to
|
||||
be contiguous on a processor, or to be within the range of 0 to NumGlobalElements. As
|
||||
long as the index values are consistently defined and used, any set of NumGlobalElements
|
||||
distinct integer values is acceptable.
|
||||
|
||||
\param In
|
||||
IndexBase - Minimum index value used for arrays that use this map. Typically 0 for
|
||||
C/C++ and 1 for Fortran.
|
||||
|
||||
\param In
|
||||
Comm - Epetra_Comm communicator containing information on the number of
|
||||
processors.
|
||||
|
||||
\return Pointer to a Epetra_Map object.
|
||||
|
||||
*/
|
||||
Epetra_Map(int NumGlobalElements, int NumMyElements,
|
||||
const int *MyGlobalElements,
|
||||
int IndexBase, const Epetra_Comm& Comm);
|
||||
|
||||
//! Epetra_Map copy constructor.
|
||||
Epetra_Map(const Epetra_Map& map);
|
||||
|
||||
//! Epetra_Map destructor.
|
||||
virtual ~Epetra_Map(void);
|
||||
|
||||
//! Assignment Operator
|
||||
Epetra_Map & operator=(const Epetra_Map & map);
|
||||
|
||||
};
|
||||
|
||||
#endif /* EPETRA_MAP_H */
|
||||
@@ -0,0 +1,306 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_MAPCOLORING_H
|
||||
#define EPETRA_MAPCOLORING_H
|
||||
#include "Epetra_DistObject.h"
|
||||
#include "Epetra_BlockMap.h"
|
||||
#include "Epetra_Distributor.h"
|
||||
class Epetra_HashTable;
|
||||
class Epetra_Map;
|
||||
|
||||
//! Epetra_MapColoring: A class for coloring Epetra_Map and Epetra_BlockMap objects.
|
||||
|
||||
/*! This class allows the user to associate an integer value, i.e., a color, to each element of
|
||||
an existing Epetra_Map or Epetra_BlockMap object. Colors may be assigned at construction, or
|
||||
via set methods. Any elements that are not explicitly assigned a color are assigned the color
|
||||
0 (integer zero).
|
||||
|
||||
This class has the following features:
|
||||
|
||||
<ul>
|
||||
|
||||
<li> A color (arbitrary integer label) can be associated locally with each element of a map.
|
||||
Color assignment can be done
|
||||
<ol>
|
||||
<li> all-at-once via the constructor, or
|
||||
<li> via operator[] (using LIDs) one-at-a-time
|
||||
<li> operator() (using GIDs) one-at-a-time
|
||||
<li> or some combination of the above.
|
||||
</ol>
|
||||
|
||||
Any element that is not explicitly colored takes on the default color. The default
|
||||
color is implicitly zero, unless specified differently at the time of construction.
|
||||
|
||||
<li> Color information may be accessed in the following ways:
|
||||
<ol>
|
||||
<li> By local element ID (LID) - Returns the color of a specified LID, where the LID is associated
|
||||
with the Epetra_Map or BlockMap that was passed in to the Epetra_MapColoring constructor.
|
||||
<li> By global element ID (GID) - Returns the color of the specified GID. There two methods
|
||||
for accessing GIDs, one assumes the request is for GIDs owned by the calling processor,
|
||||
the second allows arbitrary requested for GIDs, as long as the GID is defined on some processor
|
||||
for the Epetra_Map or Epetra_BlockMap.
|
||||
<li> By color groups - Elements are grouped by color so that all elements of a given color can
|
||||
be accessed.
|
||||
<li> Epetra_Map/Epetra_BlockMap pointers for a specified color - This facilitates
|
||||
use of coloring with Epetra distributed objects that are distributed via the map
|
||||
that was colored. For example, if users want to work with all rows of a matrix that have
|
||||
a certain color, they can create a map for that color and use it to access only those rows.
|
||||
</ol>
|
||||
|
||||
|
||||
<li> The Epetra_MapColoring class implements the Epetra_DistObject interface. Therefore, a map coloring
|
||||
can be computed for a map with a given distribution and then redistributed across the parallel machine.
|
||||
For example, it would be possible to compute a map coloring on a single processor (perhaps because the
|
||||
algorithm for computing the color assignment is too difficult to implement in parallel or because it
|
||||
is cheap to run and not worth parallelizing), and then re-distribute the coloring using an Epetra_Export
|
||||
or Epetra_Import object.
|
||||
</ul>
|
||||
|
||||
*/
|
||||
|
||||
class Epetra_MapColoring: public Epetra_DistObject {
|
||||
|
||||
public:
|
||||
|
||||
//! @name Constructors/destructors
|
||||
//@{
|
||||
//! Epetra_MapColoring basic constructor.
|
||||
/*!
|
||||
\param In
|
||||
Map - An Epetra_Map or Epetra_BlockMap (Note: Epetra_BlockMap is a base class of
|
||||
Epetra_Map, so either can be passed in to this constructor.
|
||||
\param In
|
||||
DefaultColor - The integer value to use as the default color for this map. This constructor
|
||||
will initially define the color of all map elements to the default color.
|
||||
|
||||
\return Pointer to a Epetra_MapColoring object.
|
||||
|
||||
*/
|
||||
Epetra_MapColoring(const Epetra_BlockMap& Map, const int DefaultColor = 0);
|
||||
|
||||
//! Epetra_MapColoring constructor.
|
||||
/*!
|
||||
\param In
|
||||
Map - An Epetra_Map or Epetra_BlockMap (Note: Epetra_BlockMap is a base class of
|
||||
Epetra_Map, so either can be passed in to this constructor.
|
||||
|
||||
\param In
|
||||
ElementColors - Array of dimension Map.NumMyElements() containing the list of colors
|
||||
that should be assigned the map elements on this processor. If this argument is
|
||||
set to 0 (zero), all elements will initially be assigned color 0 (zero). Element
|
||||
colors can be modified by using methods described below.
|
||||
\param In
|
||||
DefaultColor - The color that will be assigned by default when no other value is specified.
|
||||
This value has no meaning for this constructor, but is used by certain methods now and
|
||||
in the future.
|
||||
|
||||
\return Pointer to a Epetra_MapColoring object.
|
||||
|
||||
*/
|
||||
Epetra_MapColoring(const Epetra_BlockMap& Map, int * ElementColors, const int DefaultColor = 0);
|
||||
|
||||
//! Epetra_MapColoring copy constructor.
|
||||
|
||||
Epetra_MapColoring(const Epetra_MapColoring& Source);
|
||||
|
||||
//! Epetra_MapColoring destructor.
|
||||
|
||||
virtual ~Epetra_MapColoring();
|
||||
//@}
|
||||
|
||||
//! @name Set Color methods
|
||||
//@{
|
||||
|
||||
//! LID element color assignment method.
|
||||
/*! Allows color assignment of ith LID: colormap[i] = color
|
||||
\return MapColor(LID).
|
||||
*/
|
||||
int& operator [] (int LID) {ListsAreValid_ = false; return ElementColors_[LID];};
|
||||
|
||||
//! GID element color assignment method, Note: Valid only for GIDs owned by calling processor.
|
||||
/*! Allows color assignment of specified GID \e only if the GID is owned by map on
|
||||
the calling processor. If you are unsure about the ownership of a GID, check by using the MyGID()
|
||||
method. MyGID(GID) returns true if the GID is owned by the calling processor.
|
||||
\return MapColor(GID).
|
||||
*/
|
||||
int& operator () (int GID) {ListsAreValid_ = false; return ElementColors_[Map().LID(GID)];};
|
||||
//@}
|
||||
|
||||
//! @name Local/Global color accessor methods
|
||||
//@{
|
||||
//! LID element color access method.
|
||||
/*! Returns color of ith LID: colormap[i] = color
|
||||
\return MapColor[LID].
|
||||
*/
|
||||
const int& operator [] (int LID) const { return ElementColors_[LID];};
|
||||
|
||||
//! GID element color assignment method, Note: Valid only for GIDs owned by calling processor.
|
||||
/*! Allows color assignment of specified GID \e only if the GID is owned by map on
|
||||
the calling processor. If you are unsure about the ownership, check by using the MyGID()
|
||||
method on the map object.
|
||||
\return MapColor(GID).
|
||||
*/
|
||||
const int& operator () (int GID) const {return ElementColors_[Map().LID(GID)];};
|
||||
//@}
|
||||
|
||||
//! @name Color Information Access Methods
|
||||
//@{
|
||||
//! Returns number of colors on the calling processor.
|
||||
int NumColors() const {if (!ListsAreValid_) GenerateLists(); return(NumColors_);};
|
||||
|
||||
//! Returns maximum over all processors of the number of colors.
|
||||
int MaxNumColors() const;
|
||||
|
||||
//! Array of length NumColors() containing List of color values used in this coloring.
|
||||
/*! Color values can be arbitrary integer values. As a result, a user of a previously
|
||||
constructed MapColoring object may need to know exactly which color values are present.
|
||||
This array contains that information as a sorted list of integer values.
|
||||
*/
|
||||
int * ListOfColors() const {if (!ListsAreValid_) GenerateLists(); return(ListOfColors_);};
|
||||
|
||||
//! Returns default color.
|
||||
int DefaultColor() const {return(DefaultColor_);};
|
||||
|
||||
//! Returns number of map elements on calling processor having specified Color
|
||||
int NumElementsWithColor(int Color) const;
|
||||
|
||||
//! Returns pointer to array of Map LIDs associated with the specified color.
|
||||
/*! Returns a pointer to a list of Map LIDs associated with the specified color.
|
||||
This is a purely local list with no information about other processors. If there
|
||||
are no LIDs associated with the specified color, the pointer is set to zero.
|
||||
*/
|
||||
int * ColorLIDList(int Color) const;
|
||||
|
||||
//! Returns pointer to array of the colors associated with the LIDs on the calling processor.
|
||||
/*! Returns a pointer to the list of colors associated with the elements on this processor
|
||||
such that ElementColor[LID] is the color assigned to that LID.
|
||||
*/
|
||||
int * ElementColors() const{if (!ListsAreValid_) GenerateLists(); return(ElementColors_);};
|
||||
|
||||
//@}
|
||||
//! @name Epetra_Map and Epetra_BlockMap generators
|
||||
//@{
|
||||
//! Generates an Epetra_Map of the GIDs associated with the specified color.
|
||||
/*! This method will create an Epetra_Map such that on each processor the GIDs associated with
|
||||
the specified color will be part of the map on that processor. Note that this
|
||||
method always generates an Epetra_Map, not an Epetra_BlockMap, even if the map associated
|
||||
with this map coloring is a block map. Once the map is generated, the user is responsible for
|
||||
deleting it.
|
||||
*/
|
||||
Epetra_Map * GenerateMap(int Color) const;
|
||||
|
||||
//! Generates an Epetra_BlockMap of the GIDs associated with the specified color.
|
||||
/*! This method will create an Epetra_BlockMap such that on each processor the GIDs associated with
|
||||
the specified color will be part of the map on that processor. Note that this
|
||||
method will generate an Epetra_BlockMap such that each element as the same element size as the
|
||||
corresponding element of map associated with the map coloring.
|
||||
Once the map is generated, the user is responsible for
|
||||
deleting it.
|
||||
*/
|
||||
Epetra_BlockMap * GenerateBlockMap(int Color) const;
|
||||
//@}
|
||||
|
||||
//! @name I/O methods
|
||||
//@{
|
||||
|
||||
//! Print method
|
||||
virtual void Print(ostream & os) const;
|
||||
//@}
|
||||
|
||||
private:
|
||||
int Allocate(int * ElementColors, int Increment);
|
||||
int GenerateLists() const;
|
||||
int DeleteLists() const;
|
||||
bool InItemList(int ColorValue) const;
|
||||
|
||||
// Routines to implement Epetra_DistObject virtual methods
|
||||
|
||||
int CheckSizes(const Epetra_SrcDistObject& A);
|
||||
int CopyAndPermute(const Epetra_SrcDistObject & Source,
|
||||
int NumSameIDs,
|
||||
int NumPermuteIDs,
|
||||
int * PermuteToLIDs,
|
||||
int * PermuteFromLIDs,
|
||||
const Epetra_OffsetIndex * Indexor);
|
||||
|
||||
int PackAndPrepare(const Epetra_SrcDistObject & Source,
|
||||
int NumExportIDs,
|
||||
int * ExportLIDs,
|
||||
int & LenExports,
|
||||
char * & Exports,
|
||||
int & SizeOfPacket,
|
||||
int * Sizes,
|
||||
bool & VarSizes,
|
||||
Epetra_Distributor & Distor);
|
||||
|
||||
int UnpackAndCombine(const Epetra_SrcDistObject & Source,
|
||||
int NumImportIDs,
|
||||
int * ImportLIDs,
|
||||
int LenImports,
|
||||
char * Imports,
|
||||
int & SizeOfPacket,
|
||||
Epetra_Distributor & Distor,
|
||||
Epetra_CombineMode CombineMode,
|
||||
const Epetra_OffsetIndex * Indexor );
|
||||
|
||||
|
||||
struct ListItem {
|
||||
int ItemValue;
|
||||
ListItem * NextItem;
|
||||
|
||||
ListItem( const int itemValue = 0, ListItem * nextItem = 0)
|
||||
: ItemValue(itemValue), NextItem(nextItem){}
|
||||
|
||||
// Constructors commented out due to Intel v.7.1 compiler error (4/2005).
|
||||
//ListItem(const Epetra_MapColoring::ListItem & Item); // Make these inaccessible
|
||||
//ListItem & operator=(const Epetra_MapColoring::ListItem & Item);
|
||||
};
|
||||
|
||||
int DefaultColor_;
|
||||
mutable Epetra_HashTable * ColorIDs_;
|
||||
mutable ListItem * FirstColor_;
|
||||
mutable int NumColors_;
|
||||
mutable int * ListOfColors_;
|
||||
mutable int * ColorCount_;
|
||||
mutable int * ElementColors_;
|
||||
mutable int ** ColorLists_;
|
||||
bool Allocated_;
|
||||
mutable bool ListsAreGenerated_;
|
||||
mutable bool ListsAreValid_;
|
||||
|
||||
Epetra_MapColoring & operator=(const Epetra_MapColoring & Coloring); // Make these inaccessible
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif /* EPETRA_MAPCOLORING_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,197 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_OBJECT_H
|
||||
#define EPETRA_OBJECT_H
|
||||
|
||||
#include "Epetra_CombineMode.h"
|
||||
#include "Epetra_DataAccess.h"
|
||||
#include "Epetra_ConfigDefs.h"
|
||||
|
||||
//! Epetra_Object: The base Epetra class.
|
||||
/*! The Epetra_Object class provides capabilities common to all Epetra objects,
|
||||
such as a label that identifies an object instance, constant definitions,
|
||||
enum types.
|
||||
|
||||
*/
|
||||
class Epetra_Object {
|
||||
|
||||
public:
|
||||
//! @name Constructors/destructor
|
||||
//@{
|
||||
//! Epetra_Object Constructor.
|
||||
/*! Epetra_Object is the primary base class in Epetra. All Epetra class
|
||||
are derived from it, directly or indirectly. This class is seldom
|
||||
used explictly.
|
||||
*/
|
||||
Epetra_Object(int TracebackModeIn = -1, bool set_label = true);
|
||||
|
||||
//! Epetra_Object Constructor.
|
||||
/*! Creates a Epetra_Object with the given label.
|
||||
*/
|
||||
Epetra_Object(const char * const Label, int TracebackModeIn = -1);
|
||||
|
||||
//! Epetra_Object Copy Constructor.
|
||||
/*! Makes an exact copy of an existing Epetra_Object instance.
|
||||
*/
|
||||
Epetra_Object(const Epetra_Object& Object);
|
||||
|
||||
//! Epetra_Object Destructor.
|
||||
/*! Completely deletes a Epetra_Object object.
|
||||
*/
|
||||
virtual ~Epetra_Object();
|
||||
//@}
|
||||
|
||||
//! @name Attribute set/get methods
|
||||
//@{
|
||||
|
||||
//! Epetra_Object Label definition using char *.
|
||||
/*! Defines the label used to describe the \e this object.
|
||||
*/
|
||||
virtual void SetLabel(const char * const Label);
|
||||
|
||||
//! Epetra_Object Label access funtion.
|
||||
/*! Returns the string used to define this object.
|
||||
*/
|
||||
virtual const char * Label() const;
|
||||
|
||||
//! Set the value of the Epetra_Object error traceback report mode.
|
||||
/*! Sets the integer error traceback behavior.
|
||||
TracebackMode controls whether or not traceback information is printed when run time
|
||||
integer errors are detected:
|
||||
|
||||
<= 0 - No information report
|
||||
|
||||
= 1 - Fatal (negative) values are reported
|
||||
|
||||
>= 2 - All values (except zero) reported.
|
||||
|
||||
Default is set to 1.
|
||||
*/
|
||||
static void SetTracebackMode(int TracebackModeValue);
|
||||
|
||||
//! Get the value of the Epetra_Object error report mode.
|
||||
static int GetTracebackMode();
|
||||
|
||||
//! Get the output stream for error reporting
|
||||
static std::ostream& GetTracebackStream();
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Miscellaneous
|
||||
//@{
|
||||
|
||||
//! Print object to an output stream
|
||||
//! Print method
|
||||
virtual void Print(ostream & os) const;
|
||||
|
||||
//! Error reporting method
|
||||
virtual int ReportError(const string Message, int ErrorCode) const;
|
||||
//@}
|
||||
|
||||
|
||||
// TracebackMode controls how much traceback information is printed when run time
|
||||
// integer errors are detected:
|
||||
// = 0 - No information report
|
||||
// = 1 - Fatal (negative) values are reported
|
||||
// = 2 - All values (except zero) reported.
|
||||
|
||||
// Default is set to 1. Can be set to different value using SetTracebackMode() method in
|
||||
// Epetra_Object class
|
||||
static int TracebackMode;
|
||||
|
||||
|
||||
protected:
|
||||
string toString(const int& x) const {
|
||||
char s[100];
|
||||
sprintf(s, "%d", x);
|
||||
return string(s);
|
||||
}
|
||||
|
||||
string toString(const double& x) const {
|
||||
char s[100];
|
||||
sprintf(s, "%g", x);
|
||||
return string(s);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
Epetra_Object& operator=(const Epetra_Object& src) {
|
||||
SetLabel(src.Label());
|
||||
return *this;
|
||||
}
|
||||
|
||||
char * Label_;
|
||||
|
||||
};
|
||||
|
||||
inline ostream& operator<<(ostream& os, const Epetra_Object& obj)
|
||||
{
|
||||
if (Epetra_FormatStdout) {
|
||||
/* const Epetra_fmtflags olda = os.setf(ios::right,ios::adjustfield);
|
||||
const Epetra_fmtflags oldf = os.setf(ios::scientific,ios::floatfield);
|
||||
const int oldp = os.precision(12); */
|
||||
|
||||
os << obj.Label() << endl;
|
||||
obj.Print(os);
|
||||
|
||||
/* os.setf(olda,ios::adjustfield);
|
||||
os.setf(oldf,ios::floatfield);
|
||||
os.precision(oldp); */
|
||||
}
|
||||
else {
|
||||
|
||||
os << obj.Label();
|
||||
obj.Print(os);
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
/** \brief Macro for testing for and throwing and int exception for objects
|
||||
* derived from Epetra_Object.
|
||||
*
|
||||
* This macro adds the file name and line number to teh
|
||||
*/
|
||||
#define EPETRA_TEST_FOR_EXCEPTION(throw_exception_test,errCode,msg) \
|
||||
{ \
|
||||
const bool throw_exception = (throw_exception_test); \
|
||||
if(throw_exception) { \
|
||||
std::ostringstream omsg; \
|
||||
omsg \
|
||||
<< __FILE__ << ":" << __LINE__ << ":" \
|
||||
<< " Throw test that evaluated to true: "#throw_exception_test << ":" \
|
||||
<< "Error message : " << msg; \
|
||||
throw ReportError(omsg.str(),errCode); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* EPETRA_OBJECT_H */
|
||||
@@ -0,0 +1,108 @@
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_OFFSETINDEX_H
|
||||
#define EPETRA_OFFSETINDEX_H
|
||||
|
||||
#include "Epetra_Object.h"
|
||||
|
||||
class Epetra_Import;
|
||||
class Epetra_Export;
|
||||
class Epetra_CrsGraph;
|
||||
class Epetra_Distributor;
|
||||
|
||||
//! Epetra_OffsetIndex: This class builds index for efficient mapping of data from one Epetra_CrsGraph based object to another.
|
||||
|
||||
/*! Epetra_OffsetIndex generates and index of offsets allowing direct access to data
|
||||
for Import/Export operations on Epetra_CrsGraph based objects such as Epetra_CrsMatrix.
|
||||
*/
|
||||
|
||||
class Epetra_OffsetIndex: public Epetra_Object {
|
||||
|
||||
public:
|
||||
|
||||
//! Constructs a Epetra_OffsetIndex object from the graphs and an importer.
|
||||
Epetra_OffsetIndex( const Epetra_CrsGraph & SourceGraph,
|
||||
const Epetra_CrsGraph & TargetGraph,
|
||||
Epetra_Import & Importer );
|
||||
|
||||
//! Constructs a Epetra_OffsetIndex object from the graphs and an exporter.
|
||||
Epetra_OffsetIndex( const Epetra_CrsGraph & SourceGraph,
|
||||
const Epetra_CrsGraph & TargetGraph,
|
||||
Epetra_Export & Exporter );
|
||||
|
||||
//! Epetra_OffsetIndex copy constructor.
|
||||
Epetra_OffsetIndex(const Epetra_OffsetIndex & Indexor);
|
||||
|
||||
//! Epetra_OffsetIndex destructor.
|
||||
virtual ~Epetra_OffsetIndex(void);
|
||||
|
||||
//! @name Print object to an output stream
|
||||
//@{
|
||||
virtual void Print(ostream & os) const;
|
||||
//@}
|
||||
|
||||
//! Accessor
|
||||
int ** SameOffsets() const { return SameOffsets_; }
|
||||
|
||||
//! Accessor
|
||||
int ** PermuteOffsets() const { return PermuteOffsets_; }
|
||||
|
||||
//! Accessor
|
||||
int ** RemoteOffsets() const { return RemoteOffsets_; }
|
||||
|
||||
private:
|
||||
|
||||
void GenerateLocalOffsets_( const Epetra_CrsGraph & SourceGraph,
|
||||
const Epetra_CrsGraph & TargetGraph,
|
||||
const int * PermuteLIDs );
|
||||
|
||||
void GenerateRemoteOffsets_( const Epetra_CrsGraph & SourceGraph,
|
||||
const Epetra_CrsGraph & TargetGraph,
|
||||
const int * ExportLIDs,
|
||||
const int * RemoteLIDs,
|
||||
Epetra_Distributor & Distor );
|
||||
|
||||
//! Epetra_OffsetIndex copy constructor.
|
||||
Epetra_OffsetIndex & operator=(const Epetra_OffsetIndex & Indexor);
|
||||
public:
|
||||
|
||||
int NumSame_;
|
||||
int ** SameOffsets_;
|
||||
int NumPermute_;
|
||||
int ** PermuteOffsets_;
|
||||
int NumExport_;
|
||||
int NumRemote_;
|
||||
int ** RemoteOffsets_;
|
||||
|
||||
bool DataOwned_;
|
||||
};
|
||||
|
||||
#endif /* EPETRA_OFFSETINDEX_H */
|
||||
@@ -0,0 +1,134 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_OPERATOR_H
|
||||
#define EPETRA_OPERATOR_H
|
||||
|
||||
class Epetra_MultiVector;
|
||||
class Epetra_Map;
|
||||
class Epetra_Comm;
|
||||
|
||||
//! Epetra_Operator: A pure virtual class for using real-valued double-precision operators.
|
||||
/*! The Epetra_Operator class is a pure virtual class (specifies interface only) that
|
||||
enable the use of real-valued double-precision operators. It is currently implemented by both the
|
||||
Epetra_CrsMatrix and Epetra_VbrMatrix classes and the Ifpack_CrsRiluk preconditioner class.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class Epetra_Operator {
|
||||
|
||||
public:
|
||||
|
||||
//! @name Destructor
|
||||
//@{
|
||||
//! Destructor
|
||||
virtual ~Epetra_Operator() {};
|
||||
//@}
|
||||
|
||||
//! @name Atribute set methods
|
||||
//@{
|
||||
|
||||
//! If set true, transpose of this operator will be applied.
|
||||
/*! This flag allows the transpose of the given operator to be used implicitly. Setting this flag
|
||||
affects only the Apply() and ApplyInverse() methods. If the implementation of this interface
|
||||
does not support transpose use, this method should return a value of -1.
|
||||
|
||||
\param In
|
||||
UseTranspose -If true, multiply by the transpose of operator, otherwise just use operator.
|
||||
|
||||
\return Integer error code, set to 0 if successful. Set to -1 if this implementation does not support transpose.
|
||||
*/
|
||||
virtual int SetUseTranspose(bool UseTranspose) = 0;
|
||||
//@}
|
||||
|
||||
//! @name Mathematical functions
|
||||
//@{
|
||||
|
||||
//! Returns the result of a Epetra_Operator applied to a Epetra_MultiVector X in Y.
|
||||
/*!
|
||||
\param In
|
||||
X - A Epetra_MultiVector of dimension NumVectors to multiply with matrix.
|
||||
\param Out
|
||||
Y -A Epetra_MultiVector of dimension NumVectors containing result.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual int Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const = 0;
|
||||
|
||||
//! Returns the result of a Epetra_Operator inverse applied to an Epetra_MultiVector X in Y.
|
||||
/*!
|
||||
\param In
|
||||
X - A Epetra_MultiVector of dimension NumVectors to solve for.
|
||||
\param Out
|
||||
Y -A Epetra_MultiVector of dimension NumVectors containing result.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
|
||||
\warning In order to work with AztecOO, any implementation of this method must
|
||||
support the case where X and Y are the same object.
|
||||
*/
|
||||
virtual int ApplyInverse(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const = 0;
|
||||
|
||||
//! Returns the infinity norm of the global matrix.
|
||||
/* Returns the quantity \f$ \| A \|_\infty\f$ such that
|
||||
\f[\| A \|_\infty = \max_{1\lei\lem} \sum_{j=1}^n |a_{ij}| \f].
|
||||
|
||||
\warning This method must not be called unless HasNormInf() returns true.
|
||||
*/
|
||||
virtual double NormInf() const = 0;
|
||||
//@}
|
||||
|
||||
//! @name Atribute access functions
|
||||
//@{
|
||||
|
||||
//! Returns a character string describing the operator
|
||||
virtual const char * Label() const = 0;
|
||||
|
||||
//! Returns the current UseTranspose setting.
|
||||
virtual bool UseTranspose() const = 0;
|
||||
|
||||
//! Returns true if the \e this object can provide an approximate Inf-norm, false otherwise.
|
||||
virtual bool HasNormInf() const = 0;
|
||||
|
||||
//! Returns a pointer to the Epetra_Comm communicator associated with this operator.
|
||||
virtual const Epetra_Comm & Comm() const = 0;
|
||||
|
||||
//! Returns the Epetra_Map object associated with the domain of this operator.
|
||||
virtual const Epetra_Map & OperatorDomainMap() const = 0;
|
||||
|
||||
//! Returns the Epetra_Map object associated with the range of this operator.
|
||||
virtual const Epetra_Map & OperatorRangeMap() const = 0;
|
||||
//@}
|
||||
|
||||
};
|
||||
|
||||
#endif /* EPETRA_OPERATOR_H */
|
||||
@@ -0,0 +1,257 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_ROWMATRIX_H
|
||||
#define EPETRA_ROWMATRIX_H
|
||||
|
||||
class Epetra_Comm;
|
||||
class Epetra_Import;
|
||||
class Epetra_Export;
|
||||
class Epetra_Vector;
|
||||
class Epetra_MultiVector;
|
||||
#include "Epetra_Operator.h"
|
||||
#include "Epetra_SrcDistObject.h"
|
||||
|
||||
|
||||
//! Epetra_RowMatrix: A pure virtual class for using real-valued double-precision row matrices.
|
||||
|
||||
/*! The Epetra_RowMatrix class is a pure virtual class (specifies interface only) that
|
||||
enable the use of real-valued double-precision sparse matrices
|
||||
where matrix entries are intended for row access. It is currently implemented by both the
|
||||
Epetra_CrsMatrix and Epetra_VbrMatrix classes.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
class Epetra_RowMatrix: public virtual Epetra_Operator, public virtual Epetra_SrcDistObject {
|
||||
|
||||
public:
|
||||
//! @name Destructor
|
||||
//@{
|
||||
//! Destructor
|
||||
virtual ~Epetra_RowMatrix() {};
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Matrix data extraction routines
|
||||
//@{
|
||||
|
||||
//! Returns the number of nonzero entries in MyRow.
|
||||
/*!
|
||||
\param In
|
||||
MyRow - Local row.
|
||||
\param Out
|
||||
NumEntries - Number of nonzero values present.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual int NumMyRowEntries(int MyRow, int & NumEntries) const = 0;
|
||||
|
||||
|
||||
//! Returns the maximum of NumMyRowEntries() over all rows.
|
||||
virtual int MaxNumEntries() const = 0;
|
||||
|
||||
//! Returns a copy of the specified local row in user-provided arrays.
|
||||
/*!
|
||||
\param In
|
||||
MyRow - Local row to extract.
|
||||
\param In
|
||||
Length - Length of Values and Indices.
|
||||
\param Out
|
||||
NumEntries - Number of nonzero entries extracted.
|
||||
\param Out
|
||||
Values - Extracted values for this row.
|
||||
\param Out
|
||||
Indices - Extracted global column indices for the corresponding values.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual int ExtractMyRowCopy(int MyRow, int Length, int & NumEntries, double *Values, int * Indices) const = 0;
|
||||
|
||||
//! Returns a copy of the main diagonal in a user-provided vector.
|
||||
/*!
|
||||
\param Out
|
||||
Diagonal - Extracted main diagonal.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual int ExtractDiagonalCopy(Epetra_Vector & Diagonal) const = 0;
|
||||
//@}
|
||||
|
||||
//! @name Mathematical functions
|
||||
//@{
|
||||
|
||||
//! Returns the result of a Epetra_RowMatrix multiplied by a Epetra_MultiVector X in Y.
|
||||
/*!
|
||||
\param In
|
||||
TransA -If true, multiply by the transpose of matrix, otherwise just use matrix.
|
||||
\param In
|
||||
X - A Epetra_MultiVector of dimension NumVectors to multiply with matrix.
|
||||
\param Out
|
||||
Y -A Epetra_MultiVector of dimension NumVectorscontaining result.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual int Multiply(bool TransA, const Epetra_MultiVector& X, Epetra_MultiVector& Y) const = 0;
|
||||
|
||||
//! Returns result of a local-only solve using a triangular Epetra_RowMatrix with Epetra_MultiVectors X and Y.
|
||||
/*! This method will perform a triangular solve independently on each processor of the parallel machine.
|
||||
No communication is performed.
|
||||
\param In
|
||||
Upper -If true, solve Ux = y, otherwise solve Lx = y.
|
||||
\param In
|
||||
Trans -If true, solve transpose problem.
|
||||
\param In
|
||||
UnitDiagonal -If true, assume diagonal is unit (whether it's stored or not).
|
||||
\param In
|
||||
X - A Epetra_MultiVector of dimension NumVectors to solve for.
|
||||
\param Out
|
||||
Y -A Epetra_MultiVector of dimension NumVectors containing result.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual int Solve(bool Upper, bool Trans, bool UnitDiagonal, const Epetra_MultiVector& X,
|
||||
Epetra_MultiVector& Y) const = 0;
|
||||
|
||||
//! Computes the sum of absolute values of the rows of the Epetra_RowMatrix, results returned in x.
|
||||
/*! The vector x will return such that x[i] will contain the inverse of sum of the absolute values of the
|
||||
\e this matrix will be scaled such that A(i,j) = x(i)*A(i,j) where i denotes the global row number of A
|
||||
and j denotes the global column number of A. Using the resulting vector from this function as input to LeftScale()
|
||||
will make the infinity norm of the resulting matrix exactly 1.
|
||||
\param Out
|
||||
x -A Epetra_Vector containing the row sums of the \e this matrix.
|
||||
\warning It is assumed that the distribution of x is the same as the rows of \e this.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual int InvRowSums(Epetra_Vector& x) const = 0;
|
||||
|
||||
//! Scales the Epetra_RowMatrix on the left with a Epetra_Vector x.
|
||||
/*! The \e this matrix will be scaled such that A(i,j) = x(i)*A(i,j) where i denotes the row number of A
|
||||
and j denotes the column number of A.
|
||||
\param In
|
||||
x -A Epetra_Vector to solve for.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual int LeftScale(const Epetra_Vector& x) = 0;
|
||||
|
||||
//! Computes the sum of absolute values of the columns of the Epetra_RowMatrix, results returned in x.
|
||||
/*! The vector x will return such that x[j] will contain the inverse of sum of the absolute values of the
|
||||
\e this matrix will be sca such that A(i,j) = x(j)*A(i,j) where i denotes the global row number of A
|
||||
and j denotes the global column number of A. Using the resulting vector from this function as input to
|
||||
RighttScale() will make the one norm of the resulting matrix exactly 1.
|
||||
\param Out
|
||||
x -A Epetra_Vector containing the column sums of the \e this matrix.
|
||||
\warning It is assumed that the distribution of x is the same as the rows of \e this.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual int InvColSums(Epetra_Vector& x) const = 0;
|
||||
|
||||
//! Scales the Epetra_RowMatrix on the right with a Epetra_Vector x.
|
||||
/*! The \e this matrix will be scaled such that A(i,j) = x(j)*A(i,j) where i denotes the global row number of A
|
||||
and j denotes the global column number of A.
|
||||
\param In
|
||||
x -The Epetra_Vector used for scaling \e this.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual int RightScale(const Epetra_Vector& x) = 0;
|
||||
//@}
|
||||
|
||||
//! @name Atribute access functions
|
||||
//@{
|
||||
|
||||
//! If FillComplete() has been called, this query returns true, otherwise it returns false.
|
||||
virtual bool Filled() const = 0;
|
||||
|
||||
//! Returns the infinity norm of the global matrix.
|
||||
/* Returns the quantity \f$ \| A \|_\infty\f$ such that
|
||||
\f[\| A \|_\infty = \max_{1\lei\len} \sum_{i=1}^m |a_{ij}| \f].
|
||||
*/
|
||||
virtual double NormInf() const = 0;
|
||||
|
||||
//! Returns the one norm of the global matrix.
|
||||
/* Returns the quantity \f$ \| A \|_1\f$ such that
|
||||
\f[\| A \|_1= \max_{1\lej\len} \sum_{j=1}^n |a_{ij}| \f].
|
||||
*/
|
||||
virtual double NormOne() const = 0;
|
||||
|
||||
//! Returns the number of nonzero entries in the global matrix.
|
||||
/*
|
||||
Note that depending on the matrix implementation, it is sometimes
|
||||
possible to have some nonzeros that appear on multiple processors.
|
||||
In that case, those nonzeros may be counted multiple times (also
|
||||
depending on the matrix implementation).
|
||||
*/
|
||||
virtual int NumGlobalNonzeros() const = 0;
|
||||
|
||||
//! Returns the number of global matrix rows.
|
||||
virtual int NumGlobalRows() const = 0;
|
||||
|
||||
//! Returns the number of global matrix columns.
|
||||
virtual int NumGlobalCols() const= 0;
|
||||
|
||||
//! Returns the number of global nonzero diagonal entries, based on global row/column index comparisons.
|
||||
virtual int NumGlobalDiagonals() const = 0;
|
||||
|
||||
//! Returns the number of nonzero entries in the calling processor's portion of the matrix.
|
||||
virtual int NumMyNonzeros() const = 0;
|
||||
|
||||
//! Returns the number of matrix rows owned by the calling processor.
|
||||
virtual int NumMyRows() const = 0;
|
||||
|
||||
//! Returns the number of matrix columns owned by the calling processor.
|
||||
virtual int NumMyCols() const = 0;
|
||||
|
||||
//! Returns the number of local nonzero diagonal entries, based on global row/column index comparisons.
|
||||
virtual int NumMyDiagonals() const = 0;
|
||||
|
||||
//! If matrix is lower triangular in local index space, this query returns true, otherwise it returns false.
|
||||
virtual bool LowerTriangular() const = 0;
|
||||
|
||||
//! If matrix is upper triangular in local index space, this query returns true, otherwise it returns false.
|
||||
virtual bool UpperTriangular() const = 0;
|
||||
|
||||
//! Returns the Epetra_Map object associated with the rows of this matrix.
|
||||
virtual const Epetra_Map & RowMatrixRowMap() const = 0;
|
||||
|
||||
//! Returns the Epetra_Map object associated with the columns of this matrix.
|
||||
virtual const Epetra_Map & RowMatrixColMap() const = 0;
|
||||
|
||||
//! Returns the Epetra_Import object that contains the import operations for distributed operations.
|
||||
virtual const Epetra_Import * RowMatrixImporter() const = 0;
|
||||
//@}
|
||||
};
|
||||
|
||||
#endif /* EPETRA_ROWMATRIX_H */
|
||||
@@ -0,0 +1,154 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_CRSMATRIXTRANSPOSER_H
|
||||
#define EPETRA_CRSMATRIXTRANSPOSER_H
|
||||
#include <Epetra_Object.h>
|
||||
class Epetra_RowMatrix;
|
||||
class Epetra_CrsMatrix;
|
||||
class Epetra_Map;
|
||||
class Epetra_Export;
|
||||
|
||||
//! Epetra_RowMatrixTransposer: A class for transposing an Epetra_RowMatrix object.
|
||||
|
||||
/*! This class provides capabilities to construct a transpose matrix of an existing Epetra_RowMatrix
|
||||
object and (optionally) redistribute it across a parallel distributed memory machine.
|
||||
*/
|
||||
|
||||
class Epetra_RowMatrixTransposer {
|
||||
|
||||
public:
|
||||
|
||||
//! @name Constructors/destructors
|
||||
//@{
|
||||
//! Primary Epetra_RowMatrixTransposer constructor.
|
||||
/*!
|
||||
\param Matrix (In) An existing Epetra_RowMatrix object. The Epetra_RowMatrix, the LHS and RHS pointers
|
||||
do not need to be defined before this constructor is called.
|
||||
|
||||
\return Pointer to a Epetra_RowMatrixTransposer object.
|
||||
|
||||
*/
|
||||
Epetra_RowMatrixTransposer(Epetra_RowMatrix * OrigMatrix);
|
||||
|
||||
//! Epetra_RowMatrixTransposer copy constructor.
|
||||
|
||||
Epetra_RowMatrixTransposer(const Epetra_RowMatrixTransposer& Source);
|
||||
|
||||
//! Epetra_RowMatrixTransposer destructor.
|
||||
|
||||
virtual ~Epetra_RowMatrixTransposer();
|
||||
//@}
|
||||
|
||||
//! @name Forward transformation methods
|
||||
//@{
|
||||
|
||||
//! Generate a new Epetra_CrsMatrix as the transpose of an Epetra_RowMatrix passed into the constructor.
|
||||
/*! Constructs a new Epetra_CrsMatrix that is a copy of the Epetra_RowMatrix passed in to the constructor.
|
||||
|
||||
\param MakeDataContiguous (In) Causes the output matrix, LHS and RHS to be stored in a form compatible with
|
||||
Fortran-style solvers. The output matrix will be compatible with the Harwell-Boeing compressed
|
||||
column format. The RHS and LHS will be stored such that the last value in column j of the
|
||||
multivector is stored next to the first value in column j+1.
|
||||
\param TransposeRowMap (Optional/In) If this argument is defined, the transpose matrix will be distributed
|
||||
using this map as the row map for the transpose. If it is set to zero, the transpose matrix will use
|
||||
the OrigMatrix->RowMatrixDomainMap as the row map.
|
||||
|
||||
\return Integer error code, 0 if no errors. Negative if some fatal error occured.
|
||||
|
||||
*/
|
||||
int CreateTranspose(const bool MakeDataContiguous,
|
||||
Epetra_CrsMatrix *& TransposeMatrix,
|
||||
Epetra_Map * TransposeRowMap = 0);
|
||||
|
||||
|
||||
//! Update the values of an already-redistributed problem.
|
||||
/*! Updates the values of an already-redistributed problem. This method allows updating
|
||||
the redistributed problem without
|
||||
allocating new storage.
|
||||
|
||||
\param MatrixWithNewValues (In) The values from MatrixWithNewValues will be copied into the TransposeMatrix. The
|
||||
MatrixWithNewValues object must be identical in structure to the original matrix object used to create
|
||||
this instance of Epetra_RowMatrixTransposer.
|
||||
|
||||
\return Integer error code, 0 if no errors. Negative if some fatal error occured.
|
||||
|
||||
*/
|
||||
int UpdateTransposeValues(Epetra_RowMatrix * MatrixWithNewValues);
|
||||
//@}
|
||||
|
||||
//! @name Reverse transformation methods
|
||||
//@{
|
||||
//! Update values of original matrix (Not implemented and not sure if we will implement this).
|
||||
int UpdateOriginalMatrixValues();
|
||||
//@}
|
||||
|
||||
//! @name Attribute accessor methods
|
||||
//@{
|
||||
|
||||
//! Returns const reference to the Epetra_Map object describing the row distribution of the transpose matrix.
|
||||
/*! The RedistExporter object can be used to redistribute other Epetra_DistObject objects whose maps are compatible with
|
||||
the original linear problem map, or with the RedistMap().
|
||||
\warning Must not be called before CreateTranspose()is called.
|
||||
*/
|
||||
const Epetra_Map & TransposeRowMap() const {return(*TransposeRowMap_);};
|
||||
//! Returns const reference to the Epetra_Export object used to redistribute the original matrix.
|
||||
/*! The TransposeExporter object can be used to redistribute other Epetra_DistObject objects whose maps are compatible with
|
||||
the original matrix.
|
||||
\warning Must not be called before CreateTranspose() is called.
|
||||
*/
|
||||
const Epetra_Export & TransposeExporter() const{return(*TransposeExporter_);};
|
||||
//@}
|
||||
|
||||
private:
|
||||
void DeleteData();
|
||||
Epetra_RowMatrixTransposer& operator=(const Epetra_RowMatrixTransposer& src);
|
||||
|
||||
Epetra_RowMatrix * OrigMatrix_;
|
||||
Epetra_CrsMatrix * TransposeMatrix_;
|
||||
Epetra_Export * TransposeExporter_;
|
||||
Epetra_Map * TransposeRowMap_;
|
||||
bool TransposeCreated_;
|
||||
bool MakeDataContiguous_;
|
||||
int NumMyRows_;
|
||||
int NumMyCols_;
|
||||
int MaxNumEntries_;
|
||||
int * Indices_;
|
||||
double * Values_;
|
||||
int * TransNumNz_;
|
||||
int ** TransIndices_;
|
||||
double ** TransValues_;
|
||||
int * TransMyGlobalEquations_;
|
||||
bool OrigMatrixIsCrsMatrix_;
|
||||
|
||||
};
|
||||
|
||||
#endif /* EPETRA_CRSMATRIXTRANSPOSER_H */
|
||||
@@ -0,0 +1,380 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_SERIALCOMM_H
|
||||
#define EPETRA_SERIALCOMM_H
|
||||
|
||||
#include "Epetra_Object.h"
|
||||
#include "Epetra_Comm.h"
|
||||
#include "Epetra_SerialCommData.h"
|
||||
class Epetra_Distributor;
|
||||
|
||||
//! Epetra_SerialComm: The Epetra Serial Communication Class.
|
||||
/*! The Epetra_SerialComm class is an implementation of Epetra_Comm, providing the general
|
||||
information and services needed for other Epetra classes to run on a serial computer.
|
||||
*/
|
||||
|
||||
class Epetra_SerialComm: public Epetra_Object, public virtual Epetra_Comm {
|
||||
|
||||
public:
|
||||
//! @name Constructor/Destructor Methods
|
||||
//@{
|
||||
|
||||
//! Epetra_SerialComm Serial Constructor.
|
||||
/*! Builds an instance of a serial communicator. Even
|
||||
if the application is running in parallel via MPI, this communicator
|
||||
will execute in serial. The access functions return the number of
|
||||
processors to be 1 and the processor ID to be 0.
|
||||
*/
|
||||
Epetra_SerialComm();
|
||||
|
||||
|
||||
//! Epetra_SerialComm Copy Constructor.
|
||||
/*! Makes an exact copy of an existing Epetra_SerialComm instance.
|
||||
*/
|
||||
Epetra_SerialComm(const Epetra_SerialComm& Comm);
|
||||
|
||||
//! Clone method.
|
||||
Epetra_Comm * Clone() const {
|
||||
return(dynamic_cast<Epetra_Comm *>(new Epetra_SerialComm(*this)));
|
||||
};
|
||||
|
||||
//! Epetra_SerialComm Destructor.
|
||||
/*! Completely deletes a Epetra_SerialComm object.
|
||||
\warning Note: All objects that depend
|
||||
on a Epetra_SerialComm instance should be destroyed prior to calling this
|
||||
function.
|
||||
*/
|
||||
virtual ~Epetra_SerialComm();
|
||||
//@}
|
||||
|
||||
//! @name Barrier Methods
|
||||
//@{
|
||||
//! Epetra_SerialComm Barrier function.
|
||||
/*! A no-op for a serial communicator.
|
||||
*/
|
||||
void Barrier() const;
|
||||
//@}
|
||||
|
||||
//! @name Broadcast Methods
|
||||
//@{
|
||||
//! Epetra_SerialComm Broadcast function.
|
||||
/*! A no-op for a serial communicator.
|
||||
\param MyVals InOut
|
||||
On entry, the root processor contains the list of values. On exit,
|
||||
all processors will have the same list of values. Note that values must be
|
||||
allocated on all processor before the broadcast.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of MyVals.
|
||||
\param Root In
|
||||
On entry, contains the processor from which all processors will receive a copy of MyVals.
|
||||
*/
|
||||
|
||||
int Broadcast(double * MyVals, int Count, int Root) const;
|
||||
|
||||
//! Epetra_SerialComm Broadcast function.
|
||||
/*! A no-op for a serial communicator.
|
||||
\param MyVals InOut
|
||||
On entry, the root processor contains the list of values. On exit,
|
||||
all processors will have the same list of values. Note that values must be
|
||||
allocated on all processor before the broadcast.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of MyVals.
|
||||
\param Root In
|
||||
On entry, contains the processor from which all processors will receive a copy of MyVals.
|
||||
*/
|
||||
|
||||
int Broadcast(int * MyVals, int Count, int Root) const;
|
||||
|
||||
//! Epetra_SerialComm Broadcast function.
|
||||
/*! A no-op for a serial communicator.
|
||||
\param MyVals InOut
|
||||
On entry, the root processor contains the list of values. On exit,
|
||||
all processors will have the same list of values. Note that values must be
|
||||
allocated on all processor before the broadcast.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of MyVals.
|
||||
\param Root In
|
||||
On entry, contains the processor from which all processors will receive a copy of MyVals.
|
||||
*/
|
||||
|
||||
int Broadcast(long * MyVals, int Count, int Root) const;
|
||||
//@}
|
||||
|
||||
//! @name Gather Methods
|
||||
//@{
|
||||
//! Epetra_SerialComm All Gather function.
|
||||
/*! A copy for a serial communicator.
|
||||
\param MyVals In
|
||||
On entry, contains the list of values, to be sent to all processors.
|
||||
\param AllVals Out
|
||||
On exit, contains the list of values from all processors. Must by of size NumProc*Count.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of MyVals.
|
||||
*/
|
||||
|
||||
int GatherAll(double * MyVals, double * AllVals, int Count) const;
|
||||
|
||||
//! Epetra_SerialComm All Gather function.
|
||||
/*! A copy for a serial communicator.
|
||||
\param MyVals In
|
||||
On entry, contains the list of values, to be sent to all processors.
|
||||
\param AllVals Out
|
||||
On exit, contains the list of values from all processors. Must by of size NumProc*Count.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of MyVals.
|
||||
*/
|
||||
|
||||
int GatherAll(int * MyVals, int * AllVals, int Count) const;
|
||||
|
||||
//! Epetra_SerialComm All Gather function.
|
||||
/*! A copy for a serial communicator.
|
||||
\param MyVals In
|
||||
On entry, contains the list of values, to be sent to all processors.
|
||||
\param AllVals Out
|
||||
On exit, contains the list of values from all processors. Must by of size NumProc*Count.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of MyVals.
|
||||
*/
|
||||
|
||||
int GatherAll(long * MyVals, long * AllVals, int Count) const;
|
||||
//@}
|
||||
|
||||
//! @name Sum Methods
|
||||
//@{
|
||||
//! Epetra_SerialComm Global Sum function.
|
||||
/*! A copy for a serial communicator.
|
||||
\param PartialSums In
|
||||
On entry, contains the list of values, usually partial sums computed locally,
|
||||
to be summed across all processors.
|
||||
\param GlobalSums Out
|
||||
On exit, contains the list of values summed across all processors.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of values.
|
||||
*/
|
||||
|
||||
int SumAll(double * PartialSums, double * GlobalSums, int Count) const;
|
||||
|
||||
//! Epetra_SerialComm Global Sum function.
|
||||
/*! A copy for a serial communicator.
|
||||
\param PartialSums In
|
||||
On entry, contains the list of values, usually partial sums computed locally,
|
||||
to be summed across all processors.
|
||||
\param GlobalSums Out
|
||||
On exit, contains the list of values summed across all processors.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of values.
|
||||
*/
|
||||
int SumAll(int * PartialSums, int * GlobalSums, int Count) const;
|
||||
|
||||
//! Epetra_SerialComm Global Sum function.
|
||||
/*! A copy for a serial communicator.
|
||||
\param PartialSums In
|
||||
On entry, contains the list of values, usually partial sums computed locally,
|
||||
to be summed across all processors.
|
||||
\param GlobalSums Out
|
||||
On exit, contains the list of values summed across all processors.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of values.
|
||||
*/
|
||||
int SumAll(long * PartialSums, long * GlobalSums, int Count) const;
|
||||
//@}
|
||||
|
||||
//! @name Max/Min Methods
|
||||
//@{
|
||||
//! Epetra_SerialComm Global Max function.
|
||||
/*! A copy for a serial communicator.
|
||||
\param PartialMaxs In
|
||||
On entry, contains the list of values, usually partial maxs computed locally,
|
||||
using these Partial Maxs, the max across all processors will be computed.
|
||||
\param GlobalMaxs Out
|
||||
On exit, contains the list of maxs computed across all processors.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of values.
|
||||
*/
|
||||
int MaxAll(double * PartialMaxs, double * GlobalMaxs, int Count) const;
|
||||
|
||||
//! Epetra_SerialComm Global Max function.
|
||||
/*! A copy for a serial communicator.
|
||||
\param PartialMaxs In
|
||||
On entry, contains the list of values, usually partial maxs computed locally;
|
||||
using these Partial Maxs, the max across all processors will be computed.
|
||||
\param GlobalMaxs Out
|
||||
On exit, contains the list of maxs computed across all processors.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of values.
|
||||
*/
|
||||
int MaxAll(int * PartialMaxs, int * GlobalMaxs, int Count) const;
|
||||
|
||||
//! Epetra_SerialComm Global Max function.
|
||||
/*! A copy for a serial communicator.
|
||||
\param PartialMaxs In
|
||||
On entry, contains the list of values, usually partial maxs computed locally;
|
||||
using these Partial Maxs, the max across all processors will be computed.
|
||||
\param GlobalMaxs Out
|
||||
On exit, contains the list of maxs computed across all processors.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of values.
|
||||
*/
|
||||
int MaxAll(long * PartialMaxs, long * GlobalMaxs, int Count) const;
|
||||
|
||||
//! Epetra_SerialComm Global Min function.
|
||||
/*! A copy for a serial communicator.
|
||||
\param PartialMins In
|
||||
On entry, contains the list of values, usually partial mins computed locally;
|
||||
using these Partial Mins, the min across all processors will be computed.
|
||||
\param GlobalMins Out
|
||||
On exit, contains the list of mins computed across all processors.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of values.
|
||||
*/
|
||||
int MinAll(double * PartialMins, double * GlobalMins, int Count) const;
|
||||
|
||||
//! Epetra_SerialComm Global Min function.
|
||||
/*! A copy for a serial communicator.
|
||||
\param PartialMins In
|
||||
On entry, contains the list of values, usually partial mins computed locally;
|
||||
using these Partial Mins, the min across all processors will be computed.
|
||||
\param GlobalMins Out
|
||||
On exit, contains the list of mins computed across all processors.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of values.
|
||||
*/
|
||||
int MinAll(int * PartialMins, int * GlobalMins, int Count) const;
|
||||
|
||||
//! Epetra_SerialComm Global Min function.
|
||||
/*! A copy for a serial communicator.
|
||||
\param PartialMins In
|
||||
On entry, contains the list of values, usually partial mins computed locally;
|
||||
using these Partial Mins, the min across all processors will be computed.
|
||||
\param GlobalMins Out
|
||||
On exit, contains the list of mins computed across all processors.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of values.
|
||||
*/
|
||||
int MinAll(long * PartialMins, long * GlobalMins, int Count) const;
|
||||
//@}
|
||||
|
||||
//! @name Parallel Prefix Methods
|
||||
//@{
|
||||
//! Epetra_SerialComm Scan Sum function.
|
||||
/*! A copy for a serial communicator.
|
||||
\param MyVals In
|
||||
On entry, contains the list of values to be summed across all processors.
|
||||
\param ScanSums Out
|
||||
On exit, contains the list of values summed across processors 0 through i.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of values.
|
||||
*/
|
||||
int ScanSum(double * MyVals, double * ScanSums, int Count) const;
|
||||
|
||||
//! Epetra_SerialComm Scan Sum function.
|
||||
/*! A copy for a serial communicator.
|
||||
\param MyVals In
|
||||
On entry, contains the list of values to be summed across all processors.
|
||||
\param ScanSums Out
|
||||
On exit, contains the list of values summed across processors 0 through i.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of values.
|
||||
*/
|
||||
int ScanSum(int * MyVals, int * ScanSums, int Count) const;
|
||||
|
||||
//! Epetra_SerialComm Scan Sum function.
|
||||
/*! A copy for a serial communicator.
|
||||
\param MyVals In
|
||||
On entry, contains the list of values to be summed across all processors.
|
||||
\param ScanSums Out
|
||||
On exit, contains the list of values summed across processors 0 through i.
|
||||
\param Count In
|
||||
On entry, contains the length of the list of values.
|
||||
*/
|
||||
int ScanSum(long * MyVals, long * ScanSums, int Count) const;
|
||||
//@}
|
||||
|
||||
//! @name Attribute Accessor Methods
|
||||
//@{
|
||||
|
||||
//! Return my process ID.
|
||||
/*! In MPI mode returns the rank of the calling process. In serial mode
|
||||
returns 0.
|
||||
*/
|
||||
int MyPID() const {return(SerialCommData_->MyPID_);};
|
||||
|
||||
//! Returns total number of processes (always returns 1 for SerialComm).
|
||||
int NumProc() const {return(SerialCommData_->NumProc_);};
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Gather/Scatter and Directory Constructors
|
||||
//@{
|
||||
//! Create a distributor object.
|
||||
Epetra_Distributor * CreateDistributor() const;
|
||||
//! Create a directory object for the given Epetra_BlockMap.
|
||||
Epetra_Directory * CreateDirectory(const Epetra_BlockMap & Map) const;
|
||||
//@}
|
||||
|
||||
//! @name Print object to an output stream
|
||||
//@{
|
||||
//! Print method that implements Epetra_Object virtual Print method
|
||||
inline void Print(ostream & os) const {
|
||||
os << "::Processor "<< MyPID()<<" of " << NumProc() << " total processors.";
|
||||
return;
|
||||
}
|
||||
//! Print method that implements Epetra_Comm virtual PrintInfo method
|
||||
void PrintInfo(ostream & os) const {
|
||||
Epetra_SerialComm::Print(os);
|
||||
return;
|
||||
};
|
||||
//@}
|
||||
|
||||
//! @name Expert Users and Developers Only
|
||||
//@{
|
||||
|
||||
//! Returns the reference count of SerialCommData.
|
||||
/*! (Intended for testing purposes.) */
|
||||
int ReferenceCount() const;
|
||||
|
||||
//! Returns a pointer to the SerialCommData instance this SerialComm uses.
|
||||
/*! (Intended for developer use only for testing purposes.) */
|
||||
const Epetra_SerialCommData * DataPtr() const {return(SerialCommData_);};
|
||||
|
||||
//@}
|
||||
|
||||
//! Assignment Operator
|
||||
Epetra_SerialComm & operator=(const Epetra_SerialComm & Comm);
|
||||
|
||||
private:
|
||||
|
||||
void CleanupData();
|
||||
Epetra_SerialCommData * SerialCommData_;
|
||||
|
||||
};
|
||||
#endif /* EPETRA_SERIALCOMM_H */
|
||||
@@ -0,0 +1,65 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_SERIALCOMMDATA_H
|
||||
#define EPETRA_SERIALCOMMDATA_H
|
||||
|
||||
#include "Epetra_Data.h"
|
||||
|
||||
//! Epetra_SerialCommData: The Epetra Serial Communication Data Class.
|
||||
/*! The Epetra_SerialCommData class is an implementation detail of Epetra_SerialComm.
|
||||
It is reference-counted, and can be shared by multiple Epetra_SerialComm instances.
|
||||
It derives from Epetra_Data, and inherits reference-counting from it.
|
||||
*/
|
||||
|
||||
class Epetra_SerialCommData : public Epetra_Data {
|
||||
friend class Epetra_SerialComm;
|
||||
private:
|
||||
//! @name Constructor/Destructor Methods
|
||||
//@{
|
||||
|
||||
//! Epetra_SerialCommData Default Constructor.
|
||||
Epetra_SerialCommData();
|
||||
|
||||
//! Epetra_SerialCommData Destructor.
|
||||
~Epetra_SerialCommData();
|
||||
|
||||
//@}
|
||||
|
||||
int MyPID_;
|
||||
int NumProc_;
|
||||
|
||||
// these are intentionally declared but not defined. See Epetra Developer's Guide for details.
|
||||
Epetra_SerialCommData(const Epetra_SerialCommData & CommData);
|
||||
Epetra_SerialCommData& operator=(const Epetra_SerialCommData & CommData);
|
||||
|
||||
};
|
||||
#endif /* EPETRA_SERIALCOMMDATA_H */
|
||||
@@ -0,0 +1,529 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_SERIALDENSEMATRIX_H
|
||||
#define EPETRA_SERIALDENSEMATRIX_H
|
||||
|
||||
#include "Epetra_Object.h"
|
||||
#include "Epetra_CompObject.h"
|
||||
#include "Epetra_BLAS.h"
|
||||
#include "Epetra_SerialDenseOperator.h"
|
||||
class Epetra_SerialSymDenseMatrix;
|
||||
class Epetra_VbrMatrix;
|
||||
|
||||
//! Epetra_SerialDenseMatrix: A class for constructing and using real double precision general dense matrices.
|
||||
|
||||
/*! The Epetra_SerialDenseMatrix class enables the construction and use of real-valued, general,
|
||||
double-precision dense matrices. It is built on the BLAS, and derives from the Epetra_BLAS.
|
||||
|
||||
The Epetra_SerialDenseMatrix class is intended to provide very basic support for dense rectangular matrices.
|
||||
|
||||
|
||||
<b>Constructing Epetra_SerialDenseMatrix Objects</b>
|
||||
|
||||
There are four Epetra_SerialDenseMatrix constructors. The first constructs a zero-sized object which should be made
|
||||
to appropriate length using the Shape() or Reshape() functions and then filled with the [] or () operators.
|
||||
The second constructs an object sized to the dimensions specified, which should be filled with the [] or () operators.
|
||||
The third is a constructor that accepts user
|
||||
data as a 2D array, and the fourth is a copy constructor. The third constructor has
|
||||
two data access modes (specified by the Epetra_DataAccess argument):
|
||||
<ol>
|
||||
<li> Copy mode - Allocates memory and makes a copy of the user-provided data. In this case, the
|
||||
user data is not needed after construction.
|
||||
<li> View mode - Creates a "view" of the user data. In this case, the
|
||||
user data is required to remain intact for the life of the object.
|
||||
</ol>
|
||||
|
||||
\warning View mode is \e extremely dangerous from a data hiding perspective.
|
||||
Therefore, we strongly encourage users to develop code using Copy mode first and
|
||||
only use the View mode in a secondary optimization phase.
|
||||
|
||||
<b>Extracting Data from Epetra_SerialDenseMatrix Objects</b>
|
||||
|
||||
Once a Epetra_SerialDenseMatrix is constructed, it is possible to view the data via access functions.
|
||||
|
||||
\warning Use of these access functions cam be \e extremely dangerous from a data hiding perspective.
|
||||
|
||||
|
||||
<b>Vector and Utility Functions</b>
|
||||
|
||||
Once a Epetra_SerialDenseMatrix is constructed, several mathematical functions can be applied to
|
||||
the object. Specifically:
|
||||
<ul>
|
||||
<li> Multiplication.
|
||||
<li> Norms.
|
||||
</ul>
|
||||
|
||||
<b>Counting floating point operations </b>
|
||||
The Epetra_SerialDenseMatrix class has Epetra_CompObject as a base class. Thus, floating point operations
|
||||
are counted and accumulated in the Epetra_Flop object (if any) that was set using the SetFlopCounter()
|
||||
method in the Epetra_CompObject base class.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//=========================================================================
|
||||
class Epetra_SerialDenseMatrix : public Epetra_CompObject, public Epetra_Object, public Epetra_SerialDenseOperator, public Epetra_BLAS {
|
||||
|
||||
public:
|
||||
|
||||
//! @name Constructor/Destructor Methods
|
||||
//@{
|
||||
//! Default constructor; defines a zero size object.
|
||||
/*!
|
||||
Epetra_SerialDenseMatrix objects defined by the default constructor should be sized with the
|
||||
Shape() or Reshape functions.
|
||||
Values should be defined by using the [] or () operators.
|
||||
*/
|
||||
Epetra_SerialDenseMatrix(bool set_object_label=true);
|
||||
|
||||
//! Shaped constructor; defines a variable-sized object
|
||||
/*!
|
||||
\param In
|
||||
NumRows - Number of rows in object.
|
||||
\param In
|
||||
NumCols - Number of columns in object.
|
||||
|
||||
Epetra_SerialDenseMatrix objects defined by the shaped constructor are already shaped to the
|
||||
dimensions given as a parameters. All values are initialized to 0. Calling this constructor
|
||||
is equivalent to using the default constructor, and then calling the Shape function on it.
|
||||
Values should be defined by using the [] or () operators.
|
||||
*/
|
||||
Epetra_SerialDenseMatrix(int NumRows, int NumCols, bool set_object_label=true);
|
||||
|
||||
//! Set object values from two-dimensional array.
|
||||
/*!
|
||||
\param In
|
||||
Epetra_DataAccess - Enumerated type set to Copy or View.
|
||||
\param In
|
||||
A - Pointer to an array of double precision numbers. The first vector starts at A.
|
||||
The second vector starts at A+LDA, the third at A+2*LDA, and so on.
|
||||
\param In
|
||||
LDA - The "Leading Dimension", or stride between vectors in memory.
|
||||
\param In
|
||||
NumRows - Number of rows in object.
|
||||
\param In
|
||||
NumCols - Number of columns in object.
|
||||
|
||||
See Detailed Description section for further discussion.
|
||||
*/
|
||||
Epetra_SerialDenseMatrix(Epetra_DataAccess CV, double* A, int LDA, int NumRows, int NumCols,
|
||||
bool set_object_label=true);
|
||||
|
||||
//! Epetra_SerialDenseMatrix copy constructor.
|
||||
|
||||
Epetra_SerialDenseMatrix(const Epetra_SerialDenseMatrix& Source);
|
||||
|
||||
//! Epetra_SerialDenseMatrix destructor.
|
||||
virtual ~Epetra_SerialDenseMatrix ();
|
||||
//@}
|
||||
|
||||
//! @name Shaping/sizing Methods
|
||||
//@{
|
||||
//! Set dimensions of a Epetra_SerialDenseMatrix object; init values to zero.
|
||||
/*!
|
||||
\param In
|
||||
NumRows - Number of rows in object.
|
||||
\param In
|
||||
NumCols - Number of columns in object.
|
||||
|
||||
Allows user to define the dimensions of a Epetra_SerialDenseMatrix at any point. This function can
|
||||
be called at any point after construction. Any values that were previously in this object are
|
||||
destroyed and the resized matrix starts off with all zero values.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int Shape(int NumRows, int NumCols);
|
||||
|
||||
//! Reshape a Epetra_SerialDenseMatrix object.
|
||||
/*!
|
||||
\param In
|
||||
NumRows - Number of rows in object.
|
||||
\param In
|
||||
NumCols - Number of columns in object.
|
||||
|
||||
Allows user to define the dimensions of a Epetra_SerialDenseMatrix at any point. This function can
|
||||
be called at any point after construction. Any values that were previously in this object are
|
||||
copied into the new shape. If the new shape is smaller than the original, the upper left portion
|
||||
of the original matrix (the principal submatrix) is copied to the new matrix.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int Reshape(int NumRows, int NumCols);
|
||||
//@}
|
||||
|
||||
//! @name Mathematical methods
|
||||
//@{
|
||||
|
||||
//! Matrix-Matrix multiplication, \e this = ScalarThis*\e this + ScalarAB*A*B.
|
||||
/*! This function performs a variety of matrix-matrix multiply operations.
|
||||
|
||||
\param In
|
||||
TransA - Operate with the transpose of A if = 'T', else no transpose if = 'N'.
|
||||
\param In
|
||||
TransB - Operate with the transpose of B if = 'T', else no transpose if = 'N'.
|
||||
|
||||
\param In
|
||||
ScalarAB - Scalar to multiply with A*B.
|
||||
\param In
|
||||
A - Dense Matrix.
|
||||
\param In
|
||||
B - Dense Matrix.
|
||||
\param In
|
||||
ScalarThis - Scalar to multiply with \e this.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
|
||||
*/
|
||||
int Multiply(char TransA, char TransB, double ScalarAB,
|
||||
const Epetra_SerialDenseMatrix& A,
|
||||
const Epetra_SerialDenseMatrix& B,
|
||||
double ScalarThis);
|
||||
|
||||
//! Matrix-Vector multiplication, y = A*x, where 'this' == A.
|
||||
/* This method is intended to imitate the semantics of the matrix-vector
|
||||
multiplication provided by Epetra's sparse matrices. The 'vector' arguments
|
||||
are actually matrices; this method will return an error if the
|
||||
dimensions of 'x' are not compatible. 'y' will be reshaped if necessary.
|
||||
*/
|
||||
int Multiply(bool transA,
|
||||
const Epetra_SerialDenseMatrix& x,
|
||||
Epetra_SerialDenseMatrix& y);
|
||||
|
||||
//! Matrix-Matrix multiplication with a symmetric matrix A.
|
||||
/*! If SideA = 'L', compute \e this = ScalarThis*\e this + ScalarAB*A*B.
|
||||
If SideA = 'R', compute \e this = ScalarThis*\e this + ScalarAB*B*A.
|
||||
|
||||
This function performs a variety of matrix-matrix multiply operations.
|
||||
|
||||
\param In
|
||||
SideA - Specifies order of A relative to B.
|
||||
|
||||
\param In
|
||||
ScalarAB - Scalar to multiply with A*B.
|
||||
\param In
|
||||
A - Symmetric Dense Matrix, either upper or lower triangle will be used depending on
|
||||
value of A.Upper().
|
||||
\param In
|
||||
B - Dense Matrix.
|
||||
\param In
|
||||
ScalarThis - Scalar to multiply with \e this.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
|
||||
*/
|
||||
int Multiply(char SideA, double ScalarAB,
|
||||
const Epetra_SerialSymDenseMatrix& A,
|
||||
const Epetra_SerialDenseMatrix& B,
|
||||
double ScalarThis);
|
||||
|
||||
//! Inplace scalar-matrix product A = \e a A.
|
||||
/*! Scale a matrix, entry-by-entry using the value ScalarA.
|
||||
|
||||
|
||||
\param ScalarA (In) Scalar to multiply with A.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
|
||||
*/
|
||||
int Scale(double ScalarA);
|
||||
|
||||
//! Computes the 1-Norm of the \e this matrix.
|
||||
/*!
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual double NormOne() const;
|
||||
|
||||
//! Computes the Infinity-Norm of the \e this matrix.
|
||||
virtual double NormInf() const;
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Data Accessor methods
|
||||
//@{
|
||||
|
||||
//! Value copy from one matrix to another.
|
||||
/*!
|
||||
The operator= allows one to copy the values from one existing SerialDenseMatrix to another, as
|
||||
long as there is enough room in the target to hold the source.
|
||||
|
||||
\return Values of the left hand side matrix are modified by the values of the right hand side matrix.
|
||||
*/
|
||||
Epetra_SerialDenseMatrix & operator = (const Epetra_SerialDenseMatrix& Source);
|
||||
|
||||
//! Comparison operator.
|
||||
/*! operator== compares two Epetra_SerialDenseMatrix objects, returns false if sizes are different,
|
||||
or if any coefficients differ by an amount greater than Epetra_MinDouble.
|
||||
*/
|
||||
bool operator==(const Epetra_SerialDenseMatrix& rhs) const;
|
||||
|
||||
//! Inequality operator
|
||||
/*! operator!= simply returns the negation of operator==.
|
||||
*/
|
||||
bool operator!=(const Epetra_SerialDenseMatrix& rhs) const
|
||||
{ return !(*this == rhs); }
|
||||
|
||||
//! Add one matrix to another.
|
||||
/*!
|
||||
The operator+= allows one to add the values from one existin SerialDenseMatrix to another, as
|
||||
long as there is enough room in the target to hold the source.
|
||||
|
||||
\return Values of the left hand side matrix are modified by the addition
|
||||
of the values of the right hand side matrix.
|
||||
*/
|
||||
Epetra_SerialDenseMatrix & operator += (const Epetra_SerialDenseMatrix& Source);
|
||||
|
||||
//! Element access function.
|
||||
/*!
|
||||
The parentheses operator returns the element in the ith row and jth column if A(i,j) is
|
||||
specified, the expression A[j][i] (note that i and j are reversed) will return the same element.
|
||||
Thus, A(i,j) = A[j][i] for all valid i and j.
|
||||
|
||||
\return Element from the specified row and column.
|
||||
|
||||
\warning No bounds checking is done unless Epetra is compiled with HAVE_EPETRA_ARRAY_BOUNDS_CHECK.
|
||||
*/
|
||||
double& operator () (int RowIndex, int ColIndex);
|
||||
|
||||
//! Element access function.
|
||||
/*!
|
||||
The parentheses operator returns the element in the ith row and jth column if A(i,j) is
|
||||
specified, the expression A[j][i] (note that i and j are reversed) will return the same element.
|
||||
Thus, A(i,j) = A[j][i] for all valid i and j.
|
||||
|
||||
\return Element from the specified row and column.
|
||||
|
||||
\warning No bounds checking is done unless Epetra is compiled with HAVE_EPETRA_ARRAY_BOUNDS_CHECK.
|
||||
*/
|
||||
const double& operator () (int RowIndex, int ColIndex) const;
|
||||
|
||||
//! Column access function.
|
||||
/*!
|
||||
The parentheses operator returns the element in the ith row and jth column if A(i,j) is
|
||||
specified, the expression A[j][i] (note that i and j are reversed) will return the same element.
|
||||
Thus, A(i,j) = A[j][i] for all valid i and j.
|
||||
|
||||
\return Pointer to address of specified column.
|
||||
|
||||
\warning No bounds checking can be done for the index i in the expression A[j][i].
|
||||
\warning No bounds checking is done unless Epetra is compiled with HAVE_EPETRA_ARRAY_BOUNDS_CHECK.
|
||||
*/
|
||||
double* operator [] (int ColIndex);
|
||||
|
||||
//! Column access function.
|
||||
/*!
|
||||
The parentheses operator returns the element in the ith row and jth column if A(i,j) is
|
||||
specified, the expression A[j][i] (note that i and j are reversed) will return the same element.
|
||||
Thus, A(i,j) = A[j][i] for all valid i and j.
|
||||
|
||||
\return Pointer to address of specified column.
|
||||
|
||||
\warning No bounds checking can be done for the index i in the expression A[j][i].
|
||||
\warning No bounds checking is done unless Epetra is compiled with HAVE_EPETRA_ARRAY_BOUNDS_CHECK.
|
||||
*/
|
||||
const double* operator [] (int ColIndex) const;
|
||||
|
||||
//! Set matrix values to random numbers.
|
||||
/*!
|
||||
SerialDenseMatrix uses the random number generator provided by Epetra_Util.
|
||||
The matrix values will be set to random values on the interval (-1.0, 1.0).
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int Random();
|
||||
|
||||
//! Returns row dimension of system.
|
||||
int M() const {return(M_);};
|
||||
|
||||
//! Returns column dimension of system.
|
||||
int N() const {return(N_);};
|
||||
|
||||
//! Returns pointer to the \e this matrix.
|
||||
double* A() const {return(A_);};
|
||||
|
||||
//! Returns pointer to the \e this matrix.
|
||||
double* A() {return(A_);};
|
||||
|
||||
//! Returns the leading dimension of the \e this matrix.
|
||||
int LDA() const {return(LDA_);};
|
||||
|
||||
//! Returns the data access mode of the \e this matrix.
|
||||
Epetra_DataAccess CV() const {return(CV_);};
|
||||
//@}
|
||||
|
||||
//! @name I/O methods
|
||||
//@{
|
||||
//! Print service methods; defines behavior of ostream << operator.
|
||||
virtual void Print(ostream& os) const;
|
||||
//@}
|
||||
|
||||
//! @name Deprecated methods (will be removed in later versions of this class)
|
||||
//@{
|
||||
|
||||
//! Computes the 1-Norm of the \e this matrix (identical to NormOne() method).
|
||||
/*!
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual double OneNorm() const {return(NormOne());};
|
||||
|
||||
//! Computes the Infinity-Norm of the \e this matrix (identical to NormInf() method).
|
||||
virtual double InfNorm() const {return(NormInf());};
|
||||
//@}
|
||||
|
||||
//! @name Additional methods to support Epetra_SerialDenseOperator interface
|
||||
//@{
|
||||
|
||||
//! If set true, transpose of this operator will be applied.
|
||||
/*! This flag allows the transpose of the given operator to be used implicitly. Setting this flag
|
||||
affects only the Apply() and ApplyInverse() methods. If the implementation of this interface
|
||||
does not support transpose use, this method should return a value of -1.
|
||||
|
||||
\param In
|
||||
UseTranspose -If true, multiply by the transpose of operator, otherwise just use operator.
|
||||
|
||||
\return Integer error code, set to 0 if successful. Set to -1 if this implementation does not support transpose.
|
||||
*/
|
||||
virtual int SetUseTranspose(bool UseTranspose) { UseTranspose_ = UseTranspose; return (0); }
|
||||
|
||||
//! Returns the result of a Epetra_SerialDenseOperator applied to a Epetra_SerialDenseMatrix X in Y.
|
||||
/*!
|
||||
\param In
|
||||
X - A Epetra_SerialDenseMatrix to multiply with operator.
|
||||
\param Out
|
||||
Y -A Epetra_SerialDenseMatrix containing result.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual int Apply(const Epetra_SerialDenseMatrix& X, Epetra_SerialDenseMatrix& Y);
|
||||
|
||||
//! Returns the result of a Epetra_SerialDenseOperator inverse applied to an Epetra_SerialDenseMatrix X in Y.
|
||||
/*!
|
||||
\param In
|
||||
X - A Epetra_SerialDenseMatrix to solve for.
|
||||
\param Out
|
||||
Y -A Epetra_SerialDenseMatrix containing result.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
|
||||
*/
|
||||
virtual int ApplyInverse(const Epetra_SerialDenseMatrix & X, Epetra_SerialDenseMatrix & Y)
|
||||
{
|
||||
(void)X;//prevents unused variable compiler warning
|
||||
(void)Y;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
//! Returns a character string describing the operator
|
||||
virtual const char * Label() const { return Epetra_Object::Label(); }
|
||||
|
||||
//! Returns the current UseTranspose setting.
|
||||
virtual bool UseTranspose() const { return UseTranspose_; }
|
||||
|
||||
//! Returns true if the \e this object can provide an approximate Inf-norm, false otherwise.
|
||||
virtual bool HasNormInf() const { return true; }
|
||||
|
||||
//! Returns the row dimension of operator
|
||||
virtual int RowDim() const { return M(); }
|
||||
|
||||
//! Returns the column dimension of operator
|
||||
virtual int ColDim() const { return N(); }
|
||||
//@}
|
||||
|
||||
protected:
|
||||
|
||||
void CopyMat(double* Source, int Source_LDA, int NumRows, int NumCols,
|
||||
double* Target, int Target_LDA, bool add=false);
|
||||
void CleanupData();
|
||||
|
||||
int M_;
|
||||
int N_;
|
||||
bool A_Copied_;
|
||||
Epetra_DataAccess CV_;
|
||||
|
||||
//For performance reasons, it's better if Epetra_VbrMatrix can access the
|
||||
//LDA_ and A_ members of this class directly without going through an
|
||||
//accessor method. Rather than making them public members, we'll make
|
||||
//Epetra_VbrMatrix a friend class.
|
||||
|
||||
friend class Epetra_VbrMatrix;
|
||||
|
||||
int LDA_;
|
||||
double* A_;
|
||||
|
||||
bool UseTranspose_;
|
||||
};
|
||||
|
||||
// inlined definitions of op() and op[]
|
||||
//=========================================================================
|
||||
inline double& Epetra_SerialDenseMatrix::operator () (int RowIndex, int ColIndex) {
|
||||
#ifdef HAVE_EPETRA_ARRAY_BOUNDS_CHECK
|
||||
if (RowIndex >= M_ || RowIndex < 0)
|
||||
throw ReportError("Row index = " +toString(RowIndex) +
|
||||
" Out of Range 0 - " + toString(M_-1),-1);
|
||||
if (ColIndex >= N_ || ColIndex < 0)
|
||||
throw ReportError("Column index = " +toString(ColIndex) +
|
||||
" Out of Range 0 - " + toString(N_-1),-2);
|
||||
#endif
|
||||
return(A_[ColIndex*LDA_ + RowIndex]);
|
||||
}
|
||||
//=========================================================================
|
||||
inline const double& Epetra_SerialDenseMatrix::operator () (int RowIndex, int ColIndex) const {
|
||||
#ifdef HAVE_EPETRA_ARRAY_BOUNDS_CHECK
|
||||
if (RowIndex >= M_ || RowIndex < 0)
|
||||
throw ReportError("Row index = " +toString(RowIndex) +
|
||||
" Out of Range 0 - " + toString(M_-1),-1);
|
||||
if (ColIndex >= N_ || ColIndex < 0)
|
||||
throw ReportError("Column index = " +toString(ColIndex) +
|
||||
" Out of Range 0 - " + toString(N_-1),-2);
|
||||
#endif
|
||||
return(A_[ColIndex*LDA_ + RowIndex]);
|
||||
}
|
||||
//=========================================================================
|
||||
inline double* Epetra_SerialDenseMatrix::operator [] (int ColIndex) {
|
||||
#ifdef HAVE_EPETRA_ARRAY_BOUNDS_CHECK
|
||||
if (ColIndex >= N_ || ColIndex < 0)
|
||||
throw ReportError("Column index = " +toString(ColIndex) +
|
||||
" Out of Range 0 - " + toString(N_-1),-2);
|
||||
#endif
|
||||
return(A_ + ColIndex*LDA_);
|
||||
}
|
||||
//=========================================================================
|
||||
inline const double* Epetra_SerialDenseMatrix::operator [] (int ColIndex) const {
|
||||
#ifdef HAVE_EPETRA_ARRAY_BOUNDS_CHECK
|
||||
if (ColIndex >= N_ || ColIndex < 0)
|
||||
throw ReportError("Column index = " +toString(ColIndex) +
|
||||
" Out of Range 0 - " + toString(N_-1),-2);
|
||||
#endif
|
||||
return(A_+ ColIndex*LDA_);
|
||||
}
|
||||
//=========================================================================
|
||||
|
||||
#endif /* EPETRA_SERIALDENSEMATRIX_H */
|
||||
@@ -0,0 +1,120 @@
|
||||
|
||||
/* Copyright (2001) Sandia Corportation. Under the terms of Contract
|
||||
* DE-AC04-94AL85000, there is a non-exclusive license for use of this
|
||||
* work by or on behalf of the U.S. Government. Export of this program
|
||||
* may require a license from the United States Government. */
|
||||
|
||||
|
||||
/* NOTICE: The United States Government is granted for itself and others
|
||||
* acting on its behalf a paid-up, nonexclusive, irrevocable worldwide
|
||||
* license in ths data to reproduce, prepare derivative works, and
|
||||
* perform publicly and display publicly. Beginning five (5) years from
|
||||
* July 25, 2001, the United States Government is granted for itself and
|
||||
* others acting on its behalf a paid-up, nonexclusive, irrevocable
|
||||
* worldwide license in this data to reproduce, prepare derivative works,
|
||||
* distribute copies to the public, perform publicly and display
|
||||
* publicly, and to permit others to do so.
|
||||
*
|
||||
* NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED STATES DEPARTMENT
|
||||
* OF ENERGY, NOR SANDIA CORPORATION, NOR ANY OF THEIR EMPLOYEES, MAKES
|
||||
* ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LEGAL LIABILITY OR
|
||||
* RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR USEFULNESS OF ANY
|
||||
* INFORMATION, APPARATUS, PRODUCT, OR PROCESS DISCLOSED, OR REPRESENTS
|
||||
* THAT ITS USE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS. */
|
||||
|
||||
#ifndef _EPETRA_SERIALDENSEOPERATOR_H_
|
||||
#define _EPETRA_SERIALDENSEOPERATOR_H_
|
||||
|
||||
class Epetra_SerialDenseMatrix;
|
||||
|
||||
//! Epetra_SerialDenseOperator: A pure virtual class for using real-valued double-precision operators.
|
||||
/*! The Epetra_SerialDenseOperator class is a pure virtual class (specifies interface only) that
|
||||
enable the use of real-valued double-precision operators. It is currently implemented by the
|
||||
Epetra_SerialDenseMatrix, Epetra_SerialDenseSolver and Epetra_SerialDenseSVD classes.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class Epetra_SerialDenseOperator {
|
||||
|
||||
public:
|
||||
|
||||
//! @name Destructor
|
||||
//@{
|
||||
//! Destructor
|
||||
virtual ~Epetra_SerialDenseOperator() {};
|
||||
//@}
|
||||
|
||||
//! @name Atribute set methods
|
||||
//@{
|
||||
|
||||
//! If set true, transpose of this operator will be applied.
|
||||
/*! This flag allows the transpose of the given operator to be used implicitly. Setting this flag
|
||||
affects only the Apply() and ApplyInverse() methods. If the implementation of this interface
|
||||
does not support transpose use, this method should return a value of -1.
|
||||
|
||||
\param In
|
||||
UseTranspose -If true, multiply by the transpose of operator, otherwise just use operator.
|
||||
|
||||
\return Integer error code, set to 0 if successful. Set to -1 if this implementation does not support transpose.
|
||||
*/
|
||||
virtual int SetUseTranspose(bool UseTranspose) = 0;
|
||||
//@}
|
||||
|
||||
//! @name Mathematical functions
|
||||
//@{
|
||||
|
||||
//! Returns the result of a Epetra_SerialDenseOperator applied to a Epetra_SerialDenseMatrix X in Y.
|
||||
/*!
|
||||
\param In
|
||||
X - A Epetra_SerialDenseMatrix to multiply with operator.
|
||||
\param Out
|
||||
Y -A Epetra_SerialDenseMatrix containing result.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual int Apply(const Epetra_SerialDenseMatrix& X, Epetra_SerialDenseMatrix& Y) = 0;
|
||||
|
||||
//! Returns the result of a Epetra_SerialDenseOperator inverse applied to an Epetra_SerialDenseMatrix X in Y.
|
||||
/*!
|
||||
\param In
|
||||
X - A Epetra_SerialDenseMatrix to solve for.
|
||||
\param Out
|
||||
Y -A Epetra_SerialDenseMatrix containing result.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
|
||||
*/
|
||||
virtual int ApplyInverse(const Epetra_SerialDenseMatrix & X, Epetra_SerialDenseMatrix & Y) = 0;
|
||||
|
||||
//! Returns the infinity norm of the global matrix.
|
||||
/* Returns the quantity \f$ \| A \|_\infty\f$ such that
|
||||
\f[\| A \|_\infty = \max_{1\lei\lem} \sum_{j=1}^n |a_{ij}| \f].
|
||||
|
||||
\warning This method must not be called unless HasNormInf() returns true.
|
||||
*/
|
||||
virtual double NormInf() const = 0;
|
||||
//@}
|
||||
|
||||
//! @name Atribute access functions
|
||||
//@{
|
||||
|
||||
//! Returns a character string describing the operator
|
||||
virtual const char * Label() const = 0;
|
||||
|
||||
//! Returns the current UseTranspose setting.
|
||||
virtual bool UseTranspose() const = 0;
|
||||
|
||||
//! Returns true if the \e this object can provide an approximate Inf-norm, false otherwise.
|
||||
virtual bool HasNormInf() const = 0;
|
||||
|
||||
//! Returns the row dimension of operator
|
||||
virtual int RowDim() const = 0;
|
||||
|
||||
//! Returns the column dimension of operator
|
||||
virtual int ColDim() const = 0;
|
||||
//@}
|
||||
|
||||
};
|
||||
|
||||
#endif /* _EPETRA_OPERATOR_H_ */
|
||||
@@ -0,0 +1,507 @@
|
||||
|
||||
/* Copyright (2001) Sandia Corportation. Under the terms of Contract
|
||||
* DE-AC04-94AL85000, there is a non-exclusive license for use of this
|
||||
* work by or on behalf of the U.S. Government. Export of this program
|
||||
* may require a license from the United States Government. */
|
||||
|
||||
|
||||
/* NOTICE: The United States Government is granted for itself and others
|
||||
* acting on its behalf a paid-up, nonexclusive, irrevocable worldwide
|
||||
* license in ths data to reproduce, prepare derivative works, and
|
||||
* perform publicly and display publicly. Beginning five (5) years from
|
||||
* July 25, 2001, the United States Government is granted for itself and
|
||||
* others acting on its behalf a paid-up, nonexclusive, irrevocable
|
||||
* worldwide license in this data to reproduce, prepare derivative works,
|
||||
* distribute copies to the public, perform publicly and display
|
||||
* publicly, and to permit others to do so.
|
||||
*
|
||||
* NEITHER THE UNITED STATES GOVERNMENT, NOR THE UNITED STATES DEPARTMENT
|
||||
* OF ENERGY, NOR SANDIA CORPORATION, NOR ANY OF THEIR EMPLOYEES, MAKES
|
||||
* ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LEGAL LIABILITY OR
|
||||
* RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR USEFULNESS OF ANY
|
||||
* INFORMATION, APPARATUS, PRODUCT, OR PROCESS DISCLOSED, OR REPRESENTS
|
||||
* THAT ITS USE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS. */
|
||||
|
||||
#ifndef _EPETRA_SERIALDENSESVD_H_
|
||||
#define _EPETRA_SERIALDENSESVD_H_
|
||||
|
||||
#include "Epetra_SerialDenseOperator.h"
|
||||
#include "Epetra_SerialDenseMatrix.h"
|
||||
#include "Epetra_Object.h"
|
||||
#include "Epetra_CompObject.h"
|
||||
#include "Epetra_BLAS.h"
|
||||
#include "Epetra_LAPACK.h"
|
||||
|
||||
|
||||
//! Epetra_SerialDenseSVD: A class for SVDing dense linear problems.
|
||||
|
||||
/*! The Epetra_SerialDenseSVD class enables the definition, in terms of Epetra_SerialDenseMatrix
|
||||
and Epetra_SerialDenseVector objects, of a dense linear problem, followed by the solution of that problem via the
|
||||
most sophisticated techniques available in LAPACK.
|
||||
|
||||
The Epetra_SerialDenseSVD class is intended to provide full-featured support for solving linear
|
||||
problems for general dense rectangular (or square) matrices. It is written on top of BLAS and LAPACK and thus has excellent
|
||||
performance and numerical capabilities. Using this class, one can either perform simple factorizations and solves or
|
||||
apply all the tricks available in LAPACK to get the best possible solution for very ill-conditioned problems.
|
||||
|
||||
<b>Epetra_SerialDenseSVD vs. Epetra_LAPACK</b>
|
||||
|
||||
The Epetra_LAPACK class provides access to most of the same functionality as Epetra_SerialDenseSolver.
|
||||
The primary difference is that Epetra_LAPACK is a "thin" layer on top of LAPACK and Epetra_SerialDenseSolver
|
||||
attempts to provide easy access to the more sophisticated aspects of solving dense linear and eigensystems.
|
||||
<ul>
|
||||
<li> When you should use Epetra_LAPACK: If you are simply looking for a convenient wrapper around the Fortran LAPACK
|
||||
routines and you have a well-conditioned problem, you should probably use Epetra_LAPACK directly.
|
||||
<li> When you should use Epetra_SerialDenseSolver: If you want to (or potentially want to) solve ill-conditioned
|
||||
problems or want to work with a more object-oriented interface, you should probably use Epetra_SerialDenseSolver.
|
||||
|
||||
</ul>
|
||||
|
||||
<b>Constructing Epetra_SerialDenseSVD Objects</b>
|
||||
|
||||
There is a single Epetra_SerialDenseSVD constructor. However, the matrix, right hand side and solution
|
||||
vectors must be set prior to executing most methods in this class.
|
||||
|
||||
<b>Setting vectors used for linear solves</b>
|
||||
|
||||
The matrix A, the left hand side X and the right hand side B (when solving AX = B, for X), can be set by appropriate set
|
||||
methods. Each of these three objects must be an Epetra_SerialDenseMatrix or and Epetra_SerialDenseVector object. The
|
||||
set methods are as follows:
|
||||
<ul>
|
||||
<li> SetMatrix() - Sets the matrix.
|
||||
<li> SetVectors() - Sets the left and right hand side vector(s).
|
||||
</ul>
|
||||
|
||||
<b>Vector and Utility Functions</b>
|
||||
|
||||
Once a Epetra_SerialDenseSVD is constructed, several mathematical functions can be applied to
|
||||
the object. Specifically:
|
||||
<ul>
|
||||
<li> Factorizations.
|
||||
<li> Solves.
|
||||
<li> Condition estimates.
|
||||
<li> Norms.
|
||||
</ul>
|
||||
|
||||
<b>Counting floating point operations </b>
|
||||
The Epetra_SerialDenseSVD class has Epetra_CompObject as a base class. Thus, floating point operations
|
||||
are counted and accumulated in the Epetra_Flop object (if any) that was set using the SetFlopCounter()
|
||||
method in the Epetra_CompObject base class.
|
||||
|
||||
Examples using Epetra_SerialDenseSVD can be found in the Epetra test directories.
|
||||
|
||||
*/
|
||||
|
||||
//=========================================================================
|
||||
class Epetra_SerialDenseSVD : public virtual Epetra_SerialDenseOperator, public Epetra_CompObject, public virtual Epetra_Object, public Epetra_BLAS, public Epetra_LAPACK{
|
||||
public:
|
||||
|
||||
//! @name Constructor/Destructor Methods
|
||||
//@{
|
||||
//! Default constructor; matrix should be set using SetMatrix(), LHS and RHS set with SetVectors().
|
||||
Epetra_SerialDenseSVD();
|
||||
|
||||
//! Epetra_SerialDenseSVD destructor.
|
||||
virtual ~Epetra_SerialDenseSVD();
|
||||
//@}
|
||||
|
||||
//! @name Set Methods
|
||||
//@{
|
||||
|
||||
//! Sets the pointers for coefficient matrix
|
||||
int SetMatrix(Epetra_SerialDenseMatrix & A);
|
||||
|
||||
//! Sets the pointers for left and right hand side vector(s).
|
||||
/*! Row dimension of X must match column dimension of matrix A, row dimension of B
|
||||
must match row dimension of A. X and B must have the same dimensions.
|
||||
*/
|
||||
int SetVectors(Epetra_SerialDenseMatrix & X, Epetra_SerialDenseMatrix & B);
|
||||
//@}
|
||||
|
||||
//! @name Strategy modifying Methods
|
||||
//@{
|
||||
|
||||
//! Causes equilibration to be called just before the matrix factorization as part of the call to Factor.
|
||||
/*! This function must be called before the factorization is performed.
|
||||
*/
|
||||
// void FactorWithEquilibration(bool Flag) {Equilibrate_ = Flag; return;};
|
||||
|
||||
//! If Flag is true, causes all subsequent function calls to work with the transpose of \e this matrix, otherwise not.
|
||||
void SolveWithTranspose(bool Flag) {Transpose_ = Flag; if (Flag) TRANS_ = 'T'; else TRANS_ = 'N'; return;};
|
||||
|
||||
//! Causes all solves to compute solution to best ability using iterative refinement.
|
||||
// void SolveToRefinedSolution(bool Flag) {RefineSolution_ = Flag; return;};
|
||||
|
||||
// NOTE: doxygen-style documentation needs to be re-enabled if this function is re-enabled
|
||||
// Causes all solves to estimate the forward and backward solution error.
|
||||
/* Error estimates will be in the arrays FERR and BERR, resp, after the solve step is complete.
|
||||
These arrays are accessible via the FERR() and BERR() access functions.
|
||||
*/
|
||||
// void EstimateSolutionErrors(bool Flag) {EstimateSolutionErrors_ = Flag; return;};
|
||||
//@}
|
||||
|
||||
//! @name Factor/Solve/Invert Methods
|
||||
//@{
|
||||
|
||||
// NOTE: doxygen-style documentation needs to be re-enabled if this function is re-enabled
|
||||
// Computes the SVD factorization of the matrix using the LAPACK routine \e DGESVD.
|
||||
/*
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
// virtual int Factor(void);
|
||||
virtual int Factor(void);
|
||||
|
||||
//! Computes the solution X to AX = B for the \e this matrix and the B provided to SetVectors()..
|
||||
/*! Inverse of Matrix must be formed
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual int Solve(void);
|
||||
|
||||
//! Inverts the \e this matrix.
|
||||
/*!
|
||||
\return Integer error code, set to 0 if successful. Otherwise returns the LAPACK error code INFO.
|
||||
*/
|
||||
virtual int Invert( double rthresh = 0.0, double athresh = 0.0 );
|
||||
|
||||
// NOTE: doxygen-style documentation needs to be re-enabled if this function is re-enabled
|
||||
// Computes the scaling vector S(i) = 1/sqrt(A(i,i) of the \e this matrix.
|
||||
/*
|
||||
\return Integer error code, set to 0 if successful. Otherwise returns the LAPACK error code INFO.
|
||||
*/
|
||||
// virtual int ComputeEquilibrateScaling(void);
|
||||
|
||||
// NOTE: doxygen-style documentation needs to be re-enabled if this function is re-enabled
|
||||
// Equilibrates the \e this matrix.
|
||||
/*
|
||||
\return Integer error code, set to 0 if successful. Otherwise returns the LAPACK error code INFO.
|
||||
*/
|
||||
// virtual int EquilibrateMatrix(void);
|
||||
|
||||
// NOTE: doxygen-style documentation needs to be re-enabled if this function is re-enabled
|
||||
// Equilibrates the current RHS.
|
||||
/*
|
||||
\return Integer error code, set to 0 if successful. Otherwise returns the LAPACK error code INFO.
|
||||
*/
|
||||
// int EquilibrateRHS(void);
|
||||
|
||||
|
||||
// NOTE: doxygen-style documentation needs to be re-enabled if this function is re-enabled
|
||||
// Apply Iterative Refinement.
|
||||
/*
|
||||
\return Integer error code, set to 0 if successful. Otherwise returns the LAPACK error code INFO.
|
||||
*/
|
||||
// virtual int ApplyRefinement(void);
|
||||
|
||||
// NOTE: doxygen-style documentation needs to be re-enabled if this function is re-enabled
|
||||
// Unscales the solution vectors if equilibration was used to solve the system.
|
||||
/*
|
||||
\return Integer error code, set to 0 if successful. Otherwise returns the LAPACK error code INFO.
|
||||
*/
|
||||
// int UnequilibrateLHS(void);
|
||||
|
||||
// NOTE: doxygen-style documentation needs to be re-enabled if this function is re-enabled
|
||||
// Returns the reciprocal of the 1-norm condition number of the \e this matrix.
|
||||
/*
|
||||
\param Value Out
|
||||
On return contains the reciprocal of the 1-norm condition number of the \e this matrix.
|
||||
|
||||
\return Integer error code, set to 0 if successful. Otherwise returns the LAPACK error code INFO.
|
||||
*/
|
||||
// virtual int ReciprocalConditionEstimate(double & Value);
|
||||
//@}
|
||||
|
||||
//! @name Query methods
|
||||
//@{
|
||||
|
||||
//! Returns true if transpose of \e this matrix has and will be used.
|
||||
bool Transpose() {return(Transpose_);};
|
||||
|
||||
//! Returns true if matrix is factored (factor available via AF() and LDAF()).
|
||||
bool Factored() {return(Factored_);};
|
||||
|
||||
// NOTE: doxygen-style documentation needs to be re-enabled if this function is re-enabled
|
||||
// Returns true if factor is equilibrated (factor available via AF() and LDAF()).
|
||||
// bool A_Equilibrated() {return(A_Equilibrated_);};
|
||||
|
||||
// NOTE: doxygen-style documentation needs to be re-enabled if this function is re-enabled
|
||||
// Returns true if RHS is equilibrated (RHS available via B() and LDB()).
|
||||
// bool B_Equilibrated() {return(B_Equilibrated_);};
|
||||
|
||||
// NOTE: doxygen-style documentation needs to be re-enabled if this function is re-enabled
|
||||
// Returns true if the LAPACK general rules for equilibration suggest you should equilibrate the system.
|
||||
// virtual bool ShouldEquilibrate() {ComputeEquilibrateScaling(); return(ShouldEquilibrate_);};
|
||||
|
||||
// NOTE: doxygen-style documentation needs to be re-enabled if this function is re-enabled
|
||||
// Returns true if forward and backward error estimated have been computed (available via FERR() and BERR()).
|
||||
// bool SolutionErrorsEstimated() {return(SolutionErrorsEstimated_);};
|
||||
|
||||
//! Returns true if matrix inverse has been computed (inverse available via AF() and LDAF()).
|
||||
bool Inverted() {return(Inverted_);};
|
||||
|
||||
// NOTE: doxygen-style documentation needs to be re-enabled if this function is re-enabled
|
||||
// Returns true if the condition number of the \e this matrix has been computed (value available via ReciprocalConditionEstimate()).
|
||||
// bool ReciprocalConditionEstimated() {return(ReciprocalConditionEstimated_);};
|
||||
|
||||
//! Returns true if the current set of vectors has been solved.
|
||||
bool Solved() {return(Solved_);};
|
||||
|
||||
// NOTE: doxygen-style documentation needs to be re-enabled if this function is re-enabled
|
||||
// Returns true if the current set of vectors has been refined.
|
||||
// bool SolutionRefined() {return(SolutionRefined_);};
|
||||
//@}
|
||||
|
||||
//! @name Data Accessor methods
|
||||
//@{
|
||||
|
||||
//! Returns pointer to current matrix.
|
||||
Epetra_SerialDenseMatrix * Matrix() const {return(Matrix_);};
|
||||
|
||||
// NOTE: doxygen-style documentation needs to be re-enabled if this function is re-enabled
|
||||
// Returns pointer to factored matrix (assuming factorization has been performed).
|
||||
// Epetra_SerialDenseMatrix * FactoredMatrix() const {return(Factor_);};
|
||||
|
||||
//! Returns pointer to inverted matrix (assuming inverse has been performed).
|
||||
Epetra_SerialDenseMatrix * InvertedMatrix() const {return(Inverse_);};
|
||||
|
||||
//! Returns pointer to current LHS.
|
||||
Epetra_SerialDenseMatrix * LHS() const {return(LHS_);};
|
||||
|
||||
//! Returns pointer to current RHS.
|
||||
Epetra_SerialDenseMatrix * RHS() const {return(RHS_);};
|
||||
|
||||
//! Returns row dimension of system.
|
||||
int M() const {return(M_);};
|
||||
|
||||
//! Returns column dimension of system.
|
||||
int N() const {return(N_);};
|
||||
|
||||
//! Returns pointer to the \e this matrix.
|
||||
double * A() const {return(A_);};
|
||||
|
||||
//! Returns the leading dimension of the \e this matrix.
|
||||
int LDA() const {return(LDA_);};
|
||||
|
||||
//! Returns pointer to current RHS.
|
||||
double * B() const {return(B_);};
|
||||
|
||||
//! Returns the leading dimension of the RHS.
|
||||
int LDB() const {return(LDB_);};
|
||||
|
||||
//! Returns the number of current right hand sides and solution vectors.
|
||||
int NRHS() const {return(NRHS_);};
|
||||
|
||||
//! Returns pointer to current solution.
|
||||
double * X() const {return(X_);};
|
||||
|
||||
//! Returns the leading dimension of the solution.
|
||||
int LDX() const {return(LDX_);};
|
||||
|
||||
double * S() const {return(S_);};
|
||||
|
||||
// NOTE: doxygen-style documentation needs to be re-enabled if this function is re-enabled
|
||||
// Returns pointer to the factored matrix (may be the same as A() if factorization done in place).
|
||||
// double * AF() const {return(AF_);};
|
||||
|
||||
// NOTE: doxygen-style documentation needs to be re-enabled if this function is re-enabled
|
||||
// Returns the leading dimension of the factored matrix.
|
||||
// int LDAF() const {return(LDAF_);};
|
||||
|
||||
//! Returns pointer to the inverted matrix (may be the same as A() if factorization done in place).
|
||||
double * AI() const {return(AI_);};
|
||||
|
||||
//! Returns the leading dimension of the inverted matrix.
|
||||
int LDAI() const {return(LDAI_);};
|
||||
|
||||
// NOTE: doxygen-style documentation needs to be re-enabled if this function is re-enabled
|
||||
// Returns pointer to pivot vector (if factorization has been computed), zero otherwise.
|
||||
// int * IPIV() const {return(IPIV_);};
|
||||
|
||||
//! Returns the 1-Norm of the \e this matrix (returns -1 if not yet computed).
|
||||
double ANORM() const {return(ANORM_);};
|
||||
|
||||
// NOTE: doxygen-style documentation needs to be re-enabled if this function is re-enabled
|
||||
// Returns the reciprocal of the condition number of the \e this matrix (returns -1 if not yet computed).
|
||||
// double RCOND() const {return(RCOND_);};
|
||||
|
||||
// NOTE: doxygen-style documentation needs to be re-enabled if this function is re-enabled
|
||||
// Ratio of smallest to largest row scale factors for the \e this matrix (returns -1 if not yet computed).
|
||||
/* If ROWCND() is >= 0.1 and AMAX() is not close to overflow or underflow, then equilibration is not needed.
|
||||
*/
|
||||
// double ROWCND() const {return(ROWCND_);};
|
||||
|
||||
// NOTE: doxygen-style documentation needs to be re-enabled if this function is re-enabled
|
||||
// Ratio of smallest to largest column scale factors for the \e this matrix (returns -1 if not yet computed).
|
||||
/* If COLCND() is >= 0.1 then equilibration is not needed.
|
||||
*/
|
||||
// double COLCND() const {return(COLCND_);};
|
||||
|
||||
// NOTE: doxygen-style documentation needs to be re-enabled if this function is re-enabled
|
||||
// Returns the absolute value of the largest entry of the \e this matrix (returns -1 if not yet computed).
|
||||
// double AMAX() const {return(AMAX_);};
|
||||
|
||||
// NOTE: doxygen-style documentation needs to be re-enabled if this function is re-enabled
|
||||
// Returns a pointer to the forward error estimates computed by LAPACK.
|
||||
// double * FERR() const {return(FERR_);};
|
||||
|
||||
// NOTE: doxygen-style documentation needs to be re-enabled if this function is re-enabled
|
||||
// Returns a pointer to the backward error estimates computed by LAPACK.
|
||||
// double * BERR() const {return(BERR_);};
|
||||
|
||||
// NOTE: doxygen-style documentation needs to be re-enabled if this function is re-enabled
|
||||
// Returns a pointer to the row scaling vector used for equilibration.
|
||||
// double * R() const {return(R_);};
|
||||
|
||||
// NOTE: doxygen-style documentation needs to be re-enabled if this function is re-enabled
|
||||
// Returns a pointer to the column scale vector used for equilibration.
|
||||
// double * C() const {return(C_);};
|
||||
//@}
|
||||
|
||||
//! @name I/O methods
|
||||
//@{
|
||||
//! Print service methods; defines behavior of ostream << operator.
|
||||
virtual void Print(ostream& os) const;
|
||||
//@}
|
||||
|
||||
//! @name Additional methods for support of Epetra_SerialDenseOperator interface
|
||||
//@{
|
||||
|
||||
//! If set true, transpose of this operator will be applied.
|
||||
/*! This flag allows the transpose of the given operator to be used implicitly. Setting this flag
|
||||
affects only the Apply() and ApplyInverse() methods. If the implementation of this interface
|
||||
does not support transpose use, this method should return a value of -1.
|
||||
|
||||
\param In
|
||||
UseTranspose -If true, multiply by the transpose of operator, otherwise just use operator.
|
||||
|
||||
\return Integer error code, set to 0 if successful. Set to -1 if this implementation does not support transpose.
|
||||
*/
|
||||
virtual int SetUseTranspose(bool UseTranspose) { UseTranspose_ = UseTranspose; return (0); }
|
||||
|
||||
//! Returns the result of a Epetra_SerialDenseOperator applied to a Epetra_SerialDenseMatrix X in Y.
|
||||
/*!
|
||||
\param In
|
||||
X - A Epetra_SerialDenseMatrix to multiply with operator.
|
||||
\param Out
|
||||
Y -A Epetra_SerialDenseMatrix containing result.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual int Apply(const Epetra_SerialDenseMatrix& X, Epetra_SerialDenseMatrix& Y)
|
||||
{ return Y.Multiply( UseTranspose_, false, 1.0, *Matrix(), X, 0.0 ); }
|
||||
|
||||
//! Returns the result of a Epetra_SerialDenseOperator inverse applied to an Epetra_SerialDenseMatrix X in Y.
|
||||
/*!
|
||||
\param In
|
||||
X - A Epetra_SerialDenseMatrix to solve for.
|
||||
\param Out
|
||||
Y -A Epetra_SerialDenseMatrix containing result.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
|
||||
*/
|
||||
virtual int ApplyInverse(const Epetra_SerialDenseMatrix & X, Epetra_SerialDenseMatrix & Y)
|
||||
{ SetVectors(const_cast<Epetra_SerialDenseMatrix&>(X),Y);
|
||||
SolveWithTranspose(UseTranspose_);
|
||||
return Solve(); }
|
||||
|
||||
//! Returns the infinity norm of the global matrix.
|
||||
/* Returns the quantity \f$ \| A \|_\infty\f$ such that
|
||||
\f[\| A \|_\infty = \max_{1\lei\lem} \sum_{j=1}^n |a_{ij}| \f].
|
||||
|
||||
\warning This method must not be called unless HasNormInf() returns true.
|
||||
*/
|
||||
virtual double NormInf() const { return Matrix()->NormInf(); }
|
||||
|
||||
//! Returns a character string describing the operator
|
||||
virtual const char * Label() const { return Epetra_Object::Label(); }
|
||||
|
||||
//! Returns the current UseTranspose setting.
|
||||
virtual bool UseTranspose() const { return UseTranspose_; }
|
||||
|
||||
//! Returns true if the \e this object can provide an approximate Inf-norm, false otherwise.
|
||||
virtual bool HasNormInf() const { return true; }
|
||||
|
||||
//! Returns the row dimension of operator
|
||||
virtual int RowDim() const { return M(); }
|
||||
|
||||
//! Returns the column dimension of operator
|
||||
virtual int ColDim() const { return N(); }
|
||||
|
||||
//@}
|
||||
|
||||
void AllocateWORK() {if (WORK_==0) {LWORK_ = 4*N_; WORK_ = new double[LWORK_];} return;};
|
||||
void AllocateIWORK() {if (IWORK_==0) IWORK_ = new int[N_]; return;};
|
||||
void InitPointers();
|
||||
void DeleteArrays();
|
||||
void ResetMatrix();
|
||||
void ResetVectors();
|
||||
|
||||
|
||||
// bool Equilibrate_;
|
||||
// bool ShouldEquilibrate_;
|
||||
// bool A_Equilibrated_;
|
||||
// bool B_Equilibrated_;
|
||||
bool Transpose_;
|
||||
bool Factored_;
|
||||
// bool EstimateSolutionErrors_;
|
||||
// bool SolutionErrorsEstimated_;
|
||||
bool Solved_;
|
||||
bool Inverted_;
|
||||
// bool ReciprocalConditionEstimated_;
|
||||
// bool RefineSolution_;
|
||||
// bool SolutionRefined_;
|
||||
|
||||
char TRANS_;
|
||||
|
||||
int M_;
|
||||
int N_;
|
||||
int Min_MN_;
|
||||
int NRHS_;
|
||||
int LDA_;
|
||||
// int LDAF_;
|
||||
int LDAI_;
|
||||
int LDB_;
|
||||
int LDX_;
|
||||
int INFO_;
|
||||
int LWORK_;
|
||||
|
||||
// int * IPIV_;
|
||||
int * IWORK_;
|
||||
|
||||
double ANORM_;
|
||||
// double RCOND_;
|
||||
// double ROWCND_;
|
||||
// double COLCND_;
|
||||
// double AMAX_;
|
||||
|
||||
Epetra_SerialDenseMatrix * Matrix_;
|
||||
Epetra_SerialDenseMatrix * LHS_;
|
||||
Epetra_SerialDenseMatrix * RHS_;
|
||||
// Epetra_SerialDenseMatrix * Factor_;
|
||||
Epetra_SerialDenseMatrix * Inverse_;
|
||||
|
||||
double * A_;
|
||||
// double * FERR_;
|
||||
// double * BERR_;
|
||||
// double * AF_;
|
||||
double * AI_;
|
||||
double * WORK_;
|
||||
// double * R_;
|
||||
// double * C_;
|
||||
double * U_;
|
||||
double * S_;
|
||||
double * Vt_;
|
||||
|
||||
double * B_;
|
||||
double * X_;
|
||||
|
||||
bool UseTranspose_;
|
||||
|
||||
private:
|
||||
// Epetra_SerialDenseSolver copy constructor (put here because we don't want user access)
|
||||
|
||||
Epetra_SerialDenseSVD(const Epetra_SerialDenseSVD& Source);
|
||||
Epetra_SerialDenseSVD & operator=(const Epetra_SerialDenseSVD& Source);
|
||||
};
|
||||
|
||||
#endif /* _EPETRA_SERIALDENSESVD_H_ */
|
||||
@@ -0,0 +1,422 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_SERIALDENSESOLVER_H
|
||||
#define EPETRA_SERIALDENSESOLVER_H
|
||||
class Epetra_SerialDenseMatrix;
|
||||
#include "Epetra_Object.h"
|
||||
#include "Epetra_CompObject.h"
|
||||
#include "Epetra_BLAS.h"
|
||||
#include "Epetra_LAPACK.h"
|
||||
|
||||
|
||||
//! Epetra_SerialDenseSolver: A class for solving dense linear problems.
|
||||
|
||||
/*! The Epetra_SerialDenseSolver class enables the definition, in terms of Epetra_SerialDenseMatrix
|
||||
and Epetra_SerialDenseVector objects, of a dense linear problem, followed by the solution of that problem via the
|
||||
most sophisticated techniques available in LAPACK.
|
||||
|
||||
The Epetra_SerialDenseSolver class is intended to provide full-featured support for solving linear
|
||||
problems for general dense rectangular (or square) matrices. It is written on top of BLAS and LAPACK and thus has excellent
|
||||
performance and numerical capabilities. Using this class, one can either perform simple factorizations and solves or
|
||||
apply all the tricks available in LAPACK to get the best possible solution for very ill-conditioned problems.
|
||||
|
||||
<b>Epetra_SerialDenseSolver vs. Epetra_LAPACK</b>
|
||||
|
||||
The Epetra_LAPACK class provides access to most of the same functionality as Epetra_SerialDenseSolver.
|
||||
The primary difference is that Epetra_LAPACK is a "thin" layer on top of LAPACK and Epetra_SerialDenseSolver
|
||||
attempts to provide easy access to the more sophisticated aspects of solving dense linear and eigensystems.
|
||||
<ul>
|
||||
<li> When you should use Epetra_LAPACK: If you are simply looking for a convenient wrapper around the Fortran LAPACK
|
||||
routines and you have a well-conditioned problem, you should probably use Epetra_LAPACK directly.
|
||||
<li> When you should use Epetra_SerialDenseSolver: If you want to (or potentially want to) solve ill-conditioned
|
||||
problems or want to work with a more object-oriented interface, you should probably use Epetra_SerialDenseSolver.
|
||||
|
||||
</ul>
|
||||
|
||||
<b>Constructing Epetra_SerialDenseSolver Objects</b>
|
||||
|
||||
There is a single Epetra_SerialDenseSolver constructor. However, the matrix, right hand side and solution
|
||||
vectors must be set prior to executing most methods in this class.
|
||||
|
||||
<b>Setting vectors used for linear solves</b>
|
||||
|
||||
The matrix A, the left hand side X and the right hand side B (when solving AX = B, for X), can be set by appropriate set
|
||||
methods. Each of these three objects must be an Epetra_SerialDenseMatrix or and Epetra_SerialDenseVector object. The
|
||||
set methods are as follows:
|
||||
<ul>
|
||||
<li> SetMatrix() - Sets the matrix.
|
||||
<li> SetVectors() - Sets the left and right hand side vector(s).
|
||||
</ul>
|
||||
|
||||
<b>Vector and Utility Functions</b>
|
||||
|
||||
Once a Epetra_SerialDenseSolver is constructed, several mathematical functions can be applied to
|
||||
the object. Specifically:
|
||||
<ul>
|
||||
<li> Factorizations.
|
||||
<li> Solves.
|
||||
<li> Condition estimates.
|
||||
<li> Equilibration.
|
||||
<li> Norms.
|
||||
</ul>
|
||||
|
||||
<b>Counting floating point operations </b>
|
||||
The Epetra_SerialDenseSolver class has Epetra_CompObject as a base class. Thus, floating point operations
|
||||
are counted and accumulated in the Epetra_Flop object (if any) that was set using the SetFlopCounter()
|
||||
method in the Epetra_CompObject base class.
|
||||
|
||||
<b>Strategies for Solving Linear Systems</b>
|
||||
In many cases, linear systems can be accurately solved by simply computing the LU factorization
|
||||
of the matrix and then performing a forward back solve with a given set of right hand side vectors. However,
|
||||
in some instances, the factorization may be very poorly conditioned and this simple approach may not work. In
|
||||
these situations, equilibration and iterative refinement may improve the accuracy, or prevent a breakdown in
|
||||
the factorization.
|
||||
|
||||
Epetra_SerialDenseSolver will use equilibration with the factorization if, once the object
|
||||
is constructed and \e before it is factored, you call the function FactorWithEquilibration(true) to force
|
||||
equilibration to be used. If you are uncertain if equilibration should be used, you may call the function
|
||||
ShouldEquilibrate() which will return true if equilibration could possibly help. ShouldEquilibrate() uses
|
||||
guidelines specified in the LAPACK User Guide, namely if SCOND < 0.1 and AMAX < Underflow or AMAX > Overflow, to
|
||||
determine if equilibration \e might be useful.
|
||||
|
||||
Epetra_SerialDenseSolver will use iterative refinement after a forward/back solve if you call
|
||||
SolveToRefinedSolution(true). It will also compute forward and backward error estimates if you call
|
||||
EstimateSolutionErrors(true). Access to the forward (back) error estimates is available via FERR() (BERR()).
|
||||
|
||||
Examples using Epetra_SerialDenseSolver can be found in the Epetra test directories.
|
||||
|
||||
*/
|
||||
|
||||
//=========================================================================
|
||||
class Epetra_SerialDenseSolver : public Epetra_CompObject, public Epetra_BLAS,
|
||||
public Epetra_LAPACK, public Epetra_Object {
|
||||
public:
|
||||
|
||||
//! @name Constructor/Destructor Methods
|
||||
//@{
|
||||
//! Default constructor; matrix should be set using SetMatrix(), LHS and RHS set with SetVectors().
|
||||
Epetra_SerialDenseSolver();
|
||||
|
||||
|
||||
//! Epetra_SerialDenseSolver destructor.
|
||||
virtual ~Epetra_SerialDenseSolver();
|
||||
//@}
|
||||
|
||||
//! @name Set Methods
|
||||
//@{
|
||||
|
||||
//! Sets the pointers for coefficient matrix
|
||||
int SetMatrix(Epetra_SerialDenseMatrix & A);
|
||||
|
||||
//! Sets the pointers for left and right hand side vector(s).
|
||||
/*! Row dimension of X must match column dimension of matrix A, row dimension of B
|
||||
must match row dimension of A. X and B must have the same dimensions.
|
||||
*/
|
||||
int SetVectors(Epetra_SerialDenseMatrix & X, Epetra_SerialDenseMatrix & B);
|
||||
//@}
|
||||
|
||||
//! @name Strategy modifying Methods
|
||||
//@{
|
||||
|
||||
//! Causes equilibration to be called just before the matrix factorization as part of the call to Factor.
|
||||
/*! This function must be called before the factorization is performed.
|
||||
*/
|
||||
void FactorWithEquilibration(bool Flag) {Equilibrate_ = Flag; return;};
|
||||
|
||||
//! If Flag is true, causes all subsequent function calls to work with the transpose of \e this matrix, otherwise not.
|
||||
void SolveWithTranspose(bool Flag) {Transpose_ = Flag; if (Flag) TRANS_ = 'T'; else TRANS_ = 'N'; return;};
|
||||
|
||||
//! Causes all solves to compute solution to best ability using iterative refinement.
|
||||
void SolveToRefinedSolution(bool Flag) {RefineSolution_ = Flag; return;};
|
||||
|
||||
//! Causes all solves to estimate the forward and backward solution error.
|
||||
/*! Error estimates will be in the arrays FERR and BERR, resp, after the solve step is complete.
|
||||
These arrays are accessible via the FERR() and BERR() access functions.
|
||||
*/
|
||||
void EstimateSolutionErrors(bool Flag) ;
|
||||
//@}
|
||||
|
||||
//! @name Factor/Solve/Invert Methods
|
||||
//@{
|
||||
|
||||
//! Computes the in-place LU factorization of the matrix using the LAPACK routine \e DGETRF.
|
||||
/*!
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual int Factor(void);
|
||||
|
||||
//! Computes the solution X to AX = B for the \e this matrix and the B provided to SetVectors()..
|
||||
/*!
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
virtual int Solve(void);
|
||||
|
||||
//! Inverts the \e this matrix.
|
||||
/*!
|
||||
\return Integer error code, set to 0 if successful. Otherwise returns the LAPACK error code INFO.
|
||||
*/
|
||||
virtual int Invert(void);
|
||||
|
||||
//! Computes the scaling vector S(i) = 1/sqrt(A(i,i)) of the \e this matrix.
|
||||
/*!
|
||||
\return Integer error code, set to 0 if successful. Otherwise returns the LAPACK error code INFO.
|
||||
*/
|
||||
virtual int ComputeEquilibrateScaling(void);
|
||||
|
||||
//! Equilibrates the \e this matrix.
|
||||
/*!
|
||||
\return Integer error code, set to 0 if successful. Otherwise returns the LAPACK error code INFO.
|
||||
*/
|
||||
virtual int EquilibrateMatrix(void);
|
||||
|
||||
//! Equilibrates the current RHS.
|
||||
/*!
|
||||
\return Integer error code, set to 0 if successful. Otherwise returns the LAPACK error code INFO.
|
||||
*/
|
||||
int EquilibrateRHS(void);
|
||||
|
||||
|
||||
//! Apply Iterative Refinement.
|
||||
/*!
|
||||
\return Integer error code, set to 0 if successful. Otherwise returns the LAPACK error code INFO.
|
||||
*/
|
||||
virtual int ApplyRefinement(void);
|
||||
|
||||
//! Unscales the solution vectors if equilibration was used to solve the system.
|
||||
/*!
|
||||
\return Integer error code, set to 0 if successful. Otherwise returns the LAPACK error code INFO.
|
||||
*/
|
||||
int UnequilibrateLHS(void);
|
||||
|
||||
//! Returns the reciprocal of the 1-norm condition number of the \e this matrix.
|
||||
/*!
|
||||
\param Value Out
|
||||
On return contains the reciprocal of the 1-norm condition number of the \e this matrix.
|
||||
|
||||
\return Integer error code, set to 0 if successful. Otherwise returns the LAPACK error code INFO.
|
||||
*/
|
||||
virtual int ReciprocalConditionEstimate(double & Value);
|
||||
//@}
|
||||
|
||||
//! @name Query methods
|
||||
//@{
|
||||
|
||||
//! Returns true if transpose of \e this matrix has and will be used.
|
||||
bool Transpose() {return(Transpose_);};
|
||||
|
||||
//! Returns true if matrix is factored (factor available via AF() and LDAF()).
|
||||
bool Factored() {return(Factored_);};
|
||||
|
||||
//! Returns true if factor is equilibrated (factor available via AF() and LDAF()).
|
||||
bool A_Equilibrated() {return(A_Equilibrated_);};
|
||||
|
||||
//! Returns true if RHS is equilibrated (RHS available via B() and LDB()).
|
||||
bool B_Equilibrated() {return(B_Equilibrated_);};
|
||||
|
||||
//! Returns true if the LAPACK general rules for equilibration suggest you should equilibrate the system.
|
||||
virtual bool ShouldEquilibrate() {ComputeEquilibrateScaling(); return(ShouldEquilibrate_);};
|
||||
|
||||
//! Returns true if forward and backward error estimated have been computed (available via FERR() and BERR()).
|
||||
bool SolutionErrorsEstimated() {return(SolutionErrorsEstimated_);};
|
||||
|
||||
//! Returns true if matrix inverse has been computed (inverse available via AF() and LDAF()).
|
||||
bool Inverted() {return(Inverted_);};
|
||||
|
||||
//! Returns true if the condition number of the \e this matrix has been computed (value available via ReciprocalConditionEstimate()).
|
||||
bool ReciprocalConditionEstimated() {return(ReciprocalConditionEstimated_);};
|
||||
|
||||
//! Returns true if the current set of vectors has been solved.
|
||||
bool Solved() {return(Solved_);};
|
||||
|
||||
//! Returns true if the current set of vectors has been refined.
|
||||
bool SolutionRefined() {return(SolutionRefined_);};
|
||||
//@}
|
||||
|
||||
//! @name Data Accessor methods
|
||||
//@{
|
||||
|
||||
//! Returns pointer to current matrix.
|
||||
Epetra_SerialDenseMatrix * Matrix() const {return(Matrix_);};
|
||||
|
||||
//! Returns pointer to factored matrix (assuming factorization has been performed).
|
||||
Epetra_SerialDenseMatrix * FactoredMatrix() const {return(Factor_);};
|
||||
|
||||
//! Returns pointer to current LHS.
|
||||
Epetra_SerialDenseMatrix * LHS() const {return(LHS_);};
|
||||
|
||||
//! Returns pointer to current RHS.
|
||||
Epetra_SerialDenseMatrix * RHS() const {return(RHS_);};
|
||||
|
||||
//! Returns row dimension of system.
|
||||
int M() const {return(M_);};
|
||||
|
||||
//! Returns column dimension of system.
|
||||
int N() const {return(N_);};
|
||||
|
||||
//! Returns pointer to the \e this matrix.
|
||||
double * A() const {return(A_);};
|
||||
|
||||
//! Returns the leading dimension of the \e this matrix.
|
||||
int LDA() const {return(LDA_);};
|
||||
|
||||
//! Returns pointer to current RHS.
|
||||
double * B() const {return(B_);};
|
||||
|
||||
//! Returns the leading dimension of the RHS.
|
||||
int LDB() const {return(LDB_);};
|
||||
|
||||
//! Returns the number of current right hand sides and solution vectors.
|
||||
int NRHS() const {return(NRHS_);};
|
||||
|
||||
//! Returns pointer to current solution.
|
||||
double * X() const {return(X_);};
|
||||
|
||||
//! Returns the leading dimension of the solution.
|
||||
int LDX() const {return(LDX_);};
|
||||
|
||||
//! Returns pointer to the factored matrix (may be the same as A() if factorization done in place).
|
||||
double * AF() const {return(AF_);};
|
||||
|
||||
//! Returns the leading dimension of the factored matrix.
|
||||
int LDAF() const {return(LDAF_);};
|
||||
|
||||
//! Returns pointer to pivot vector (if factorization has been computed), zero otherwise.
|
||||
int * IPIV() const {return(IPIV_);};
|
||||
|
||||
//! Returns the 1-Norm of the \e this matrix (returns -1 if not yet computed).
|
||||
double ANORM() const {return(ANORM_);};
|
||||
|
||||
//! Returns the reciprocal of the condition number of the \e this matrix (returns -1 if not yet computed).
|
||||
double RCOND() const {return(RCOND_);};
|
||||
|
||||
//! Ratio of smallest to largest row scale factors for the \e this matrix (returns -1 if not yet computed).
|
||||
/*! If ROWCND() is >= 0.1 and AMAX() is not close to overflow or underflow, then equilibration is not needed.
|
||||
*/
|
||||
double ROWCND() const {return(ROWCND_);};
|
||||
|
||||
//! Ratio of smallest to largest column scale factors for the \e this matrix (returns -1 if not yet computed).
|
||||
/*! If COLCND() is >= 0.1 then equilibration is not needed.
|
||||
*/
|
||||
double COLCND() const {return(COLCND_);};
|
||||
|
||||
//! Returns the absolute value of the largest entry of the \e this matrix (returns -1 if not yet computed).
|
||||
double AMAX() const {return(AMAX_);};
|
||||
|
||||
//! Returns a pointer to the forward error estimates computed by LAPACK.
|
||||
double * FERR() const {return(FERR_);};
|
||||
|
||||
//! Returns a pointer to the backward error estimates computed by LAPACK.
|
||||
double * BERR() const {return(BERR_);};
|
||||
|
||||
//! Returns a pointer to the row scaling vector used for equilibration.
|
||||
double * R() const {return(R_);};
|
||||
|
||||
//! Returns a pointer to the column scale vector used for equilibration.
|
||||
double * C() const {return(C_);};
|
||||
//@}
|
||||
|
||||
//! @name I/O methods
|
||||
//@{
|
||||
//! Print service methods; defines behavior of ostream << operator.
|
||||
virtual void Print(ostream& os) const;
|
||||
//@}
|
||||
protected:
|
||||
|
||||
void AllocateWORK() {if (WORK_==0) {LWORK_ = 4*N_; WORK_ = new double[LWORK_];} return;};
|
||||
void AllocateIWORK() {if (IWORK_==0) IWORK_ = new int[N_]; return;};
|
||||
void InitPointers();
|
||||
void DeleteArrays();
|
||||
void ResetMatrix();
|
||||
void ResetVectors();
|
||||
|
||||
|
||||
bool Equilibrate_;
|
||||
bool ShouldEquilibrate_;
|
||||
bool A_Equilibrated_;
|
||||
bool B_Equilibrated_;
|
||||
bool Transpose_;
|
||||
bool Factored_;
|
||||
bool EstimateSolutionErrors_;
|
||||
bool SolutionErrorsEstimated_;
|
||||
bool Solved_;
|
||||
bool Inverted_;
|
||||
bool ReciprocalConditionEstimated_;
|
||||
bool RefineSolution_;
|
||||
bool SolutionRefined_;
|
||||
|
||||
char TRANS_;
|
||||
|
||||
int M_;
|
||||
int N_;
|
||||
int Min_MN_;
|
||||
int NRHS_;
|
||||
int LDA_;
|
||||
int LDAF_;
|
||||
int LDB_;
|
||||
int LDX_;
|
||||
int INFO_;
|
||||
int LWORK_;
|
||||
|
||||
int * IPIV_;
|
||||
int * IWORK_;
|
||||
|
||||
double ANORM_;
|
||||
double RCOND_;
|
||||
double ROWCND_;
|
||||
double COLCND_;
|
||||
double AMAX_;
|
||||
|
||||
Epetra_SerialDenseMatrix * Matrix_;
|
||||
Epetra_SerialDenseMatrix * LHS_;
|
||||
Epetra_SerialDenseMatrix * RHS_;
|
||||
Epetra_SerialDenseMatrix * Factor_;
|
||||
|
||||
double * A_;
|
||||
double * FERR_;
|
||||
double * BERR_;
|
||||
double * AF_;
|
||||
double * WORK_;
|
||||
double * R_;
|
||||
double * C_;
|
||||
|
||||
double * B_;
|
||||
double * X_;
|
||||
|
||||
|
||||
private:
|
||||
// Epetra_SerialDenseSolver copy constructor (put here because we don't want user access)
|
||||
|
||||
Epetra_SerialDenseSolver(const Epetra_SerialDenseSolver& Source);
|
||||
Epetra_SerialDenseSolver & operator=(const Epetra_SerialDenseSolver& Source);
|
||||
};
|
||||
|
||||
#endif /* EPETRA_SERIALDENSESOLVER_H */
|
||||
@@ -0,0 +1,311 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_SERIALDENSEVECTOR_H
|
||||
#define EPETRA_SERIALDENSEVECTOR_H
|
||||
|
||||
#include "Epetra_Object.h"
|
||||
#include "Epetra_SerialDenseMatrix.h"
|
||||
|
||||
//! Epetra_SerialDenseVector: A class for constructing and using dense vectors.
|
||||
|
||||
/*! The Epetra_SerialDenseVector class enables the construction and use of real-valued,
|
||||
double-precision dense vectors. It is built on the BLAS and LAPACK and derives from the Epetra_SerialDenseMatrix class.
|
||||
|
||||
The Epetra_SerialDenseVector class is intended to provide convenient vector notation but derives all signficant
|
||||
functionality from Epetra_SerialDenseMatrix.
|
||||
|
||||
<b>Constructing Epetra_SerialDenseVector Objects</b>
|
||||
|
||||
There are four Epetra_SerialDenseVector constructors. The first constructs a zero-length object which should be made
|
||||
to appropriate length using the Size() or Resize() functions and then filled with the [] or () operators.
|
||||
The second constructs an object sized to the dimension specified, which should be filled with the [] or () operators.
|
||||
The third is a constructor that accepts user
|
||||
data as a 1D array, and the fourth is a copy constructor. The third constructor has
|
||||
two data access modes (specified by the Epetra_DataAccess argument):
|
||||
<ol>
|
||||
<li> Copy mode - Allocates memory and makes a copy of the user-provided data. In this case, the
|
||||
user data is not needed after construction.
|
||||
<li> View mode - Creates a "view" of the user data. In this case, the
|
||||
user data is required to remain intact for the life of the object.
|
||||
</ol>
|
||||
|
||||
\warning View mode is \e extremely dangerous from a data hiding perspective.
|
||||
Therefore, we strongly encourage users to develop code using Copy mode first and
|
||||
only use the View mode in a secondary optimization phase.
|
||||
|
||||
<b>Extracting Data from Epetra_SerialDenseVector Objects</b>
|
||||
|
||||
Once a Epetra_SerialDenseVector is constructed, it is possible to view the data via access functions.
|
||||
|
||||
\warning Use of these access functions cam be \e extremely dangerous from a data hiding perspective.
|
||||
|
||||
|
||||
The final useful function is Flops(). Each Epetra_SerialDenseVector object keep track of the number
|
||||
of \e serial floating point operations performed using the specified object as the \e this argument
|
||||
to the function. The Flops() function returns this number as a double precision number. Using this
|
||||
information, in conjunction with the Epetra_Time class, one can get accurate parallel performance
|
||||
numbers.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//=========================================================================
|
||||
class Epetra_SerialDenseVector : public Epetra_SerialDenseMatrix{
|
||||
|
||||
public:
|
||||
|
||||
//! @name Constructors/destructors
|
||||
//@{
|
||||
//! Default constructor; defines a zero size object.
|
||||
/*!
|
||||
Epetra_SerialDenseVector objects defined by the default constructor should be sized with the
|
||||
Size() or Resize functions.
|
||||
Values should be defined by using the [] or () operators.
|
||||
*/
|
||||
Epetra_SerialDenseVector();
|
||||
|
||||
//! Sized constructor; defines a variable-sized object
|
||||
/*!
|
||||
\param In
|
||||
Length - Length of vector.
|
||||
|
||||
Epetra_SerialDenseVector objects defined by the sized constructor are already sized to the
|
||||
dimension given as a parameter. All values are initialized to 0. Calling this constructor
|
||||
is equivalent to using the default constructor, and then calling the Size function on it.
|
||||
Values should be defined by using the [] or () operators.
|
||||
*/
|
||||
Epetra_SerialDenseVector(int Length);
|
||||
|
||||
//! Set object values from one-dimensional array.
|
||||
/*!
|
||||
\param In
|
||||
Epetra_DataAccess - Enumerated type set to Copy or View.
|
||||
\param In
|
||||
Values - Pointer to an array of double precision numbers containing the values.
|
||||
\param In
|
||||
Length - Length of vector.
|
||||
|
||||
See Detailed Description section for further discussion.
|
||||
*/
|
||||
Epetra_SerialDenseVector(Epetra_DataAccess CV, double* Values, int Length);
|
||||
|
||||
//! Epetra_SerialDenseVector copy constructor.
|
||||
|
||||
Epetra_SerialDenseVector(const Epetra_SerialDenseVector& Source);
|
||||
|
||||
|
||||
//! Epetra_SerialDenseVector destructor.
|
||||
virtual ~Epetra_SerialDenseVector ();
|
||||
//@}
|
||||
|
||||
//! @name Post-construction modification routines
|
||||
//@{
|
||||
|
||||
//! Set length of a Epetra_SerialDenseVector object; init values to zero.
|
||||
/*!
|
||||
\param In
|
||||
Length - Length of vector object.
|
||||
|
||||
Allows user to define the dimension of a Epetra_SerialDenseVector. This function can
|
||||
be called at any point after construction. Any values that were previously in this object are
|
||||
destroyed and the resized vector starts off with all zero values.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int Size(int Length) {return(Epetra_SerialDenseMatrix::Shape(Length, 1));};
|
||||
|
||||
//! Resize a Epetra_SerialDenseVector object.
|
||||
/*!
|
||||
\param In
|
||||
Length - Length of vector object.
|
||||
|
||||
Allows user to define the dimension of a Epetra_SerialDenseVector. This function can
|
||||
be called at any point after construction. Any values that were previously in this object are
|
||||
copied into the new size. If the new shape is smaller than the original, the first Length values
|
||||
are copied to the new vector.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int Resize(int Length) {return(Epetra_SerialDenseMatrix::Reshape(Length, 1));};
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Element access methods
|
||||
//@{
|
||||
//! Value copy from one vector to another.
|
||||
/*!
|
||||
The operator= allows one to copy the values from one existing SerialDenseVector to another, as
|
||||
long as there is enough room in the target to hold the source.
|
||||
|
||||
\return Values of the left hand side vector are modified by the values of the right hand side vector.
|
||||
*/
|
||||
Epetra_SerialDenseVector& operator = (const Epetra_SerialDenseVector& Source);
|
||||
|
||||
//let the compiler know we intend to overload the base-class function
|
||||
//operator() rather than hide it.
|
||||
using Epetra_SerialDenseMatrix::operator();
|
||||
|
||||
//! Element access function.
|
||||
/*!
|
||||
Returns the specified element of the vector. Bounds checking is enforced.
|
||||
\return Specified element in vector.
|
||||
|
||||
\warning No bounds checking is done unless Epetra is compiled with HAVE_EPETRA_ARRAY_BOUNDS_CHECK.
|
||||
*/
|
||||
double& operator () (int Index);
|
||||
|
||||
//! Element access function.
|
||||
/*!
|
||||
Returns the specified element of the vector. Bounds checking is enforced.
|
||||
\return Specified element in vector.
|
||||
|
||||
\warning No bounds checking is done unless Epetra is compiled with HAVE_EPETRA_ARRAY_BOUNDS_CHECK.
|
||||
*/
|
||||
const double& operator () (int Index) const;
|
||||
|
||||
//! Element access function.
|
||||
/*!
|
||||
Returns the specified element of the vector.
|
||||
\return Specified element in vector.
|
||||
|
||||
\warning No bounds checking is done unless Epetra is compiled with HAVE_EPETRA_ARRAY_BOUNDS_CHECK.
|
||||
*/
|
||||
double& operator [] (int Index);
|
||||
|
||||
//! Column access function.
|
||||
/*!
|
||||
Returns the specified element of the vector.
|
||||
\return Specified element in vector.
|
||||
|
||||
\warning No bounds checking is done unless Epetra is compiled with HAVE_EPETRA_ARRAY_BOUNDS_CHECK.
|
||||
*/
|
||||
const double& operator [] (int Index) const;
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Mathematical methods
|
||||
//@{
|
||||
//! Set vector values to random numbers.
|
||||
/*!
|
||||
SerialDenseVector uses the random number generator provided by Epetra_Util.
|
||||
The vector values will be set to random values on the interval (-1.0, 1.0).
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int Random();
|
||||
|
||||
//! Compute 1-norm of each vector in multi-vector.
|
||||
/*!
|
||||
\param x (In) Input vector x.
|
||||
|
||||
\return Dot-product of the \e this vector and x.
|
||||
*/
|
||||
double Dot(const Epetra_SerialDenseVector & x) const;
|
||||
|
||||
//! Compute 1-norm of each vector in multi-vector.
|
||||
/*!
|
||||
\return 1-norm of the vector.
|
||||
*/
|
||||
double Norm1() const;
|
||||
|
||||
//! Compute 2-norm of each vector in multi-vector.
|
||||
/*!
|
||||
\param Out
|
||||
\return 2-norm of the vector.
|
||||
*/
|
||||
double Norm2() const;
|
||||
|
||||
//! Compute Inf-norm of each vector in multi-vector.
|
||||
/*!
|
||||
\return Infinity-norm of the vector.
|
||||
*/
|
||||
double NormInf() const;
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Attribute access methods
|
||||
//@{
|
||||
//! Returns length of vector.
|
||||
int Length() const {return(M_);};
|
||||
|
||||
//! Returns pointer to the values in vector.
|
||||
double* Values() const {return(A_);};
|
||||
|
||||
//! Returns the data access mode of the \e this vector.
|
||||
Epetra_DataAccess CV() const {return(CV_);};
|
||||
|
||||
//@}
|
||||
|
||||
//! @name I/O methods
|
||||
//@{
|
||||
//! Print service methods; defines behavior of ostream << operator.
|
||||
virtual void Print(ostream& os) const;
|
||||
//@}
|
||||
};
|
||||
|
||||
// inlined definitions of op() and op[]
|
||||
//=========================================================================
|
||||
inline double& Epetra_SerialDenseVector::operator() (int Index) {
|
||||
#ifdef HAVE_EPETRA_ARRAY_BOUNDS_CHECK
|
||||
if (Index >= M_ || Index < 0)
|
||||
throw ReportError("Index = " +toString(Index) + " Out of Range 0 - " + toString(M_-1), -1);
|
||||
#endif
|
||||
return(A_[Index]);
|
||||
}
|
||||
//=========================================================================
|
||||
inline const double& Epetra_SerialDenseVector::operator() (int Index) const {
|
||||
#ifdef HAVE_EPETRA_ARRAY_BOUNDS_CHECK
|
||||
if (Index >= M_ || Index < 0)
|
||||
throw ReportError("Index = " +toString(Index) + " Out of Range 0 - " + toString(M_-1), -1);
|
||||
#endif
|
||||
return(A_[Index]);
|
||||
}
|
||||
//=========================================================================
|
||||
inline double& Epetra_SerialDenseVector::operator [] (int Index) {
|
||||
#ifdef HAVE_EPETRA_ARRAY_BOUNDS_CHECK
|
||||
if (Index >= M_ || Index < 0)
|
||||
throw ReportError("Index = " +toString(Index) + " Out of Range 0 - " + toString(M_-1), -1);
|
||||
#endif
|
||||
return(A_[Index]);
|
||||
}
|
||||
//=========================================================================
|
||||
inline const double& Epetra_SerialDenseVector::operator [] (int Index) const {
|
||||
#ifdef HAVE_EPETRA_ARRAY_BOUNDS_CHECK
|
||||
if (Index >= M_ || Index < 0)
|
||||
throw ReportError("Index = " +toString(Index) + " Out of Range 0 - " + toString(M_-1), -1);
|
||||
#endif
|
||||
return(A_[Index]);
|
||||
}
|
||||
//=========================================================================
|
||||
|
||||
#endif /* EPETRA_SERIALDENSEVECTOR_H */
|
||||
@@ -0,0 +1,133 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_SERIALDISTRIBUTOR_H
|
||||
#define EPETRA_SERIALDISTRIBUTOR_H
|
||||
|
||||
#include "Epetra_Object.h"
|
||||
#include "Epetra_Distributor.h"
|
||||
class Epetra_SerialComm;
|
||||
|
||||
//! Epetra_SerialDistributor: The Epetra Serial implementation of the Epetra_Distributor Gather/Scatter Setup Class.
|
||||
/*! The Epetra_SerialDistributor class is an Serial implement of Epetra_Distributor that is essentially a trivial class
|
||||
since a serial machine is a trivial parallel machine.
|
||||
An Epetra_SerialDistributor object is actually produced by calling a method in the Epetra_SerialComm class.
|
||||
|
||||
*/
|
||||
|
||||
class Epetra_SerialDistributor: public Epetra_Object, public virtual Epetra_Distributor {
|
||||
|
||||
public:
|
||||
|
||||
//! @name Constructor/Destructor
|
||||
//@{
|
||||
|
||||
//! Constructor.
|
||||
Epetra_SerialDistributor(const Epetra_SerialComm & Comm);
|
||||
|
||||
//! Epetra_SerialDistributor Copy Constructor.
|
||||
Epetra_SerialDistributor(const Epetra_SerialDistributor & Plan);
|
||||
|
||||
//! Clone method
|
||||
Epetra_Distributor * Clone(){return(dynamic_cast<Epetra_Distributor *>(new Epetra_SerialDistributor(*this)));};
|
||||
|
||||
//! Epetra_Comm Destructor.
|
||||
virtual ~Epetra_SerialDistributor();
|
||||
//@}
|
||||
|
||||
|
||||
int CreateFromSends( const int & NumExportIDs,
|
||||
const int * ExportPIDs,
|
||||
bool Deterministic,
|
||||
int & NumRemoteIDs );
|
||||
|
||||
int CreateFromRecvs( const int & NumRemoteIDs,
|
||||
const int * RemoteGIDs,
|
||||
const int * RemotePIDs,
|
||||
bool Deterministic,
|
||||
int & NumExportIDs,
|
||||
int *& ExportGIDs,
|
||||
int *& ExportPIDs);
|
||||
|
||||
|
||||
int Do (char * export_objs,
|
||||
int obj_size,
|
||||
int & len_import_objs,
|
||||
char *& import_objs);
|
||||
int DoReverse(char * export_objs,
|
||||
int obj_size,
|
||||
int & len_import_objs,
|
||||
char *& import_objs);
|
||||
|
||||
int DoPosts(char * export_objs,
|
||||
int obj_size,
|
||||
int & len_import_objs,
|
||||
char *& import_objs);
|
||||
int DoWaits();
|
||||
|
||||
int DoReversePosts(char * export_objs,
|
||||
int obj_size,
|
||||
int & len_import_objs,
|
||||
char *& import_objs);
|
||||
int DoReverseWaits();
|
||||
|
||||
|
||||
int Do (char * export_objs,
|
||||
int obj_size,
|
||||
int *& sizes,
|
||||
int & len_import_objs,
|
||||
char *& import_objs);
|
||||
int DoReverse(char * export_objs,
|
||||
int obj_size,
|
||||
int *& sizes,
|
||||
int & len_import_objs,
|
||||
char *& import_objs);
|
||||
|
||||
int DoPosts(char * export_objs,
|
||||
int obj_size,
|
||||
int *& sizes,
|
||||
int & len_import_objs,
|
||||
char *& import_objs);
|
||||
|
||||
int DoReversePosts(char * export_objs,
|
||||
int obj_size,
|
||||
int *& sizes,
|
||||
int & len_import_objs,
|
||||
char *& import_objs);
|
||||
|
||||
|
||||
virtual void Print(ostream & os) const;
|
||||
|
||||
private:
|
||||
int nrecvs_;
|
||||
int nsends_;
|
||||
};
|
||||
#endif /* EPETRA_SERIALDISTRIBUTOR_H */
|
||||
@@ -0,0 +1,265 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_SERIALSPDDENSESOLVER_H
|
||||
#define EPETRA_SERIALSPDDENSESOLVER_H
|
||||
#include "Epetra_SerialDenseSolver.h"
|
||||
class Epetra_SerialSymDenseMatrix;
|
||||
|
||||
//! Epetra_SerialSpdDenseSolver: A class for constructing and using symmetric positive definite dense matrices.
|
||||
|
||||
/*! The Epetra_SerialSpdDenseSolver class enables the construction and use of real-valued, symmetric positive definite,
|
||||
double-precision dense matrices. It is built on the Epetra_DenseMatrix class which in turn is built on the
|
||||
BLAS and LAPACK via the Epetra_BLAS and
|
||||
Epetra_LAPACK classes.
|
||||
|
||||
The Epetra_SerialSpdDenseSolver class is intended to provide full-featured support for solving linear and eigen system
|
||||
problems for symmetric positive definite matrices. It is written on top of BLAS and LAPACK and thus has excellent
|
||||
performance and numerical capabilities. Using this class, one can either perform simple factorizations and solves or
|
||||
apply all the tricks available in LAPACK to get the best possible solution for very ill-conditioned problems.
|
||||
|
||||
<b>Epetra_SerialSpdDenseSolver vs. Epetra_LAPACK</b>
|
||||
|
||||
The Epetra_LAPACK class provides access to most of the same functionality as Epetra_SerialSpdDenseSolver.
|
||||
The primary difference is that Epetra_LAPACK is a "thin" layer on top of LAPACK and Epetra_SerialSpdDenseSolver
|
||||
attempts to provide easy access to the more sophisticated aspects of solving dense linear and eigensystems.
|
||||
<ul>
|
||||
<li> When you should use Epetra_LAPACK: If you are simply looking for a convenient wrapper around the Fortran LAPACK
|
||||
routines and you have a well-conditioned problem, you should probably use Epetra_LAPACK directly.
|
||||
<li> When you should use Epetra_SerialSpdDenseSolver: If you want to (or potentially want to) solve ill-conditioned
|
||||
problems or want to work with a more object-oriented interface, you should probably use Epetra_SerialSpdDenseSolver.
|
||||
|
||||
</ul>
|
||||
|
||||
<b>Constructing Epetra_SerialSpdDenseSolver Objects</b>
|
||||
|
||||
There are three Epetra_DenseMatrix constructors. The first constructs a zero-sized object which should be made
|
||||
to appropriate length using the Shape() or Reshape() functions and then filled with the [] or () operators.
|
||||
The second is a constructor that accepts user
|
||||
data as a 2D array, the third is a copy constructor. The second constructor has
|
||||
two data access modes (specified by the Epetra_DataAccess argument):
|
||||
<ol>
|
||||
<li> Copy mode - Allocates memory and makes a copy of the user-provided data. In this case, the
|
||||
user data is not needed after construction.
|
||||
<li> View mode - Creates a "view" of the user data. In this case, the
|
||||
user data is required to remain intact for the life of the object.
|
||||
</ol>
|
||||
|
||||
\warning View mode is \e extremely dangerous from a data hiding perspective.
|
||||
Therefore, we strongly encourage users to develop code using Copy mode first and
|
||||
only use the View mode in a secondary optimization phase.
|
||||
|
||||
<b>Setting vectors used for linear solves</b>
|
||||
|
||||
Setting the X and B vectors (which are Epetra_DenseMatrix objects) used for solving linear systems
|
||||
is done separately from the constructor. This allows
|
||||
a single matrix factor to be used for multiple solves. Similar to the constructor, the vectors X and B can
|
||||
be copied or viewed using the Epetra_DataAccess argument.
|
||||
|
||||
<b>Extracting Data from Epetra_SerialSpdDenseSolver Objects</b>
|
||||
|
||||
Once a Epetra_SerialSpdDenseSolver is constructed, it is possible to view the data via access functions.
|
||||
|
||||
\warning Use of these access functions cam be \e extremely dangerous from a data hiding perspective.
|
||||
|
||||
|
||||
<b>Vector and Utility Functions</b>
|
||||
|
||||
Once a Epetra_SerialSpdDenseSolver is constructed, several mathematical functions can be applied to
|
||||
the object. Specifically:
|
||||
<ul>
|
||||
<li> Factorizations.
|
||||
<li> Solves.
|
||||
<li> Condition estimates.
|
||||
<li> Equilibration.
|
||||
<li> Norms.
|
||||
</ul>
|
||||
|
||||
The final useful function is Flops(). Each Epetra_SerialSpdDenseSolver object keep track of the number
|
||||
of \e serial floating point operations performed using the specified object as the \e this argument
|
||||
to the function. The Flops() function returns this number as a double precision number. Using this
|
||||
information, in conjunction with the Epetra_Time class, one can get accurate parallel performance
|
||||
numbers.
|
||||
|
||||
<b>Strategies for Solving Linear Systems</b>
|
||||
In many cases, linear systems can be accurately solved by simply computing the Cholesky factorization
|
||||
of the matrix and then performing a forward back solve with a given set of right hand side vectors. However,
|
||||
in some instances, the factorization may be very poorly conditioned and the simple approach may not work. In
|
||||
these situations, equilibration and iterative refinement may improve the accuracy, or prevent a breakdown in
|
||||
the factorization.
|
||||
|
||||
Epetra_SerialSpdDenseSolver will use equilibration with the factorization if, once the object
|
||||
is constructed and \e before it is factored, you call the function FactorWithEquilibration(true) to force
|
||||
equilibration to be used. If you are uncertain if equilibration should be used, you may call the function
|
||||
ShouldEquilibrate() which will return true if equilibration could possibly help. ShouldEquilibrate() uses
|
||||
guidelines specified in the LAPACK User Guide, namely if SCOND < 0.1 and AMAX < Underflow or AMAX > Overflow, to
|
||||
determine if equilibration \e might be useful.
|
||||
|
||||
Epetra_SerialSpdDenseSolver will use iterative refinement after a forward/back solve if you call
|
||||
SolveToRefinedSolution(true). It will also compute forward and backward error estimates if you call
|
||||
EstimateSolutionErrors(true). Access to the forward (back) error estimates is available via FERR() (BERR()).
|
||||
|
||||
Examples using Epetra_SerialSpdDenseSolver can be found in the Epetra test directories.
|
||||
|
||||
*/
|
||||
|
||||
//=========================================================================
|
||||
class Epetra_SerialSpdDenseSolver : public Epetra_SerialDenseSolver {
|
||||
|
||||
public:
|
||||
//! @name Constructor/Destructor Methods
|
||||
//@{
|
||||
//! Default constructor; matrix should be set using SetMatrix(), LHS and RHS set with SetVectors().
|
||||
Epetra_SerialSpdDenseSolver();
|
||||
|
||||
|
||||
//! Epetra_SerialDenseSolver destructor.
|
||||
virtual ~Epetra_SerialSpdDenseSolver();
|
||||
//@}
|
||||
|
||||
//! @name Set Methods
|
||||
//@{
|
||||
|
||||
//Let the compiler know we intend to overload the SetMatrix function,
|
||||
//rather than hide it.
|
||||
using Epetra_SerialDenseSolver::SetMatrix;
|
||||
|
||||
//! Sets the pointers for coefficient matrix; special version for symmetric matrices
|
||||
int SetMatrix(Epetra_SerialSymDenseMatrix & A);
|
||||
//@}
|
||||
|
||||
//! @name Factor/Solve/Invert Methods
|
||||
//@{
|
||||
|
||||
//! Computes the in-place Cholesky factorization of the matrix using the LAPACK routine \e DPOTRF.
|
||||
/*!
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int Factor(void);
|
||||
|
||||
//! Computes the solution X to AX = B for the \e this matrix and the B provided to SetVectors()..
|
||||
/*!
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int Solve(void);
|
||||
|
||||
//! Inverts the \e this matrix.
|
||||
/*! Note: This function works a little differently that DPOTRI in that it fills the entire
|
||||
matrix with the inverse, independent of the UPLO specification.
|
||||
|
||||
\return Integer error code, set to 0 if successful. Otherwise returns the LAPACK error code INFO.
|
||||
*/
|
||||
int Invert(void);
|
||||
|
||||
//! Computes the scaling vector S(i) = 1/sqrt(A(i,i) of the \e this matrix.
|
||||
/*!
|
||||
\return Integer error code, set to 0 if successful. Otherwise returns the LAPACK error code INFO.
|
||||
*/
|
||||
int ComputeEquilibrateScaling(void);
|
||||
|
||||
//! Equilibrates the \e this matrix.
|
||||
/*!
|
||||
\return Integer error code, set to 0 if successful. Otherwise returns the LAPACK error code INFO.
|
||||
*/
|
||||
int EquilibrateMatrix(void);
|
||||
|
||||
//! Equilibrates the current RHS.
|
||||
/*!
|
||||
\return Integer error code, set to 0 if successful. Otherwise returns the LAPACK error code INFO.
|
||||
*/
|
||||
int EquilibrateRHS(void);
|
||||
|
||||
|
||||
//! Apply Iterative Refinement.
|
||||
/*!
|
||||
\return Integer error code, set to 0 if successful. Otherwise returns the LAPACK error code INFO.
|
||||
*/
|
||||
int ApplyRefinement(void);
|
||||
|
||||
//! Unscales the solution vectors if equilibration was used to solve the system.
|
||||
/*!
|
||||
\return Integer error code, set to 0 if successful. Otherwise returns the LAPACK error code INFO.
|
||||
*/
|
||||
int UnequilibrateLHS(void);
|
||||
|
||||
//! Returns the reciprocal of the 1-norm condition number of the \e this matrix.
|
||||
/*!
|
||||
\param Value Out
|
||||
On return contains the reciprocal of the 1-norm condition number of the \e this matrix.
|
||||
|
||||
\return Integer error code, set to 0 if successful. Otherwise returns the LAPACK error code INFO.
|
||||
*/
|
||||
int ReciprocalConditionEstimate(double & Value);
|
||||
//@}
|
||||
|
||||
//! @name Query methods
|
||||
//@{
|
||||
|
||||
|
||||
//! Returns true if the LAPACK general rules for equilibration suggest you should equilibrate the system.
|
||||
bool ShouldEquilibrate() {ComputeEquilibrateScaling(); return(ShouldEquilibrate_);};
|
||||
//@}
|
||||
|
||||
//! @name Data Accessor methods
|
||||
//@{
|
||||
|
||||
//! Returns pointer to current matrix.
|
||||
Epetra_SerialSymDenseMatrix * SymMatrix() const {return(SymMatrix_);};
|
||||
|
||||
//! Returns pointer to factored matrix (assuming factorization has been performed).
|
||||
Epetra_SerialSymDenseMatrix * SymFactoredMatrix() const {return(SymFactor_);};
|
||||
|
||||
//! Ratio of smallest to largest equilibration scale factors for the \e this matrix (returns -1 if not yet computed).
|
||||
/*! If SCOND() is >= 0.1 and AMAX() is not close to overflow or underflow, then equilibration is not needed.
|
||||
*/
|
||||
double SCOND() {return(SCOND_);};
|
||||
|
||||
//Let the compiler know we intend to overload the AMAX function,
|
||||
//rather than hide it.
|
||||
using Epetra_SerialDenseSolver::AMAX;
|
||||
|
||||
//! Returns the absolute value of the largest entry of the \e this matrix (returns -1 if not yet computed).
|
||||
double AMAX() {return(AMAX_);};
|
||||
//@}
|
||||
|
||||
private:
|
||||
|
||||
double SCOND_;
|
||||
Epetra_SerialSymDenseMatrix * SymMatrix_; // Need pointer to symmetric matrix for Spd-specific methods
|
||||
Epetra_SerialSymDenseMatrix * SymFactor_; // Need pointer to symmetric matrix for Spd-specific methods
|
||||
|
||||
// Epetra_SerialSpdDenseSolver copy constructor (put here because we don't want user access)
|
||||
|
||||
Epetra_SerialSpdDenseSolver(const Epetra_SerialSpdDenseSolver& Source);
|
||||
Epetra_SerialSpdDenseSolver & operator=(const Epetra_SerialSpdDenseSolver& Source);
|
||||
};
|
||||
|
||||
#endif /* EPETRA_SERIALSPDDENSESOLVER_H */
|
||||
@@ -0,0 +1,270 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_SERIALSYMDENSEMATRIX_H
|
||||
#define EPETRA_SERIALSYMDENSEMATRIX_H
|
||||
#include "Epetra_SerialDenseMatrix.h"
|
||||
|
||||
|
||||
//! Epetra_SerialSymDenseMatrix: A class for constructing and using symmetric positive definite dense matrices.
|
||||
|
||||
/*! The Epetra_SerialSymDenseMatrix class enables the construction and use of
|
||||
real-valued, symmetric positive definite,
|
||||
double-precision dense matrices. It is built on the Epetra_SerialDenseMatrix class which
|
||||
in turn is built on the
|
||||
BLAS via the Epetra_BLAS class.
|
||||
|
||||
The Epetra_SerialSymDenseMatrix class is intended to provide full-featured support for solving
|
||||
linear and eigen system
|
||||
problems for symmetric positive definite matrices. It is written on top of BLAS and LAPACK
|
||||
and thus has excellent
|
||||
performance and numerical capabilities. Using this class, one can either perform simple
|
||||
factorizations and solves or
|
||||
apply all the tricks available in LAPACK to get the best possible solution for very
|
||||
ill-conditioned problems.
|
||||
|
||||
<b>Epetra_SerialSymDenseMatrix vs. Epetra_LAPACK</b>
|
||||
|
||||
The Epetra_LAPACK class provides access to most of the same functionality as
|
||||
Epetra_SerialSymDenseMatrix.
|
||||
The primary difference is that Epetra_LAPACK is a "thin" layer on top of
|
||||
LAPACK and Epetra_SerialSymDenseMatrix
|
||||
attempts to provide easy access to the more sophisticated aspects of
|
||||
solving dense linear and eigensystems.
|
||||
<ul>
|
||||
<li> When you should use Epetra_LAPACK: If you are simply looking for a
|
||||
convenient wrapper around the Fortran LAPACK
|
||||
routines and you have a well-conditioned problem, you should probably use Epetra_LAPACK directly.
|
||||
<li> When you should use Epetra_SerialSymDenseMatrix: If you want to (or potentially want to)
|
||||
solve ill-conditioned
|
||||
problems or want to work with a more object-oriented interface, you should
|
||||
probably use Epetra_SerialSymDenseMatrix.
|
||||
|
||||
</ul>
|
||||
|
||||
<b>Constructing Epetra_SerialSymDenseMatrix Objects</b>
|
||||
|
||||
There are three Epetra_DenseMatrix constructors. The first constructs a zero-sized object
|
||||
which should be made
|
||||
to appropriate length using the Shape() or Reshape() functions and then filled with
|
||||
the [] or () operators.
|
||||
The second is a constructor that accepts user
|
||||
data as a 2D array, the third is a copy constructor. The second constructor has
|
||||
two data access modes (specified by the Epetra_DataAccess argument):
|
||||
<ol>
|
||||
<li> Copy mode - Allocates memory and makes a copy of the user-provided data. In this case, the
|
||||
user data is not needed after construction.
|
||||
<li> View mode - Creates a "view" of the user data. In this case, the
|
||||
user data is required to remain intact for the life of the object.
|
||||
</ol>
|
||||
|
||||
\warning View mode is \e extremely dangerous from a data hiding perspective.
|
||||
Therefore, we strongly encourage users to develop code using Copy mode first and
|
||||
only use the View mode in a secondary optimization phase.
|
||||
|
||||
<b>Extracting Data from Epetra_SerialSymDenseMatrix Objects</b>
|
||||
|
||||
Once a Epetra_SerialSymDenseMatrix is constructed, it is possible to view the data via access functions.
|
||||
|
||||
\warning Use of these access functions cam be \e extremely dangerous from a data hiding perspective.
|
||||
|
||||
|
||||
<b>Vector and Utility Functions</b>
|
||||
|
||||
Once a Epetra_SerialSymDenseMatrix is constructed, several mathematical functions can be applied to
|
||||
the object. Specifically:
|
||||
<ul>
|
||||
<li> Multiplication.
|
||||
<li> Norms.
|
||||
</ul>
|
||||
|
||||
<b>Counting floating point operations </b>
|
||||
The Epetra_SerialSymDenseMatrix class has Epetra_CompObject as a base class. Thus, floating
|
||||
point operations
|
||||
are counted and accumulated in the Epetra_Flop object (if any) that was set using the SetFlopCounter()
|
||||
method in the Epetra_CompObject base class.
|
||||
|
||||
*/
|
||||
|
||||
//=========================================================================
|
||||
class Epetra_SerialSymDenseMatrix : public Epetra_SerialDenseMatrix {
|
||||
|
||||
public:
|
||||
//! @name Constructor/Destructor Methods
|
||||
//@{
|
||||
//! Default constructor; defines a zero size object.
|
||||
/*!
|
||||
Epetra_SerialSymDenseMatrix objects defined by the default constructor
|
||||
should be sized with the Shape()
|
||||
or Reshape() functions.
|
||||
Values should be defined by using the [] or ()operators.
|
||||
|
||||
Note: By default the active part of the matrix is assumed to be in the lower triangle.
|
||||
To set the upper part as active, call SetUpper().
|
||||
See Detailed Description section for further discussion.
|
||||
*/
|
||||
Epetra_SerialSymDenseMatrix(void);
|
||||
//! Set object values from two-dimensional array.
|
||||
/*!
|
||||
\param In
|
||||
Epetra_DataAccess - Enumerated type set to Copy or View.
|
||||
\param In
|
||||
A - Pointer to an array of double precision numbers. The first vector starts at A.
|
||||
The second vector starts at A+LDA, the third at A+2*LDA, and so on.
|
||||
\param In
|
||||
LDA - The "Leading Dimension", or stride between vectors in memory.
|
||||
\param In
|
||||
NumRowsCols - Number of rows and columns in object.
|
||||
|
||||
Note: By default the active part of the matrix is assumed to be in the lower triangle.
|
||||
To set the upper part as active, call SetUpper().
|
||||
See Detailed Description section for further discussion.
|
||||
*/
|
||||
Epetra_SerialSymDenseMatrix(Epetra_DataAccess CV, double *A, int LDA, int NumRowsCols);
|
||||
|
||||
//! Epetra_SerialSymDenseMatrix copy constructor.
|
||||
|
||||
Epetra_SerialSymDenseMatrix(const Epetra_SerialSymDenseMatrix& Source);
|
||||
|
||||
|
||||
//! Epetra_SerialSymDenseMatrix destructor.
|
||||
virtual ~Epetra_SerialSymDenseMatrix ();
|
||||
//@}
|
||||
|
||||
//! @name Set Methods
|
||||
//@{
|
||||
|
||||
//let the compiler know we intend to overload the base-class Shape function,
|
||||
//rather than hide it.
|
||||
using Epetra_SerialDenseMatrix::Shape;
|
||||
|
||||
//! Set dimensions of a Epetra_SerialSymDenseMatrix object; init values to zero.
|
||||
/*!
|
||||
\param In
|
||||
NumRowsCols - Number of rows and columns in object.
|
||||
|
||||
Allows user to define the dimensions of a Epetra_DenseMatrix at any point. This function can
|
||||
be called at any point after construction. Any values that were previously in this object are
|
||||
destroyed and the resized matrix starts off with all zero values.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int Shape(int NumRowsCols) {return(Epetra_SerialDenseMatrix::Shape(NumRowsCols,NumRowsCols));};
|
||||
|
||||
//let the compiler know we intend to overload the base-class Reshape function,
|
||||
//rather than hide it.
|
||||
|
||||
using Epetra_SerialDenseMatrix::Reshape;
|
||||
|
||||
//! Reshape a Epetra_SerialSymDenseMatrix object.
|
||||
/*!
|
||||
\param In
|
||||
NumRowsCols - Number of rows and columns in object.
|
||||
|
||||
Allows user to define the dimensions of a Epetra_SerialSymDenseMatrix at any point. This function can
|
||||
be called at any point after construction. Any values that were previously in this object are
|
||||
copied into the new shape. If the new shape is smaller than the original, the upper left portion
|
||||
of the original matrix (the principal submatrix) is copied to the new matrix.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int Reshape(int NumRowsCols) {return(Epetra_SerialDenseMatrix::Reshape(NumRowsCols,NumRowsCols));};
|
||||
|
||||
|
||||
//! Specify that the lower triangle of the \e this matrix should be used.
|
||||
void SetLower() {Upper_ = false; UPLO_ = 'L';};
|
||||
|
||||
//! Specify that the upper triangle of the \e this matrix should be used.
|
||||
void SetUpper() {Upper_ = true; UPLO_ = 'U';};
|
||||
//@}
|
||||
|
||||
//! @name Query methods
|
||||
//@{
|
||||
|
||||
//! Returns true if upper triangle of \e this matrix has and will be used.
|
||||
bool Upper() const {return(Upper_);};
|
||||
|
||||
//! Returns character value of UPLO used by LAPACK routines.
|
||||
char UPLO() const {return(UPLO_);};
|
||||
//@}
|
||||
|
||||
//! @name Mathematical Methods
|
||||
//@{
|
||||
|
||||
//! Inplace scalar-matrix product A = \e a A.
|
||||
/*! Scale a matrix, entry-by-entry using the value ScalarA. This method is sensitive to
|
||||
the UPLO() parameter.
|
||||
|
||||
|
||||
\param ScalarA (In) Scalar to multiply with A.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
|
||||
*/
|
||||
int Scale ( double ScalarA );
|
||||
|
||||
|
||||
//! Computes the 1-Norm of the \e this matrix.
|
||||
/*!
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
double NormOne() const;
|
||||
|
||||
//! Computes the Infinity-Norm of the \e this matrix.
|
||||
double NormInf() const;
|
||||
|
||||
//@}
|
||||
|
||||
void CopyUPLOMat(bool Upper, double * A, int LDA, int NumRows);
|
||||
|
||||
//! @name Deprecated methods (will be removed in later versions of this class)
|
||||
//@{
|
||||
|
||||
//! Computes the 1-Norm of the \e this matrix (identical to NormOne() method).
|
||||
/*!
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
double OneNorm() const {return(Epetra_SerialSymDenseMatrix::NormOne());};
|
||||
|
||||
//! Computes the Infinity-Norm of the \e this matrix (identical to NormInf() method).
|
||||
double InfNorm() const {return(Epetra_SerialSymDenseMatrix::NormInf());};
|
||||
//@}
|
||||
|
||||
private:
|
||||
|
||||
bool Upper_;
|
||||
|
||||
char UPLO_;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif /* EPETRA_SERIALSYMDENSEMATRIX_H */
|
||||
@@ -0,0 +1,64 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_SRCDISTOBJECT_H
|
||||
#define EPETRA_SRCDISTOBJECT_H
|
||||
class Epetra_BlockMap;
|
||||
|
||||
|
||||
//! Epetra_SrcDistObject: A class for supporting flexible source distributed objects for import/export operations.
|
||||
|
||||
/*! The Epetra_SrcDistObject is a base class for all Epetra distributed global objects that are potential
|
||||
source objects for the general Epetra_DistObject class. It provides a way to send a very general distributed
|
||||
object as the potential source object for an import or export object. For example, it is possible to pass
|
||||
an Epetra_RowMatrix object as the source object for an import/export where the target is an Epetra_CrsMatrix, or
|
||||
an Epetra_CrsGraph (where the RowMatrix values will be ignored).
|
||||
|
||||
*/
|
||||
|
||||
//==========================================================================
|
||||
class Epetra_SrcDistObject {
|
||||
|
||||
public:
|
||||
//! @name Destructor
|
||||
//@{
|
||||
//! Epetra_SrcDistObject destructor.
|
||||
virtual ~Epetra_SrcDistObject() {};
|
||||
//@}
|
||||
|
||||
|
||||
//! @name Attribute accessor methods
|
||||
//@{
|
||||
//! Returns a reference to the Epetra_BlockMap for this object.
|
||||
virtual const Epetra_BlockMap & Map() const = 0;
|
||||
};
|
||||
|
||||
#endif /* EPETRA_SRCDISTOBJECT_H */
|
||||
@@ -0,0 +1,117 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_TIME_H
|
||||
#define EPETRA_TIME_H
|
||||
|
||||
//! Epetra_Time: The Epetra Timing Class.
|
||||
/*! The Epetra_Time class is a wrapper that encapsulates the general
|
||||
information needed getting timing information. Currently it return
|
||||
the elapsed time for each calling processor..
|
||||
A Epetra_Comm object is required for building all Epetra_Time objects.
|
||||
|
||||
Epetra_Time support both serial execution and (via MPI) parallel
|
||||
distributed memory execution. It is meant to insulate the user from
|
||||
the specifics of timing across a variety of platforms.
|
||||
*/
|
||||
|
||||
#include "Epetra_Object.h"
|
||||
#include "Epetra_Comm.h"
|
||||
|
||||
#ifdef EPETRA_MPI
|
||||
#include "mpi.h"
|
||||
#elif ICL
|
||||
#include <time.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#ifndef MINGW
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
class Epetra_Time: public Epetra_Object {
|
||||
|
||||
public:
|
||||
//! Epetra_Time Constructor.
|
||||
/*! Creates a Epetra_Time instance. This instance can be queried for
|
||||
elapsed time on the calling processor. StartTime is also set
|
||||
for use with the ElapsedTime function.
|
||||
*/
|
||||
Epetra_Time(const Epetra_Comm & Comm);
|
||||
|
||||
//! Epetra_Time Copy Constructor.
|
||||
/*! Makes an exact copy of an existing Epetra_Time instance.
|
||||
*/
|
||||
Epetra_Time(const Epetra_Time& Time);
|
||||
|
||||
//! Epetra_Time wall-clock time function.
|
||||
/*! Returns the wall-clock time in seconds. A code section can be
|
||||
timed by putting it between two calls to WallTime and taking the
|
||||
difference of the times.
|
||||
*/
|
||||
double WallTime(void) const;
|
||||
|
||||
//! Epetra_Time function to reset the start time for a timer object.
|
||||
/*! Resets the start time for the timer object to the current time
|
||||
A code section can be
|
||||
timed by putting it between a call to ResetStartTime and ElapsedTime.
|
||||
*/
|
||||
void ResetStartTime(void);
|
||||
|
||||
//! Epetra_Time elapsed time function.
|
||||
/*! Returns the elapsed time in seconds since the timer object was
|
||||
constructed, or since the ResetStartTime function was called.
|
||||
A code section can be
|
||||
timed by putting it between the Epetra_Time constructor and a call to
|
||||
ElapsedTime, or between a call to ResetStartTime and ElapsedTime.
|
||||
*/
|
||||
double ElapsedTime(void) const;
|
||||
|
||||
//! Epetra_Time Destructor.
|
||||
/*! Completely deletes a Epetra_Time object.
|
||||
*/
|
||||
virtual ~Epetra_Time(void);
|
||||
|
||||
Epetra_Time& operator=(const Epetra_Time& src)
|
||||
{
|
||||
StartTime_ = src.StartTime_;
|
||||
Comm_ = src.Comm_;
|
||||
return( *this );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
double StartTime_;
|
||||
const Epetra_Comm * Comm_;
|
||||
|
||||
};
|
||||
|
||||
#endif /* EPETRA_TIME_H */
|
||||
@@ -0,0 +1,290 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_UTIL_H
|
||||
#define EPETRA_UTIL_H
|
||||
|
||||
#include "Epetra_Object.h"
|
||||
class Epetra_Map;
|
||||
class Epetra_BlockMap;
|
||||
class Epetra_CrsMatrix;
|
||||
class Epetra_MultiVector;
|
||||
|
||||
//! Epetra_Util: The Epetra Util Wrapper Class.
|
||||
/*! The Epetra_Util class is a collection of useful functions that cut across a broad
|
||||
set of other classes.
|
||||
<ul>
|
||||
<li> A random number generator is provided, along with methods to set and
|
||||
retrieve the random-number seed.
|
||||
|
||||
The random number generator is a multiplicative linear congruential generator,
|
||||
with multiplier 16807 and modulus 2^31 - 1. It is based on the algorithm described in
|
||||
"Random Number Generators: Good Ones Are Hard To Find", S. K. Park and K. W. Miller,
|
||||
Communications of the ACM, vol. 31, no. 10, pp. 1192-1201.
|
||||
|
||||
<li> Sorting is provided by a static function on this class (i.e., it is not
|
||||
necessary to construct an instance of this class to use the Sort function).
|
||||
|
||||
<li> A static function is provided for creating a new Epetra_Map object with
|
||||
1-to-1 ownership of entries from an existing map which may have entries that
|
||||
appear on multiple processors.
|
||||
</ul>
|
||||
|
||||
Epetra_Util is a serial interface only. This is appropriate since the standard
|
||||
utilities are only specified for serial execution (or shared memory parallel).
|
||||
*/
|
||||
class Epetra_Util {
|
||||
|
||||
public:
|
||||
//! Epetra_Util Constructor.
|
||||
/*! Builds an instance of a serial Util object.
|
||||
*/
|
||||
Epetra_Util();
|
||||
|
||||
|
||||
//! Epetra_Util Copy Constructor.
|
||||
/*! Makes an exact copy of an existing Epetra_Util instance.
|
||||
*/
|
||||
Epetra_Util(const Epetra_Util& Util);
|
||||
|
||||
//! Epetra_Util Destructor.
|
||||
virtual ~Epetra_Util();
|
||||
|
||||
//! @name Random number utilities
|
||||
//@{
|
||||
|
||||
//! Returns a random integer on the interval (0, 2^31-1)
|
||||
unsigned int RandomInt();
|
||||
|
||||
//! Returns a random double on the interval (-1.0,1.0)
|
||||
double RandomDouble();
|
||||
|
||||
//! Get seed from Random function.
|
||||
/*!
|
||||
\return Current random number seed.
|
||||
*/
|
||||
unsigned int Seed() const;
|
||||
|
||||
//! Set seed for Random function.
|
||||
/*!
|
||||
\param In
|
||||
Seed - An integer on the interval [1, 2^31-2]
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int SetSeed(unsigned int Seed);
|
||||
|
||||
//@}
|
||||
|
||||
//! Epetra_Util Sort Routine (Shell sort)
|
||||
/*!
|
||||
|
||||
This function sorts a list of integer values in ascending or descending order. Additionally it sorts any
|
||||
number of companion lists of doubles or ints. A shell sort is used, which is fast if indices are already sorted.
|
||||
|
||||
\param In
|
||||
SortAscending - Sort keys in ascending order if true, otherwise sort in descending order..
|
||||
\param In
|
||||
NumKeys - Number of integer values to be sorted.
|
||||
\param In/Out
|
||||
Keys - List of integers to be sorted.
|
||||
\param In
|
||||
NumDoubleCompanions - Number of lists of double precision numbers to be sorted with the key. If set to zero,
|
||||
DoubleCompanions is ignored and can be set to zero.
|
||||
\param In
|
||||
DoubleCompanions - DoubleCompanions[i] is a pointer to the ith list of doubles to be sorted with key.
|
||||
\param In
|
||||
NumIntCompanions - Number of lists of integers to be sorted with the key. If set to zero,
|
||||
IntCompanions is ignored and can be set to zero.
|
||||
\param In
|
||||
IntCompanions - IntCompanions[i] is a pointer to the ith list of integers to be sorted with key.
|
||||
|
||||
*/
|
||||
static void Sort(bool SortAscending, int NumKeys, int * Keys,
|
||||
int NumDoubleCompanions,double ** DoubleCompanions,
|
||||
int NumIntCompanions, int ** IntCompanions);
|
||||
|
||||
//! Epetra_Util Create_Root_Map function
|
||||
/*! Function to create a new Epetra_Map object with all GIDs sent to the root processor
|
||||
which is zero by default. All all processors will have no GIDs. This root map can then
|
||||
be used to create an importer or exporter that will migrate all data to the root processor.
|
||||
|
||||
If root is set to -1 then the user map will be replicated completely on all processors.
|
||||
*/
|
||||
static Epetra_Map Create_Root_Map(const Epetra_Map & usermap,
|
||||
int root = 0);
|
||||
|
||||
//! Epetra_Util Create_OneToOne_Map function
|
||||
/*! Function to create a new Epetra_Map object with 1-to-1 ownership of
|
||||
entries from an existing map which may have entries that appear on
|
||||
multiple processors.
|
||||
*/
|
||||
static Epetra_Map Create_OneToOne_Map(const Epetra_Map& usermap,
|
||||
bool high_rank_proc_owns_shared=false);
|
||||
|
||||
//! Epetra_Util Create_OneToOne_Map function
|
||||
/*! Function to create a new Epetra_Map object with 1-to-1 ownership of
|
||||
entries from an existing map which may have entries that appear on
|
||||
multiple processors.
|
||||
*/
|
||||
static Epetra_BlockMap Create_OneToOne_BlockMap(const Epetra_BlockMap& usermap,
|
||||
bool high_rank_proc_owns_shared=false);
|
||||
|
||||
//! Epetra_Util Chop method. Return zero if input Value is less than ChopValue
|
||||
static double Chop(const double & Value){
|
||||
if (std::abs(Value) < chopVal_) return 0;
|
||||
return Value;
|
||||
};
|
||||
|
||||
static const double chopVal_;
|
||||
|
||||
private:
|
||||
unsigned int Seed_;
|
||||
};
|
||||
|
||||
|
||||
// Epetra_Util constructor
|
||||
inline Epetra_Util::Epetra_Util() : Seed_(std::rand()) {}
|
||||
// Epetra_Util constructor
|
||||
inline Epetra_Util::Epetra_Util(const Epetra_Util& Util) : Seed_(Util.Seed_) {}
|
||||
// Epetra_Util destructor
|
||||
inline Epetra_Util::~Epetra_Util(){}
|
||||
|
||||
/** Utility function to perform a binary-search on a list of data.
|
||||
Important assumption: data is assumed to be sorted.
|
||||
|
||||
@param item to be searched for
|
||||
@param list to be searched in
|
||||
@param len Length of list
|
||||
@param insertPoint Input/Output. If item is found, insertPoint is not
|
||||
referenced. If item is not found, insertPoint is set to the offset at which
|
||||
item should be inserted in list such that order (sortedness) would be
|
||||
maintained.
|
||||
@return offset Location in list at which item was found. -1 if not found.
|
||||
*/
|
||||
int Epetra_Util_binary_search(int item,
|
||||
const int* list,
|
||||
int len,
|
||||
int& insertPoint);
|
||||
|
||||
/** Function to insert an item in a list, at a specified offset.
|
||||
@return error-code 0 if successful, -1 if input parameters seem
|
||||
unreasonable (offset > usedLength, offset<0, etc).
|
||||
|
||||
@param item to be inserted
|
||||
@param offset location at which to insert item
|
||||
@param list array into which item is to be inserted. This array may be
|
||||
re-allocated by this function.
|
||||
@param usedLength number of items already present in list. Will be updated
|
||||
to reflect the new length.
|
||||
@param allocatedLength current allocated length of list. Will be updated
|
||||
to reflect the new allocated-length, if applicable. Re-allocation
|
||||
occurs only if usedLength==allocatedLength on entry.
|
||||
@param allocChunkSize Optional argument, defaults to 32. Increment by
|
||||
which the array should be expanded, if re-allocation is necessary.
|
||||
@return error-code 0 if successful. -1 if input parameters don't make sense.
|
||||
*/
|
||||
template<class T>
|
||||
int Epetra_Util_insert(T item, int offset, T*& list,
|
||||
int& usedLength,
|
||||
int& allocatedLength,
|
||||
int allocChunkSize=32)
|
||||
{
|
||||
if (offset < 0 || offset > usedLength) {
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if (usedLength < allocatedLength) {
|
||||
for(int i=usedLength; i>offset; --i) {
|
||||
list[i] = list[i-1];
|
||||
}
|
||||
list[offset] = item;
|
||||
++usedLength;
|
||||
return(0);
|
||||
}
|
||||
|
||||
T* newlist = new T[allocatedLength+allocChunkSize];
|
||||
if (newlist == NULL) {
|
||||
return(-1);
|
||||
}
|
||||
|
||||
allocatedLength += allocChunkSize;
|
||||
int i;
|
||||
for(i=0; i<offset; ++i) {
|
||||
newlist[i] = list[i];
|
||||
}
|
||||
|
||||
newlist[offset] = item;
|
||||
|
||||
for(i=offset+1; i<=usedLength; ++i) {
|
||||
newlist[i] = list[i-1];
|
||||
}
|
||||
|
||||
++usedLength;
|
||||
delete [] list;
|
||||
list = newlist;
|
||||
return(0);
|
||||
}
|
||||
|
||||
//! Harwell-Boeing data extraction routine
|
||||
/*! This routine will extract data from an existing Epetra_Crs Matrix, and
|
||||
optionally from related rhs and lhs objects in a form that is compatible with
|
||||
software that requires the Harwell-Boeing data format. The matrix must be passed
|
||||
in, but the RHS and LHS arguments may be set to zero (either or both of them).
|
||||
For each of the LHS or RHS arguments, if non-trivial and contain more than one vector, the
|
||||
vectors must have strided access. If both LHS and RHS are non-trivial, they must have the
|
||||
same number of vectors. If the input objects are distributed, the returned matrices will
|
||||
contain the local part of the matrix and vectors only.
|
||||
|
||||
\param A (In) Epetra_CrsMatrix.
|
||||
\param LHS (In) Left hand side multivector. Set to zero if none not available or needed.
|
||||
\param RHS (In) Right hand side multivector. Set to zero if none not available or needed.
|
||||
\param M (Out) Local row dimension of matrix.
|
||||
\param N (Out) Local column dimension of matrix.
|
||||
\param nz (Out) Number of nonzero entries in matrix.
|
||||
\param ptr (Out) Offsets into ind and val arrays pointing to start of each row's data.
|
||||
\param ind (Out) Column indices of the matrix, in compressed form.
|
||||
\param val (Out) Matrix values, in compressed form corresponding to the ind array.
|
||||
\param Nrhs (Out) Number of right/left hand sides found (if any) in RHS and LHS.
|
||||
\param rhs (Out) Fortran-style 2D array of RHS values.
|
||||
\param ldrhs (Out) Stride between columns of rhs.
|
||||
\param lhs (Out) Fortran-style 2D array of LHS values.
|
||||
\param ldrhs (Out) Stride between columns of lhs.
|
||||
*/
|
||||
int Epetra_Util_ExtractHbData(Epetra_CrsMatrix * A, Epetra_MultiVector * LHS,
|
||||
Epetra_MultiVector * RHS,
|
||||
int & M, int & N, int & nz, int * & ptr,
|
||||
int * & ind, double * & val, int & Nrhs,
|
||||
double * & rhs, int & ldrhs,
|
||||
double * & lhs, int & ldlhs);
|
||||
|
||||
|
||||
#endif /* EPETRA_UTIL_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,236 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_VBRROWMATRIX_H
|
||||
#define EPETRA_VBRROWMATRIX_H
|
||||
|
||||
#include "Epetra_BasicRowMatrix.h"
|
||||
#include "Epetra_VbrMatrix.h"
|
||||
#include "Epetra_Map.h"
|
||||
#include "Epetra_Comm.h"
|
||||
#include "Epetra_Vector.h"
|
||||
#include "Epetra_MultiVector.h"
|
||||
|
||||
//! Epetra_VbrRowMatrix: A class for using an existing Epetra_VbrMatrix object as an Epetra_RowMatrix object.
|
||||
|
||||
/*! The Epetra_VbrRowMatrix class takes an existing Epetra_VbrMatrix object and allows its
|
||||
use as an Epetra_RowMatrix without allocating additional storage. Although the Epetra_VbrMatrix itself
|
||||
inherits from Epetra_RowMatrix, a design flaw in the inheritance structure of Epetra prohibits the use of
|
||||
an Epetra_VbrMatrix object as an Epetra_RowMatrix in some important situations. Therefore we recommend the
|
||||
use of this class to wrap an Epetra_VbrMatrix object.
|
||||
|
||||
\warning This class takes a pointer to an existing Epetra_VbrMatrix object. It is assumed that the user
|
||||
will pass in a pointer to a valid Epetra_VbrMatrix object, and will retain it throughout the life of the
|
||||
Epetra_VbrRowMatrix object.
|
||||
|
||||
*/
|
||||
|
||||
class Epetra_VbrRowMatrix: public Epetra_BasicRowMatrix {
|
||||
|
||||
public:
|
||||
|
||||
//! @name Constructors/Destructor
|
||||
//@{
|
||||
//! Epetra_VbrRowMatrix constuctor.
|
||||
/* The constructor for this class requires a pointer to a fully constructed instance of an Epetra_VbrMatrix
|
||||
object.
|
||||
\param Matrix (In) Pointer to an existing Epetra_VbrMatrix. The input matrix must be retained by the user
|
||||
throughout the existance of the dependent Epetra_VbrRowmatrix object.
|
||||
\pre Matrix must have Matrix->Filled()==true.
|
||||
*/
|
||||
Epetra_VbrRowMatrix(Epetra_VbrMatrix * Matrix): Epetra_BasicRowMatrix(Matrix->Comm()), matrix_(Matrix) {
|
||||
if (Matrix==0) throw Matrix->RowMatrixRowMap().ReportError("Input matrix must have called FillComplete()", -1);
|
||||
SetMaps(Matrix->RowMatrixRowMap(), Matrix->RowMatrixColMap(), Matrix->OperatorDomainMap(), Matrix->OperatorRangeMap());
|
||||
if (!Matrix->Filled()) throw Matrix->RowMatrixRowMap().ReportError("Input matrix must have called FillComplete()", -1);
|
||||
SetLabel("Epetra::VbrRowMatrix");
|
||||
}
|
||||
|
||||
//! Epetra_VbrRowMatrix Destructor
|
||||
virtual ~Epetra_VbrRowMatrix(){}
|
||||
//@}
|
||||
|
||||
//! @name Post-construction modifications
|
||||
//@{
|
||||
//! Update the matrix to which this object points.
|
||||
/* Updates the matrix that the Epetra_VbrRowMatrix will use to satisfy the Epetra_RowMatrix functionality.
|
||||
\param Matrix (In) A pointer to an existing, fully constructed Epetra_VbrMatrix.
|
||||
\pre Matrix must have Matrix->Filled()==true.
|
||||
*/
|
||||
int UpdateMatrix(Epetra_VbrMatrix * Matrix){
|
||||
if (Matrix ==0) {
|
||||
EPETRA_CHK_ERR(-1);
|
||||
}
|
||||
else matrix_ = Matrix;
|
||||
return(0);
|
||||
}
|
||||
//@}
|
||||
|
||||
//! @name Methods required for implementing Epetra_BasicRowMatrix
|
||||
//@{
|
||||
|
||||
//! Returns a copy of the specified local row in user-provided arrays.
|
||||
/*!
|
||||
\param MyRow (In) - Local row to extract.
|
||||
\param Length (In) - Length of Values and Indices.
|
||||
\param NumEntries (Out) - Number of nonzero entries extracted.
|
||||
\param Values (Out) - Extracted values for this row.
|
||||
\param Indices (Out) - Extracted global column indices for the corresponding values.
|
||||
|
||||
\return Integer error code, set to 0 if successful, set to -1 if MyRow not valid, -2 if Length is too short (NumEntries will have required length).
|
||||
*/
|
||||
int ExtractMyRowCopy(int MyRow, int Length, int & NumEntries, double *Values, int * Indices) const {
|
||||
|
||||
EPETRA_CHK_ERR(matrix_->ExtractMyRowCopy(MyRow, Length, NumEntries, Values, Indices));
|
||||
return(0);
|
||||
}
|
||||
|
||||
//! Returns a reference to the ith entry in the matrix, along with its row and column index
|
||||
/*!
|
||||
\param CurEntry (In) - Local entry to extract.
|
||||
\param Value (Out) - Extracted reference to current values.
|
||||
\param RowIndex (Out) - Row index for current entry.
|
||||
\param ColIndex (Out) - Column index for current entry.
|
||||
|
||||
\return Integer error code, set to 0 if successful, set to -1 if CurEntry not valid.
|
||||
*/
|
||||
int ExtractMyEntryView(int CurEntry, double * &Value, int & RowIndex, int & ColIndex) {
|
||||
return(-1);
|
||||
}
|
||||
|
||||
//! Returns a const reference to the ith entry in the matrix, along with its row and column index.
|
||||
/*!
|
||||
\param CurEntry (In) - Local entry to extract.
|
||||
\param Value (Out) - Extracted reference to current values.
|
||||
\param RowIndex (Out) - Row index for current entry.
|
||||
\param ColIndex (Out) - Column index for current entry.
|
||||
|
||||
\return Integer error code, set to 0 if successful, set to -1 if CurEntry not valid.
|
||||
*/
|
||||
int ExtractMyEntryView(int CurEntry, double const * & Value, int & RowIndex, int & ColIndex) const {
|
||||
return(-1);
|
||||
}
|
||||
|
||||
//! Return the current number of values stored for the specified local row.
|
||||
/*! Similar to NumMyEntries() except NumEntries is returned as an argument
|
||||
and error checking is done on the input value MyRow.
|
||||
\param MyRow - (In) Local row.
|
||||
\param NumEntries - (Out) Number of nonzero values.
|
||||
|
||||
\return Integer error code, set to 0 if successful, set to -1 if MyRow not valid.
|
||||
\pre None.
|
||||
\post Unchanged.
|
||||
*/
|
||||
int NumMyRowEntries(int MyRow, int & NumEntries) const {
|
||||
EPETRA_CHK_ERR(matrix_->NumMyRowEntries(MyRow, NumEntries));
|
||||
return(0);
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
//! @name Computational methods
|
||||
//@{
|
||||
|
||||
//! Scales the Epetra_VbrMatrix on the right with a Epetra_Vector x.
|
||||
/*! The \e this matrix will be scaled such that A(i,j) = x(j)*A(i,j) where i denotes the global row number of A
|
||||
and j denotes the global column number of A.
|
||||
\param In
|
||||
x -The Epetra_Vector used for scaling \e this.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int RightScale(const Epetra_Vector& x){
|
||||
HaveNumericConstants_ = false;
|
||||
UpdateFlops(NumGlobalNonzeros());
|
||||
EPETRA_CHK_ERR(matrix_->RightScale(x));
|
||||
return(0);
|
||||
}
|
||||
|
||||
//! Scales the Epetra_VbrMatrix on the left with a Epetra_Vector x.
|
||||
/*! The \e this matrix will be scaled such that A(i,j) = x(i)*A(i,j) where i denotes the row number of A
|
||||
and j denotes the column number of A.
|
||||
\param In
|
||||
x -A Epetra_Vector to solve for.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int LeftScale(const Epetra_Vector& x){
|
||||
HaveNumericConstants_ = false;
|
||||
UpdateFlops(NumGlobalNonzeros());
|
||||
EPETRA_CHK_ERR(matrix_->LeftScale(x));
|
||||
return(0);
|
||||
}
|
||||
|
||||
//! Returns the result of a Epetra_VbrRowMatrix multiplied by a Epetra_MultiVector X in Y.
|
||||
/*!
|
||||
\param In
|
||||
TransA -If true, multiply by the transpose of matrix, otherwise just use matrix.
|
||||
\param In
|
||||
X - A Epetra_MultiVector of dimension NumVectors to multiply with matrix.
|
||||
\param Out
|
||||
Y -A Epetra_MultiVector of dimension NumVectorscontaining result.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int Multiply(bool TransA, const Epetra_MultiVector& X, Epetra_MultiVector& Y) const{
|
||||
EPETRA_CHK_ERR(matrix_->Multiply(TransA, X, Y));
|
||||
return(0);
|
||||
}
|
||||
|
||||
//! Returns the result of a Epetra_VbrRowMatrix solve with a Epetra_MultiVector X in Y (not implemented).
|
||||
/*!
|
||||
\param In
|
||||
Upper -If true, solve Ux = y, otherwise solve Lx = y.
|
||||
\param In
|
||||
Trans -If true, solve transpose problem.
|
||||
\param In
|
||||
UnitDiagonal -If true, assume diagonal is unit (whether it's stored or not).
|
||||
\param In
|
||||
X - A Epetra_MultiVector of dimension NumVectors to solve for.
|
||||
\param Out
|
||||
Y -A Epetra_MultiVector of dimension NumVectors containing result.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int Solve(bool Upper, bool Trans, bool UnitDiagonal,
|
||||
const Epetra_MultiVector& X,
|
||||
Epetra_MultiVector& Y) const {
|
||||
EPETRA_CHK_ERR(matrix_->Solve(Upper, Trans, UnitDiagonal, X, Y));
|
||||
return(0);
|
||||
} //@}
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
Epetra_VbrMatrix * matrix_;
|
||||
|
||||
};
|
||||
#endif /* EPETRA_VBRROWMATRIX_H */
|
||||
@@ -0,0 +1,450 @@
|
||||
|
||||
//@HEADER
|
||||
/*
|
||||
************************************************************************
|
||||
|
||||
Epetra: Linear Algebra Services Package
|
||||
Copyright (2001) Sandia Corporation
|
||||
|
||||
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
license for use of this work by or on behalf of the U.S. Government.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
USA
|
||||
Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
//@HEADER
|
||||
|
||||
#ifndef EPETRA_VECTOR_H
|
||||
#define EPETRA_VECTOR_H
|
||||
|
||||
#include "Epetra_MultiVector.h"
|
||||
class Epetra_Map;
|
||||
|
||||
//! Epetra_Vector: A class for constructing and using dense vectors on a parallel computer.
|
||||
|
||||
/*! The Epetra_Vector class enables the construction and use of real-valued,
|
||||
double-precision dense vectors in a distributed memory environment. The distribution of the dense
|
||||
vector is determined in part by a Epetra_Comm object and a Epetra_Map (or Epetra_LocalMap
|
||||
or Epetra_BlockMap).
|
||||
|
||||
This class is derived from the Epetra_MultiVector class. As such, it has full access
|
||||
to all of the functionality provided in the Epetra_MultiVector class.
|
||||
|
||||
<b> Distributed Global vs. Replicated Local</b>
|
||||
<ul>
|
||||
<li> Distributed Global Vectors - In most instances, a multi-vector will be partitioned
|
||||
across multiple memory images associated with multiple processors. In this case, there is
|
||||
a unique copy of each element and elements are spread across all processors specified by
|
||||
the Epetra_Comm communicator.
|
||||
<li> Replicated Local Vectors - Some algorithms use vectors that are too small to
|
||||
be distributed across all processors. Replicated local vectors handle
|
||||
these types of situation.
|
||||
</ul>
|
||||
|
||||
<b>Constructing Epetra_Vectors</b>
|
||||
|
||||
There are four Epetra_Vector constructors. The first is a basic constructor that allocates
|
||||
space and sets all values to zero, the second is a
|
||||
copy constructor. The third and fourth constructors work with user data. These constructors have
|
||||
two data access modes:
|
||||
<ol>
|
||||
<li> Copy mode - Allocates memory and makes a copy of the user-provided data. In this case, the
|
||||
user data is not needed after construction.
|
||||
<li> View mode - Creates a "view" of the user data. In this case, the
|
||||
user data is required to remain intact for the life of the vector.
|
||||
</ol>
|
||||
|
||||
\warning View mode is \e extremely dangerous from a data hiding perspective.
|
||||
Therefore, we strongly encourage users to develop code using Copy mode first and
|
||||
only use the View mode in a secondary optimization phase.
|
||||
|
||||
All Epetra_Vector constructors require a map argument that describes the layout of elements
|
||||
on the parallel machine. Specifically,
|
||||
\c map is a Epetra_Map, Epetra_LocalMap or Epetra_BlockMap object describing the desired
|
||||
memory layout for the vector.
|
||||
|
||||
There are four different Epetra_Vector constructors:
|
||||
<ul>
|
||||
<li> Basic - All values are zero.
|
||||
<li> Copy - Copy an existing vector.
|
||||
<li> Copy from or make view of user double array.
|
||||
<li> Copy or make view of a vector from a Epetra_MultiVector object.
|
||||
</ul>
|
||||
|
||||
<b>Extracting Data from Epetra_Vectors</b>
|
||||
|
||||
Once a Epetra_Vector is constructed, it is possible to extract a copy of the values or create
|
||||
a view of them.
|
||||
|
||||
\warning ExtractView functions are \e extremely dangerous from a data hiding perspective.
|
||||
For both ExtractView fuctions, there is a corresponding ExtractCopy function. We
|
||||
strongly encourage users to develop code using ExtractCopy functions first and
|
||||
only use the ExtractView functions in a secondary optimization phase.
|
||||
|
||||
There are two Extract functions:
|
||||
<ul>
|
||||
<li> ExtractCopy - Copy values into a user-provided array.
|
||||
<li> ExtractView - Set user-provided array to point to Epetra_Vector data.
|
||||
</ul>
|
||||
|
||||
<b>Vector and Utility Functions</b>
|
||||
|
||||
Once a Epetra_Vector is constructed, a variety of mathematical functions can be applied to
|
||||
the vector. Specifically:
|
||||
<ul>
|
||||
<li> Dot Products.
|
||||
<li> Vector Updates.
|
||||
<li> \e p Norms.
|
||||
<li> Weighted Norms.
|
||||
<li> Minimum, Maximum and Average Values.
|
||||
</ul>
|
||||
|
||||
The final useful function is Flops(). Each Epetra_Vector object keep track of the number
|
||||
of \e serial floating point operations performed using the specified object as the \e this argument
|
||||
to the function. The Flops() function returns this number as a double precision number. Using this
|
||||
information, in conjunction with the Epetra_Time class, one can get accurate parallel performance
|
||||
numbers.
|
||||
|
||||
\warning A Epetra_Map, Epetra_LocalMap or Epetra_BlockMap object is required for all
|
||||
Epetra_Vector constructors.
|
||||
|
||||
*/
|
||||
|
||||
//=========================================================================
|
||||
class Epetra_Vector : public Epetra_MultiVector {
|
||||
|
||||
public:
|
||||
|
||||
//! @name Constructors/destructors
|
||||
//@{
|
||||
//! Basic Epetra_Vector constuctor.
|
||||
/*! Creates a Epetra_Vector object and fills with zero values.
|
||||
|
||||
\param In
|
||||
Map - A Epetra_LocalMap, Epetra_Map or Epetra_BlockMap.
|
||||
\param In
|
||||
zeroOut - If <tt>true</tt> then the allocated memory will be zeroed
|
||||
out initialy. If <tt>false</tt> then this memory will not
|
||||
be touched which can be significantly faster.
|
||||
|
||||
\warning Note that, because Epetra_LocalMap
|
||||
derives from Epetra_Map and Epetra_Map derives from Epetra_BlockMap, this constructor works
|
||||
for all three types of Epetra map classes.
|
||||
|
||||
\return Pointer to a Epetra_Vector.
|
||||
|
||||
*/
|
||||
Epetra_Vector(const Epetra_BlockMap& Map, bool zeroOut = true);
|
||||
|
||||
//! Epetra_Vector copy constructor.
|
||||
|
||||
Epetra_Vector(const Epetra_Vector& Source);
|
||||
|
||||
//! Set vector values from user array.
|
||||
/*!
|
||||
\param In
|
||||
Epetra_DataAccess - Enumerated type set to Copy or View.
|
||||
\param In
|
||||
Map - A Epetra_LocalMap, Epetra_Map or Epetra_BlockMap.
|
||||
\param In
|
||||
V - Pointer to an array of double precision numbers..
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
|
||||
See Detailed Description section for further discussion.
|
||||
*/
|
||||
Epetra_Vector(Epetra_DataAccess CV, const Epetra_BlockMap& Map, double *V);
|
||||
|
||||
//! Set vector values from a vector in an existing Epetra_MultiVector.
|
||||
/*!
|
||||
\param In
|
||||
Epetra_DataAccess - Enumerated type set to Copy or View.
|
||||
\param In
|
||||
Map - A Epetra_LocalMap, Epetra_Map or Epetra_BlockMap.
|
||||
\param In
|
||||
Source - An existing fully constructed Epetra_MultiVector.
|
||||
\param In
|
||||
Index - Index of vector to access.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
|
||||
See Detailed Description section for further discussion.
|
||||
*/
|
||||
Epetra_Vector(Epetra_DataAccess CV, const Epetra_MultiVector& Source, int Index);
|
||||
|
||||
//! Epetra_Vector destructor.
|
||||
virtual ~Epetra_Vector ();
|
||||
//@}
|
||||
|
||||
//! @name Post-construction modification routines
|
||||
//@{
|
||||
|
||||
//! Replace values in a vector with a given indexed list of values, indices are in global index space.
|
||||
/*!
|
||||
Replace the Indices[i] entry in the \e this object with Values[i], for i=0; i<NumEntries. The indices
|
||||
are in global index space.
|
||||
|
||||
\param In
|
||||
NumEntries - Number of vector entries to modify.
|
||||
\param In
|
||||
Values - Values which will replace existing values in vector, of length NumEntries.
|
||||
\param In
|
||||
Indices - Indices in global index space corresponding to Values.
|
||||
|
||||
\return Integer error code, set to 0 if successful, set to 1 if one or more indices are not associated with calling processor.
|
||||
*/
|
||||
int ReplaceGlobalValues(int NumEntries, double * Values, int * Indices);
|
||||
|
||||
//! Replace values in a vector with a given indexed list of values, indices are in local index space.
|
||||
/*!
|
||||
Replace the Indices[i] entry in the \e this object with Values[i], for i=0; i<NumEntries. The indices
|
||||
are in local index space.
|
||||
|
||||
\param In
|
||||
NumEntries - Number of vector entries to modify.
|
||||
\param In
|
||||
Values - Values which will replace existing values in vector, of length NumEntries.
|
||||
\param In
|
||||
Indices - Indices in local index space corresponding to Values.
|
||||
|
||||
\return Integer error code, set to 0 if successful, set to 1 if one or more indices are not associated with calling processor.
|
||||
*/
|
||||
int ReplaceMyValues(int NumEntries, double * Values, int * Indices);
|
||||
|
||||
//! Sum values into a vector with a given indexed list of values, indices are in global index space.
|
||||
/*!
|
||||
Sum Values[i] into the Indices[i] entry in the \e this object, for i=0; i<NumEntries. The indices
|
||||
are in global index space.
|
||||
|
||||
\param In
|
||||
NumEntries - Number of vector entries to modify.
|
||||
\param In
|
||||
Values - Values which will replace existing values in vector, of length NumEntries.
|
||||
\param In
|
||||
Indices - Indices in global index space corresponding to Values.
|
||||
|
||||
\return Integer error code, set to 0 if successful, set to 1 if one or more indices are not associated with calling processor.
|
||||
*/
|
||||
int SumIntoGlobalValues(int NumEntries, double * Values, int * Indices);
|
||||
|
||||
//! Sum values into a vector with a given indexed list of values, indices are in local index space.
|
||||
/*!
|
||||
Sum Values[i] into the Indices[i] entry in the \e this object, for i=0; i<NumEntries. The indices
|
||||
are in local index space.
|
||||
|
||||
\param In
|
||||
NumEntries - Number of vector entries to modify.
|
||||
\param In
|
||||
Values - Values which will replace existing values in vector, of length NumEntries.
|
||||
\param In
|
||||
Indices - Indices in local index space corresponding to Values.
|
||||
|
||||
\return Integer error code, set to 0 if successful, set to 1 if one or more indices are not associated with calling processor.
|
||||
*/
|
||||
int SumIntoMyValues(int NumEntries, double * Values, int * Indices);
|
||||
|
||||
// Blockmap Versions
|
||||
|
||||
//! Replace values in a vector with a given indexed list of values at the specified BlockOffset, indices are in global index space.
|
||||
/*!
|
||||
Replace the Indices[i] entry in the \e this object with Values[i], for i=0; i<NumEntries. The indices
|
||||
are in global index space. This method is intended for vector that are defined using block maps. In this situation,
|
||||
an index value is associated with one or more vector entries, depending on the element size of the given index.
|
||||
The BlockOffset argument indicates which vector entry to modify as an offset from the first vector entry associated with
|
||||
the given index. The offset is used for each entry in the input list.
|
||||
|
||||
\param In
|
||||
NumEntries - Number of vector entries to modify.
|
||||
\param In
|
||||
BlockOffset - Offset from the first vector entry associated with each of the given indices.
|
||||
\param In
|
||||
Values - Values which will replace existing values in vector, of length NumEntries.
|
||||
\param In
|
||||
Indices - Indices in global index space corresponding to Values.
|
||||
|
||||
\return Integer error code, set to 0 if successful, set to 1 if one or more indices are not associated with calling processor.
|
||||
*/
|
||||
int ReplaceGlobalValues(int NumEntries, int BlockOffset, double * Values, int * Indices);
|
||||
|
||||
//! Replace values in a vector with a given indexed list of values at the specified BlockOffset, indices are in local index space.
|
||||
/*!
|
||||
Replace the (Indices[i], BlockOffset) entry in the \e this object with Values[i], for i=0; i<NumEntries. The indices
|
||||
are in local index space. This method is intended for vector that are defined using block maps. In this situation,
|
||||
an index value is associated with one or more vector entries, depending on the element size of the given index.
|
||||
The BlockOffset argument indicates which vector entry to modify as an offset from the first vector entry associated with
|
||||
the given index. The offset is used for each entry in the input list.
|
||||
|
||||
\param In
|
||||
NumEntries - Number of vector entries to modify.
|
||||
\param In
|
||||
BlockOffset - Offset from the first vector entry associated with each of the given indices.
|
||||
\param In
|
||||
Values - Values which will replace existing values in vector, of length NumEntries.
|
||||
\param In
|
||||
Indices - Indices in local index space corresponding to Values.
|
||||
|
||||
\return Integer error code, set to 0 if successful, set to 1 if one or more indices are not associated with calling processor.
|
||||
*/
|
||||
int ReplaceMyValues(int NumEntries, int BlockOffset, double * Values, int * Indices);
|
||||
|
||||
//! Sum values into a vector with a given indexed list of values at the specified BlockOffset, indices are in global index space.
|
||||
/*!
|
||||
Sum Values[i] into the Indices[i] entry in the \e this object, for i=0; i<NumEntries. The indices
|
||||
are in global index space. This method is intended for vector that are defined using block maps. In this situation,
|
||||
an index value is associated with one or more vector entries, depending on the element size of the given index.
|
||||
The BlockOffset argument indicates which vector entry to modify as an offset from the first vector entry associated with
|
||||
the given index. The offset is used for each entry in the input list.
|
||||
|
||||
\param In
|
||||
NumEntries - Number of vector entries to modify.
|
||||
\param In
|
||||
BlockOffset - Offset from the first vector entry associated with each of the given indices.
|
||||
\param In
|
||||
Values - Values which will replace existing values in vector, of length NumEntries.
|
||||
\param In
|
||||
Indices - Indices in global index space corresponding to Values.
|
||||
|
||||
\return Integer error code, set to 0 if successful, set to 1 if one or more indices are not associated with calling processor.
|
||||
*/
|
||||
int SumIntoGlobalValues(int NumEntries, int BlockOffset, double * Values, int * Indices);
|
||||
|
||||
//! Sum values into a vector with a given indexed list of values at the specified BlockOffset, indices are in local index space.
|
||||
/*!
|
||||
Sum Values[i] into the Indices[i] entry in the \e this object, for i=0; i<NumEntries. The indices
|
||||
are in local index space. This method is intended for vector that are defined using block maps. In this situation,
|
||||
an index value is associated with one or more vector entries, depending on the element size of the given index.
|
||||
The BlockOffset argument indicates which vector entry to modify as an offset from the first vector entry associated with
|
||||
the given index. The offset is used for each entry in the input list.
|
||||
|
||||
\param In
|
||||
NumEntries - Number of vector entries to modify.
|
||||
\param In
|
||||
BlockOffset - Offset from the first vector entry associated with each of the given indices.
|
||||
\param In
|
||||
Values - Values which will replace existing values in vector, of length NumEntries.
|
||||
\param In
|
||||
Indices - Indices in local index space corresponding to Values.
|
||||
|
||||
\return Integer error code, set to 0 if successful, set to 1 if one or more indices are not associated with calling processor.
|
||||
*/
|
||||
int SumIntoMyValues(int NumEntries, int BlockOffset, double * Values, int * Indices);
|
||||
//@}
|
||||
|
||||
//! @name Extraction methods
|
||||
//@{
|
||||
|
||||
//Let the compiler know we intend to overload the base-class ExtractCopy
|
||||
//function, rather than hide it.
|
||||
using Epetra_MultiVector::ExtractCopy;
|
||||
|
||||
//! Put vector values into user-provided array.
|
||||
/*!
|
||||
\param Out
|
||||
V - Pointer to memory space that will contain the vector values.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int ExtractCopy(double *V) const;
|
||||
|
||||
//Let the compiler know we intend to overload the base-class ExtractView
|
||||
//function, rather than hide it.
|
||||
using Epetra_MultiVector::ExtractView;
|
||||
|
||||
//! Set user-provided address of V.
|
||||
/*!
|
||||
\param Out
|
||||
V - Address of a pointer to that will be set to point to the values of the vector.
|
||||
|
||||
\return Integer error code, set to 0 if successful.
|
||||
*/
|
||||
int ExtractView(double **V) const;
|
||||
//@}
|
||||
|
||||
//! @name Overloaded operators
|
||||
//@{
|
||||
|
||||
//! Element access function.
|
||||
/*!
|
||||
\return V[Index].
|
||||
*/
|
||||
double& operator [] (int index)
|
||||
{
|
||||
#ifdef HAVE_EPETRA_ARRAY_BOUNDS_CHECK
|
||||
EPETRA_TEST_FOR_EXCEPTION(
|
||||
!( 0 <= index && index < this->MyLength() ), -99,
|
||||
"Epetra_Vector::operator[](int): "
|
||||
"The index = " << index << " does not fall in the range"
|
||||
"[0,"<<this->MyLength()<<")"
|
||||
);
|
||||
#endif
|
||||
return Values_[index];
|
||||
}
|
||||
//! Element access function.
|
||||
/*!
|
||||
\return V[Index].
|
||||
*/
|
||||
const double& operator [] (int index) const
|
||||
{
|
||||
#ifdef HAVE_EPETRA_ARRAY_BOUNDS_CHECK
|
||||
EPETRA_TEST_FOR_EXCEPTION(
|
||||
!( 0 <= index && index < this->MyLength() ), -99,
|
||||
"Epetra_Vector::operator[](int) const: "
|
||||
"The index = " << index << " does not fall in the range"
|
||||
"[0,"<<this->MyLength()<<")"
|
||||
);
|
||||
#endif
|
||||
return Values_[index];
|
||||
}
|
||||
//@}
|
||||
|
||||
//! @name Expert-only unsupported methods
|
||||
//@{
|
||||
|
||||
//Let the compiler know we intend to overload the base-class ResetView
|
||||
//function, rather than hide it.
|
||||
using Epetra_MultiVector::ResetView;
|
||||
|
||||
//! Reset the view of an existing vector to point to new user data.
|
||||
/*! Allows the (very) light-weight replacement of multivector values for an
|
||||
existing vector that was constructed using an Epetra_DataAccess mode of View.
|
||||
No checking is performed to see if the values passed in contain valid
|
||||
data. It is assumed that the user has verified the integrity of data before calling
|
||||
this method. This method is useful for situations where a vector is needed
|
||||
for use with an Epetra operator or matrix and the user is not passing in a multivector,
|
||||
or the multivector is being passed in with another map that is not exactly compatible
|
||||
with the operator, but has the correct number of entries.
|
||||
|
||||
This method is used by AztecOO and Ifpack in the matvec and solve methods to improve
|
||||
performance and reduce repeated calls to constructors and destructors.
|
||||
|
||||
@param Values Vector data.
|
||||
|
||||
\return Integer error code, set to 0 if successful, -1 if the multivector was not created as a View.
|
||||
|
||||
\warning This method is extremely dangerous and should only be used by experts.
|
||||
*/
|
||||
|
||||
int ResetView(double * Values) {EPETRA_CHK_ERR(Epetra_MultiVector::ResetView(&Values)); return(0);};
|
||||
//@}
|
||||
private:
|
||||
|
||||
int ChangeValues(int NumEntries, int BlockOffset, double * Values, int * Indices, bool IndicesGlobal, bool SumInto);
|
||||
|
||||
};
|
||||
|
||||
#endif /* EPETRA_VECTOR_H */
|
||||
@@ -0,0 +1,33 @@
|
||||
// @HEADER
|
||||
// ***********************************************************************
|
||||
//
|
||||
// Epetra: Linear Algebra Services Package
|
||||
// Copyright (2001) Sandia Corporation
|
||||
//
|
||||
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
||||
// license for use of this work by or on behalf of the U.S. Government.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
|
||||
//
|
||||
// ***********************************************************************
|
||||
// @HEADER
|
||||
|
||||
#include "Epetra_ConfigDefs.h"
|
||||
|
||||
string Epetra_Version() {
|
||||
return("Epetra Version 3.6 - 08/17/2007");
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user