fei_Lookup_Impl.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 <fei_Lookup_Impl.hpp>
00012 
00013 #include <fei_VectorSpace.hpp>
00014 
00015 #include <snl_fei_Utils.hpp>
00016 #include <fei_TemplateUtils.hpp>
00017 #include <fei_CommUtils.hpp>
00018 
00019 #include <snl_fei_Constraint.hpp>
00020 
00021 #include <snl_fei_SubdMsgHandler.hpp>
00022 
00023 #undef fei_file
00024 #define fei_file "fei_Lookup_Impl.cpp"
00025 #include <fei_ErrMacros.hpp>
00026 
00027 //----------------------------------------------------------------------------
00028 fei::Lookup_Impl::Lookup_Impl(fei::SharedPtr<fei::MatrixGraph> matGraph,
00029           int nodeIDType)
00030   : matGraph_(matGraph),
00031     ptBlkMap_(NULL),
00032     vspace_(),
00033     nodeIDType_(nodeIDType),
00034     nodenumPairs_(),
00035     eqnnumPairs_(),
00036     nodenumSubdomainDB_(),
00037     databasesBuilt_(false),
00038     fieldIDs_(),
00039     fieldSizes_(),
00040     elemBlockIDs_(0, 4),
00041     fieldIDs_2D_(),
00042     workspace_()
00043 {
00044   vspace_ = matGraph_->getRowSpace();
00045   ptBlkMap_ = vspace_->getPointBlockMap();
00046 
00047   int err = buildDatabases();
00048   if (err != 0) {
00049     voidERReturn;
00050   }
00051 }
00052 
00053 //----------------------------------------------------------------------------
00054 fei::Lookup_Impl::~Lookup_Impl()
00055 {
00056   fei::destroyValues(nodenumSubdomainDB_);
00057   nodenumSubdomainDB_.clear();
00058 }
00059 
00060 //----------------------------------------------------------------------------
00061 int fei::Lookup_Impl::getEqnNumber(int nodeNumber, int fieldID)
00062 {
00063   std::map<int,fei::Record<int>*>::iterator
00064     nnp_iter = nodenumPairs_.find(nodeNumber);
00065 
00066   if (nnp_iter == nodenumPairs_.end()) return(-1);
00067 
00068   fei::Record<int>* node = (*nnp_iter).second;
00069 
00070   std::vector<int>& eqnNums = vspace_->getEqnNumbers();
00071   int* eqnNumbers = eqnNums.size() > 0 ? &eqnNums[0] : NULL;
00072   if (eqnNumbers == NULL) {
00073     throw std::runtime_error("Fatal error in fei::Lookup_Impl::getEqnNumber");
00074   }
00075   eqnNumbers += node->getOffsetIntoEqnNumbers();
00076   int numInstances = 1;
00077   int offset = -1;
00078   node->getFieldMask()->getFieldEqnOffset(fieldID, offset, numInstances);
00079   return(eqnNumbers[offset]);
00080 }
00081 
00082 //----------------------------------------------------------------------------
00083 int fei::Lookup_Impl::getAssociatedNodeNumber(int eqnNumber)
00084 {
00085   std::map<int,fei::Record<int>*>::iterator
00086     enp_iter = eqnnumPairs_.find(eqnNumber);
00087 
00088   if (enp_iter == eqnnumPairs_.end()) return(-1);
00089 
00090   fei::Record<int>* node = (*enp_iter).second;
00091 
00092   return( node->getNumber() );
00093 }
00094 
00095 //----------------------------------------------------------------------------
00096 int fei::Lookup_Impl::getAssociatedNodeID(int eqnNumber)
00097 {
00098   std::map<int,fei::Record<int>*>::iterator
00099     enp_iter = eqnnumPairs_.find(eqnNumber);
00100 
00101   if (enp_iter == eqnnumPairs_.end()) return(-1);
00102 
00103   fei::Record<int>* node = (*enp_iter).second;
00104 
00105   return( node->getID() );
00106 }
00107 
00108 bool fei::Lookup_Impl::isInLocalElement(int nodeNumber)
00109 {
00110   std::map<int,std::vector<int>* >::iterator
00111     nns_iter = nodenumSubdomainDB_.find(nodeNumber);
00112   if (nns_iter != nodenumSubdomainDB_.end()) {
00113     return( true );
00114   }
00115 
00116   std::map<int,fei::Record<int>*>::iterator
00117     nnp_iter = nodenumPairs_.find(nodeNumber);
00118 
00119   return(nnp_iter != nodenumPairs_.end() ? true : false);
00120 }
00121 
00122 //----------------------------------------------------------------------------
00123 int fei::Lookup_Impl::getOffsetIntoBlkEqn(int blkEqn, int ptEqn)
00124 {
00125   //assume blkEqn is a node-number, for now.
00126   std::map<int,fei::Record<int>*>::iterator
00127     nnp_iter = nodenumPairs_.find(blkEqn);
00128 
00129   if (nnp_iter == nodenumPairs_.end()) return(-1);
00130 
00131   fei::Record<int>* node = (*nnp_iter).second;
00132 
00133   int eqn = vspace_->getEqnNumbers()[node->getOffsetIntoEqnNumbers()];
00134   return(ptEqn - eqn);
00135 }
00136 
00137 //----------------------------------------------------------------------------
00138 int fei::Lookup_Impl::buildDatabases()
00139 {
00140   if (databasesBuilt_) return(0);
00141 
00142   snl_fei::RecordCollection* collection = NULL;
00143   int err = vspace_->getRecordCollection(nodeIDType_, collection);
00144   if (err != 0) {
00145     //probably means that vspace_ doesn't have 'nodeIDType_', so we'll skip the
00146     //rest of this function. It's not a problem if vspace_ doesn't have nodeIDType_.
00147     return(0);
00148   }
00149 
00150   std::vector<int>& vspcEqnNumbers = vspace_->getEqnNumbers();
00151 
00152   snl_fei::RecordCollection::map_type& rmap = collection->getRecords();
00153 
00154   snl_fei::RecordCollection::map_type::iterator
00155     r_iter = rmap.begin(),
00156     r_end = rmap.end();
00157 
00158   for(; r_iter != r_end; ++r_iter) {
00159     fei::Record<int>* node = (*r_iter).second;
00160 
00161     std::pair<int,fei::Record<int>* > int_node_pair(node->getNumber(), node);
00162 
00163     nodenumPairs_.insert(int_node_pair);
00164 
00165     int numEqns = node->getFieldMask()->getNumIndices();
00166     int* eqnNumbers = &vspcEqnNumbers[0]
00167                     + node->getOffsetIntoEqnNumbers();
00168 
00169     for(int eq=0; eq<numEqns; ++eq) {
00170       std::pair<int,fei::Record<int>* > eqn_node_pair(eqnNumbers[eq], node);
00171       eqnnumPairs_.insert(eqn_node_pair);
00172     }
00173   }
00174 
00175   MPI_Comm comm = matGraph_->getRowSpace()->getCommunicator();
00176 
00177   int numLocalLagrangeConstraints = matGraph_->getLagrangeConstraints().size();
00178 
00179   int numGlobalLagrangeConstraints = 0;
00180   fei::GlobalSum(comm, numLocalLagrangeConstraints, numGlobalLagrangeConstraints);
00181 
00182   bool noconstraints = numGlobalLagrangeConstraints<1 ? true : false;
00183 
00184   fei::SharedIDs<int> subdomainIDs;
00185   fei::SharedIDs<int>& sharedIDs = vspace_->getSharedIDs_private(nodeIDType_);
00186 
00187   if (noconstraints == false) {
00188     snl_fei::SubdMsgHandler subdmsghndlr(collection, &sharedIDs, &subdomainIDs);
00189 
00190     if (vspace_->ownerPatterns_.size() > 0 && vspace_->sharerPatterns_.size() > 0) {
00191       subdmsghndlr.setSendPattern(vspace_->ownerPatterns_.find(nodeIDType_)->second);
00192       subdmsghndlr.setRecvPattern(vspace_->sharerPatterns_.find(nodeIDType_)->second);
00193       CHK_ERR( fei::exchange(comm, &subdmsghndlr) );
00194     }
00195 
00196     //Now the subdomainIDs object contains a mapping from each shared ID to a
00197     //list of processors that have that ID in their local subdomain.
00198     //So what we'll do next is run through the list of IDs in subdomainIDs and
00199     //for each ID, store the corresponding node-number in a database together
00200     //with a pointer to a list (vector) of the subdomain-processors.
00201   }
00202   else {
00203     subdomainIDs = sharedIDs;
00204   }
00205 
00206   int local_proc = fei::localProc(comm);
00207 
00208   fei::SharedIDs<int>::map_type& sdIDTable = subdomainIDs.getSharedIDs();
00209   fei::SharedIDs<int>::map_type::iterator
00210     sd_iter = sdIDTable.begin(),
00211     sd_end  = sdIDTable.end();
00212 
00213   for(int i=0; sd_iter != sd_end; ++i, ++sd_iter) {
00214     int id = sd_iter->first;
00215     std::set<int>& procList = sd_iter->second;
00216 
00217     fei::Record<int>* node = collection->getRecordWithID(id);
00218     if (node == NULL) {
00219       ERReturn(-1);
00220     }
00221 
00222     std::vector<int>* newarray = new std::vector<int>;
00223     std::set<int>::const_iterator
00224       p_iter = procList.begin(), p_end = procList.end();
00225 
00226     for(; p_iter != p_end; ++p_iter) {
00227       int proc = *p_iter;
00228       newarray->push_back(proc);
00229     }
00230 
00231     if (node->isInLocalSubdomain_) {
00232       fei::sortedListInsert(local_proc, *newarray);
00233     }
00234 
00235     nodenumSubdomainDB_.insert(std::pair<int,std::vector<int>*>(node->getNumber(), newarray));
00236   }
00237 
00238   databasesBuilt_ = true;
00239   return(0);
00240 }
00241 

Generated on Tue Jul 13 09:27:45 2010 for FEI by  doxygen 1.4.7