//============================================================================= int Ifpack_CrsRiluk::Multiply(bool Trans, const Epetra_MultiVector& X, Epetra_MultiVector& Y) const { // // This function finds X such that LDU Y = X or U(trans) D L(trans) Y = X for multiple RHS // // First generate X and Y as needed for this function Teuchos::RefCountPtr<Epetra_MultiVector> X1; Teuchos::RefCountPtr<Epetra_MultiVector> Y1; EPETRA_CHK_ERR(GenerateXY(Trans, X, Y, &X1, &Y1)); #ifdef IFPACK_FLOPCOUNTERS Epetra_Flops * counter = this->GetFlopCounter(); if (counter!=0) { L_->SetFlopCounter(*counter); Y1->SetFlopCounter(*counter); U_->SetFlopCounter(*counter); } #endif if (!Trans) { EPETRA_CHK_ERR(U_->Multiply(Trans, *X1, *Y1)); // EPETRA_CHK_ERR(Y1->Update(1.0, *X1, 1.0)); // Y1 = Y1 + X1 (account for implicit unit diagonal) EPETRA_CHK_ERR(Y1->ReciprocalMultiply(1.0, *D_, *Y1, 0.0)); // y = D*y (D_ has inverse of diagonal) Epetra_MultiVector Y1temp(*Y1); // Need a temp copy of Y1 EPETRA_CHK_ERR(L_->Multiply(Trans, Y1temp, *Y1)); EPETRA_CHK_ERR(Y1->Update(1.0, Y1temp, 1.0)); // (account for implicit unit diagonal) if (IsOverlapped_) {EPETRA_CHK_ERR(Y.Export(*Y1,*L_->Exporter(), OverlapMode_));} // Export computed Y values if needed } else { EPETRA_CHK_ERR(L_->Multiply(Trans, *X1, *Y1)); EPETRA_CHK_ERR(Y1->Update(1.0, *X1, 1.0)); // Y1 = Y1 + X1 (account for implicit unit diagonal) EPETRA_CHK_ERR(Y1->ReciprocalMultiply(1.0, *D_, *Y1, 0.0)); // y = D*y (D_ has inverse of diagonal) Epetra_MultiVector Y1temp(*Y1); // Need a temp copy of Y1 EPETRA_CHK_ERR(U_->Multiply(Trans, Y1temp, *Y1)); EPETRA_CHK_ERR(Y1->Update(1.0, Y1temp, 1.0)); // (account for implicit unit diagonal) if (IsOverlapped_) {EPETRA_CHK_ERR(Y.Export(*Y1,*L_->Exporter(), OverlapMode_));} } return(0); }
//============================================================================= int Ifpack_CrsIct::Multiply(bool Trans, const Epetra_MultiVector& X, Epetra_MultiVector& Y) const { // // This function finds X such that LDU Y = X or U(trans) D L(trans) Y = X for multiple RHS // if (X.NumVectors()!=Y.NumVectors()) EPETRA_CHK_ERR(-1); // Return error: X and Y not the same size //bool Upper = true; //bool Lower = false; //bool UnitDiagonal = true; Epetra_MultiVector * X1 = (Epetra_MultiVector *) &X; Epetra_MultiVector * Y1 = (Epetra_MultiVector *) &Y; U_->Multiply(false, *X1, *Y1); Y1->Update(1.0, *X1, 1.0); // Y1 = Y1 + X1 (account for implicit unit diagonal) Y1->ReciprocalMultiply(1.0, *D_, *Y1, 0.0); // y = D*y (D_ has inverse of diagonal) Epetra_MultiVector Y1temp(*Y1); // Need a temp copy of Y1 U_->Multiply(true, Y1temp, *Y1); Y1->Update(1.0, Y1temp, 1.0); // (account for implicit unit diagonal) return(0); }