FEI Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
fei_NodeDatabase.cpp
Go to the documentation of this file.
1/*--------------------------------------------------------------------*/
2/* Copyright 2005 Sandia Corporation. */
3/* Under the terms of Contract DE-AC04-94AL85000, there is a */
4/* non-exclusive license for use of this work by or on behalf */
5/* of the U.S. Government. Export of this program may require */
6/* a license from the United States Government. */
7/*--------------------------------------------------------------------*/
8
10
11#include <fei_CommUtils.hpp>
13#include <fei_NodeCommMgr.hpp>
14
15#include <fei_macros.hpp>
16#include <fei_TemplateUtils.hpp>
17#undef fei_file
18#define fei_file "fei_NodeDatabase.cpp"
19
20#include <fei_ErrMacros.hpp>
21
22//------------------------------------------------------------------------------
23NodeDatabase::NodeDatabase(std::map<int,int>* fieldDatabase,
24 NodeCommMgr* nodeCommMgr)
25 : nodePtrs_(),
26 eqnNumbers_(0), eqnNodeIndices_(),
27 nodeIDs_(),
28 nodeNumbers_(),
29 synchronized_(false),
30 need_to_alloc_and_sync_(true),
31 fieldDB_(fieldDatabase),
32 nodeCommMgr_(nodeCommMgr),
33 numLocalNodes_(0),
34 firstLocalNodeNumber_(-1), lastLocalNodeNumber_(-1),
35 nodePool_()
36{
37}
38
39//------------------------------------------------------------------------------
41{
43}
44
45//------------------------------------------------------------------------------
47{
48 for(size_t i=0; i<nodePtrs_.size(); ++i) {
51 }
52}
53
54//------------------------------------------------------------------------------
56{
57 int index = getIndexOfID(nodeID);
58 if (index < 0) {
59 //fei::console_out() << "FEI NodeDatabase: node " << (int)nodeID << " not found."<<FEI_ENDL;
60 return(-1);
61 }
62
63 node = nodePtrs_[index];
64 return(0);
65}
66
67//------------------------------------------------------------------------------
69{
70 int index = getIndexOfID(nodeID);
71 if (index < 0) {
72 //fei::console_out() << "FEI NodeDatabase: node " << (int)nodeID << " not found."<<FEI_ENDL;
73 return(-1);
74 }
75
76 node = nodePtrs_[index];
77 return(0);
78}
79
80//------------------------------------------------------------------------------
81int NodeDatabase::getNodeWithNumber(int nodeNumber, const NodeDescriptor*& node) const
82{
83 if (!synchronized_) ERReturn(-1);
84
85 std::map<int,int>::const_iterator iter = nodeNumbers_.find(nodeNumber);
86 if (iter == nodeNumbers_.end()) {
87 // The node wasn't found, return a NULL ptr.
88 node = NULL;
89 // Indicate that the node is NULL.
90 return -1;
91 }
92
93 int index = iter->second;
94 node = nodePtrs_[index];
95
96 return(0);
97}
98
99//------------------------------------------------------------------------------
100int NodeDatabase::getNodeWithEqn(int eqnNumber, const NodeDescriptor*& node) const
101{
102 int insertPoint = -1;
103 int index = fei::binarySearch(eqnNumber, eqnNumbers_, insertPoint);
104
105 if (index >= 0) {
106 node = nodePtrs_[eqnNodeIndices_[index]];
107 }
108 else if (insertPoint > 0) {
109 node = nodePtrs_[eqnNodeIndices_[insertPoint-1]];
110 }
111 else {
112 //We only reach this line if insertPoint==0, which means the specified
113 //eqnNumber lies below the equation-number for the first node in our list.
114 //In other words, we don't have the requested node.
115 return(-1);
116 }
117
118 //Now let's make sure that the specified equation is less than or equal to
119 //this node's last equation.
120
121 int numNodeFields = node->getNumFields();
122 if (numNodeFields <= 0) return(-1);
123
124 int lastFieldOnNode = node->getFieldIDList()[numNodeFields-1];
125
126 int lastFieldSize = (*fieldDB_)[lastFieldOnNode];
127
128 int lastEqnOnNode = node->getFieldEqnNumbers()[numNodeFields-1] +
129 lastFieldSize - 1;
130
131 if (eqnNumber <= lastEqnOnNode) return(0);
132
133 return(-1);
134}
135
136//------------------------------------------------------------------------------
137void NodeDatabase::getNodeAtIndex(int i, const NodeDescriptor*& node) const
138{
139 int nnodes = nodePtrs_.size();
140 if (i>=0 && i < nnodes) {
141 node = nodePtrs_[i];
142 }
143 else {
144 node = NULL;
145 }
146}
147
148//------------------------------------------------------------------------------
150{
151 int nnodes = nodePtrs_.size();
152 if (i>=0 && i < nnodes) {
153 node = nodePtrs_[i];
154 }
155 else {
156 node = NULL;
157 }
158}
159
160//------------------------------------------------------------------------------
162{
163 int numEqns = 0;
164
165 for(size_t i=0; i<nodePtrs_.size(); i++) {
166 NodeDescriptor* node = nodePtrs_[i];
167
168 if (node->getOwnerProc() == localRank) {
169 int numFields = node->getNumFields();
170 const int* fieldIDList = node->getFieldIDList();
171
172 for(int j=0; j<numFields; j++) {
173 int numParams = (*fieldDB_)[fieldIDList[j]];
174
175 numEqns += numParams;
176 }
177 }
178 }
179
180 return(numEqns);
181}
182
183//------------------------------------------------------------------------------
185{
186 int numLocal = 0;
187 for(size_t i=0; i<nodePtrs_.size(); i++) {
188 if (nodePtrs_[i]->getOwnerProc() == localRank) numLocal++;
189 }
190
191 return(numLocal);
192}
193
194//------------------------------------------------------------------------------
196{
197 std::map<GlobalID,int>::const_iterator
198 iter = nodeIDs_.find(nodeID);
199
200 if (iter == nodeIDs_.end()) return(-1);
201
202 return( iter->second );
203}
204
205//------------------------------------------------------------------------------
207{
208 static NodeDescriptor dummyNode;
209
210 int index = nodeIDs_.size();
211 std::map<GlobalID,int>::iterator
212 iter = nodeIDs_.lower_bound(nodeID);
213
214 if (iter == nodeIDs_.end() || iter->first != nodeID) {
215 nodeIDs_.insert(iter, std::make_pair(nodeID,index));
216
217 NodeDescriptor* nodePtr = nodePool_.allocate(1);
218 nodePool_.construct(nodePtr, dummyNode);
219
220 nodePtr->setGlobalNodeID(nodeID);
221
222 nodePtrs_.push_back(nodePtr);
223
225 }
226
227 return(0);
228}
229
230//------------------------------------------------------------------------------
231int NodeDatabase::initNodeIDs(GlobalID* nodeIDs, int numNodes)
232{
233 static NodeDescriptor dummyNode;
234
235 for(int i=0; i<numNodes; i++) {
236 initNodeID(nodeIDs[i]);
237 }
238
239 return(0);
240}
241
242//------------------------------------------------------------------------------
243int NodeDatabase::synchronize(int firstLocalNodeNumber,
244 int firstLocalEqn,
245 int localRank,
246 MPI_Comm comm)
247{
248 eqnNumbers_.reserve(nodePtrs_.size());
249 eqnNodeIndices_.reserve(nodePtrs_.size());
250
251 eqnNumbers_.resize(0);
252 eqnNodeIndices_.resize(0);
253
254 firstLocalNodeNumber_ = firstLocalNodeNumber;
255 int nodeNumber = firstLocalNodeNumber;
256 int numEqns = 0;
257
258 nodeNumbers_.clear();
259
260 numLocalNodes_ = 0;
261 std::map<GlobalID,int>::iterator
262 iter = nodeIDs_.begin(), iter_end = nodeIDs_.end();
263
264 for(; iter!=iter_end; ++iter) {
265 int i = iter->second;
266 NodeDescriptor* node = NULL;
267 getNodeAtIndex(i, node);
268 if (node==NULL) continue;
269
270 int numFields = node->getNumFields();
271 const int* fieldIDList = node->getFieldIDList();
272
273 int numNodalDOF = 0;
274 int firstEqnNumber, eqnNumber;
275
276 for(int j=0; j<numFields; j++) {
277 int numFieldParams = (*fieldDB_)[fieldIDList[j]];
278 numNodalDOF += numFieldParams;
279
280 if (node->getOwnerProc() == localRank) {
281 eqnNumber = firstLocalEqn + numEqns;
282 if (j==0) firstEqnNumber = eqnNumber;
283
284 numEqns += numFieldParams;
285
286 node->setFieldEqnNumber(fieldIDList[j], eqnNumber);
287 }
288 }
289
290 if (node->getOwnerProc() == localRank) {
291 node->setNodeNumber(nodeNumber++);
293
294 int insertPoint = fei::sortedListInsert(firstEqnNumber, eqnNumbers_);
295 if (insertPoint == -2) ERReturn(-2);
296 if (insertPoint >= 0) eqnNodeIndices_.insert(eqnNodeIndices_.begin()+insertPoint, i);
297 }
298
299 node->setNumNodalDOF(numNodalDOF);
300
301 int thisNodeNumber = node->getNodeNumber();
302 nodeNumbers_.insert(std::make_pair(thisNodeNumber, i));
303 }
304
305 lastLocalNodeNumber_ = nodeNumber - 1;
306
307 // next, have the node comm manager get the field IDs and
308 // equation numbers for all of the nodes that we know about but don't
309 // own. i.e., the remotely-owned shared nodes.
310 // Again, we'll get the nodeNumber info for those nodes while we're at it.
311 //
313
314 //Now finish up by inserting equation-numbers for shared nodes into our
315 //eqnNumbers_ and eqnNodeIndices_ lists, for future lookups...
316
317 int numSharedNodes = nodeCommMgr_->getNumSharedNodes();
318 for(int i=0; i<numSharedNodes; i++) {
320 GlobalID nodeID = node.getGlobalNodeID();
321 int index = getIndexOfID(nodeID);
322 int nDOF = node.getNumNodalDOF();
323 if (nDOF <= 0) {
324 continue;
325 //FEI_COUT << "localRank " << localRank << ", node "<<nodeID<<" has nDOF=" << nDOF<<FEI_ENDL;
326 //ERReturn(-1);
327 }
328 int firstEqn = node.getFieldEqnNumbers()[0];
329 int insertPoint = fei::sortedListInsert(firstEqn, eqnNumbers_);
330 if (insertPoint == -2) ERReturn(-2);
331 if (insertPoint >= 0) eqnNodeIndices_.insert(eqnNodeIndices_.begin()+insertPoint, index);
332
333 int thisNodeNumber = node.getNodeNumber();
334 nodeNumbers_.insert(std::make_pair(thisNodeNumber, index));
335 }
336
337 synchronized_ = true;
339
340 return(0);
341}
342
343//------------------------------------------------------------------------------
345{
346 int insertPoint = -1;
347 int index = fei::binarySearch(eqnNumber, eqnNumbers_, insertPoint);
348
349 if (index >= 0) {
350 return( nodePtrs_[eqnNodeIndices_[index]]->getNodeNumber() );
351 }
352
353 if (insertPoint > 0) {
354 NodeDescriptor& node = *(nodePtrs_[eqnNodeIndices_[insertPoint-1]]);
355 const int* fieldEqnNumbers = node.getFieldEqnNumbers();
356 const int* fieldIDList = node.getFieldIDList();
357 int numFields = node.getNumFields();
358
359 int lastEqn = fieldEqnNumbers[numFields-1];
360
361 int fieldSize = -1;
362 std::map<int,int>::const_iterator f_iter
363 = fieldDB_->find(fieldIDList[numFields-1]);
364 if (f_iter == fieldDB_->end()) ERReturn(-1);
365 fieldSize = (*f_iter).second;
366
367 //if eqnNumber is inside the range of eqn-numbers assocated with this node,
368 //then return this node's node-number
369 if (eqnNumber >= fieldEqnNumbers[0] && (lastEqn+fieldSize - 1) >= eqnNumber) {
370 return( node.getNodeNumber() );
371 }
372 }
373
374 //if we get to here, then we don't know how to locate the node with this
375 //eqn-number...
376 return(-1);
377}
378
379//------------------------------------------------------------------------------
381{
382 int insertPoint = -1;
383 int index = fei::binarySearch(eqnNumber, eqnNumbers_, insertPoint);
384
385 int index2 = index;
386 if (index2 < 0) index2 = insertPoint-1;
387
388 if (index2 < 0) ERReturn(-1);
389
390 NodeDescriptor& node = *(nodePtrs_[eqnNodeIndices_[index2]]);
391
392 const int* fieldEqnNumbers = node.getFieldEqnNumbers();
393 const int* fieldIDList = node.getFieldIDList();
394 int numFields = node.getNumFields();
395
396 int lastEqn = fieldEqnNumbers[numFields-1];
397
398 int fieldSize = -1;
399 std::map<int,int>::const_iterator f_iter
400 = fieldDB_->find(fieldIDList[numFields-1]);
401 if (f_iter == fieldDB_->end()) ERReturn(-1);
402 fieldSize = (*f_iter).second;
403
404 //if eqnNumber is outside the range of eqn-numbers that are associated with
405 //this node, then we're in trouble...
406 if (eqnNumber < fieldEqnNumbers[0] || eqnNumber > lastEqn+fieldSize) {
407 ERReturn(-1);
408 }
409
410 //ok, so we're ready to figure out which fieldID eqnNumber is associated with.
411 for(int i=0; i<numFields-1; i++) {
412 if (eqnNumber >= fieldEqnNumbers[i] && eqnNumber < fieldEqnNumbers[i+1]) {
413 return(fieldIDList[i]);
414 }
415 }
416
417 //if we get to here, then eqnNumber is associated with the last fieldID on the
418 //node.
419 return(fieldIDList[numFields-1]);
420}
NodeDescriptor & getSharedNodeAtIndex(int index)
size_t getNumSharedNodes()
std::vector< NodeDescriptor * > nodePtrs_
int getIndexOfID(GlobalID nodeID) const
int synchronize(int firstLocalNodeNumber, int firstLocalEqn, int localRank, MPI_Comm comm)
int getNodeWithID(GlobalID nodeID, const NodeDescriptor *&node) const
int getNodeWithNumber(int nodeNumber, const NodeDescriptor *&node) const
virtual ~NodeDatabase()
std::vector< int > eqnNodeIndices_
int getAssociatedNodeNumber(int eqnNumber)
NodeCommMgr * nodeCommMgr_
std::map< int, int > * fieldDB_
int getNodeWithEqn(int eqnNumber, const NodeDescriptor *&node) const
int initNodeIDs(GlobalID *nodeIDs, int numNodes)
NodeDatabase(std::map< int, int > *fieldDatabase, NodeCommMgr *nodeCommMgr)
int countLocalNodalEqns(int localRank)
void getNodeAtIndex(int i, const NodeDescriptor *&node) const
std::vector< int > eqnNumbers_
std::map< int, int > nodeNumbers_
int getAssociatedFieldID(int eqnNumber)
int initNodeID(GlobalID nodeID)
int countLocalNodeDescriptors(int localRank)
fei_Pool_alloc< NodeDescriptor > nodePool_
std::map< GlobalID, int > nodeIDs_
void setFieldEqnNumber(int fieldID, int eqn)
void setNumNodalDOF(int dof)
void setNodeNumber(int nn)
void setGlobalNodeID(GlobalID node)
int getNumNodalDOF() const
int getNodeNumber() const
int getOwnerProc() const
GlobalID getGlobalNodeID() const
const int * getFieldEqnNumbers() const
int getNumFields() const
const int * getFieldIDList() const
void construct(U *p, const U &val)
pointer allocate(size_type n, const void *hint=NULL)
void deallocate(pointer p, size_type n)
void destroy(U *p)
#define ERReturn(a)
#define CHK_ERR(a)
int GlobalID
Definition: fei_defs.h:60
#define MPI_Comm
Definition: fei_mpi.h:56
int binarySearch(const T &item, const T *list, int len)
int sortedListInsert(const T &item, std::vector< T > &list)