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*>::iterator
00064     nnp_iter = nodenumPairs_.find(nodeNumber);
00065 
00066   if (nnp_iter == nodenumPairs_.end()) return(-1);
00067 
00068   fei::Record* 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*>::iterator
00086     enp_iter = eqnnumPairs_.find(eqnNumber);
00087 
00088   if (enp_iter == eqnnumPairs_.end()) return(-1);
00089 
00090   fei::Record* 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*>::iterator
00099     enp_iter = eqnnumPairs_.find(eqnNumber);
00100 
00101   if (enp_iter == eqnnumPairs_.end()) return(-1);
00102 
00103   fei::Record* 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*>::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*>::iterator
00127     nnp_iter = nodenumPairs_.find(blkEqn);
00128 
00129   if (nnp_iter == nodenumPairs_.end()) return(-1);
00130 
00131   fei::Record* 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* node = (*r_iter).second;
00160 
00161     std::pair<int,fei::Record* > 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* > 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* subdomainIDs = NULL;
00185   fei::SharedIDs* sharedIDs = NULL;
00186   vspace_->getSharedIDs_private(nodeIDType_, sharedIDs);
00187 
00188   if (noconstraints == false) {
00189     subdomainIDs = new fei::SharedIDs;
00190 
00191     snl_fei::SubdMsgHandler subdmsghndlr(collection, sharedIDs, subdomainIDs);
00192 
00193     int idx = snl_fei::binarySearch(nodeIDType_, vspace_->sharedIDTypes_);
00194     if (idx < 0) ERReturn(-1);
00195 
00196     if ((int)vspace_->ownerPatterns_.size() > idx &&
00197   (int)vspace_->sharerPatterns_.size() > idx) {
00198       subdmsghndlr.setSendPattern(vspace_->ownerPatterns_[idx]);
00199       subdmsghndlr.setRecvPattern(vspace_->sharerPatterns_[idx]);
00200       CHK_ERR( fei::exchange(comm, &subdmsghndlr) );
00201     }
00202 
00203     //Now the subdomainIDs object contains a mapping from each shared ID to a
00204     //list of processors that have that ID in their local subdomain.
00205     //So what we'll do next is run through the list of IDs in subdomainIDs and
00206     //for each ID, store the corresponding node-number in a database together
00207     //with a pointer to a list (vector) of the subdomain-processors.
00208   }
00209   else {
00210     subdomainIDs = sharedIDs;
00211   }
00212 
00213   int local_proc = fei::localProc(comm);
00214 
00215   fei::SharedIDs::table_type& sdIDTable = subdomainIDs->getSharedIDs();
00216   fei::SharedIDs::table_type::iterator
00217     sd_iter = sdIDTable.begin(),
00218     sd_end  = sdIDTable.end();
00219 
00220   for(int i=0; sd_iter != sd_end; ++i, ++sd_iter) {
00221     int id = (*sd_iter).first;
00222     fei::SharedIDs::table_type::row_type* procList = (*sd_iter).second;
00223 
00224     fei::Record* node = collection->getRecordWithID(id);
00225     if (node == NULL) {
00226       ERReturn(-1);
00227     }
00228 
00229     std::vector<int>* newarray = new std::vector<int>;
00230     fei::SharedIDs::table_type::row_type::const_iterator
00231       p_iter = procList->begin(),
00232       p_end = procList->end();
00233     for(; p_iter != p_end; ++p_iter) {
00234       int proc = *p_iter;
00235       newarray->push_back(proc);
00236     }
00237 
00238     if (node->isInLocalSubdomain_) {
00239       snl_fei::sortedListInsert(local_proc, *newarray);
00240     }
00241 
00242     nodenumSubdomainDB_.insert(std::pair<int,std::vector<int>*>(node->getNumber(), newarray));
00243   }
00244 
00245   if (!noconstraints) {
00246     delete subdomainIDs;
00247   }
00248 
00249   databasesBuilt_ = true;
00250   return(0);
00251 }
00252 

Generated on Wed May 12 21:30:41 2010 for FEI by  doxygen 1.4.7