Esempio n. 1
0
      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);
    }
Esempio n. 3
0
  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);
      }
    }
  }