snl_fei_BlkSizeMsgHandler.cpp

00001 /*--------------------------------------------------------------------*/
00002 /*    Copyright 2005 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_macros.hpp>
00010 
00011 #include <snl_fei_BlkSizeMsgHandler.hpp>
00012 
00013 #include <fei_utils.hpp>
00014 
00015 #include <snl_fei_Utils.hpp>
00016 #include <fei_FieldMask.hpp>
00017 #include <snl_fei_RecordCollection.hpp>
00018 #include <fei_VectorSpace.hpp>
00019 #include <fei_ParameterSet.hpp>
00020 #include <fei_Graph.hpp>
00021 #include <snl_fei_Constraint.hpp>
00022 #include <fei_TemplateUtils.hpp>
00023 
00024 #include <fei_EqnBuffer.hpp>
00025 #include <fei_EqnCommMgr.hpp>
00026 #include <SNL_FEI_Structure.hpp>
00027 
00028 #undef fei_file
00029 #define fei_file "snl_fei_BlkSizeMsgHandler.cpp"
00030 #include <fei_ErrMacros.hpp>
00031 
00032 //----------------------------------------------------------------------------
00033 snl_fei::BlkSizeMsgHandler::BlkSizeMsgHandler(fei::VectorSpace* vspace,
00034                                               fei::Graph* graph,
00035                                               MPI_Comm comm)
00036   : remote_colIndices_(NULL),
00037     local_colIndices_(NULL),
00038     vecSpace_(vspace),
00039     ptBlkMap_(NULL),
00040     graph_(graph),
00041     comm_(comm),
00042     sendProcs_(0, 64),
00043     recvProcs_(0, 64),
00044     firstExchange_(true)
00045 {
00046   remote_colIndices_ = new fei::comm_map(0,1);
00047   local_colIndices_ = new fei::comm_map(0,1);
00048 
00049   ptBlkMap_ = vspace->getPointBlockMap();
00050 }
00051 
00052 //----------------------------------------------------------------------------
00053 snl_fei::BlkSizeMsgHandler::~BlkSizeMsgHandler()
00054 {
00055   delete remote_colIndices_;
00056   delete local_colIndices_;
00057 }
00058 
00059 //----------------------------------------------------------------------------
00060 int snl_fei::BlkSizeMsgHandler::do_the_exchange()
00061 {
00062   int local_proc = fei::localProc(comm_);
00063   if (fei::numProcs(comm_) < 2) {
00064     return(0);
00065   }
00066 
00067   fei::Graph::table_type* localgraph = graph_->getLocalGraph();
00068   fei::Graph::table_type::iterator
00069     g_iter = localgraph->begin(),
00070     g_end = localgraph->end();
00071 
00072   //First create a table that maps remote processors to column-indices from our
00073   //graph.
00074   //These are remotely-owned column-indices for which we will need block-sizes.
00075 
00076   for(; g_iter != g_end; ++g_iter) {
00077     fei::Graph::table_type::row_type* row = (*g_iter).second;
00078 
00079     fei::Graph::table_type::row_type::const_iterator
00080       iter = row->begin(),
00081       iter_end = row->end();
00082 
00083     int owner;
00084 
00085     for(; iter != iter_end; ++iter) {
00086       int col = *iter;
00087       owner = vecSpace_->getOwnerProcBlkIndex(col);
00088 
00089       if (owner != local_proc) {
00090         remote_colIndices_->addIndices(owner, 1, &col);
00091       }
00092     }
00093   }
00094 
00095   //Next, we need to send our lists of remotely-owned column-indices to the
00096   //owning processors. After that, those processors can respond by sending us
00097   //the sizes for those column-indices.
00098   fei::copyKeysToVector(remote_colIndices_->getMap(), sendProcs_);
00099 
00100   CHK_ERR( fei::mirrorProcs(comm_, sendProcs_, recvProcs_) );
00101 
00102   firstExchange_ = true;
00103 
00104   CHK_ERR( fei::exchange(comm_, this) );
00105 
00106   firstExchange_ = false;
00107 
00108   CHK_ERR( fei::exchange(comm_, this) );
00109 
00110   return(0);
00111 }
00112 
00113 //----------------------------------------------------------------------------
00114 std::vector<int>& snl_fei::BlkSizeMsgHandler::getSendProcs()
00115 {
00116   if (firstExchange_) {
00117     return(sendProcs_);
00118   }
00119   else {
00120     return(recvProcs_);
00121   }
00122 }
00123 
00124 //----------------------------------------------------------------------------
00125 std::vector<int>& snl_fei::BlkSizeMsgHandler::getRecvProcs()
00126 {
00127   if (firstExchange_) {
00128     return(recvProcs_);
00129   }
00130   else {
00131     return(sendProcs_);
00132   }
00133 }
00134 
00135 //----------------------------------------------------------------------------
00136 int snl_fei::BlkSizeMsgHandler::getSendMessageLength(int destProc,
00137                                                      int& messageLength)
00138 {
00139   if (firstExchange_) {
00140     fei::comm_map::row_type* cols = remote_colIndices_->getRow(destProc);
00141     messageLength = cols->size();
00142     return(0);
00143   }
00144   else {
00145     fei::comm_map::row_type* cols = local_colIndices_->getRow(destProc);
00146     messageLength = cols->size()*2;
00147     return(0);
00148   }
00149 }
00150 
00151 //----------------------------------------------------------------------------
00152 int snl_fei::BlkSizeMsgHandler::getSendMessage(int destProc,
00153                                                std::vector<int>& message)
00154 {
00155   if (firstExchange_) {
00156     fei::comm_map::row_type* cols = remote_colIndices_->getRow(destProc);
00157     message.resize(cols->size());
00158     fei::copySetToArray(*cols, message.size(), &message[0]);
00159     return(0);
00160   }
00161   else {
00162     fei::comm_map::row_type* cols = local_colIndices_->getRow(destProc);
00163 
00164     message.resize(cols->size()*2);
00165 
00166     fei::comm_map::row_type::const_iterator
00167       iter = cols->begin(),
00168       iter_end = cols->end();
00169 
00170     int offset = 0;
00171     for(; iter != iter_end; ++iter) {
00172       CHK_ERR( ptBlkMap_->getBlkEqnInfo(*iter,
00173                                         message[offset], message[offset+1]) );
00174       offset += 2;
00175     }
00176 
00177     return( 0 );
00178   }
00179 }
00180 
00181 //----------------------------------------------------------------------------
00182 int snl_fei::BlkSizeMsgHandler::processRecvMessage(int srcProc,
00183                                                    std::vector<int>& message)
00184 {
00185   if (firstExchange_) {
00186     for(unsigned i=0; i<message.size(); ++i) {
00187       local_colIndices_->addIndices(srcProc, 1, &(message[i]));
00188     }
00189   }
00190   else {
00191     fei::comm_map::row_type* cols = remote_colIndices_->getRow(srcProc);
00192     fei::comm_map::row_type::const_iterator
00193       iter = cols->begin(),
00194       iter_end = cols->end();
00195 
00196     int offset = 0;
00197     for(; iter != iter_end; ++iter) {
00198       int ptEqn = message[offset];
00199       int blkSize = message[offset+1];
00200       for(int i=0; i<blkSize; ++i) {
00201         CHK_ERR( ptBlkMap_->setEqn(ptEqn+i, *iter, blkSize) );
00202       }
00203       offset += 2;
00204     }
00205   }
00206 
00207   return(0);
00208 }
00209 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends
Generated on Wed Apr 13 10:08:24 2011 for FEI by  doxygen 1.6.3