30 #include "Epetra_Map.h"
31 #include "Epetra_Import.h"
32 #include "Epetra_CrsMatrix.h"
33 #include "Epetra_Vector.h"
34 #include "Epetra_Util.h"
39 #include "trilinos_klu_decl.h"
47 template<
class T,
class DeleteFunctor>
48 class DeallocFunctorDeleteWithCommon
51 DeallocFunctorDeleteWithCommon(
52 const RCP<trilinos_klu_common> &common
53 ,DeleteFunctor deleteFunctor
55 : common_(common), deleteFunctor_(deleteFunctor)
59 if(ptr) deleteFunctor_(&ptr,&*common_);
62 Teuchos::RCP<trilinos_klu_common> common_;
63 DeleteFunctor deleteFunctor_;
64 DeallocFunctorDeleteWithCommon();
67 template<
class T,
class DeleteFunctor>
68 DeallocFunctorDeleteWithCommon<T,DeleteFunctor>
69 deallocFunctorDeleteWithCommon(
70 const RCP<trilinos_klu_common> &common
71 ,DeleteFunctor deleteFunctor
74 return DeallocFunctorDeleteWithCommon<T,DeleteFunctor>(common,deleteFunctor);
85 Teuchos::RCP<trilinos_klu_common>
common_;
105 Teuchos::ParameterList ParamList ;
123 std::cerr <<
" The number of non zero entries in the matrix has changed since the last call to SymbolicFactorization(). " ;
129 std::cerr <<
" The number of non zero entries in the matrix has changed since the last call to SymbolicFactorization(). " ;
145 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
147 for (
int i = 0 ; i <
SerialMap_->NumGlobalElements(); i++ ) {
154 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
156 for (
long long i = 0 ; i <
SerialMap_->NumGlobalElements64(); i++ ) {
163 throw "Amesos_Klu::ExportToSerial: ERROR, GlobalIndices type unknown.";
171 std::cerr <<
" Amesos_Klu cannot handle this matrix. " ;
173 std::cerr <<
"Unknown error" << std::endl ;
176 std::cerr <<
" Try setting the Reindex parameter to true. " << std::endl ;
177 #ifndef HAVE_AMESOS_EPETRAEXT
178 std::cerr <<
" You will need to rebuild the Amesos library with the EpetraExt library to use the reindex feature" << std::endl ;
179 std::cerr <<
" To rebuild Amesos with EpetraExt, add --enable-epetraext to your configure invocation" << std::endl ;
203 const Epetra_Map &OriginalMatrixMap =
RowMatrixA_->RowMatrixRowMap() ;
204 const Epetra_Map &OriginalDomainMap =
206 GetProblem()->GetOperator()->OperatorDomainMap();
207 const Epetra_Map &OriginalRangeMap =
209 GetProblem()->GetOperator()->OperatorRangeMap();
219 int NumMyElements_ = 0 ;
227 OriginalMatrixMap.NumGlobalElements64() )?1:0;
228 if ( ! OriginalRangeMap.SameAs( OriginalMatrixMap ) )
UseDataInPlace_ = 0 ;
229 if ( ! OriginalDomainMap.SameAs( OriginalMatrixMap ) )
UseDataInPlace_ = 0 ;
243 #ifdef HAVE_AMESOS_EPETRAEXT
244 const Epetra_Map& OriginalMap =
CrsMatrixA_->RowMap();
252 std::cerr <<
"Amesos_Klu requires EpetraExt to reindex matrices." << std::endl
253 <<
" Please rebuild with the EpetraExt library by adding --enable-epetraext to your configure invocation" << std::endl ;
271 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
272 if(OriginalMatrixMap.GlobalIndicesInt()) {
273 int indexBase = OriginalMatrixMap.IndexBase();
278 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
279 if(OriginalMatrixMap.GlobalIndicesLongLong()) {
280 long long indexBase = OriginalMatrixMap.IndexBase64();
285 throw "Amesos_Klu::CreateLocalMatrixAndExporters: Unknown Global Indices";
354 Epetra_CrsMatrix *CrsMatrix =
dynamic_cast<Epetra_CrsMatrix *
>(
SerialMatrix_);
355 bool StorageOptimized = ( CrsMatrix != 0 && CrsMatrix->StorageOptimized() );
357 if (
AddToDiag_ != 0.0 ) StorageOptimized = false ;
361 if ( ! StorageOptimized ) {
371 int NumEntriesThisRow;
373 if( StorageOptimized ) {
378 ExtractMyRowView( MyRow, NumEntriesThisRow, RowValues,
385 Ap[MyRow+1] =
Ap[MyRow] + NumEntriesThisRow ;
394 if ( firsttime && CrsMatrix == 0 ) {
400 if ( CrsMatrix != 0 ) {
402 ExtractMyRowView( MyRow, NumEntriesThisRow, RowValues,
408 ExtractMyRowCopy( MyRow, MaxNumEntries_,
418 Ap[MyRow] = Ai_index ;
419 for (
int j = 0; j < NumEntriesThisRow; j++ ) {
420 VecAi[Ai_index] = ColIndices[j] ;
422 VecAval[Ai_index] = RowValues[j] ;
423 if (ColIndices[j] == MyRow) {
429 for (
int j = 0; j < NumEntriesThisRow; j++ ) {
430 VecAval[Ai_index] = RowValues[j] ;
431 if (ColIndices[j] == MyRow) {
438 Ap[MyRow] = Ai_index ;
461 if (ParameterList.isParameter(
"TrustMe") )
462 TrustMe_ = ParameterList.get<
bool>(
"TrustMe" );
468 if (ParameterList.isSublist(
"Klu") ) {
469 Teuchos::ParameterList KluParams = ParameterList.sublist(
"Klu") ;
491 ,deallocFunctorDeleteWithCommon<trilinos_klu_symbolic>(
PrivateKluData_->common_,trilinos_klu_free_symbolic)
501 Comm().Broadcast(&symbolic_ok, 1, 0);
503 if ( !symbolic_ok ) {
532 bool factor_with_pivoting = true ;
544 int result = trilinos_klu_refactor (&
Ap[0],
Ai,
Aval,
548 const bool refactor_ok = result == 1 &&
PrivateKluData_->common_->status == TRILINOS_KLU_OK ;
559 factor_with_pivoting = false ;
564 if ( factor_with_pivoting ) {
573 rcpWithDealloc( trilinos_klu_factor(&
Ap[0],
Ai,
Aval,
575 deallocFunctorDeleteWithCommon<trilinos_klu_numeric>(
PrivateKluData_->common_,trilinos_klu_free_numeric)
586 Comm().Broadcast(&numeric_ok, 1, 0);
588 if ( ! numeric_ok ) {
609 if (
GetProblem()->GetOperator()->OperatorRangeMap().NumGlobalPoints64() !=
610 GetProblem()->GetOperator()->OperatorDomainMap().NumGlobalPoints64() ) {
700 Epetra_CrsMatrix *CrsMatrixA =
dynamic_cast<Epetra_CrsMatrix *
>(
RowMatrixA_);
701 if ( CrsMatrixA == 0 )
709 if ( CrsMatrixA == 0 ) {
739 Epetra_MultiVector* vecX = 0 ;
740 Epetra_MultiVector* vecB = 0 ;
742 #ifdef HAVE_AMESOS_EPETRAEXT
743 Teuchos::RCP<Epetra_MultiVector> vecX_rcp;
744 Teuchos::RCP<Epetra_MultiVector> vecB_rcp;
750 lose_this_ = (
int *) malloc( 300 ) ;
757 if ( lose_this_[0] == 12834 ) {
758 std::cout << __FILE__ <<
"::" << __LINE__ <<
" very unlikely to happen " << std::endl ;
768 Epetra_MultiVector* OrigVecX ;
769 Epetra_MultiVector* OrigVecB ;
783 #ifdef HAVE_AMESOS_EPETRAEXT
797 if ((vecX == 0) || (vecB == 0))
807 #ifdef HAVE_AMESOS_EPETRAEXT
808 if(vecX_rcp==Teuchos::null)
809 SerialX_ = Teuchos::rcp(vecX,
false);
813 if(vecB_rcp==Teuchos::null)
814 SerialB_ = Teuchos::rcp(vecB,
false);
818 SerialB_ = Teuchos::rcp(vecB,
false);
819 SerialX_ = Teuchos::rcp(vecX,
false);
835 Epetra_Import *UseImport;
895 Epetra_Import *UseImport;
899 vecX->Export( *
SerialX_, *UseImport, Insert ) ;
934 <<
" and " <<
numentries_ <<
" nonzeros" << std::endl;
935 std::cout <<
"Amesos_Klu : Nonzero elements per row = "
937 std::cout <<
"Amesos_Klu : Percentage of nonzero elements = "
939 std::cout <<
"Amesos_Klu : Use transpose = " <<
UseTranspose_ << std::endl;
970 std::string p =
"Amesos_Klu : ";
973 std::cout << p <<
"Time to convert matrix to Klu format = "
974 << ConTime <<
" (s)" << std::endl;
975 std::cout << p <<
"Time to redistribute matrix = "
976 << MatTime <<
" (s)" << std::endl;
977 std::cout << p <<
"Time to redistribute vectors = "
978 << VecTime <<
" (s)" << std::endl;
979 std::cout << p <<
"Number of symbolic factorizations = "
981 std::cout << p <<
"Time for sym fact = "
982 << SymTime *
NumSymbolicFact_ <<
" (s), avg = " << SymTime <<
" (s)" << std::endl;
983 std::cout << p <<
"Number of numeric factorizations = "
985 std::cout << p <<
"Time for num fact = "
986 << NumTime *
NumNumericFact_ <<
" (s), avg = " << NumTime <<
" (s)" << std::endl;
987 std::cout << p <<
"Number of solve phases = "
989 std::cout << p <<
"Time for solve = "
990 << SolTime *
NumSolve_ <<
" (s), avg = " << SolTime <<
" (s)" << std::endl;
995 std::cout << p <<
"Total time spent in Amesos = " << tt <<
" (s) " << std::endl;
996 std::cout << p <<
"Total time spent in the Amesos interface = " << OveTime <<
" (s)" << std::endl;
997 std::cout << p <<
"(the above time does not include KLU time)" << std::endl;
998 std::cout << p <<
"Amesos interface time / total time = " << OveTime / tt << std::endl;