FEI Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
snl_fei_RecordCollection.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_sstream.hpp"
10
11#include "fei_FieldMask.hpp"
12#include "fei_Record.hpp"
14#include "fei_SharedIDs.hpp"
15
16#undef fei_file
17#define fei_file "snl_fei_RecordCollection.cpp"
18#include "fei_ErrMacros.hpp"
19
20//----------------------------------------------------------------------------
22 : m_records(),
23 m_global_to_local(),
24 m_minID(99999999),
25 m_maxID(0),
26 localProc_(localProc),
27 debugOutput_(false),
28 dbgOut_(NULL)
29{
30 m_records.reserve(2000);
31}
32
33//----------------------------------------------------------------------------
35 : m_records(src.m_records),
36 m_global_to_local(src.m_global_to_local),
37 m_minID(99999999),
38 m_maxID(0),
39 localProc_(src.localProc_),
40 debugOutput_(src.debugOutput_),
41 dbgOut_(src.dbgOut_)
42{
43}
44
45//----------------------------------------------------------------------------
47{
48}
49
51 const int* localIDs_begin, const int* localIDs_end,
52 const int* globalIDs_begin, const int* globalIDs_end)
53{
54 int numLocal = localIDs_end - localIDs_begin;
55 int numGlobal = globalIDs_end - globalIDs_begin;
56 if (numLocal != numGlobal) {
57 throw std::runtime_error("RecordCollection::setIDMap ERROR, num local IDs must match num global IDs.");
58 }
59 m_global_to_local.clear();
60 m_records.resize(numLocal);
61 const int* localID_iter = localIDs_begin;
62 const int* globalID_iter = globalIDs_begin;
63 for(int i=0; i<numLocal; ++i) {
64 int lid = *localID_iter++;
65 int gid = *globalID_iter++;
66 m_records[lid].setID(gid);
67 m_records[lid].setOwnerProc(localProc_);
68 m_global_to_local.insert(std::make_pair(gid, lid));
69 }
70}
71
72//----------------------------------------------------------------------------
73void snl_fei::RecordCollection::initRecords(int numIDs, const int* IDs,
74 std::vector<fei::FieldMask*>& fieldMasks,
75 int* recordLocalIDs)
76{
77 int maskID = 0;
78 fei::FieldMask* mask = NULL;
79 for(unsigned m=0; m<fieldMasks.size(); ++m) {
80 if (maskID == fieldMasks[m]->getMaskID()) {
81 mask = fieldMasks[m]; break;
82 }
83 }
84
85 if (mask == NULL) {
86 mask = new fei::FieldMask();
87 maskID = mask->getMaskID();
88 fieldMasks.push_back(mask);
89 }
90
91 for(int i=0; i<numIDs; ++i) {
92 if (m_minID > IDs[i]) m_minID = IDs[i];
93 if (m_maxID < IDs[i]) m_maxID = IDs[i];
94
95 int local_id = -1;
96 std::map<int,int>::iterator iter = m_global_to_local.lower_bound(IDs[i]);
97 if (iter == m_global_to_local.end() || iter->first != IDs[i]) {
98 //record doesn't exist, so we'll add a new one.
99 local_id = m_records.size();
100 m_global_to_local.insert(iter, std::make_pair(IDs[i], local_id));
101 fei::Record<int> record;
102 record.setID(IDs[i]);
103 record.setFieldMask(mask);
104 record.setOwnerProc(-1);
105 m_records.push_back(record);
106 }
107 else {
108 local_id = iter->second;
109 }
110
111 if (recordLocalIDs != NULL) recordLocalIDs[i] = local_id;
112 }
113}
114
115//----------------------------------------------------------------------------
116void snl_fei::RecordCollection::initRecords(int fieldID, int fieldSize,
117 int numIDs, const int* IDs,
118 std::vector<fei::FieldMask*>& fieldMasks,
119 int* recordLocalIDs)
120{
121 int maskID = fei::FieldMask::calculateMaskID(1, &fieldID);
122 fei::FieldMask* mask = NULL;
123 for(unsigned m=0; m<fieldMasks.size(); ++m) {
124 if (maskID == fieldMasks[m]->getMaskID()) {
125 mask = fieldMasks[m]; break;
126 }
127 }
128
129 if (mask == NULL) {
130 mask = new fei::FieldMask(1, &fieldID, &fieldSize);
131 maskID = mask->getMaskID();
132 fieldMasks.push_back(mask);
133 }
134
135 int lastMaskID = maskID;
136 fei::FieldMask* lastMask = mask;
137
138 for(int i=0; i<numIDs; ++i) {
139 if (m_minID > IDs[i]) m_minID = IDs[i];
140 if (m_maxID < IDs[i]) m_maxID = IDs[i];
141 int local_id;
142 std::map<int,int>::iterator iter = m_global_to_local.lower_bound(IDs[i]);
143 if (iter == m_global_to_local.end() || iter->first != IDs[i]) {
144 //record doesn't exist, so we'll add a new one.
145 local_id = m_records.size();
146 m_global_to_local.insert(iter, std::make_pair(IDs[i], local_id));
147 fei::Record<int> record;
148 record.setID(IDs[i]);
149 record.setFieldMask(mask);
150 record.setOwnerProc(-1);
151 m_records.push_back(record);
152
153 if (recordLocalIDs != NULL) {
154 recordLocalIDs[i] = local_id;
155 }
156 }
157 else {
158 local_id = iter->second;
159 fei::Record<int>& record = m_records[local_id];
160
161 if (recordLocalIDs != NULL) {
162 recordLocalIDs[i] = local_id;
163 }
164
165 fei::FieldMask* thisMask = record.getFieldMask();
166 if (thisMask == NULL) {
167 record.setFieldMask(mask);
168 }
169
170 int thisMaskID = record.getFieldMask()->getMaskID();
171
172 if (maskID == thisMaskID || thisMask->hasFieldID(fieldID)) {
173 continue;
174 }
175
176 if (lastMaskID == thisMaskID) {
177 record.setFieldMask(lastMask);
178 continue;
179 }
180
181 int newMaskID = fei::FieldMask::calculateMaskID(*thisMask, fieldID);
182 if (lastMaskID == newMaskID) {
183 record.setFieldMask(lastMask);
184 continue;
185 }
186
187 bool newMaskAlreadyExists = false;
188 for(unsigned m=0; m<fieldMasks.size(); ++m) {
189 if (newMaskID == fieldMasks[m]->getMaskID()) {
190 lastMask = fieldMasks[m];
191 lastMaskID = lastMask->getMaskID();
192 record.setFieldMask(lastMask);
193 newMaskAlreadyExists = true;
194 break;
195 }
196 }
197
198 if (!newMaskAlreadyExists) {
199 fei::FieldMask* newmask = new fei::FieldMask(*record.getFieldMask());
200 newmask->addField(fieldID, fieldSize);
201 record.setFieldMask(newmask);
202 fieldMasks.push_back(newmask);
203 lastMask = newmask;
204 lastMaskID = lastMask->getMaskID();
205 }
206 }
207 }
208}
209
210//----------------------------------------------------------------------------
212{
213 for(size_t i=0; i<m_records.size(); ++i) {
214 fei::Record<int>& rec = m_records[i];
215 if (rec.getOwnerProc() == -1) rec.setOwnerProc(localProc_);
216 }
217}
218
219//----------------------------------------------------------------------------
221{
223 s_beg = sharedIDs.getSharedIDs().begin(),
224 s_end = sharedIDs.getSharedIDs().end(),
225 s_it;
226
227 std::vector<int>& owningProcs = sharedIDs.getOwningProcs();
228
229 int i=0;
230 for(i=0, s_it = s_beg; s_it != s_end; ++i, ++s_it) {
231 int sh_id = s_it->first;
232 fei::Record<int>* record = getRecordWithID(sh_id);
233 if (record == NULL) continue;
234
235 int rec_owner = record->getOwnerProc();
236
237// if (rec_owner != -1 && rec_owner != owningProcs[i]) {
238// std::cout<<record->getID()<<": owner="<<rec_owner<<" but lowest sharer="<<owningProcs[i]<<std::endl;
239// }
240
241 if (rec_owner != -1) owningProcs[i] = rec_owner;
242 else {
243 rec_owner = owningProcs[i];
244 record->setOwnerProc(rec_owner);
245 }
246
247 if (debugOutput_) {
248 *dbgOut_ << "# setting ID " << (int)(record->getID())
249 << "'s owner to proc " << rec_owner << FEI_ENDL;
250 }
251 }
252}
253
255{
256 std::map<int,int>::iterator iter = m_global_to_local.find(ID);
257
258 if (iter == m_global_to_local.end()) {
259 return( NULL );
260 }
261
262 return(&m_records[iter->second]);
263}
264
266{
267 std::map<int,int>::const_iterator iter = m_global_to_local.find(ID);
268
269 if (iter == m_global_to_local.end()) {
270 return( NULL );
271 }
272
273 return(&m_records[iter->second]);
274}
275
276int snl_fei::RecordCollection::getGlobalBlkIndex(int ID, int& globalBlkIndex)
277{
278 fei::Record<int>* record = getRecordWithID(ID);
279 if (record == NULL) {
280 globalBlkIndex = -1;
281 ERReturn(-1);
282 }
283
284 globalBlkIndex = record->getNumber();
285 return(0);
286}
287
288//----------------------------------------------------------------------------
290 int fieldID,
291 int fieldSize,
292 int fieldOffset,
293 int whichComponentOfField,
294 const int* eqnNumbers)
295{
296 fei::Record<int>* record = getRecordWithID(ID);
297 if (record == NULL) {
298 return -1;
299 }
300
301 fei::FieldMask* mask = record->getFieldMask();
302 int offset = 0;
303 int err = mask->getFieldEqnOffset(fieldID, offset);
304 if (err != 0) {
305 return -1;
306 }
307
308 const int* eqnNums = eqnNumbers + record->getOffsetIntoEqnNumbers();
309 if (eqnNums == NULL) {
310 FEI_OSTRINGSTREAM osstr;
311 osstr << "snl_fei::RecordCollection::getGlobalIndex ERROR: null pointer,"
312 << " possibly because initComplete() hasn't been called yet?";
313 throw std::runtime_error(osstr.str());
314 }
315
316 int globalIndex = -1;
317 if (fieldOffset > 0) {
318 globalIndex = eqnNums[offset + fieldOffset*fieldSize + whichComponentOfField];
319 }
320 else {
321 globalIndex = eqnNums[offset + whichComponentOfField];
322 }
323
324 return(globalIndex);
325}
326
327//----------------------------------------------------------------------------
329 int fieldID,
330 int fieldSize,
331 int fieldOffset,
332 int whichComponentOfField,
333 const int* eqnNumbers)
334{
335 fei::Record<int>* record = getRecordWithLocalID(localID);
336 if (record == NULL) {
337 FEI_OSTRINGSTREAM osstr;
338 osstr << "snl_fei::RecordCollection::getGlobalIndexLocalID ERROR, no record with "
339 << "localID=" << localID;
340 throw std::runtime_error(osstr.str());
341 }
342
343 fei::FieldMask* mask = record->getFieldMask();
344 int offset = 0;
345 int err = mask->getFieldEqnOffset(fieldID, offset);
346 if (err != 0) {
347 return -1;
348 }
349
350 const int* eqnNums = eqnNumbers + record->getOffsetIntoEqnNumbers();
351 if (eqnNums == NULL) {
352 FEI_OSTRINGSTREAM osstr;
353 osstr << "snl_fei::RecordCollection::getGlobalIndex ERROR: null pointer,"
354 << " possibly because initComplete() hasn't been called yet?";
355 throw std::runtime_error(osstr.str());
356 }
357
358 int globalIndex = -1;
359 if (fieldOffset > 0) {
360 globalIndex = eqnNums[offset + fieldOffset*fieldSize + whichComponentOfField];
361 }
362 else {
363 globalIndex = eqnNums[offset + whichComponentOfField];
364 }
365
366 return(globalIndex);
367}
bool hasFieldID(int fieldID) const
void addField(int fieldID, int fieldSize)
int getFieldEqnOffset(int fieldID, int &offset) const
void setID(const GlobalIDType &ID)
Definition: fei_Record.hpp:40
fei::FieldMask * getFieldMask()
Definition: fei_Record.hpp:106
GlobalIDType getID() const
Definition: fei_Record.hpp:46
int getOffsetIntoEqnNumbers() const
Definition: fei_Record.hpp:126
void setOwnerProc(int owner)
Definition: fei_Record.hpp:88
void setFieldMask(fei::FieldMask *fm)
Definition: fei_Record.hpp:100
GlobalIDType getNumber() const
Definition: fei_Record.hpp:58
int getOwnerProc() const
Definition: fei_Record.hpp:94
map_type & getSharedIDs()
std::vector< int > & getOwningProcs()
int getGlobalIndex(int ID, int fieldID, int fieldSize, int fieldOffset, int whichComponentOfField, const int *eqnNumbers)
void initRecords(int numIDs, const int *IDs, std::vector< fei::FieldMask * > &fieldMasks, int *recordLocalIDs=NULL)
void setOwners_lowestSharing(fei::SharedIDs< int > &sharedIDs)
int getGlobalIndexLocalID(int localID, int fieldID, int fieldSize, int fieldOffset, int whichComponentOfField, const int *eqnNumbers)
void setIDMap(const int *localIDs_begin, const int *localIDs_end, const int *globalIDs_begin, const int *globalIDs_end)
int getGlobalBlkIndex(int ID, int &globalBlkIndex)
fei::Record< int > * getRecordWithID(int ID)
std::vector< fei::Record< int > > m_records
#define ERReturn(a)
#define FEI_ENDL
#define FEI_OSTRINGSTREAM
Definition: fei_sstream.hpp:32