snl_fei_RecordCollection.cpp

00001 /*--------------------------------------------------------------------*/
00002 /*    Copyright 2005 Sandia Corporation.                              */
00003 /*    Under the terms of Contract DE-AC04-94AL85000, there is a       */
00004 /*    non-exclusive license for use of this work by or on behalf      */
00005 /*    of the U.S. Government.  Export of this program may require     */
00006 /*    a license from the United States Government.                    */
00007 /*--------------------------------------------------------------------*/
00008 
00009 #include "fei_sstream.hpp"
00010 
00011 #include "fei_FieldMask.hpp"
00012 #include "fei_Record.hpp"
00013 #include "snl_fei_RecordCollection.hpp"
00014 #include "fei_SharedIDs.hpp"
00015 
00016 #undef fei_file
00017 #define fei_file "snl_fei_RecordCollection.cpp"
00018 #include "fei_ErrMacros.hpp"
00019 
00020 //----------------------------------------------------------------------------
00021 snl_fei::RecordCollection::RecordCollection(int localProc)
00022   : records_(),
00023     localProc_(localProc),
00024     recordPool_(),
00025     debugOutput_(false),
00026     dbgOut_(NULL)
00027 {
00028 }
00029 
00030 //----------------------------------------------------------------------------
00031 snl_fei::RecordCollection::RecordCollection(const RecordCollection& src)
00032   : records_(),
00033     localProc_(src.localProc_),
00034     recordPool_(),
00035     debugOutput_(src.debugOutput_),
00036     dbgOut_(src.dbgOut_)
00037 {
00038   map_type& srcRecords =
00039     const_cast<map_type&>(src.records_);
00040   map_type::iterator
00041     iter = srcRecords.begin(),
00042     iter_end = srcRecords.end();
00043 
00044   map_type::iterator records_end = records_.end();
00045 
00046   static fei::Record<int> dummyRecord;
00047 
00048   for(; iter != iter_end; ++iter) {
00049     map_type::value_type srcpair = *iter;
00050     int srcID = srcpair.first;
00051     fei::Record<int>* srcRec = srcpair.second;
00052 
00053     fei::Record<int>* record = recordPool_.allocate(1);
00054     recordPool_.construct(record,dummyRecord);
00055     *record = *srcRec;
00056     records_.insert(records_end, map_type::value_type(srcID, record));
00057   }
00058 }
00059 
00060 //----------------------------------------------------------------------------
00061 snl_fei::RecordCollection::~RecordCollection()
00062 {
00063 }
00064 
00065 //----------------------------------------------------------------------------
00066 void snl_fei::RecordCollection::initRecords(int numIDs, const int* IDs,
00067                                             std::vector<fei::FieldMask*>& fieldMasks,
00068                                             fei::Record<int>** records)
00069 {
00070   int maskID = 0;
00071   fei::FieldMask* mask = NULL;
00072   for(unsigned m=0; m<fieldMasks.size(); ++m) {
00073     if (maskID == fieldMasks[m]->getMaskID()) {
00074       mask = fieldMasks[m]; break;
00075     }
00076   }
00077 
00078   if (mask == NULL) {
00079     mask = new fei::FieldMask();
00080     maskID = mask->getMaskID();
00081     fieldMasks.push_back(mask);
00082   }
00083 
00084   static fei::Record<int> dummyRecord;
00085 
00086   for(int i=0; i<numIDs; ++i) {
00087     fei::Record<int>* record = NULL;
00088 
00089     map_type::iterator riter = records_.lower_bound(IDs[i]);
00090     if (riter != records_.end()) {
00091       if ((*riter).first != IDs[i]) {
00092         record = recordPool_.allocate(1);
00093         recordPool_.construct(record,dummyRecord);
00094 
00095         record->setID(IDs[i]);
00096         record->setFieldMask(mask);
00097         record->setOwnerProc(localProc_);
00098 
00099         records_.insert(riter, map_type::value_type(IDs[i], record));
00100       }
00101       else {
00102         record = (*riter).second;
00103 
00104         record->setFieldMask(mask);
00105       }
00106     }
00107     else {
00108       record = recordPool_.allocate(1);
00109       recordPool_.construct(record,dummyRecord);
00110 
00111       record->setID(IDs[i]);
00112       record->setFieldMask(mask);
00113       record->setOwnerProc(localProc_);
00114 
00115       records_.insert(riter, map_type::value_type(IDs[i], record));
00116     }
00117 
00118     if (records != NULL) {
00119       records[i] = record;
00120     }
00121   }
00122 }
00123 
00124 //----------------------------------------------------------------------------
00125 void snl_fei::RecordCollection::initRecords(int fieldID, int fieldSize,
00126                                             int numInstances,
00127                                             int numIDs, const int* IDs,
00128                                             std::vector<fei::FieldMask*>& fieldMasks,
00129                                             bool skipIDsWithThisField)
00130 {
00131   int maskID = fei::FieldMask::calculateMaskID(1, &fieldID,
00132                                                       &numInstances);
00133   fei::FieldMask* mask = NULL;
00134   for(unsigned m=0; m<fieldMasks.size(); ++m) {
00135     if (maskID == fieldMasks[m]->getMaskID()) {
00136       mask = fieldMasks[m]; break;
00137     }
00138   }
00139 
00140   if (mask == NULL) {
00141     mask = new fei::FieldMask(1, &fieldID, &fieldSize, &numInstances);
00142     maskID = mask->getMaskID();
00143     fieldMasks.push_back(mask);
00144   }
00145 
00146   fei::FieldMask* lastMask = mask;
00147   int lastMaskID = maskID;
00148   static fei::Record<int> dummyRecord;
00149 
00150   for(int i=0; i<numIDs; ++i) {
00151     fei::Record<int>* record = NULL;
00152 
00153     map_type::iterator riter = records_.lower_bound(IDs[i]);
00154 
00155     if (riter != records_.end()) {
00156       if ((*riter).first != IDs[i]) {
00157         record = recordPool_.allocate(1);
00158         recordPool_.construct(record,dummyRecord);
00159 
00160         record->setID(IDs[i]);
00161         record->setFieldMask(mask);
00162         record->setOwnerProc(localProc_);
00163 
00164         records_.insert(riter, map_type::value_type(IDs[i], record));
00165       }
00166       else {
00167         record = (*riter).second;
00168 
00169         int thisMaskID = record->getFieldMask()->getMaskID();
00170 
00171         if (skipIDsWithThisField) {
00172           if (maskID == thisMaskID) continue;
00173           if (record->getFieldMask()->hasFieldID(fieldID)) continue;
00174         }
00175 
00176         if (lastMaskID == thisMaskID) {
00177           record->setFieldMask(lastMask);
00178           continue;
00179         }
00180 
00181         fei::FieldMask* thisMask = record->getFieldMask();
00182         int newMaskID = fei::FieldMask::calculateMaskID(*thisMask,
00183                                                             fieldID, numInstances);
00184         if (lastMaskID == newMaskID) {
00185           record->setFieldMask(lastMask);
00186           continue;
00187         }
00188 
00189         bool newMaskAlreadyExists = false;
00190         for(unsigned m=0; m<fieldMasks.size(); ++m) {
00191           if (newMaskID == fieldMasks[m]->getMaskID()) {
00192             lastMask = fieldMasks[m];
00193             lastMaskID = lastMask->getMaskID();
00194             record->setFieldMask(lastMask);
00195             newMaskAlreadyExists = true;
00196             break;
00197           }
00198         }
00199 
00200         if (!newMaskAlreadyExists) {
00201           fei::FieldMask* newmask = new fei::FieldMask(*record->getFieldMask());
00202           newmask->addField(fieldID, fieldSize, numInstances);
00203           record->setFieldMask(newmask);
00204           fieldMasks.push_back(newmask);
00205           lastMask = newmask;
00206           lastMaskID = lastMask->getMaskID();
00207         }
00208       }
00209     }
00210     else {
00211       record = recordPool_.allocate(1);
00212       recordPool_.construct(record,dummyRecord);
00213       record->setID(IDs[i]);
00214       record->setFieldMask(mask);
00215       record->setOwnerProc(localProc_);
00216 
00217       records_.insert(riter, map_type::value_type(IDs[i], record));
00218     }
00219   }
00220 }
00221 
00222 //----------------------------------------------------------------------------
00223 void snl_fei::RecordCollection::initRecords(int fieldID, int fieldSize,
00224                                               int numInstances,
00225                                               int numIDs, const int* IDs,
00226                                               std::vector<fei::FieldMask*>& fieldMasks,
00227                                               fei::Record<int>** records,
00228                                               bool skipIDsWithThisField)
00229 {
00230   int maskID = fei::FieldMask::calculateMaskID(1, &fieldID,
00231                                                       &numInstances);
00232   fei::FieldMask* mask = NULL;
00233   for(unsigned m=0; m<fieldMasks.size(); ++m) {
00234     if (maskID == fieldMasks[m]->getMaskID()) {
00235       mask = fieldMasks[m]; break;
00236     }
00237   }
00238 
00239   if (mask == NULL) {
00240     mask = new fei::FieldMask(1, &fieldID, &fieldSize, &numInstances);
00241     maskID = mask->getMaskID();
00242     fieldMasks.push_back(mask);
00243   }
00244 
00245   fei::FieldMask* lastMask = mask;
00246   int lastMaskID = maskID;
00247   static fei::Record<int> dummyRecord;
00248 
00249   map_type::iterator rend = records_.end();
00250 
00251   for(int i=0; i<numIDs; ++i) {
00252     fei::Record<int>* record = NULL;
00253     int ID = IDs[i];
00254 
00255     map_type::iterator riter = records_.lower_bound(ID);
00256 
00257     if (riter != rend) {
00258       const map_type::value_type& rval = *riter;
00259 
00260       if (rval.first != ID) {
00261         record = recordPool_.allocate(1);
00262         recordPool_.construct(record,dummyRecord);
00263 
00264         record->setID(ID);
00265         record->setFieldMask(mask);
00266         record->setOwnerProc(localProc_);
00267 
00268         records_.insert(riter, map_type::value_type(ID, record));
00269 
00270         records[i] = record;
00271       }
00272       else {
00273         record = rval.second;
00274 
00275         records[i] = record;
00276 
00277         int thisMaskID = record->getFieldMask()->getMaskID();
00278 
00279         if (skipIDsWithThisField) {
00280           if (maskID == thisMaskID) continue;
00281           if (record->getFieldMask()->hasFieldID(fieldID)) continue;
00282         }
00283 
00284         if (lastMaskID == thisMaskID) {
00285           record->setFieldMask(lastMask);
00286           continue;
00287         }
00288 
00289         fei::FieldMask* thisMask = record->getFieldMask();
00290         int newMaskID = fei::FieldMask::calculateMaskID(*thisMask,
00291                                                             fieldID, numInstances);
00292         if (lastMaskID == newMaskID) {
00293           record->setFieldMask(lastMask);
00294           continue;
00295         }
00296 
00297         bool newMaskAlreadyExists = false;
00298         for(unsigned m=0; m<fieldMasks.size(); ++m) {
00299           if (newMaskID == fieldMasks[m]->getMaskID()) {
00300             lastMask = fieldMasks[m];
00301             lastMaskID = lastMask->getMaskID();
00302             record->setFieldMask(lastMask);
00303             newMaskAlreadyExists = true;
00304             break;
00305           }
00306         }
00307 
00308         if (!newMaskAlreadyExists) {
00309           fei::FieldMask* newmask = new fei::FieldMask(*record->getFieldMask());
00310           newmask->addField(fieldID, fieldSize, numInstances);
00311           record->setFieldMask(newmask);
00312           fieldMasks.push_back(newmask);
00313           lastMask = newmask;
00314           lastMaskID = lastMask->getMaskID();
00315         }
00316       }
00317     }
00318     else {
00319       record = recordPool_.allocate(1);
00320       recordPool_.construct(record,dummyRecord);
00321       record->setID(ID);
00322       record->setFieldMask(mask);
00323       record->setOwnerProc(localProc_);
00324 
00325       records_.insert(riter, map_type::value_type(ID, record));
00326 
00327       records[i] = record;
00328     }
00329   }
00330 }
00331 
00332 //----------------------------------------------------------------------------
00333 void snl_fei::RecordCollection::
00334 setOwners_lowestSharing(fei::SharedIDs<int>& sharedIDs)
00335 {
00336   fei::SharedIDs<int>::map_type::iterator
00337     s_beg = sharedIDs.getSharedIDs().begin(),
00338     s_end = sharedIDs.getSharedIDs().end(),
00339     s_it;
00340 
00341   std::vector<int>& owningProcs = sharedIDs.getOwningProcs();
00342 
00343   map_type::iterator rend = records_.end();
00344 
00345   int i;
00346   for(i=0, s_it = s_beg; s_it != s_end; ++i, ++s_it) {
00347     fei::Record<int>* record = NULL;
00348     int sh_id = s_it->first;
00349     map_type::iterator riter = records_.find(sh_id);
00350     if (riter == rend) continue;
00351 
00352     record = (*riter).second;
00353 
00354     int proc = owningProcs[i];
00355 
00356     if (debugOutput_) {
00357       *dbgOut_ << "#   setting ID " << (int)(record->getID())
00358                << "'s owner to proc " << proc << FEI_ENDL;
00359     }
00360 
00361     record->setOwnerProc(proc);
00362   }
00363 }
00364 
00365 fei::Record<int>* snl_fei::RecordCollection::getRecordWithID(int ID)
00366 {
00367   map_type::iterator rend = records_.end();
00368   map_type::iterator riter = records_.find(ID);
00369 
00370   if (riter == rend) {
00371     return( NULL );
00372   }
00373 
00374   return(riter->second);
00375 }
00376 
00377 const fei::Record<int>* snl_fei::RecordCollection::getRecordWithID(int ID) const
00378 {
00379   map_type::const_iterator rend = records_.end();
00380   map_type::const_iterator riter = records_.find(ID);
00381 
00382   if (riter == rend) {
00383     return( NULL );
00384   }
00385 
00386   return(riter->second);
00387 }
00388 
00389 int snl_fei::RecordCollection::getGlobalBlkIndex(int ID, int& globalBlkIndex)
00390 {
00391   fei::Record<int>* record = getRecordWithID(ID);
00392   if (record == NULL) {
00393     globalBlkIndex = -1;
00394     ERReturn(-1);
00395   }
00396 
00397   globalBlkIndex = record->getNumber();
00398   return(0);
00399 }
00400 
00401 //----------------------------------------------------------------------------
00402 int snl_fei::RecordCollection::getGlobalIndex(int ID,
00403                                               int fieldID,
00404                                               int fieldSize,
00405                                               int fieldOffset,
00406                                               int whichComponentOfField,
00407                                               const int* eqnNumbers)
00408 {
00409   fei::Record<int>* record = getRecordWithID(ID);
00410   if (record == NULL) {
00411     FEI_OSTRINGSTREAM osstr;
00412     osstr << "snl_fei::RecordCollection::getGlobalIndex ERROR, no record with "
00413        << "ID=" << ID;
00414     throw std::runtime_error(osstr.str());
00415   }
00416 
00417   fei::FieldMask* mask = record->getFieldMask();
00418   int numInstances = 0;
00419   int offset = 0;
00420   try {
00421     mask->getFieldEqnOffset(fieldID, offset, numInstances);
00422   }
00423   catch (...) {
00424     FEI_OSTRINGSTREAM osstr;
00425     osstr << "failed to get eqn-offset for fieldID " << fieldID
00426           << " on record with ID " << ID << ".";
00427     throw std::runtime_error(osstr.str());
00428   }
00429 
00430   if (fieldOffset >= numInstances) {
00431     FEI_OSTRINGSTREAM osstr;
00432     osstr << "snl_fei::RecordCollection::getGlobalIndex: fieldOffset ("<<fieldOffset
00433           << ") should be less than numInstances ("<<numInstances<<").";
00434     throw std::runtime_error(osstr.str());
00435   }
00436 
00437   const int* eqnNums = eqnNumbers + record->getOffsetIntoEqnNumbers();
00438   if (eqnNums == NULL) {
00439     FEI_OSTRINGSTREAM osstr;
00440     osstr << "snl_fei::RecordCollection::getGlobalIndex ERROR: null pointer,"
00441          << " possibly because initComplete() hasn't been called yet?";
00442     throw std::runtime_error(osstr.str());
00443   }
00444 
00445   int globalIndex = -1;
00446   if (fieldOffset > 0) {
00447     globalIndex = eqnNums[offset + fieldOffset*fieldSize + whichComponentOfField];
00448   }
00449   else {
00450     globalIndex = eqnNums[offset + whichComponentOfField];
00451   }
00452 
00453   return(globalIndex);
00454 }

Generated on Tue Jul 13 09:27:46 2010 for FEI by  doxygen 1.4.7