FEI Version of the Day
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   : m_records(),
00023     m_global_to_local(),
00024     localProc_(localProc),
00025     debugOutput_(false),
00026     dbgOut_(NULL)
00027 {
00028   m_records.reserve(2000);
00029 }
00030 
00031 //----------------------------------------------------------------------------
00032 snl_fei::RecordCollection::RecordCollection(const RecordCollection& src)
00033   : m_records(src.m_records),
00034     m_global_to_local(src.m_global_to_local),
00035     localProc_(src.localProc_),
00036     debugOutput_(src.debugOutput_),
00037     dbgOut_(src.dbgOut_)
00038 {
00039 }
00040 
00041 //----------------------------------------------------------------------------
00042 snl_fei::RecordCollection::~RecordCollection()
00043 {
00044 }
00045 
00046 //----------------------------------------------------------------------------
00047 void snl_fei::RecordCollection::initRecords(int numIDs, const int* IDs,
00048                                             std::vector<fei::FieldMask*>& fieldMasks,
00049                                             int* recordLocalIDs)
00050 {
00051   int maskID = 0;
00052   fei::FieldMask* mask = NULL;
00053   for(unsigned m=0; m<fieldMasks.size(); ++m) {
00054     if (maskID == fieldMasks[m]->getMaskID()) {
00055       mask = fieldMasks[m]; break;
00056     }
00057   }
00058 
00059   if (mask == NULL) {
00060     mask = new fei::FieldMask();
00061     maskID = mask->getMaskID();
00062     fieldMasks.push_back(mask);
00063   }
00064 
00065   for(int i=0; i<numIDs; ++i) {
00066     int local_id;
00067     std::map<int,int>::iterator iter = m_global_to_local.lower_bound(IDs[i]);
00068     if (iter == m_global_to_local.end() || iter->first != IDs[i]) {
00069       //record doesn't exist, so we'll add a new one.
00070       local_id = m_records.size();
00071       m_global_to_local.insert(iter, std::make_pair(IDs[i], local_id));
00072       fei::Record<int> record;
00073       record.setID(IDs[i]);
00074       record.setFieldMask(mask);
00075       record.setOwnerProc(localProc_);
00076       m_records.push_back(record);
00077     }
00078     else {
00079       local_id = iter->second;
00080     }
00081 
00082     if (recordLocalIDs != NULL) recordLocalIDs[i] = local_id;
00083   }
00084 }
00085 
00086 //----------------------------------------------------------------------------
00087 void snl_fei::RecordCollection::initRecords(int fieldID, int fieldSize,
00088                                               int numIDs, const int* IDs,
00089                                               std::vector<fei::FieldMask*>& fieldMasks,
00090                                               int* recordLocalIDs)
00091 {
00092   int maskID = fei::FieldMask::calculateMaskID(1, &fieldID);
00093   fei::FieldMask* mask = NULL;
00094   for(unsigned m=0; m<fieldMasks.size(); ++m) {
00095     if (maskID == fieldMasks[m]->getMaskID()) {
00096       mask = fieldMasks[m]; break;
00097     }
00098   }
00099 
00100   if (mask == NULL) {
00101     mask = new fei::FieldMask(1, &fieldID, &fieldSize);
00102     maskID = mask->getMaskID();
00103     fieldMasks.push_back(mask);
00104   }
00105 
00106   int lastMaskID = maskID;
00107   fei::FieldMask* lastMask = mask;
00108 
00109   for(int i=0; i<numIDs; ++i) {
00110     int local_id;
00111     std::map<int,int>::iterator iter = m_global_to_local.lower_bound(IDs[i]);
00112     if (iter == m_global_to_local.end() || iter->first != IDs[i]) {
00113       //record doesn't exist, so we'll add a new one.
00114       local_id = m_records.size();
00115       m_global_to_local.insert(iter, std::make_pair(IDs[i], local_id));
00116       fei::Record<int> record;
00117       record.setID(IDs[i]);
00118       record.setFieldMask(mask);
00119       record.setOwnerProc(localProc_);
00120       m_records.push_back(record);
00121 
00122       if (recordLocalIDs != NULL) {
00123         recordLocalIDs[i] = local_id;
00124       }
00125     }
00126     else {
00127       local_id = iter->second;
00128       fei::Record<int>& record = m_records[local_id];
00129 
00130       if (recordLocalIDs != NULL) {
00131         recordLocalIDs[i] = local_id;
00132       }
00133 
00134       int thisMaskID = record.getFieldMask()->getMaskID();
00135 
00136       fei::FieldMask* thisMask = record.getFieldMask();
00137       if (maskID == thisMaskID || thisMask->hasFieldID(fieldID)) {
00138         continue;
00139       }
00140 
00141       if (lastMaskID == thisMaskID) {
00142         record.setFieldMask(lastMask);
00143        continue;
00144       }
00145 
00146       int newMaskID = fei::FieldMask::calculateMaskID(*thisMask, fieldID);
00147       if (lastMaskID == newMaskID) {
00148         record.setFieldMask(lastMask);
00149         continue;
00150       }
00151 
00152       bool newMaskAlreadyExists = false;
00153       for(unsigned m=0; m<fieldMasks.size(); ++m) {
00154         if (newMaskID == fieldMasks[m]->getMaskID()) {
00155           lastMask = fieldMasks[m];
00156           lastMaskID = lastMask->getMaskID();
00157           record.setFieldMask(lastMask);
00158           newMaskAlreadyExists = true;
00159           break;
00160         }
00161       }
00162 
00163       if (!newMaskAlreadyExists) {
00164         fei::FieldMask* newmask = new fei::FieldMask(*record.getFieldMask());
00165         newmask->addField(fieldID, fieldSize);
00166         record.setFieldMask(newmask);
00167         fieldMasks.push_back(newmask);
00168         lastMask = newmask;
00169         lastMaskID = lastMask->getMaskID();
00170       }
00171     }
00172   }
00173 }
00174 
00175 //----------------------------------------------------------------------------
00176 void snl_fei::RecordCollection::
00177 setOwners_lowestSharing(fei::SharedIDs<int>& sharedIDs)
00178 {
00179   fei::SharedIDs<int>::map_type::iterator
00180     s_beg = sharedIDs.getSharedIDs().begin(),
00181     s_end = sharedIDs.getSharedIDs().end(),
00182     s_it;
00183 
00184   std::vector<int>& owningProcs = sharedIDs.getOwningProcs();
00185 
00186   int i=0;
00187   for(i=0, s_it = s_beg; s_it != s_end; ++i, ++s_it) {
00188     int sh_id = s_it->first;
00189     fei::Record<int>* record = getRecordWithID(sh_id);
00190     if (record == NULL) continue;
00191 
00192     int proc = owningProcs[i];
00193 
00194     if (debugOutput_) {
00195       *dbgOut_ << "#   setting ID " << (int)(record->getID())
00196                << "'s owner to proc " << proc << FEI_ENDL;
00197     }
00198 
00199     record->setOwnerProc(proc);
00200   }
00201 }
00202 
00203 fei::Record<int>* snl_fei::RecordCollection::getRecordWithID(int ID)
00204 {
00205   std::map<int,int>::iterator iter = m_global_to_local.find(ID);
00206 
00207   if (iter == m_global_to_local.end()) {
00208     return( NULL );
00209   }
00210 
00211   return(&m_records[iter->second]);
00212 }
00213 
00214 const fei::Record<int>* snl_fei::RecordCollection::getRecordWithID(int ID) const
00215 {
00216   std::map<int,int>::const_iterator iter = m_global_to_local.find(ID);
00217 
00218   if (iter == m_global_to_local.end()) {
00219     return( NULL );
00220   }
00221 
00222   return(&m_records[iter->second]);
00223 }
00224 
00225 int snl_fei::RecordCollection::getGlobalBlkIndex(int ID, int& globalBlkIndex)
00226 {
00227   fei::Record<int>* record = getRecordWithID(ID);
00228   if (record == NULL) {
00229     globalBlkIndex = -1;
00230     ERReturn(-1);
00231   }
00232 
00233   globalBlkIndex = record->getNumber();
00234   return(0);
00235 }
00236 
00237 //----------------------------------------------------------------------------
00238 int snl_fei::RecordCollection::getGlobalIndex(int ID,
00239                                               int fieldID,
00240                                               int fieldSize,
00241                                               int fieldOffset,
00242                                               int whichComponentOfField,
00243                                               const int* eqnNumbers)
00244 {
00245   fei::Record<int>* record = getRecordWithID(ID);
00246   if (record == NULL) {
00247     FEI_OSTRINGSTREAM osstr;
00248     osstr << "snl_fei::RecordCollection::getGlobalIndex ERROR, no record with "
00249        << "ID=" << ID;
00250     throw std::runtime_error(osstr.str());
00251   }
00252 
00253   fei::FieldMask* mask = record->getFieldMask();
00254   int offset = 0;
00255   try {
00256     mask->getFieldEqnOffset(fieldID, offset);
00257   }
00258   catch (...) {
00259     FEI_OSTRINGSTREAM osstr;
00260     osstr << "failed to get eqn-offset for fieldID " << fieldID
00261           << " on record with ID " << ID << ".";
00262     throw std::runtime_error(osstr.str());
00263   }
00264 
00265   const int* eqnNums = eqnNumbers + record->getOffsetIntoEqnNumbers();
00266   if (eqnNums == NULL) {
00267     FEI_OSTRINGSTREAM osstr;
00268     osstr << "snl_fei::RecordCollection::getGlobalIndex ERROR: null pointer,"
00269          << " possibly because initComplete() hasn't been called yet?";
00270     throw std::runtime_error(osstr.str());
00271   }
00272 
00273   int globalIndex = -1;
00274   if (fieldOffset > 0) {
00275     globalIndex = eqnNums[offset + fieldOffset*fieldSize + whichComponentOfField];
00276   }
00277   else {
00278     globalIndex = eqnNums[offset + whichComponentOfField];
00279   }
00280 
00281   return(globalIndex);
00282 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends