TSFVectorSpace2EpetraMap.cpp
Go to the documentation of this file.
00001 /* ***********************************************************************
00002 // 
00003 //           TSFExtended: Trilinos Solver Framework Extended
00004 //                 Copyright (2004) Sandia Corporation
00005 // 
00006 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00007 // license for use of this work by or on behalf of the U.S. Government.
00008 // 
00009 // This library is free software; you can redistribute it and/or modify
00010 // it under the terms of the GNU Lesser General Public License as
00011 // published by the Free Software Foundation; either version 2.1 of the
00012 // License, or (at your option) any later version.
00013 //  
00014 // This library is distributed in the hope that it will be useful, but
00015 // WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 // Lesser General Public License for more details.
00018 //  
00019 // You should have received a copy of the GNU Lesser General Public
00020 // License along with this library; if not, write to the Free Software
00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00022 // USA
00023 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00024 // 
00025 // **********************************************************************/
00026 
00027 #include "TSFVectorSpace2EpetraMap.hpp"
00028 #include "TSFEpetraVectorSpace.hpp"
00029 #include "TSFEpetraVector.hpp"
00030 #include "Teuchos_Utils.hpp"
00031 #include "Teuchos_DefaultSerialComm.hpp"
00032 
00033 
00034 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00035 #include "TSFVectorSpaceImpl.hpp"
00036 #endif
00037 
00038 #ifdef HAVE_MPI
00039 #include "Teuchos_DefaultMpiComm.hpp"
00040 #include "Epetra_MpiComm.h"
00041 #endif
00042 #include "Epetra_SerialComm.h"
00043 
00044 
00045 #ifdef TRILINOS_6
00046 #include "Thyra_MultiVectorCols.hpp"
00047 #ifdef HAVE_MPI
00048 #include "Thyra_MPIVectorSpaceBase.hpp"
00049 #endif
00050 #include "Thyra_SerialVectorSpaceStd.hpp"
00051 #define DefaultSerialVectorSpace SerialVectorSpaceStd
00052 #define DefaultColumnwiseMultiVector MultiVectorCols
00053 #else
00054 #include "Thyra_DefaultSpmdVector.hpp"
00055 #include "Thyra_SpmdVectorSpaceDefaultBase.hpp"
00056 #include "Thyra_DefaultColumnwiseMultiVector.hpp"
00057 #define MPIVectorSpaceBase SpmdVectorSpaceDefaultBase
00058 #endif
00059 
00060 namespace TSFExtended {
00061   using namespace Teuchos;
00062   using namespace Thyra;
00063 
00064 
00065   RCP<const Epetra_Map> tsfVectorSpace2EpetraMap(const VectorSpace<double>& tsfSpace)
00066   {
00067     const EpetraVectorSpace* ep 
00068       = dynamic_cast<const EpetraVectorSpace*>(tsfSpace.ptr().get());
00069     // See if we have an honest EpetraVectorSpace
00070     if (ep) 
00071       {
00072   return ep->epetraMap();
00073       }
00074     // Otherwise, make a EpetraMap with the same structure
00075     Array<int> globIndices;
00076     for (SequentialIterator<double> i = tsfSpace.begin(); 
00077    i != tsfSpace.end(); i++)
00078       {
00079   globIndices.append(i.globalIndex());
00080       }
00081     int dim = tsfSpace.dim();
00082 
00083     RCP<Epetra_Comm> comm;
00084     TSFExtended::getComm(tsfSpace, comm);
00085 
00086     RCP<const Epetra_Map> rtn = rcp(new Epetra_Map(dim, globIndices.size(),
00087                  &(globIndices[0]),
00088                  0, *comm));
00089     return rtn;
00090   }
00091 
00092 
00093 void getComm(const TSFExtended::VectorSpace<double>& tsfSpace,
00094     Teuchos::RCP<Epetra_Comm>& comm)
00095   {
00096 #ifdef HAVE_MPI
00097     if (tsfSpace.numBlocks()==1)
00098       {
00099   const MPIVectorSpaceBase<double>* mv 
00100     = dynamic_cast<const MPIVectorSpaceBase<double>*>(tsfSpace.getBlock(0).ptr().get());
00101   RCP<const Teuchos::Comm<OrdType> > tc = mv->getComm();
00102   const Teuchos::MpiComm<int>* mc 
00103     = dynamic_cast<const Teuchos::MpiComm<int>*>(tc.get());
00104   const Teuchos::SerialComm<int>* sc 
00105     = dynamic_cast<const Teuchos::SerialComm<int>*>(tc.get());
00106   if (mc != 0)
00107     {
00108       comm = rcp(new Epetra_MpiComm(*(mc->getRawMpiComm())));
00109     }
00110   else if (sc != 0) 
00111     {
00112       comm = rcp(new Epetra_SerialComm());
00113     }
00114   else
00115     {
00116       TEST_FOR_EXCEPTION(true, std::runtime_error, 
00117              "Could not find communicator "
00118              "for vector space " << tsfSpace);
00119     }
00120       }
00121     else
00122       {
00123   getComm(tsfSpace.getBlock(0), comm);
00124   int myRank = comm->MyPID();
00125   int np = comm->NumProc();
00126   for (int i=1; i<tsfSpace.numBlocks(); i++)
00127     {
00128       getComm(tsfSpace.getBlock(i), comm);
00129       TEST_FOR_EXCEPTION(myRank != comm->MyPID(), std::runtime_error,
00130              "inconsistent processor ranks in "
00131              "block vector space " << tsfSpace);
00132       TEST_FOR_EXCEPTION(np != comm->NumProc(), std::runtime_error,
00133              "inconsistent processor counts in "
00134              "block vector space " << tsfSpace);
00135     }
00136       }
00137 #else
00138     comm = rcp(new Epetra_SerialComm());
00139 #endif
00140   }
00141 
00142 }
00143 
00144 #undef MPIVectorSpaceBase 
00145 
00146 
00147 
00148 
00149 

Site Contact