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()
00051 {
00052 }
00053 
00054 const std::vector<int>&
00055 EqnComm::getGlobalOffsets() const
00056 {
00057   return(globalOffsets_);
00058 }
00059 
00060 int
00061 EqnComm::getOwnerProc(int eqn) const
00062 {
00063 //  std::vector<int>::const_iterator
00064 //   iter = std::lower_bound(globalOffsets_.begin(), globalOffsets_.end(),
00065 //                           eqn);
00066 //  int proc = iter - globalOffsets_.begin() - 1;
00067 //  if (*iter==eqn) ++proc;
00068   int proc = 0;
00069   for(unsigned p=1; p<globalOffsets_.size(); ++p) {
00070     if (eqn < globalOffsets_[p]) {
00071       proc = p-1;
00072       break;
00073     }
00074   }
00075 
00076 #ifndef NDEBUG
00077   int numProcs = globalOffsets_.size()-1;
00078   if (proc >= numProcs) {
00079     FEI_OSTRINGSTREAM osstr;
00080     osstr << "fei::EqnComm::getOwnerProc: input eqn="<<eqn<<", proc="<<proc
00081       << ", ERROR, proc should be in [0.."<<numProcs-1<<"].";
00082     throw std::runtime_error(std::string(osstr.str().c_str()));
00083   }
00084 #endif
00085 
00086   return((int)proc);
00087 }
00088 
00089 }//namespace fei
00090 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends