FEI Version of the Day
fei_EqnComm.cpp
00001 /*--------------------------------------------------------------------*/
00002 /*    Copyright 2007 Sandia Corporation.                              */
00003 /*    Under the terms of Contract DE-AC04-94AL85000, there is a       */
00004 /*    non-exclusive license for use of this work by or on behalf      */
00005 /*    of the U.S. Government.  Export of this program may require     */
00006 /*    a license from the United States Government.                    */
00007 /*--------------------------------------------------------------------*/
00008 
00009 #include "fei_EqnComm.hpp"
00010 #include "fei_sstream.hpp"
00011 
00012 namespace fei {
00013 
00014 EqnComm::EqnComm(MPI_Comm comm, int numLocalEqns)
00015  : comm_(comm),
00016    globalOffsets_(2)
00017 {
00018 #ifndef FEI_SER
00019 
00020   int numProcs, localProc;
00021   MPI_Comm_size(comm, &numProcs);
00022   MPI_Comm_rank(comm, &localProc);
00023 
00024   std::vector<int> local(numProcs*2, 0);
00025   int* global = &local[0] + numProcs;
00026 
00027   if (numLocalEqns < 0) {
00028     throw std::runtime_error("fei::EqnComm ERROR, negative numLocalEqns not allowed.");
00029   }
00030 
00031   local[localProc] = numLocalEqns;
00032 
00033   MPI_Allreduce(&local[0], global, numProcs, MPI_INT, MPI_MAX, comm_);
00034 
00035   globalOffsets_.resize(numProcs+1);
00036 
00037   int offset = 0;
00038   for(int i=0; i<numProcs; ++i) {
00039     globalOffsets_[i] = offset;
00040     offset += global[i];
00041   }
00042   globalOffsets_[numProcs] = offset;
00043 
00044 #else
00045   globalOffsets_[0] = 0;
00046   globalOffsets_[1] = numLocalEqns;
00047 #endif
00048 }
00049   
00050 EqnComm::EqnComm(MPI_Comm comm, int numLocalEqns, const std::vector<int>& globalOffsets)
00051  : comm_(comm),
00052    globalOffsets_(globalOffsets)
00053 {
00054 }
00055   
00056 EqnComm::~EqnComm()
00057 {
00058 }
00059 
00060 const std::vector<int>&
00061 EqnComm::getGlobalOffsets() const
00062 {
00063   return(globalOffsets_);
00064 }
00065 
00066 int
00067 EqnComm::getOwnerProc(int eqn) const
00068 {
00069 //  std::vector<int>::const_iterator
00070 //   iter = std::lower_bound(globalOffsets_.begin(), globalOffsets_.end(),
00071 //                           eqn);
00072 //  int proc = iter - globalOffsets_.begin() - 1;
00073 //  if (*iter==eqn) ++proc;
00074   int proc = 0;
00075   for(unsigned p=1; p<globalOffsets_.size(); ++p) {
00076     if (eqn < globalOffsets_[p]) {
00077       proc = p-1;
00078       break;
00079     }
00080   }
00081 
00082 #ifndef NDEBUG
00083   int numProcs = globalOffsets_.size()-1;
00084   if (proc >= numProcs) {
00085     FEI_OSTRINGSTREAM osstr;
00086     osstr << "fei::EqnComm::getOwnerProc: input eqn="<<eqn<<", proc="<<proc
00087       << ", ERROR, proc should be in [0.."<<numProcs-1<<"].";
00088     throw std::runtime_error(std::string(osstr.str().c_str()));
00089   }
00090 #endif
00091 
00092   return((int)proc);
00093 }
00094 
00095 }//namespace fei
00096 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends