FEI Version of the Day
fei_ProcEqns.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_macros.hpp>
00010 #include <fei_defs.h>
00011 
00012 #include <fei_TemplateUtils.hpp>
00013 #include <fei_ProcEqns.hpp>
00014 
00015 //==============================================================================
00016 ProcEqns::ProcEqns()
00017  : procs_(),
00018    eqnsPerProc_(),
00019    procEqnNumbers_(),
00020    procEqnLengths_()
00021 {
00022 }
00023 
00024 //==============================================================================
00025 ProcEqns::~ProcEqns() {
00026    deleteMemory();
00027 }
00028 
00029 //==============================================================================
00030 ProcEqns* ProcEqns::deepCopy()
00031 {
00032 //
00033 //This function returns a DEEP copy (including all data) of 'this' object.
00034 //
00035    ProcEqns* dest = new ProcEqns;
00036 
00037    int len = procs_.size();
00038 
00039    dest->procs_.resize(len);
00040    dest->eqnsPerProc_.resize(len);
00041 
00042    dest->procEqnNumbers_.resize(len);
00043    dest->procEqnLengths_.resize(len);
00044 
00045    for(int i=0; i<len; i++) {
00046       dest->procs_[i] = procs_[i];
00047       dest->eqnsPerProc_[i] = eqnsPerProc_[i];
00048 
00049       dest->procEqnNumbers_[i] = new std::vector<int>(*(procEqnNumbers_[i]));
00050       dest->procEqnLengths_[i] = new std::vector<int>(*(procEqnLengths_[i]));
00051    }
00052 
00053    return(dest);
00054 }
00055 
00056 //==============================================================================
00057 void ProcEqns::deleteMemory() {
00058   for(unsigned i=0; i<procEqnNumbers_.size(); i++) {
00059     delete procEqnNumbers_[i];
00060     delete procEqnLengths_[i];
00061   }
00062 }
00063 
00064 //==============================================================================
00065 void ProcEqns::addEqn(int eqnNumber, int proc) {
00066 
00067    internalAddEqn(eqnNumber, 0, proc);
00068 }
00069 
00070 //==============================================================================
00071 void ProcEqns::addEqn(int eqnNumber, int eqnLength, int proc) {
00072    internalAddEqn(eqnNumber, eqnLength, proc);
00073 }
00074 
00075 //==============================================================================
00076 void ProcEqns::internalAddEqn(int eqnNumber, int eqnLength, int proc) {
00077 //
00078 //This function adds proc to the recvProcs_ list if it isn't already
00079 //present, and adds eqnNumber to the correct row of the procEqnNumbers_
00080 //table if eqnNumber isn't already in there.
00081 //
00082 
00083   //is proc already in our list of procs?
00084   std::vector<int>::iterator
00085     p_iter = std::lower_bound(procs_.begin(),procs_.end(), proc);
00086 
00087   unsigned offset = p_iter - procs_.begin();
00088 
00089   if (p_iter == procs_.end() || proc != *p_iter) {
00090     //proc was NOT already present, so
00091     //we need to insert it, and insert new rows in the tables
00092     //procEqnNumbers_ and procEqnLengths.
00093 
00094     procs_.insert(p_iter, proc);
00095 
00096     procEqnNumbers_.insert(procEqnNumbers_.begin()+offset,new std::vector<int>(1));
00097     (*(procEqnNumbers_[offset]))[0] = eqnNumber;
00098 
00099     procEqnLengths_.insert(procEqnLengths_.begin()+offset, new std::vector<int>(1));
00100     (*(procEqnLengths_[offset]))[0] = eqnLength;
00101 
00102     eqnsPerProc_.insert(eqnsPerProc_.begin()+offset, 1);
00103   }
00104   else {
00105     //proc was already in the procs_ list.
00106     //is eqnNumber already in our list of eqns for proc?
00107     //if not, add it.
00108 
00109     std::vector<int>& procEqnNums = *(procEqnNumbers_[offset]);
00110     std::vector<int>::iterator pe_iter =
00111       std::lower_bound(procEqnNums.begin(),procEqnNums.end(), eqnNumber);
00112 
00113     unsigned offset2 = pe_iter - procEqnNums.begin();
00114 
00115     if (pe_iter == procEqnNums.end() || eqnNumber != *pe_iter) {
00116       procEqnNumbers_[offset]->insert(procEqnNumbers_[offset]->begin()+offset2,eqnNumber);
00117       procEqnLengths_[offset]->insert(procEqnLengths_[offset]->begin()+offset2,eqnLength);
00118       eqnsPerProc_[offset] = procEqnNumbers_[offset]->size();
00119     }
00120     else {
00121       (*(procEqnLengths_[offset]))[offset2] = eqnLength;
00122     }
00123   }
00124 }
00125 
00126 //==============================================================================
00127 void ProcEqns::setProcEqnLengths(int* eqnNumbers, int* eqnLengths, int len)
00128 {
00129    if (len == 0) return;
00130 
00131    int numProcs = procs_.size();
00132 
00133    for(int i=0; i<numProcs; i++) {
00134       for(int j=0; j<eqnsPerProc_[i]; j++) {
00135          int eqn_j = (*(procEqnNumbers_[i]))[j];
00136          int ins = -1;
00137    int index = fei::binarySearch( eqn_j,
00138               eqnNumbers, len, ins);
00139 
00140          if (index < 0) {
00141             FEI_CERR << "fei: ProcEqns::setProcEqnLengths: ERROR, "
00142                  << eqn_j << " not found." << FEI_ENDL;
00143             std::abort();
00144          }
00145 
00146          (*(procEqnLengths_[i]))[j] = eqnLengths[index];
00147       }
00148    }
00149 }
00150 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends