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   : 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   map_type::iterator
00064     iter = records_.begin(),
00065     iter_end = records_.end();
00066 
00067   for(; iter != iter_end; ++iter) {
00068     map_type::value_type pair = *iter;
00069     recordPool_.deallocate(pair.second,1);
00070   }
00071 }
00072 
00073 //----------------------------------------------------------------------------
00074 void snl_fei::RecordCollection::initRecords(int numIDs, const int* IDs,
00075                                             std::vector<fei::FieldMask*>& fieldMasks,
00076                                             fei::Record<int>** records)
00077 {
00078   int maskID = 0;
00079   fei::FieldMask* mask = NULL;
00080   for(unsigned m=0; m<fieldMasks.size(); ++m) {
00081     if (maskID == fieldMasks[m]->getMaskID()) {
00082       mask = fieldMasks[m]; break;
00083     }
00084   }
00085 
00086   if (mask == NULL) {
00087     mask = new fei::FieldMask();
00088     maskID = mask->getMaskID();
00089     fieldMasks.push_back(mask);
00090   }
00091 
00092   static fei::Record<int> dummyRecord;
00093 
00094   for(int i=0; i<numIDs; ++i) {
00095     fei::Record<int>* record = NULL;
00096 
00097     map_type::iterator riter = records_.lower_bound(IDs[i]);
00098     if (riter != records_.end()) {
00099       if ((*riter).first != IDs[i]) {
00100         record = recordPool_.allocate(1);
00101         recordPool_.construct(record,dummyRecord);
00102 
00103         record->setID(IDs[i]);
00104         record->setFieldMask(mask);
00105         record->setOwnerProc(localProc_);
00106 
00107         records_.insert(riter, map_type::value_type(IDs[i], record));
00108       }
00109       else {
00110         record = (*riter).second;
00111 
00112         record->setFieldMask(mask);
00113       }
00114     }
00115     else {
00116       record = recordPool_.allocate(1);
00117       recordPool_.construct(record,dummyRecord);
00118 
00119       record->setID(IDs[i]);
00120       record->setFieldMask(mask);
00121       record->setOwnerProc(localProc_);
00122 
00123       records_.insert(riter, map_type::value_type(IDs[i], record));
00124     }
00125 
00126     if (records != NULL) {
00127       records[i] = record;
00128     }
00129   }
00130 }
00131 
00132 //----------------------------------------------------------------------------
00133 void snl_fei::RecordCollection::initRecords(int fieldID, int fieldSize,
00134                                             int numInstances,
00135                                             int numIDs, const int* IDs,
00136                                             std::vector<fei::FieldMask*>& fieldMasks,
00137                                             bool skipIDsWithThisField)
00138 {
00139   int maskID = fei::FieldMask::calculateMaskID(1, &fieldID,
00140                                                       &numInstances);
00141   fei::FieldMask* mask = NULL;
00142   for(unsigned m=0; m<fieldMasks.size(); ++m) {
00143     if (maskID == fieldMasks[m]->getMaskID()) {
00144       mask = fieldMasks[m]; break;
00145     }
00146   }
00147 
00148   if (mask == NULL) {
00149     mask = new fei::FieldMask(1, &fieldID, &fieldSize, &numInstances);
00150     maskID = mask->getMaskID();
00151     fieldMasks.push_back(mask);
00152   }
00153 
00154   fei::FieldMask* lastMask = mask;
00155   int lastMaskID = maskID;
00156   static fei::Record<int> dummyRecord;
00157 
00158   for(int i=0; i<numIDs; ++i) {
00159     fei::Record<int>* record = NULL;
00160 
00161     map_type::iterator riter = records_.lower_bound(IDs[i]);
00162 
00163     if (riter != records_.end()) {
00164       if ((*riter).first != IDs[i]) {
00165         record = recordPool_.allocate(1);
00166         recordPool_.construct(record,dummyRecord);
00167 
00168         record->setID(IDs[i]);
00169         record->setFieldMask(mask);
00170         record->setOwnerProc(localProc_);
00171 
00172         records_.insert(riter, map_type::value_type(IDs[i], record));
00173       }
00174       else {
00175         record = (*riter).second;
00176 
00177         int thisMaskID = record->getFieldMask()->getMaskID();
00178 
00179         if (skipIDsWithThisField) {
00180           if (maskID == thisMaskID) continue;
00181           if (record->getFieldMask()->hasFieldID(fieldID)) continue;
00182         }
00183 
00184         if (lastMaskID == thisMaskID) {
00185           record->setFieldMask(lastMask);
00186           continue;
00187         }
00188 
00189         fei::FieldMask* thisMask = record->getFieldMask();
00190         int newMaskID = fei::FieldMask::calculateMaskID(*thisMask,
00191                                                             fieldID, numInstances);
00192         if (lastMaskID == newMaskID) {
00193           record->setFieldMask(lastMask);
00194           continue;
00195         }
00196 
00197         bool newMaskAlreadyExists = false;
00198         for(unsigned m=0; m<fieldMasks.size(); ++m) {
00199           if (newMaskID == fieldMasks[m]->getMaskID()) {
00200             lastMask = fieldMasks[m];
00201             lastMaskID = lastMask->getMaskID();
00202             record->setFieldMask(lastMask);
00203             newMaskAlreadyExists = true;
00204             break;
00205           }
00206         }
00207 
00208         if (!newMaskAlreadyExists) {
00209           fei::FieldMask* newmask = new fei::FieldMask(*record->getFieldMask());
00210           newmask->addField(fieldID, fieldSize, numInstances);
00211           record->setFieldMask(newmask);
00212           fieldMasks.push_back(newmask);
00213           lastMask = newmask;
00214           lastMaskID = lastMask->getMaskID();
00215         }
00216       }
00217     }
00218     else {
00219       record = recordPool_.allocate(1);
00220       recordPool_.construct(record,dummyRecord);
00221       record->setID(IDs[i]);
00222       record->setFieldMask(mask);
00223       record->setOwnerProc(localProc_);
00224 
00225       records_.insert(riter, map_type::value_type(IDs[i], record));
00226     }
00227   }
00228 }
00229 
00230 //----------------------------------------------------------------------------
00231 void snl_fei::RecordCollection::initRecords(int fieldID, int fieldSize,
00232                                               int numInstances,
00233                                               int numIDs, const int* IDs,
00234                                               std::vector<fei::FieldMask*>& fieldMasks,
00235                                               fei::Record<int>** records,
00236                                               bool skipIDsWithThisField)
00237 {
00238   int maskID = fei::FieldMask::calculateMaskID(1, &fieldID,
00239                                                       &numInstances);
00240   fei::FieldMask* mask = NULL;
00241   for(unsigned m=0; m<fieldMasks.size(); ++m) {
00242     if (maskID == fieldMasks[m]->getMaskID()) {
00243       mask = fieldMasks[m]; break;
00244     }
00245   }
00246 
00247   if (mask == NULL) {
00248     mask = new fei::FieldMask(1, &fieldID, &fieldSize, &numInstances);
00249     maskID = mask->getMaskID();
00250     fieldMasks.push_back(mask);
00251   }
00252 
00253   fei::FieldMask* lastMask = mask;
00254   int lastMaskID = maskID;
00255   static fei::Record<int> dummyRecord;
00256 
00257   map_type::iterator rend = records_.end();
00258 
00259   for(int i=0; i<numIDs; ++i) {
00260     fei::Record<int>* record = NULL;
00261     int ID = IDs[i];
00262 
00263     map_type::iterator riter = records_.lower_bound(ID);
00264 
00265     if (riter != rend) {
00266       const map_type::value_type& rval = *riter;
00267 
00268       if (rval.first != ID) {
00269         record = recordPool_.allocate(1);
00270         recordPool_.construct(record,dummyRecord);
00271 
00272         record->setID(ID);
00273         record->setFieldMask(mask);
00274         record->setOwnerProc(localProc_);
00275 
00276         records_.insert(riter, map_type::value_type(ID, record));
00277 
00278         records[i] = record;
00279       }
00280       else {
00281         record = rval.second;
00282 
00283         records[i] = record;
00284 
00285         int thisMaskID = record->getFieldMask()->getMaskID();
00286 
00287         if (skipIDsWithThisField) {
00288           if (maskID == thisMaskID) continue;
00289           if (record->getFieldMask()->hasFieldID(fieldID)) continue;
00290         }
00291 
00292         if (lastMaskID == thisMaskID) {
00293           record->setFieldMask(lastMask);
00294           continue;
00295         }
00296 
00297         fei::FieldMask* thisMask = record->getFieldMask();
00298         int newMaskID = fei::FieldMask::calculateMaskID(*thisMask,
00299                                                             fieldID, numInstances);
00300         if (lastMaskID == newMaskID) {
00301           record->setFieldMask(lastMask);
00302           continue;
00303         }
00304 
00305         bool newMaskAlreadyExists = false;
00306         for(unsigned m=0; m<fieldMasks.size(); ++m) {
00307           if (newMaskID == fieldMasks[m]->getMaskID()) {
00308             lastMask = fieldMasks[m];
00309             lastMaskID = lastMask->getMaskID();
00310             record->setFieldMask(lastMask);
00311             newMaskAlreadyExists = true;
00312             break;
00313           }
00314         }
00315 
00316         if (!newMaskAlreadyExists) {
00317           fei::FieldMask* newmask = new fei::FieldMask(*record->getFieldMask());
00318           newmask->addField(fieldID, fieldSize, numInstances);
00319           record->setFieldMask(newmask);
00320           fieldMasks.push_back(newmask);
00321           lastMask = newmask;
00322           lastMaskID = lastMask->getMaskID();
00323         }
00324       }
00325     }
00326     else {
00327       record = recordPool_.allocate(1);
00328       recordPool_.construct(record,dummyRecord);
00329       record->setID(ID);
00330       record->setFieldMask(mask);
00331       record->setOwnerProc(localProc_);
00332 
00333       records_.insert(riter, map_type::value_type(ID, record));
00334 
00335       records[i] = record;
00336     }
00337   }
00338 }
00339 
00340 //----------------------------------------------------------------------------
00341 void snl_fei::RecordCollection::
00342 setOwners_lowestSharing(fei::SharedIDs<int>& sharedIDs)
00343 {
00344   fei::SharedIDs<int>::map_type::iterator
00345     s_beg = sharedIDs.getSharedIDs().begin(),
00346     s_end = sharedIDs.getSharedIDs().end(),
00347     s_it;
00348 
00349   std::vector<int>& owningProcs = sharedIDs.getOwningProcs();
00350 
00351   map_type::iterator rend = records_.end();
00352 
00353   int i;
00354   for(i=0, s_it = s_beg; s_it != s_end; ++i, ++s_it) {
00355     fei::Record<int>* record = NULL;
00356     int sh_id = s_it->first;
00357     map_type::iterator riter = records_.find(sh_id);
00358     if (riter == rend) continue;
00359 
00360     record = (*riter).second;
00361 
00362     int proc = owningProcs[i];
00363 
00364     if (debugOutput_) {
00365       *dbgOut_ << "#   setting ID " << (int)(record->getID())
00366                << "'s owner to proc " << proc << FEI_ENDL;
00367     }
00368 
00369     record->setOwnerProc(proc);
00370   }
00371 }
00372 
00373 fei::Record<int>* snl_fei::RecordCollection::getRecordWithID(int ID)
00374 {
00375   map_type::iterator rend = records_.end();
00376   map_type::iterator riter = records_.find(ID);
00377 
00378   if (riter == rend) {
00379     return( NULL );
00380   }
00381 
00382   return(riter->second);
00383 }
00384 
00385 const fei::Record<int>* snl_fei::RecordCollection::getRecordWithID(int ID) const
00386 {
00387   map_type::const_iterator rend = records_.end();
00388   map_type::const_iterator riter = records_.find(ID);
00389 
00390   if (riter == rend) {
00391     return( NULL );
00392   }
00393 
00394   return(riter->second);
00395 }
00396 
00397 int snl_fei::RecordCollection::getGlobalBlkIndex(int ID, int& globalBlkIndex)
00398 {
00399   fei::Record<int>* record = getRecordWithID(ID);
00400   if (record == NULL) {
00401     globalBlkIndex = -1;
00402     ERReturn(-1);
00403   }
00404 
00405   globalBlkIndex = record->getNumber();
00406   return(0);
00407 }
00408 
00409 //----------------------------------------------------------------------------
00410 int snl_fei::RecordCollection::getGlobalIndex(int ID,
00411                                               int fieldID,
00412                                               int fieldSize,
00413                                               int fieldOffset,
00414                                               int whichComponentOfField,
00415                                               const int* eqnNumbers)
00416 {
00417   fei::Record<int>* record = getRecordWithID(ID);
00418   if (record == NULL) {
00419     FEI_OSTRINGSTREAM osstr;
00420     osstr << "snl_fei::RecordCollection::getGlobalIndex ERROR, no record with "
00421        << "ID=" << ID;
00422     throw std::runtime_error(osstr.str());
00423   }
00424 
00425   fei::FieldMask* mask = record->getFieldMask();
00426   int numInstances = 0;
00427   int offset = 0;
00428   try {
00429     mask->getFieldEqnOffset(fieldID, offset, numInstances);
00430   }
00431   catch (...) {
00432     FEI_OSTRINGSTREAM osstr;
00433     osstr << "failed to get eqn-offset for fieldID " << fieldID
00434           << " on record with ID " << ID << ".";
00435     throw std::runtime_error(osstr.str());
00436   }
00437 
00438   if (fieldOffset >= numInstances) {
00439     FEI_OSTRINGSTREAM osstr;
00440     osstr << "snl_fei::RecordCollection::getGlobalIndex: fieldOffset ("<<fieldOffset
00441           << ") should be less than numInstances ("<<numInstances<<").";
00442     throw std::runtime_error(osstr.str());
00443   }
00444 
00445   const int* eqnNums = eqnNumbers + record->getOffsetIntoEqnNumbers();
00446   if (eqnNums == NULL) {
00447     FEI_OSTRINGSTREAM osstr;
00448     osstr << "snl_fei::RecordCollection::getGlobalIndex ERROR: null pointer,"
00449          << " possibly because initComplete() hasn't been called yet?";
00450     throw std::runtime_error(osstr.str());
00451   }
00452 
00453   int globalIndex = -1;
00454   if (fieldOffset > 0) {
00455     globalIndex = eqnNums[offset + fieldOffset*fieldSize + whichComponentOfField];
00456   }
00457   else {
00458     globalIndex = eqnNums[offset + whichComponentOfField];
00459   }
00460 
00461   return(globalIndex);
00462 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends