//============================================================================= // This function finds Y such that LDU Y = X or U(trans) D L(trans) Y = X for multiple RHS int Ifpack2_ILU::Solve(bool Trans, const Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& X, Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& Y) const { #ifdef ENABLE_IFPACK2_ILU_TEUCHOS_TIMERS TEUCHOS_FUNC_TIME_MONITOR("Ifpack2_ILU::ApplyInverse - Solve"); #endif // in this function the overlap is always zero bool Upper = true; bool Lower = false; bool UnitDiagonal = true; if (!Trans) { IFPACK2_CHK_ERR(L_->Solve(Lower, Trans, UnitDiagonal, X, Y)); // y = D*y (D_ has inverse of diagonal) IFPACK2_CHK_ERR(Y.Multiply(1.0, *D_, Y, 0.0)); // Solve Uy = y IFPACK2_CHK_ERR(U_->Solve(Upper, Trans, UnitDiagonal, Y, Y)); } else { // Solve Uy = y IFPACK2_CHK_ERR(U_->Solve(Upper, Trans, UnitDiagonal, X, Y)); // y = D*y (D_ has inverse of diagonal) IFPACK2_CHK_ERR(Y.Multiply(1.0, *D_, Y, 0.0)); IFPACK2_CHK_ERR(L_->Solve(Lower, Trans, UnitDiagonal, Y, Y)); } return(0); }
//============================================================================== int Ifpack2_LocalFilter::Apply(const Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& X, Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& Y) const { // skip expensive checks, I suppose input data are ok Y.PutScalar(0.0); int NumVectors = Y.NumVectors(); double** X_ptr; double** Y_ptr; X.ExtractView(&X_ptr); Y.ExtractView(&Y_ptr); for (int i = 0 ; i < NumRows_ ; ++i) { int Nnz; int ierr = Matrix_->ExtractMyRowCopy(i,MaxNumEntriesA_,Nnz,&Values_[0], &Indices_[0]); IFPACK2_CHK_ERR(ierr); for (int j = 0 ; j < Nnz ; ++j) { if (Indices_[j] < NumRows_ ) { for (int k = 0 ; k < NumVectors ; ++k) Y_ptr[k][i] += Values_[j] * X_ptr[k][Indices_[j]]; } } } return(0); }
//============================================================================== int Ifpack2_Amesos:: ApplyInverse(const Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& X, Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& Y) const { if (IsComputed() == false) IFPACK2_CHK_ERR(-1); if (X.NumVectors() != Y.NumVectors()) IFPACK2_CHK_ERR(-1); // wrong input Time_->ResetStartTime(); // AztecOO gives X and Y pointing to the same memory location, // need to create an auxiliary vector, Xcopy Teuchos::RCP<const Tpetra_MultiVector> Xcopy; if (X.Pointers()[0] == Y.Pointers()[0]) Xcopy = Teuchos::rcp( new Tpetra_MultiVector(X) ); else Xcopy = Teuchos::rcp( &X, false ); Problem_->SetLHS(&Y); Problem_->SetRHS((Tpetra_MultiVector*)Xcopy.get()); IFPACK2_CHK_ERR(Solver_->Solve()); ++NumApplyInverse_; ApplyInverseTime_ += Time_->ElapsedTime(); return(0); }
//============================================================================== int Ifpack2_ReorderFilter:: Multiply(bool TransA, const Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& X, Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& Y) const { // need two additional vectors Tpetra_MultiVector Xtilde(X.Map(),X.NumVectors()); Tpetra_MultiVector Ytilde(Y.Map(),Y.NumVectors()); // bring X back to original ordering Reordering_->Pinv(X,Xtilde); // apply original matrix IFPACK2_CHK_ERR(Matrix()->Multiply(TransA,Xtilde,Ytilde)); // now reorder result Reordering_->P(Ytilde,Y); return(0); }
void Albany::IossSTKMeshStruct::readScalarFileSerial (std::string& fname, Tpetra_MultiVector& content, const Teuchos::RCP<const Teuchos_Comm>& comm) const { GO numNodes; Teuchos::ArrayRCP<ST> content_nonConstView = content.get1dViewNonConst(); if (comm->getRank() == 0) { std::ifstream ifile; ifile.open(fname.c_str()); if (ifile.is_open()) { ifile >> numNodes; TEUCHOS_TEST_FOR_EXCEPTION (numNodes != content.getLocalLength(), Teuchos::Exceptions::InvalidParameterValue, std::endl << "Error in ExtrudedSTKMeshStruct: Number of nodes in file " << fname << " (" << numNodes << ") is different from the number expected (" << content.getLocalLength() << ")" << std::endl); for (GO i = 0; i < numNodes; i++) ifile >> content_nonConstView[i]; ifile.close(); }
//============================================================================== int Ifpack2_AMDReordering::Pinv(const Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& Xorig, Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& X) const { int NumVectors = X.NumVectors(); for (int j = 0 ; j < NumVectors ; ++j) { for (int i = 0 ; i < NumMyRows_ ; ++i) { int np = Reorder_[i]; X[j][i] = Xorig[j][np]; } } return(0); }
void Albany::MultiSTKFieldContainer<Interleaved>::saveSolnMultiVector(const Tpetra_MultiVector& solnT, stk::mesh::Selector& sel, const Teuchos::RCP<const Tpetra_Map>& node_mapT) { typedef typename AbstractSTKFieldContainer::VectorFieldType VFT; typedef typename AbstractSTKFieldContainer::ScalarFieldType SFT; // Iterate over the on-processor nodes by getting node buckets and iterating over each bucket. stk::mesh::BucketVector const& all_elements = this->bulkData->get_buckets(stk::topology::NODE_RANK, sel); this->numNodes = node_mapT->getNodeNumElements(); // Needed for the getDOF function to work correctly // This is either numOwnedNodes or numOverlapNodes, depending on // which map is passed in for(stk::mesh::BucketVector::const_iterator it = all_elements.begin() ; it != all_elements.end() ; ++it) { const stk::mesh::Bucket& bucket = **it; for(int vector_component = 0; vector_component < solnT.getNumVectors(); vector_component++){ int offset = 0; for(int k = 0; k < sol_index[vector_component].size(); k++) { if(sol_index[vector_component][k] == 1) { // Scalar SFT* field = this->metaData->template get_field<SFT>( stk::topology::NODE_RANK, sol_vector_name[vector_component][k]); this->saveMultiVectorHelper(solnT, field, node_mapT, bucket, vector_component, offset); } else { VFT* field = this->metaData->template get_field<VFT>( stk::topology::NODE_RANK, sol_vector_name[vector_component][k]); this->saveMultiVectorHelper(solnT, field, node_mapT, bucket, vector_component, offset); } offset += sol_index[vector_component][k]; } } } }
// Returns the result of a Tpetra_Operator applied to a // Tpetra_MultiVector X in Y. void LCM:: Schwarz_BoundaryJacobian:: apply( Tpetra_MultiVector const & X, Tpetra_MultiVector & Y, Teuchos::ETransp mode, ST alpha, ST beta) const { auto const zero = Teuchos::ScalarTraits<ST>::zero(); Y.putScalar(zero); }
//============================================================================= // This function finds X such that LDU Y = X or U(trans) D L(trans) Y = X for multiple RHS int Ifpack2_ILU::ApplyInverse(const Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& X, Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& Y) const { #ifdef ENABLE_IFPACK2_ILU_TEUCHOS_TIMERS TEUCHOS_FUNC_TIME_MONITOR("Ifpack2_ILU::ApplyInverse"); #endif if (!IsComputed()) IFPACK2_CHK_ERR(-3); if (X.NumVectors() != Y.NumVectors()) IFPACK2_CHK_ERR(-2); Time_.ResetStartTime(); // AztecOO gives X and Y pointing to the same memory location, // need to create an auxiliary vector, Xcopy Teuchos::RCP< const Tpetra_MultiVector > Xcopy; if (X.Pointers()[0] == Y.Pointers()[0]) Xcopy = Teuchos::rcp( new Tpetra_MultiVector(X) ); else Xcopy = Teuchos::rcp( &X, false ); IFPACK2_CHK_ERR(Solve(Ifpack2_ILU::UseTranspose(), *Xcopy, Y)); // approx is the number of nonzeros in L and U ApplyInverseFlops_ += X.NumVectors() * 4 * (L_->NumGlobalNonzeros() + U_->NumGlobalNonzeros()); ++NumApplyInverse_; ApplyInverseTime_ += Time_.ElapsedTime(); return(0); }
void Albany::OrdinarySTKFieldContainer<Interleaved>::fillSolnMultiVector(Tpetra_MultiVector &solnT, stk::mesh::Selector &sel, const Teuchos::RCP<const Tpetra_Map>& node_mapT){ typedef typename AbstractSTKFieldContainer::VectorFieldType VFT; // Iterate over the on-processor nodes by getting node buckets and iterating over each bucket. stk::mesh::BucketVector const& all_elements = this->bulkData->get_buckets(stk::topology::NODE_RANK, sel); this->numNodes = node_mapT->getNodeNumElements(); // Needed for the getDOF function to work correctly // This is either numOwnedNodes or numOverlapNodes, depending on // which map is passed in for(stk::mesh::BucketVector::const_iterator it = all_elements.begin() ; it != all_elements.end() ; ++it) { const stk::mesh::Bucket& bucket = **it; for(int vector_component = 0; vector_component < solnT.getNumVectors(); vector_component++) this->fillMultiVectorHelper(solnT, solution_field[vector_component], node_mapT, bucket, vector_component, 0); } }
//============================================================================= // This function finds X such that LDU Y = X or U(trans) D L(trans) Y = X for multiple RHS int Ifpack2_ILU::Multiply(bool Trans, const Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& X, Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& Y) const { #ifdef ENABLE_IFPACK2_ILU_TEUCHOS_TIMERS TEUCHOS_FUNC_TIME_MONITOR("Ifpack2_ILU::Multiply"); #endif if (!IsComputed()) IFPACK2_CHK_ERR(-3); if (!Trans) { IFPACK2_CHK_ERR(U_->Multiply(Trans, X, Y)); // Y1 = Y1 + X1 (account for implicit unit diagonal) IFPACK2_CHK_ERR(Y.Update(1.0, X, 1.0)); // y = D*y (D_ has inverse of diagonal) IFPACK2_CHK_ERR(Y.ReciprocalMultiply(1.0, *D_, Y, 0.0)); Tpetra_MultiVector Y1temp(Y); // Need a temp copy of Y1 IFPACK2_CHK_ERR(L_->Multiply(Trans, Y1temp, Y)); // (account for implicit unit diagonal) IFPACK2_CHK_ERR(Y.Update(1.0, Y1temp, 1.0)); } else { IFPACK2_CHK_ERR(L_->Multiply(Trans, X, Y)); // Y1 = Y1 + X1 (account for implicit unit diagonal) IFPACK2_CHK_ERR(Y.Update(1.0, X, 1.0)); // y = D*y (D_ has inverse of diagonal) IFPACK2_CHK_ERR(Y.ReciprocalMultiply(1.0, *D_, Y, 0.0)); Tpetra_MultiVector Y1temp(Y); // Need a temp copy of Y1 IFPACK2_CHK_ERR(U_->Multiply(Trans, Y1temp, Y)); // (account for implicit unit diagonal) IFPACK2_CHK_ERR(Y.Update(1.0, Y1temp, 1.0)); } return(0); }
void Albany::SolutionResponseFunction:: cullSolutionT(const Tpetra_MultiVector& xT, Tpetra_MultiVector& x_culledT) const { x_culledT.doImport(xT, *importerT, Tpetra::INSERT); }
/* //old Apply (no communication) int Ifpack2_NodeFilter::Apply(const Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& X, Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& Y) const { // skip expensive checks, I suppose input data are ok Y.PutScalar(0.0); int NumVectors = Y.NumVectors(); double** X_ptr; double** Y_ptr; X.ExtractView(&X_ptr); Y.ExtractView(&Y_ptr); for (int i = 0 ; i < NumRows_ ; ++i) { int Nnz; int ierr = Matrix_->ExtractMyRowCopy(i,MaxNumEntriesA_,Nnz,&Values_[0], &Indices_[0]); IFPACK2_CHK_ERR(ierr); for (int j = 0 ; j < Nnz ; ++j) { if (Indices_[j] < NumRows_ ) { for (int k = 0 ; k < NumVectors ; ++k) Y_ptr[k][i] += Values_[j] * X_ptr[k][Indices_[j]]; } } } return(0); } */ int Ifpack2_NodeFilter::Apply(const Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& X, Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& Y) const { // // This function forms the product Y = A * X. // int NumEntries; int NumVectors = X.NumVectors(); if (NumVectors!=Y.NumVectors()) { EPETRA_CHK_ERR(-1); // Need same number of vectors in each MV } // Make sure Import and Export Vectors are compatible UpdateImportVector(NumVectors); UpdateExportVector(NumVectors); double ** Xp = (double**) X.Pointers(); double ** Yp = (double**) Y.Pointers(); // If we have a non-trivial importer, we must import elements that are permuted or are on other processors if (Importer()!=0) { EPETRA_CHK_ERR(ImportVector_->Import(X, *Importer(), Insert)); Xp = (double**)ImportVector_->Pointers(); } // If we have a non-trivial exporter, we must export elements that are permuted or belong to other processors if (Exporter()!=0) { Yp = (double**)ExportVector_->Pointers(); } // Do actual computation assert(ovA_!=0); int *MyRows; double *MyValues; int *MyIndices; if(Acrs_){ // A rows - CrsMatrix Case IFPACK2_CHK_ERR(Acrs_->ExtractCrsDataPointers(MyRows,MyIndices,MyValues)); //special case NumVectors==1 if (NumVectors==1) { for(int i=0;i<NumMyRowsA_;i++) { int LocRow=Ar_LIDMap_[i]; double sum = 0.0; for(int j = MyRows[i]; j < MyRows[i+1]; j++) sum += MyValues[j]*Xp[0][Ac_LIDMap_[MyIndices[j]]]; Yp[0][LocRow] = sum; } } else { for(int i=0;i<NumMyRowsA_;i++) { int LocRow=Ar_LIDMap_[i]; for (int k=0; k<NumVectors; k++) { double sum = 0.0; for(int j = MyRows[i]; j < MyRows[i+1]; j++) sum += MyValues[j]*Xp[k][Ac_LIDMap_[MyIndices[j]]]; Yp[k][LocRow] = sum; } } } } else{ // A rows - RowMatrix Case MyValues=&Values_[0]; MyIndices=&Indices_[0]; for(int i=0;i<NumMyRowsA_;i++) { ovA_->A().ExtractMyRowCopy(i,MaxNumEntries_,NumEntries,MyValues,MyIndices); int LocRow=Ar_LIDMap_[i]; for (int k=0; k<NumVectors; k++) { double sum = 0.0; for(int j = 0; j < NumEntries; j++) sum += MyValues[j]*Xp[k][Ac_LIDMap_[MyIndices[j]]]; Yp[k][LocRow] = sum; } } } // B rows, always CrsMatrix IFPACK2_CHK_ERR(ovA_->B().ExtractCrsDataPointers(MyRows,MyIndices,MyValues)); //special case NumVectors==1 if (NumVectors==1) { for(int i=0;i<NumMyRowsB_;i++) { int LocRow=Br_LIDMap_[i]; double sum = 0.0; for(int j = MyRows[i]; j < MyRows[i+1]; j++) sum += MyValues[j]*Xp[0][Bc_LIDMap_[MyIndices[j]]]; Yp[0][LocRow] = sum; } } else { for(int i=0;i<NumMyRowsB_;i++) { int LocRow=Br_LIDMap_[i]; for (int k=0; k<NumVectors; k++) { //FIXME optimization, check for NumVectors=1 double sum = 0.0; for(int j = MyRows[i]; j < MyRows[i+1]; j++) sum += MyValues[j]*Xp[k][Bc_LIDMap_[MyIndices[j]]]; Yp[k][LocRow] = sum; } } } if (Exporter()!=0) { Y.PutScalar(0.0); // Make sure target is zero Y.Export(*ExportVector_, *Exporter(), Add); // Fill Y with Values from export vector } // Handle case of rangemap being a local replicated map if (!OperatorRangeMap().DistributedGlobal() && Comm().NumProc()>1) EPETRA_CHK_ERR(Y.Reduce()); return(0); } //Apply