void 
TpetraLinearObjFactory<Traits,ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT>::
ghostToGlobalTpetraMatrix(const Tpetra::CrsMatrix<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT> & in,
                          Tpetra::CrsMatrix<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT> & out) const
{
   using Teuchos::RCP;

   // do the global distribution
   RCP<ExportType> exporter = getGhostedExport();
   
   out.resumeFill();
   out.setAllToScalar(0.0);
   out.doExport(in,*exporter,Tpetra::ADD);
   out.fillComplete();
}
Exemplo n.º 2
0
int main(int argc, char* argv[]){
        Teuchos::oblackholestream blackhole;
        Teuchos::GlobalMPISession mpiSession(&argc,&argv,&blackhole);
        typedef double Scalar;
        typedef int Ordinal;
        using Tpetra::global_size_t;

        Teuchos::RCP<const Teuchos::Comm<int> > comm = Tpetra::DefaultPlatform::getDefaultPlatform().getComm();
  Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::fancyOStream(Teuchos::rcp(&std::cout,false));
  //out->setOutputToRootOnly(comm->getRank());

        size_t myRank = comm->getRank();
        size_t numProc = comm->getSize();
        bool verbose = (myRank==0);

        std::cout << *comm;

        const global_size_t numGlobalElements = 4;
        if (numGlobalElements < numProc) {
                if (verbose) {
                        std::cout << "numGlobalBlocks = " << numGlobalElements
                        << " cannot be less than the number of processors = " << numProc << std::endl;
                }
                return -1;
        }

        // Construct a Map that puts approximately the same number of equations on each processor.

        Teuchos::RCP<const Tpetra::Map<Ordinal> > map = Tpetra::createUniformContigMap<Ordinal,Ordinal>(numGlobalElements, comm);

        // Get update list and number of local equations from newly created map.

        const size_t numMyElements = map->getNodeNumElements();

        Teuchos::ArrayView<const Ordinal> myGlobalElements = map->getNodeElementList();

        // Create an OTeger vector NumNz that is used to build the Petra Matrix.
        // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation
        // on this processor

        Teuchos::ArrayRCP<size_t> NumNz = Teuchos::arcp<size_t>(numMyElements);

        // We are building a tridiagonal matrix where each row has (-1 2 -1)
        // So we need 2 off-diagonal terms (except for the first and last equation)

        for (size_t i=0; i < numMyElements; ++i) {
                if (myGlobalElements[i] == 0 || static_cast<global_size_t>(myGlobalElements[i]) == numGlobalElements-1) {
                // boundary
                        NumNz[i] = 2;
                }
                else {
                        NumNz[i] = 3;
                }
        }

        // Create a Tpetra::Matrix using the Map, with a static allocation dictated by NumNz
        Tpetra::CrsMatrix<Scalar,Ordinal>  A (map, NumNz, Tpetra::StaticProfile);
        Tpetra::CrsMatrix<Scalar,Ordinal>  AT(map, NumNz, Tpetra::StaticProfile);
        Teuchos::RCP< Tpetra::CrsMatrix<Scalar,Ordinal> > TestMatrix = Teuchos::null;

        // We are done with NumNZ
        NumNz = Teuchos::null;

        // Add  rows one-at-a-time
        // Off diagonal values will always be -1
        const Scalar two    = static_cast<Scalar>( 2.0);
        const Scalar negOne = static_cast<Scalar>(-1.0);
        const Scalar three = static_cast<Scalar>(3.0);
        for (size_t i=0; i<numMyElements; i++) {
                if (myGlobalElements[i] == 0) {
                        A.insertGlobalValues( myGlobalElements[i],
                        Teuchos::tuple<Ordinal>( myGlobalElements[i], myGlobalElements[i]+1 ),
                        Teuchos::tuple<Scalar> ( two, negOne ) );
                }
                else if (static_cast<global_size_t>(myGlobalElements[i]) == numGlobalElements-1) {
                        A.insertGlobalValues( myGlobalElements[i],
                        Teuchos::tuple<Ordinal>( myGlobalElements[i]-1, myGlobalElements[i] ),
                        Teuchos::tuple<Scalar> ( negOne, two ) );
                }
                else {
                        A.insertGlobalValues( myGlobalElements[i],
                        Teuchos::tuple<Ordinal>( myGlobalElements[i]-1, myGlobalElements[i], myGlobalElements[i]+1 ),
                        Teuchos::tuple<Scalar> ( three, two, negOne ) );
                }
        }


        for (size_t i=0; i<numMyElements; i++) {
                if (myGlobalElements[i] == 0) {
                        AT.insertGlobalValues( myGlobalElements[i],
                        Teuchos::tuple<Ordinal>( myGlobalElements[i], myGlobalElements[i]+1 ),
                        Teuchos::tuple<Scalar> ( two, three ) );
                }
                else if (static_cast<global_size_t>(myGlobalElements[i]) == numGlobalElements-1) {
                        AT.insertGlobalValues( myGlobalElements[i],
                        Teuchos::tuple<Ordinal>( myGlobalElements[i]-1, myGlobalElements[i] ),
                        Teuchos::tuple<Scalar> ( negOne, two ) );
                }
                else if(static_cast<global_size_t>(myGlobalElements[i])==1){
                        AT.insertGlobalValues( myGlobalElements[i],
                        Teuchos::tuple<Ordinal>( myGlobalElements[i]-1, myGlobalElements[i], myGlobalElements[i]+1 ),
                        Teuchos::tuple<Scalar> ( negOne, two, three ) );
                }
                else if(static_cast<global_size_t>(myGlobalElements[i])==2){
                        AT.insertGlobalValues( myGlobalElements[i],
                        Teuchos::tuple<Ordinal>( myGlobalElements[i]-1, myGlobalElements[i], myGlobalElements[i]+1 ),
                        Teuchos::tuple<Scalar> ( negOne, two, negOne ) );
                }
        }

        // Finish up
        A.fillComplete();
        AT.fillComplete();


        Tpetra::RowMatrixTransposer<Scalar, Ordinal> transposer (Teuchos::rcpFromRef (A));
        TestMatrix = transposer.createTranspose(); //, TestMatrix/*, tMap*/);

  Teuchos::RCP<Tpetra::CrsMatrix<Scalar, Ordinal> > diffMatrix = Tpetra::createCrsMatrix<Scalar, Ordinal>(TestMatrix->getRowMap());
  //Apparently there is a problem with ADD because while these two matricies are
  //identical when I add them together I don't get 0 like I should. Infact
  //I just get a matrix that has the exact same entries and sparsity structure.
  //I'll have to come back to this later. But RowMatrixTransposer is working right.
  //And all my other tests are telling me ADD works right too.
  //KLN 06/14/2011
  Tpetra::MatrixMatrix::Add(AT,false,-1.0,*TestMatrix,false, 1.0,diffMatrix);
  diffMatrix->fillComplete();
  //diffMatrix->describe(*out, Teuchos::VERB_EXTREME);
  double diffNorm = getNorm(*diffMatrix);
  double realNorm = getNorm(AT);
  double epsilon = diffNorm/realNorm;
  if(epsilon > 1e-10){
    *out << "The calculated A transpose and the real one don't match!" << std::endl;
    *out << "Diff Norm: " << diffNorm << std::endl;
    *out << "Real Norm: " << realNorm << std::endl;
    *out << "Epsilon: " << epsilon << std::endl;
    return 1;
  }




        return 0;
}