FEI Version of the Day
fei_Lookup_Impl.hpp
00001 /*
00002 // @HEADER
00003 // ************************************************************************
00004 //             FEI: Finite Element Interface to Linear Solvers
00005 //                  Copyright (2005) Sandia Corporation.
00006 //
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the
00008 // U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Alan Williams (william@sandia.gov) 
00038 //
00039 // ************************************************************************
00040 // @HEADER
00041 */
00042 
00043 
00044 #ifndef _fei_Lookup_Impl_hpp_
00045 #define _fei_Lookup_Impl_hpp_
00046 
00047 #include <fei_macros.hpp>
00048 #include <fei_MatrixGraph.hpp>
00049 #include <fei_Pattern.hpp>
00050 #include <fei_ConnectivityBlock.hpp>
00051 #include <fei_SharedIDs.hpp>
00052 #include <snl_fei_RecordCollection.hpp>
00053 #include <snl_fei_PointBlockMap.hpp>
00054 #include <fei_TemplateUtils.hpp>
00055 #include <fei_Lookup.hpp>
00056 
00057 #include <vector>
00058 
00059 namespace fei {
00062   class Lookup_Impl : public virtual Lookup {
00063   public:
00065     Lookup_Impl(fei::SharedPtr<fei::MatrixGraph> matGraph,
00066     int nodeIDType);
00067 
00069     virtual ~Lookup_Impl();
00070 
00072     int getNumFields()
00073       {
00074   return( vspace_->getNumFields() );
00075       }
00076 
00078     int getFieldSize(int fieldID)
00079       {
00080   return(vspace_->getFieldSize(fieldID));
00081       }
00082 
00084     const int* getFieldIDsPtr()
00085       {
00086   int len = getNumFields();
00087   if (len < 1) return(NULL);
00088 
00089   vspace_->getFields(fieldIDs_);
00090   return(&fieldIDs_[0]);
00091       }
00092 
00094     const int* getFieldSizesPtr()
00095       {
00096   const int* fieldIDs = getFieldIDsPtr();
00097   if (fieldIDs == NULL) return(NULL);
00098 
00099   unsigned numFields = fieldIDs_.size();
00100   fieldSizes_.resize(numFields);
00101   int* fsPtr = &fieldSizes_[0];
00102   for(unsigned i=0; i<numFields; ++i) {
00103     fsPtr[i] = vspace_->getFieldSize(fieldIDs[i]);
00104   }
00105   return(fsPtr);
00106       }
00107 
00109     int getNumElemBlocks()
00110       { return(matGraph_->getConnectivityBlocks().size()); }
00111 
00113     const GlobalID* getElemBlockIDs()
00114       {
00115   int err = matGraph_->getConnectivityBlockIDs(elemBlockIDs_);
00116   return(err==0 ? &elemBlockIDs_[0] : NULL);
00117       }
00118 
00120     void getElemBlockInfo(GlobalID blockID,
00121                          int& interleaveStrategy, int& lumpingStrategy,
00122                          int& numElemDOF, int& numElements,
00123                          int& numNodesPerElem, int& numEqnsPerElem)
00124       {
00125   interleaveStrategy = 0; lumpingStrategy = 0;
00126   numElemDOF = 0;
00127   const fei::ConnectivityBlock* cblock =
00128     matGraph_->getConnectivityBlock(blockID);
00129   numElements = cblock->getNativeConnectivityIDs().size();
00130   numNodesPerElem = cblock->getRowPattern()->getNumIDs();
00131   numEqnsPerElem = cblock->getRowPattern()->getNumIndices();
00132       }
00133 
00135     const int* getNumFieldsPerNode(GlobalID blockID)
00136       {
00137   const fei::ConnectivityBlock* cblock = matGraph_->getConnectivityBlock(blockID);
00138   if (cblock==NULL) return(NULL);
00139   return(cblock->getRowPattern()->getNumFieldsPerID());
00140       }
00141 
00143     const int* const* getFieldIDsTable(GlobalID blockID)
00144       {
00145   const fei::ConnectivityBlock* cblock = matGraph_->getConnectivityBlock(blockID);
00146   if (cblock==NULL) return(NULL);
00147   int numNodes = cblock->getRowPattern()->getNumIDs();
00148   const int* numFieldsPerNode = cblock->getRowPattern()->getNumFieldsPerID();
00149   const int* fieldIDs = cblock->getRowPattern()->getFieldIDs();
00150   fieldIDs_2D_.resize(numNodes);
00151   const int** f2dPtr = &fieldIDs_2D_[0];
00152   int offset = 0;
00153   for(int i=0; i<numNodes; ++i) {
00154     f2dPtr[i] = fieldIDs + offset;
00155     offset += numFieldsPerNode[i];
00156   }
00157   return(f2dPtr);
00158       }
00159 
00161     int getEqnNumber(int nodeNumber, int fieldID);
00162 
00164     int getAssociatedNodeNumber(int eqnNumber);
00165 
00166     int getAssociatedNodeID(int eqnNumber);
00167 
00169     int getAssociatedFieldID(int eqnNumber);
00170 
00172     bool isInLocalElement(int nodeNumber);
00173 
00175     int getNumSubdomains(int nodeNumber)
00176     {
00177       std::vector<int>* subdomains = NULL;
00178       std::map<int,std::vector<int>* >::iterator
00179         nns_iter = nodenumSubdomainDB_.find(nodeNumber);
00180       if (nns_iter != nodenumSubdomainDB_.end()) subdomains = (*nns_iter).second;
00181       return( subdomains==0 ? 0 : subdomains->size() );
00182     }
00183 
00185     int* getSubdomainList(int nodeNumber)
00186     {
00187       std::vector<int>* subdomains = NULL;
00188       std::map<int,std::vector<int>* >::iterator
00189         nns_iter = nodenumSubdomainDB_.find(nodeNumber);
00190       if (nns_iter != nodenumSubdomainDB_.end()) subdomains = (*nns_iter).second;
00191 
00192       return( subdomains==0 ? NULL : &(*subdomains)[0] );
00193     }
00194 
00196     int getNumSharedNodes()
00197     {
00198       int numShared;
00199       int err = vspace_->getNumSharedIDs(nodeIDType_, numShared);
00200       return(err==0 ? numShared : -1);
00201     }
00202 
00204     const int* getSharedNodeNumbers()
00205     {
00206       fei::SharedIDs<int>& sharedIDs = vspace_->getSharedIDs_private(nodeIDType_);
00207 
00208       int numShared = sharedIDs.getSharedIDs().size();
00209       workspace_.resize(numShared*2);
00210       int* wkPtr = &workspace_[0];
00211       fei::copyKeysToArray(sharedIDs.getSharedIDs(), numShared, wkPtr);
00212 
00213       snl_fei::RecordCollection* collection = NULL;
00214       vspace_->getRecordCollection(nodeIDType_, collection);
00215 
00216       for(int i=0; i<numShared; ++i) {
00217         fei::Record<int>* node = collection->getRecordWithID(wkPtr[i]);
00218         if (node == NULL) return NULL;
00219 
00220         wkPtr[numShared+i] = node->getNumber();
00221       }
00222       return(wkPtr+numShared);
00223     }
00224 
00226     const int* getSharedNodeProcs(int nodeNumber)
00227     {
00228       std::map<int,fei::Record<int>*>::iterator
00229         nnp_iter = nodenumPairs_.find(nodeNumber);
00230 
00231       if (nnp_iter == nodenumPairs_.end()) return(0);
00232 
00233       fei::Record<int>* node = (*nnp_iter).second;
00234 
00235       const fei::SharedIDs<int>& sharedIDs = vspace_->getSharedIDs_private(nodeIDType_);
00236 
00237       int shID = node->getID();
00238 
00239       fei::SharedIDs<int>::map_type::const_iterator
00240         iter = sharedIDs.getSharedIDs().find(shID);
00241       if (iter == sharedIDs.getSharedIDs().end()) return(NULL);
00242 
00243       const std::set<int>& shprocs = iter->second;
00244 
00245       fei::copySetToVector(shprocs, workspace_);
00246       return(&workspace_[0]);
00247     }
00248 
00250     int getNumSharingProcs(int nodeNumber)
00251     {
00252       std::map<int,fei::Record<int>*>::iterator
00253         nnp_iter = nodenumPairs_.find(nodeNumber);
00254 
00255       if (nnp_iter == nodenumPairs_.end()) return(0);
00256 
00257       fei::Record<int>* node = (*nnp_iter).second;
00258 
00259       const fei::SharedIDs<int>& sharedIDs = vspace_->getSharedIDs_private(nodeIDType_);
00260 
00261       int shID = node->getID();
00262 
00263       fei::SharedIDs<int>::map_type::const_iterator
00264         iter = sharedIDs.getSharedIDs().find(shID);
00265       if (iter == sharedIDs.getSharedIDs().end()) return(0);
00266 
00267       const std::set<int>& shprocs = iter->second;
00268       return(shprocs.size());
00269     }
00270 
00272     bool isExactlyBlkEqn(int ptEqn)
00273       { return( ptBlkMap_->isExactlyBlkEqn(ptEqn) ); }
00274 
00276     int ptEqnToBlkEqn(int ptEqn)
00277       { return( ptBlkMap_->eqnToBlkEqn(ptEqn) ); }
00278 
00280     int getOffsetIntoBlkEqn(int blkEqn, int ptEqn);
00281 
00283     int getBlkEqnSize(int blkEqn)
00284     {
00285       return( ptBlkMap_->getBlkEqnSize(blkEqn) );
00286     }
00287 
00288   private:
00289     int buildDatabases();
00290 
00291     fei::SharedPtr<fei::MatrixGraph> matGraph_;
00292     snl_fei::PointBlockMap* ptBlkMap_;
00293     fei::SharedPtr<fei::VectorSpace> vspace_;
00294     int nodeIDType_;
00295 
00296     std::map<int, fei::Record<int>*> nodenumPairs_;
00297     std::map<int,fei::Record<int>*> eqnnumPairs_;
00298 
00299     std::map<int,std::vector<int>*> nodenumSubdomainDB_;
00300 
00301     bool databasesBuilt_;
00302 
00303     std::vector<int> fieldIDs_;
00304     std::vector<int> fieldSizes_;
00305     std::vector<GlobalID> elemBlockIDs_;
00306     std::vector<const int*> fieldIDs_2D_;
00307     std::vector<int> workspace_;
00308   };//class Lookup_Impl
00309 }//namespace fei
00310 
00311 #endif // _fei_Lookup_Impl_hpp_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends