void apply (const MultiVector<S,LO,GO,Node> &X, MultiVector<S,LO,GO,Node> &Y, Teuchos::ETransp mode = Teuchos::NO_TRANS, S alpha = Teuchos::ScalarTraits<S>::one (), S beta = Teuchos::ScalarTraits<S>::zero ()) const { const size_t numVectors = X.getNumVectors (); RCP<MultiVector<S,LO,GO,Node> > mvec_inout; RCP<const MultiVector<S,LO,GO,Node> > mvec_in2; if (_importer != null) { if (_importMV != null && _importMV->getNumVectors () != numVectors) { _importMV = null; } if (_importMV == null) { _importMV = createMultiVector<S> (_importer->getTargetMap (), numVectors); } _importMV->doImport (X, *_importer, INSERT); mvec_in2 = _importMV; } else { mvec_in2 = rcpFromRef(X); } if (_exporter != null) { if (_exportMV != null && _exportMV->getNumVectors () != numVectors) { _exportMV = null; } if (_exportMV == null) { _exportMV = createMultiVector<S> (_exporter->getSourceMap (), numVectors); } mvec_inout = _exportMV; } else { mvec_inout = rcpFromRef (Y); } _kernel.setAlphaBeta (alpha, beta); // for (size_t j=0; j < numVectors; ++j) { RCP< Vector<S,LO,GO,Node> > vec_inout = mvec_inout->getVectorNonConst(j); RCP< const Vector<S,LO,GO,Node> > vec_in2 = mvec_in2->getVector(j); Tpetra::RTI::detail::binary_transform( *vec_inout, *vec_in2, _kernel ); } // export if (_exporter != null) { Y.doExport (*_exportMV, *_exporter, ADD); } }
void InsertVector(const MultiVector& partial, size_t block, MultiVector& full) const { TEUCHOS_TEST_FOR_EXCEPTION(maps_[block] == null, Xpetra::Exceptions::RuntimeError, "InsertVector: maps_[" << block << "] is null"); full.doExport(partial, *importers_[block], Xpetra::INSERT); }
void CrsMatrixSolveOp<OpScalar,MatScalar,LocalOrdinal,GlobalOrdinal,Node,LocalMatOps>::applyNonTranspose( const MultiVector<OpScalar,LocalOrdinal,GlobalOrdinal,Node> & X_in, MultiVector<OpScalar,LocalOrdinal,GlobalOrdinal,Node> & Y_in) const { // Solve U X = Y or L X = Y // X belongs to domain map, while Y belongs to range map typedef Teuchos::ScalarTraits<OpScalar> ST; using Teuchos::null; const size_t numVectors = X_in.getNumVectors(); Teuchos::RCP<const Import<LocalOrdinal,GlobalOrdinal,Node> > importer = matrix_->getGraph()->getImporter(); Teuchos::RCP<const Export<LocalOrdinal,GlobalOrdinal,Node> > exporter = matrix_->getGraph()->getExporter(); Teuchos::RCP<const MV> X; // it is okay if X and Y reference the same data, because we can perform a triangular solve in-situ. // however, we require that column access to each is strided. // set up import/export temporary multivectors if (importer != null) { if (importMV_ != null && importMV_->getNumVectors() != numVectors) importMV_ = null; if (importMV_ == null) { importMV_ = Teuchos::rcp( new MV(matrix_->getColMap(),numVectors) ); } } if (exporter != null) { if (exportMV_ != null && exportMV_->getNumVectors() != numVectors) exportMV_ = null; if (exportMV_ == null) { exportMV_ = Teuchos::rcp( new MV(matrix_->getRowMap(),numVectors) ); } } // solve(NO_TRANS): RangeMap -> DomainMap // lclMatSolve_: RowMap -> ColMap // importer: DomainMap -> ColMap // exporter: RowMap -> RangeMap // // solve = reverse(exporter) o lclMatSolve_ o reverse(importer) // RangeMap -> RowMap -> ColMap -> DomainMap // If we have a non-trivial exporter, we must import elements that are permuted or are on other processors if (exporter != null) { exportMV_->doImport(X_in, *exporter, INSERT); X = exportMV_; } else if (X_in.isConstantStride() == false) { // cannot handle non-constant stride right now // generate a copy of X_in X = Teuchos::rcp(new MV(X_in)); } else { // just temporary, so this non-owning RCP is okay X = Teuchos::rcp( &X_in, false ); } // If we have a non-trivial importer, we must export elements that are permuted or belong to other processors // We will compute solution into the to-be-exported MV if (importer != null) { matrix_->template localSolve<OpScalar,OpScalar>(*X,*importMV_,Teuchos::NO_TRANS); // Make sure target is zero: necessary because we are adding. Y_in.putScalar(ST::zero()); Y_in.doExport(*importMV_, *importer, ADD); } // otherwise, solve into Y else { // can't solve into non-strided multivector if (Y_in.isConstantStride() == false) { // generate a strided copy of Y MV Y(Y_in); matrix_->template localSolve<OpScalar,OpScalar>(*X,Y,Teuchos::NO_TRANS); Y_in = Y; } else { matrix_->template localSolve<OpScalar,OpScalar>(*X,Y_in,Teuchos::NO_TRANS); } } }