9 #include <fei_macros.hpp>
11 #include <fei_Lookup_Impl.hpp>
13 #include <fei_VectorSpace.hpp>
15 #include <snl_fei_Utils.hpp>
16 #include <fei_TemplateUtils.hpp>
17 #include <fei_CommUtils.hpp>
19 #include <snl_fei_Constraint.hpp>
21 #include <snl_fei_SubdMsgHandler.hpp>
24 #define fei_file "fei_Lookup_Impl.cpp"
25 #include <fei_ErrMacros.hpp>
30 : matGraph_(matGraph),
33 nodeIDType_(nodeIDType),
36 nodenumSubdomainDB_(),
37 databasesBuilt_(false),
47 int err = buildDatabases();
57 nodenumSubdomainDB_.clear();
63 std::map<int,fei::Record<int>*>::iterator
64 nnp_iter = nodenumPairs_.find(nodeNumber);
66 if (nnp_iter == nodenumPairs_.end())
return(-1);
70 std::vector<int>& eqnNums = vspace_->getEqnNumbers();
71 int* eqnNumbers = eqnNums.size() > 0 ? &eqnNums[0] : NULL;
72 if (eqnNumbers == NULL) {
73 throw std::runtime_error(
"Fatal error in fei::Lookup_Impl::getEqnNumber");
79 return(eqnNumbers[offset]);
88 std::map<int,fei::Record<int>*>::iterator
89 enp_iter = eqnnumPairs_.find(eqnNumber);
91 if (enp_iter == eqnnumPairs_.end())
return(-1);
99 int fei::Lookup_Impl::getAssociatedNodeID(
int eqnNumber)
101 std::map<int,fei::Record<int>*>::iterator
102 enp_iter = eqnnumPairs_.find(eqnNumber);
104 if (enp_iter == eqnnumPairs_.end())
return(-1);
108 return( node->
getID() );
114 std::map<int,fei::Record<int>*>::iterator
115 enp_iter = eqnnumPairs_.find(eqnNumber);
117 if (enp_iter == eqnnumPairs_.end())
return(-1);
122 const std::vector<int>& fieldIDs = fm->
getFieldIDs();
125 const std::vector<int>& eqnNumbers = vspace_->getEqnNumbers();
130 if (baseEqnOffset + numNodalEqns > (
int)eqnNumbers.size()) {
131 throw std::runtime_error(
"fei::Lookup_Impl::getAssociatedFieldID ERROR, nodal eqn offset out of range.");
135 int eqn = eqnNumbers[baseEqnOffset];
136 while(eqn < eqnNumber && offset < numNodalEqns) {
137 eqn = eqnNumbers[baseEqnOffset + ++offset];
140 if (eqn != eqnNumber) {
141 throw std::runtime_error(
"fei::Lookup_Impl::getAssociatedFieldID ERROR, eqnNumber not found");
144 int fieldSize_total = 0;
145 for(
size_t i=0; i<fieldSizes.size(); ++i) {
146 fieldSize_total += fieldSizes[i];
147 if (fieldSize_total > offset) {
158 std::map<int,std::vector<int>* >::iterator
159 nns_iter = nodenumSubdomainDB_.find(nodeNumber);
160 if (nns_iter != nodenumSubdomainDB_.end()) {
164 std::map<int,fei::Record<int>*>::iterator
165 nnp_iter = nodenumPairs_.find(nodeNumber);
167 return(nnp_iter != nodenumPairs_.end() ?
true :
false);
174 std::map<int,fei::Record<int>*>::iterator
175 nnp_iter = nodenumPairs_.find(blkEqn);
177 if (nnp_iter == nodenumPairs_.end())
return(-1);
186 int fei::Lookup_Impl::buildDatabases()
188 if (databasesBuilt_)
return(0);
191 int err = vspace_->getRecordCollection(nodeIDType_, collection);
198 std::vector<int>& vspcEqnNumbers = vspace_->getEqnNumbers();
200 std::vector<fei::Record<int> >& rvec = collection->
getRecords();
202 for(
size_t i=0; i<rvec.size(); ++i) {
205 std::pair<int,fei::Record<int>* > int_node_pair(node->
getNumber(), node);
207 nodenumPairs_.insert(int_node_pair);
210 int* eqnNumbers = &vspcEqnNumbers[0]
213 for(
int eq=0; eq<numEqns; ++eq) {
214 std::pair<int,fei::Record<int>* > eqn_node_pair(eqnNumbers[eq], node);
215 eqnnumPairs_.insert(eqn_node_pair);
219 MPI_Comm comm = matGraph_->getRowSpace()->getCommunicator();
221 int numLocalLagrangeConstraints = matGraph_->getLagrangeConstraints().size();
223 int numGlobalLagrangeConstraints = 0;
224 fei::GlobalSum(comm, numLocalLagrangeConstraints, numGlobalLagrangeConstraints);
226 bool noconstraints = numGlobalLagrangeConstraints<1 ?
true :
false;
231 if (noconstraints ==
false) {
234 if (vspace_->ownerPatterns_.size() > 0 && vspace_->sharerPatterns_.size() > 0) {
235 subdmsghndlr.setSendPattern(vspace_->ownerPatterns_.find(nodeIDType_)->second);
236 subdmsghndlr.setRecvPattern(vspace_->sharerPatterns_.find(nodeIDType_)->second);
237 CHK_ERR( fei::exchange(comm, &subdmsghndlr) );
247 subdomainIDs = sharedIDs;
254 sd_iter = sdIDTable.begin(),
255 sd_end = sdIDTable.end();
257 for(
int i=0; sd_iter != sd_end; ++i, ++sd_iter) {
258 int id = sd_iter->first;
259 std::set<int>& procList = sd_iter->second;
266 std::vector<int>* newarray =
new std::vector<int>;
267 std::set<int>::const_iterator
268 p_iter = procList.begin(), p_end = procList.end();
270 for(; p_iter != p_end; ++p_iter) {
272 newarray->push_back(proc);
279 nodenumSubdomainDB_.insert(std::pair<
int,std::vector<int>*>(node->
getNumber(), newarray));
282 databasesBuilt_ =
true;
int GlobalSum(MPI_Comm comm, std::vector< T > &local, std::vector< T > &global)
GlobalIDType getNumber() const
int sortedListInsert(const T &item, std::vector< T > &list)
std::map< T, std::set< int > > map_type
map_type & getSharedIDs()
Lookup_Impl(fei::SharedPtr< fei::MatrixGraph > matGraph, int nodeIDType)
int getAssociatedFieldID(int eqnNumber)
int getAssociatedNodeNumber(int eqnNumber)
std::vector< fei::Record< int > > & getRecords()
int getNumIndices() const
virtual fei::SharedPtr< fei::VectorSpace > getRowSpace()=0
std::vector< int > & getFieldSizes()
std::vector< int > & getFieldIDs()
snl_fei::PointBlockMap * getPointBlockMap()
int localProc(MPI_Comm comm)
int getEqnNumber(int nodeNumber, int fieldID)
int getFieldEqnOffset(int fieldID, int &offset) const
GlobalIDType getID() const
bool isInLocalElement(int nodeNumber)
void destroyValues(MAP_TYPE &map_obj)
int getOffsetIntoEqnNumbers() const
fei::FieldMask * getFieldMask()
fei::Record< int > * getRecordWithID(int ID)
int getOffsetIntoBlkEqn(int blkEqn, int ptEqn)