162 Time_.ResetStartTime();
164 if (A_.Comm().NumProc() != 1) {
165 cout <<
" There are too many processors !!! " << endl;
166 cerr <<
"Ifpack_IKLU can be used with Comm().NumProc() == 1" << endl;
167 cerr <<
"only. This class is a subdomain solver for Ifpack_AdditiveSchwarz," << endl;
168 cerr <<
"and it is currently not meant to be used otherwise." << endl;
180 std::vector<int> RowIndices(Length);
181 std::vector<double> RowValues(Length);
185 csrA_ = csr_spalloc( NumMyRows_, NumMyRows_, NumMyNonzeros_, 1, 0 );
190 for (
int i = 0; i < NumMyRows_; ++i ) {
192 IFPACK_CHK_ERR(A_.ExtractMyRowCopy(i,Length,RowNnz,
193 &RowValues[0],&RowIndices[0]));
194 for (
int j = 0 ; j < RowNnz ; ++j) {
195 csrA_->j[count++] = RowIndices[j];
198 csrA_->p[i+1] = csrA_->p[i] + RowNnz;
203 cssS_ = csr_sqr( order, csrA_ );
204 for (
int i = 0; i < NumMyRows_; ++i ) {
205 cout <<
"AMD Perm (from inside KLU) [" << i <<
"] = " << cssS_->q[i] << endl;
209 IsInitialized_ =
true;
211 InitializeTime_ += Time_.ElapsedTime();
236 Time_.ResetStartTime();
239 NumMyRows_ = A_.NumMyRows();
240 int Length = A_.MaxNumEntries();
242 bool distributed = (
Comm().
NumProc() > 1)?
true:
false;
243#if !defined(EPETRA_NO_32BIT_GLOBAL_INDICES) || !defined(EPETRA_NO_64BIT_GLOBAL_INDICES)
247 SerialMap_ = rcp(
new Epetra_Map(NumMyRows_, 0, *SerialComm_));
248 assert (SerialComm_.get() != 0);
249 assert (SerialMap_.get() != 0);
252 SerialMap_ = rcp(
const_cast<Epetra_Map*
>(&A_.RowMatrixRowMap()),
false);
256 std::vector<int> RowIndices(Length);
257 std::vector<double> RowValues(Length);
261 for (
int i = 0; i < NumMyRows_; ++i ) {
263 IFPACK_CHK_ERR(A_.ExtractMyRowCopy(i,Length,RowNnz,
264 &RowValues[0],&RowIndices[0]));
266 if (RowNnz != (csrA_->p[i+1]-csrA_->p[i])) {
267 cout <<
"The number of nonzeros for this row does not math the expected number of nonzeros!!!" << endl;
269 for (
int j = 0 ; j < RowNnz ; ++j) {
271 csrA_->x[count++] = RowValues[j];
278 csrnN_ = csr_lu( &*csrA_, &*cssS_, tol );
281 csr* L_tmp = csrnN_->L;
282 csr* U_tmp = csrnN_->U;
283 std::vector<int> numEntriesL( NumMyRows_ ), numEntriesU( NumMyRows_ );
284 for (
int i=0; i < NumMyRows_; ++i) {
285 numEntriesL[i] = ( L_tmp->p[i+1] - L_tmp->p[i] );
286 numEntriesU[i] = ( U_tmp->p[i+1] - U_tmp->p[i] );
292#ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
293 if(SerialMap_->GlobalIndicesInt()) {
294 for (
int i=0; i < NumMyRows_; ++i) {
295 L_->InsertGlobalValues( i, numEntriesL[i], &(L_tmp->x[L_tmp->p[i]]), &(L_tmp->j[L_tmp->p[i]]) );
296 U_->InsertGlobalValues( i, numEntriesU[i], &(U_tmp->x[U_tmp->p[i]]), &(U_tmp->j[U_tmp->p[i]]) );
301#ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
302 if(SerialMap_->GlobalIndicesLongLong()) {
304 const int MaxNumEntries_L_U = std::max(L_->MaxNumEntries(), U_->MaxNumEntries());
305 std::vector<long long> entries(MaxNumEntries_L_U);
307 for (
int i=0; i < NumMyRows_; ++i) {
308 std::copy(&(L_tmp->j[L_tmp->p[i]]), &(L_tmp->j[L_tmp->p[i]]) + numEntriesL[i], entries.begin());
309 L_->InsertGlobalValues( i, numEntriesL[i], &(L_tmp->x[L_tmp->p[i]]), &(entries[0]) );
311 std::copy(&(U_tmp->j[U_tmp->p[i]]), &(U_tmp->j[U_tmp->p[i]]) + numEntriesU[i], entries.begin());
312 U_->InsertGlobalValues( i, numEntriesU[i], &(U_tmp->x[U_tmp->p[i]]), &(entries[0]) );
317 throw "Ifpack_IKLU::Compute: GlobalIndices type unknown for SerialMap_";
319 IFPACK_CHK_ERR(L_->FillComplete());
320 IFPACK_CHK_ERR(U_->FillComplete());
322 long long MyNonzeros = L_->NumGlobalNonzeros64() + U_->NumGlobalNonzeros64();
323 Comm().
SumAll(&MyNonzeros, &GlobalNonzeros_, 1);
328 ComputeTime_ += Time_.ElapsedTime();
344 Time_.ResetStartTime();
352 std::vector<int> invq( NumMyRows_ );
354 for (
int i=0; i<NumMyRows_; ++i ) {
355 csrnN_->perm[ csrnN_->pinv[i] ] = i;
356 invq[ cssS_->q[i] ] = i;
362 for (
int i=0; i<NumMyRows_; ++i) {
364 Xcopy->ReplaceMyValue( invq[i], j, (*X(j))[i] );
371 IFPACK_CHK_ERR(L_->Solve(
false,
false,
false,*Xcopy,*Ytemp));
372 IFPACK_CHK_ERR(U_->Solve(
true,
false,
false,*Ytemp,*Ytemp));
377 IFPACK_CHK_ERR(U_->Solve(
true,
true,
false,*Xcopy,*Ytemp));
378 IFPACK_CHK_ERR(L_->Solve(
false,
true,
false,*Ytemp,*Ytemp));
382 for (
int i=0; i<NumMyRows_; ++i) {
389#ifdef IFPACK_FLOPCOUNTERS
390 ApplyInverseFlops_ += X.
NumVectors() * 2 * GlobalNonzeros_;
392 ApplyInverseTime_ += Time_.ElapsedTime();
427 if (!
Comm().MyPID()) {
429 os <<
"================================================================================" << endl;
430 os <<
"Ifpack_IKLU: " <<
Label() << endl << endl;
431 os <<
"Level-of-fill = " << LevelOfFill() << endl;
434 os <<
"Relax value = " <<
RelaxValue() << endl;
435 os <<
"Condition number estimate = " <<
Condest() << endl;
436 os <<
"Global number of rows = " << A_.NumGlobalRows64() << endl;
438 os <<
"Number of nonzeros in A = " << A_.NumGlobalNonzeros64() << endl;
439 os <<
"Number of nonzeros in L + U = " << NumGlobalNonzeros64()
440 <<
" ( = " << 100.0 * NumGlobalNonzeros64() / A_.NumGlobalNonzeros64()
441 <<
" % of A)" << endl;
442 os <<
"nonzeros / rows = "
443 << 1.0 * NumGlobalNonzeros64() / U_->NumGlobalRows64() << endl;
446 os <<
"Phase # calls Total Time (s) Total MFlops MFlops/s" << endl;
447 os <<
"----- ------- -------------- ------------ --------" << endl;
450 <<
" 0.0 0.0" << endl;
451 os <<
"Compute() " << std::setw(5) <<
NumCompute()
457 os <<
" " << std::setw(15) << 0.0 << endl;
464 os <<
" " << std::setw(15) << 0.0 << endl;
465 os <<
"================================================================================" << endl;