FEI  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
fei_ProcEqns.cpp
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_macros.hpp>
10 #include <fei_defs.h>
11 
12 #include <fei_TemplateUtils.hpp>
13 #include <fei_ProcEqns.hpp>
14 
15 //==============================================================================
17  : procs_(),
18  eqnsPerProc_(),
19  procEqnNumbers_(),
20  procEqnLengths_()
21 {
22 }
23 
24 //==============================================================================
26  deleteMemory();
27 }
28 
29 //==============================================================================
31 {
32 //
33 //This function returns a DEEP copy (including all data) of 'this' object.
34 //
35  ProcEqns* dest = new ProcEqns;
36 
37  int len = procs_.size();
38 
39  dest->procs_.resize(len);
40  dest->eqnsPerProc_.resize(len);
41 
42  dest->procEqnNumbers_.resize(len);
43  dest->procEqnLengths_.resize(len);
44 
45  for(int i=0; i<len; i++) {
46  dest->procs_[i] = procs_[i];
47  dest->eqnsPerProc_[i] = eqnsPerProc_[i];
48 
49  dest->procEqnNumbers_[i] = new std::vector<int>(*(procEqnNumbers_[i]));
50  dest->procEqnLengths_[i] = new std::vector<int>(*(procEqnLengths_[i]));
51  }
52 
53  return(dest);
54 }
55 
56 //==============================================================================
57 void ProcEqns::deleteMemory() {
58  for(unsigned i=0; i<procEqnNumbers_.size(); i++) {
59  delete procEqnNumbers_[i];
60  delete procEqnLengths_[i];
61  }
62 }
63 
64 //==============================================================================
65 void ProcEqns::addEqn(int eqnNumber, int proc) {
66 
67  internalAddEqn(eqnNumber, 0, proc);
68 }
69 
70 //==============================================================================
71 void ProcEqns::addEqn(int eqnNumber, int eqnLength, int proc) {
72  internalAddEqn(eqnNumber, eqnLength, proc);
73 }
74 
75 //==============================================================================
76 void ProcEqns::internalAddEqn(int eqnNumber, int eqnLength, int proc) {
77 //
78 //This function adds proc to the recvProcs_ list if it isn't already
79 //present, and adds eqnNumber to the correct row of the procEqnNumbers_
80 //table if eqnNumber isn't already in there.
81 //
82 
83  //is proc already in our list of procs?
84  std::vector<int>::iterator
85  p_iter = std::lower_bound(procs_.begin(),procs_.end(), proc);
86 
87  unsigned offset = p_iter - procs_.begin();
88 
89  if (p_iter == procs_.end() || proc != *p_iter) {
90  //proc was NOT already present, so
91  //we need to insert it, and insert new rows in the tables
92  //procEqnNumbers_ and procEqnLengths.
93 
94  procs_.insert(p_iter, proc);
95 
96  procEqnNumbers_.insert(procEqnNumbers_.begin()+offset,new std::vector<int>(1));
97  (*(procEqnNumbers_[offset]))[0] = eqnNumber;
98 
99  procEqnLengths_.insert(procEqnLengths_.begin()+offset, new std::vector<int>(1));
100  (*(procEqnLengths_[offset]))[0] = eqnLength;
101 
102  eqnsPerProc_.insert(eqnsPerProc_.begin()+offset, 1);
103  }
104  else {
105  //proc was already in the procs_ list.
106  //is eqnNumber already in our list of eqns for proc?
107  //if not, add it.
108 
109  std::vector<int>& procEqnNums = *(procEqnNumbers_[offset]);
110  std::vector<int>::iterator pe_iter =
111  std::lower_bound(procEqnNums.begin(),procEqnNums.end(), eqnNumber);
112 
113  unsigned offset2 = pe_iter - procEqnNums.begin();
114 
115  if (pe_iter == procEqnNums.end() || eqnNumber != *pe_iter) {
116  procEqnNumbers_[offset]->insert(procEqnNumbers_[offset]->begin()+offset2,eqnNumber);
117  procEqnLengths_[offset]->insert(procEqnLengths_[offset]->begin()+offset2,eqnLength);
118  eqnsPerProc_[offset] = procEqnNumbers_[offset]->size();
119  }
120  else {
121  (*(procEqnLengths_[offset]))[offset2] = eqnLength;
122  }
123  }
124 }
125 
126 //==============================================================================
127 void ProcEqns::setProcEqnLengths(int* eqnNumbers, int* eqnLengths, int len)
128 {
129  if (len == 0) return;
130 
131  int numProcs = procs_.size();
132 
133  for(int i=0; i<numProcs; i++) {
134  for(int j=0; j<eqnsPerProc_[i]; j++) {
135  int eqn_j = (*(procEqnNumbers_[i]))[j];
136  int ins = -1;
137  int index = fei::binarySearch( eqn_j,
138  eqnNumbers, len, ins);
139 
140  if (index < 0) {
141  fei::console_out() << "fei: ProcEqns::setProcEqnLengths: ERROR, "
142  << eqn_j << " not found." << FEI_ENDL;
143  std::abort();
144  }
145 
146  (*(procEqnLengths_[i]))[j] = eqnLengths[index];
147  }
148  }
149 }
150 
virtual ~ProcEqns()
void setProcEqnLengths(int *eqnNumbers, int *eqnLengths, int len)
void addEqn(int eqnNumber, int proc)
int binarySearch(const T &item, const T *list, int len)
std::ostream & console_out()
ProcEqns * deepCopy()
int numProcs(MPI_Comm comm)