FEI Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
fei_Lookup_Impl.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
9#include <fei_macros.hpp>
10
11#include <fei_Lookup_Impl.hpp>
12
13#include <fei_VectorSpace.hpp>
14
15#include <snl_fei_Utils.hpp>
16#include <fei_TemplateUtils.hpp>
17#include <fei_CommUtils.hpp>
18
20
22
23#undef fei_file
24#define fei_file "fei_Lookup_Impl.cpp"
25#include <fei_ErrMacros.hpp>
26
27//----------------------------------------------------------------------------
29 int nodeIDType)
30 : matGraph_(matGraph),
31 ptBlkMap_(NULL),
32 vspace_(),
33 nodeIDType_(nodeIDType),
34 nodenumPairs_(),
35 eqnnumPairs_(),
36 nodenumSubdomainDB_(),
37 databasesBuilt_(false),
38 fieldIDs_(),
39 fieldSizes_(),
40 elemBlockIDs_(0, 4),
41 fieldIDs_2D_(),
42 workspace_()
43{
46
47 int err = buildDatabases();
48 if (err != 0) {
50 }
51}
52
53//----------------------------------------------------------------------------
55{
56 fei::destroyValues(nodenumSubdomainDB_);
57 nodenumSubdomainDB_.clear();
58}
59
60//----------------------------------------------------------------------------
61int fei::Lookup_Impl::getEqnNumber(int nodeNumber, int fieldID)
62{
63 std::map<int,fei::Record<int>*>::iterator
64 nnp_iter = nodenumPairs_.find(nodeNumber);
65
66 if (nnp_iter == nodenumPairs_.end()) return(-1);
67
68 fei::Record<int>* node = (*nnp_iter).second;
69
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");
74 }
75 eqnNumbers += node->getOffsetIntoEqnNumbers();
76 int offset = -1;
77 int err = node->getFieldMask()->getFieldEqnOffset(fieldID, offset);
78 if (err == 0) {
79 return(eqnNumbers[offset]);
80 }
81
82 return -1;
83}
84
85//----------------------------------------------------------------------------
87{
88 std::map<int,fei::Record<int>*>::iterator
89 enp_iter = eqnnumPairs_.find(eqnNumber);
90
91 if (enp_iter == eqnnumPairs_.end()) return(-1);
92
93 fei::Record<int>* node = (*enp_iter).second;
94
95 return( node->getNumber() );
96}
97
98//----------------------------------------------------------------------------
100{
101 std::map<int,fei::Record<int>*>::iterator
102 enp_iter = eqnnumPairs_.find(eqnNumber);
103
104 if (enp_iter == eqnnumPairs_.end()) return(-1);
105
106 fei::Record<int>* node = (*enp_iter).second;
107
108 return( node->getID() );
109}
110
111//----------------------------------------------------------------------------
113{
114 std::map<int,fei::Record<int>*>::iterator
115 enp_iter = eqnnumPairs_.find(eqnNumber);
116
117 if (enp_iter == eqnnumPairs_.end()) return(-1);
118
119 fei::Record<int>* node = (*enp_iter).second;
120
121 fei::FieldMask* fm = node->getFieldMask();
122 const std::vector<int>& fieldIDs = fm->getFieldIDs();
123 const std::vector<int>& fieldSizes = fm->getFieldSizes();
124
125 const std::vector<int>& eqnNumbers = vspace_->getEqnNumbers();
126
127 int baseEqnOffset = node->getOffsetIntoEqnNumbers();
128 int numNodalEqns = fm->getNumIndices();
129
130 if (baseEqnOffset + numNodalEqns > (int)eqnNumbers.size()) {
131 throw std::runtime_error("fei::Lookup_Impl::getAssociatedFieldID ERROR, nodal eqn offset out of range.");
132 }
133
134 int offset = 0;
135 int eqn = eqnNumbers[baseEqnOffset];
136 while(eqn < eqnNumber && offset < numNodalEqns) {
137 eqn = eqnNumbers[baseEqnOffset + ++offset];
138 }
139
140 if (eqn != eqnNumber) {
141 throw std::runtime_error("fei::Lookup_Impl::getAssociatedFieldID ERROR, eqnNumber not found");
142 }
143
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) {
148 return fieldIDs[i];
149 }
150 }
151
152 return -1;
153}
154
155//----------------------------------------------------------------------------
157{
158 std::map<int,std::vector<int>* >::iterator
159 nns_iter = nodenumSubdomainDB_.find(nodeNumber);
160 if (nns_iter != nodenumSubdomainDB_.end()) {
161 return( true );
162 }
163
164 std::map<int,fei::Record<int>*>::iterator
165 nnp_iter = nodenumPairs_.find(nodeNumber);
166
167 return(nnp_iter != nodenumPairs_.end() ? true : false);
168}
169
170//----------------------------------------------------------------------------
172{
173 //assume blkEqn is a node-number, for now.
174 std::map<int,fei::Record<int>*>::iterator
175 nnp_iter = nodenumPairs_.find(blkEqn);
176
177 if (nnp_iter == nodenumPairs_.end()) return(-1);
178
179 fei::Record<int>* node = (*nnp_iter).second;
180
181 int eqn = vspace_->getEqnNumbers()[node->getOffsetIntoEqnNumbers()];
182 return(ptEqn - eqn);
183}
184
185//----------------------------------------------------------------------------
187{
188 if (databasesBuilt_) return(0);
189
190 snl_fei::RecordCollection* collection = NULL;
191 int err = vspace_->getRecordCollection(nodeIDType_, collection);
192 if (err != 0) {
193 //probably means that vspace_ doesn't have 'nodeIDType_', so we'll skip the
194 //rest of this function. It's not a problem if vspace_ doesn't have nodeIDType_.
195 return(0);
196 }
197
198 std::vector<int>& vspcEqnNumbers = vspace_->getEqnNumbers();
199
200 std::vector<fei::Record<int> >& rvec = collection->getRecords();
201
202 for(size_t i=0; i<rvec.size(); ++i) {
203 fei::Record<int>* node = &rvec[i];
204
205 std::pair<int,fei::Record<int>* > int_node_pair(node->getNumber(), node);
206
207 nodenumPairs_.insert(int_node_pair);
208
209 int numEqns = node->getFieldMask()->getNumIndices();
210 int* eqnNumbers = &vspcEqnNumbers[0]
211 + node->getOffsetIntoEqnNumbers();
212
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);
216 }
217 }
218
219 MPI_Comm comm = matGraph_->getRowSpace()->getCommunicator();
220
221 int numLocalLagrangeConstraints = matGraph_->getLagrangeConstraints().size();
222
223 int numGlobalLagrangeConstraints = 0;
224 fei::GlobalSum(comm, numLocalLagrangeConstraints, numGlobalLagrangeConstraints);
225
226 bool noconstraints = numGlobalLagrangeConstraints<1 ? true : false;
227
228 fei::SharedIDs<int> subdomainIDs;
229 fei::SharedIDs<int>& sharedIDs = vspace_->getSharedIDs(nodeIDType_);
230
231 if (noconstraints == false) {
232 snl_fei::SubdMsgHandler subdmsghndlr(collection, &sharedIDs, &subdomainIDs);
233
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) );
238 }
239
240 //Now the subdomainIDs object contains a mapping from each shared ID to a
241 //list of processors that have that ID in their local subdomain.
242 //So what we'll do next is run through the list of IDs in subdomainIDs and
243 //for each ID, store the corresponding node-number in a database together
244 //with a pointer to a list (vector) of the subdomain-processors.
245 }
246 else {
247 subdomainIDs = sharedIDs;
248 }
249
250 int local_proc = fei::localProc(comm);
251
252 fei::SharedIDs<int>::map_type& sdIDTable = subdomainIDs.getSharedIDs();
254 sd_iter = sdIDTable.begin(),
255 sd_end = sdIDTable.end();
256
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;
260
261 fei::Record<int>* node = collection->getRecordWithID(id);
262 if (node == NULL) {
263 ERReturn(-1);
264 }
265
266 std::vector<int>* newarray = new std::vector<int>;
267 std::set<int>::const_iterator
268 p_iter = procList.begin(), p_end = procList.end();
269
270 for(; p_iter != p_end; ++p_iter) {
271 int proc = *p_iter;
272 newarray->push_back(proc);
273 }
274
275 if (node->isInLocalSubdomain_) {
276 fei::sortedListInsert(local_proc, *newarray);
277 }
278
279 nodenumSubdomainDB_.insert(std::pair<int,std::vector<int>*>(node->getNumber(), newarray));
280 }
281
282 databasesBuilt_ = true;
283 return(0);
284}
285
std::vector< int > & getFieldSizes()
std::vector< int > & getFieldIDs()
int getFieldEqnOffset(int fieldID, int &offset) const
int getNumIndices() const
int getOffsetIntoBlkEqn(int blkEqn, int ptEqn)
bool isInLocalElement(int nodeNumber)
int getAssociatedFieldID(int eqnNumber)
int getEqnNumber(int nodeNumber, int fieldID)
fei::SharedPtr< fei::MatrixGraph > matGraph_
fei::SharedPtr< fei::VectorSpace > vspace_
int getAssociatedNodeID(int eqnNumber)
int getAssociatedNodeNumber(int eqnNumber)
Lookup_Impl(fei::SharedPtr< fei::MatrixGraph > matGraph, int nodeIDType)
snl_fei::PointBlockMap * ptBlkMap_
virtual fei::SharedPtr< fei::VectorSpace > getRowSpace()=0
fei::FieldMask * getFieldMask()
Definition: fei_Record.hpp:106
GlobalIDType getID() const
Definition: fei_Record.hpp:46
bool isInLocalSubdomain_
Definition: fei_Record.hpp:162
int getOffsetIntoEqnNumbers() const
Definition: fei_Record.hpp:126
GlobalIDType getNumber() const
Definition: fei_Record.hpp:58
map_type & getSharedIDs()
std::map< T, std::set< int > > map_type
snl_fei::PointBlockMap * getPointBlockMap()
std::vector< fei::Record< int > > & getRecords()
fei::Record< int > * getRecordWithID(int ID)
void setRecvPattern(fei::comm_map *pattern)
void setSendPattern(fei::comm_map *pattern)
#define ERReturn(a)
#define voidERReturn
#define CHK_ERR(a)
#define MPI_Comm
Definition: fei_mpi.h:56
int localProc(MPI_Comm comm)
void destroyValues(MAP_TYPE &map_obj)
int exchange(MPI_Comm comm, MessageHandler< T > *msgHandler)
int sortedListInsert(const T &item, std::vector< T > &list)
int GlobalSum(MPI_Comm comm, std::vector< T > &local, std::vector< T > &global)