FEI  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
fei_NodeDescriptor.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 <string>
10 #include <fei_macros.hpp>
11 #include <fei_defs.h>
12 
13 #include <fei_NodeDescriptor.hpp>
14 
15 //======Constructor=============================================================
16 NodeDescriptor::NodeDescriptor()
17  : nodeID_((GlobalID)-1),
18  nodeNumber_(-1),
19  numNodalDOF_(0),
20  fieldIDList_(NULL),
21  fieldEqnNumbers_(NULL),
22  numFields_(0),
23  blkEqnNumber_(0),
24  ownerProc_(-1),
25  blockList_()
26 {
27  //There's nothing for this constructor to do, apart from the
28  //above initializations.
29 }
30 
31 //======Destructor==============================================================
32 NodeDescriptor::~NodeDescriptor() {
33  delete [] fieldIDList_;
34  delete [] fieldEqnNumbers_;
35  numFields_ = 0;
36 }
37 
38 //==============================================================================
39 void NodeDescriptor::addField(int fieldID) {
40 //
41 //Add a field identifier to this node, ONLY if that field identifier
42 //is not already present.
43 //
44 //If fieldID is added, lengthen the corresponding list for equation numbers.
45 //
46 
47  int tmp = numFields_;
48  int allocLen = numFields_;
49  int index = fei::sortedListInsert(fieldID, fieldIDList_, numFields_,
50  allocLen);
51 
52  //index is the position at which fieldID was inserted, or found
53 
54  //if tmp < numFields_ then fieldID wasn't already present
55  if (tmp < numFields_) {
56  //
57  //if the length of fieldIDList_ changed, let's lengthen the
58  //fieldEqnNumbers_ list.
59  //fieldEqnNumbers_ will have an empty position 'index', which we'll set to
60  //-99 for now. The calling code (BASE_FEI) will set the fieldEqnNumber for
61  //this fieldID using setFieldEqnNumber(...).
62  //
63 
64  allocLen = numFields_ - 1;
65  fei::listInsert(-99, index, fieldEqnNumbers_, tmp, allocLen);
66  }
67 }
68 
69 //==============================================================================
70 void NodeDescriptor::setFieldEqnNumber(int fieldID, int eqn) {
71 //
72 //Set the equation number corresponding to fieldID. fieldID must
73 //already have been added to this node using the addField function.
74 //If it was already added, then the fieldEqnNumbers_ list was lengthened
75 //appropriately, with an empty spot left for this eqn number.
76 //
77  int insert = -1;
78  int index = fei::binarySearch(fieldID, fieldIDList_,
79  numFields_, insert);
80 
81  if (index < 0) {
82  return;
83  }
84 
85  fieldEqnNumbers_[index] = eqn;
86 }
87 
88 //==============================================================================
89 bool NodeDescriptor::getFieldEqnNumber(int fieldID, int& eqnNumber) const
90 {
91  int insert = -1;
92  int index = fei::binarySearch(fieldID, fieldIDList_,
93  numFields_, insert);
94 
95  if (index < 0) {
96  return(false);
97  }
98 
99  eqnNumber = fieldEqnNumbers_[index];
100  return(true);
101 }
102 
103 //==============================================================================
104 void NodeDescriptor::getFieldID(int eqnNumber, int& fieldID, int& offset_into_field) const
105 {
106  if (numFields_ < 1) {
107  throw std::runtime_error("fei::NodeDescriptor::getFieldID ERROR, no nodal dofs on this node.");
108  }
109 
110  int firstNodalEqn = fieldEqnNumbers_[0];
111  if (eqnNumber - firstNodalEqn > numNodalDOF_) {
112  throw std::runtime_error("fei::NodeDescriptor::getFieldID ERROR, eqnNumber out of range.");
113  }
114 
115  bool found_field = false;
116  for(int i=numFields_-1; i>=0; --i) {
117  if (fieldEqnNumbers_[i] <= eqnNumber) {
118  fieldID = fieldIDList_[i];
119  offset_into_field = eqnNumber - fieldEqnNumbers_[i];
120  found_field = true;
121  break;
122  }
123  }
124 
125  if (!found_field) {
126  throw std::runtime_error("fei::NodeDescriptor::getFieldID ERROR, fieldID not found for eqnNumber.");
127  }
128 }
129 
130 //==============================================================================
131 bool NodeDescriptor::hasBlockIndex(unsigned blk_idx) const
132 {
133  //return true if this node is contained in element-block-index 'blk_idx'.
134 
135  int index = fei::binarySearch(blk_idx, &blockList_[0], blockList_.size());
136  if (index >= 0) return(true);
137  else return(false);
138 }
139 
int sortedListInsert(const T &item, std::vector< T > &list)
bool getFieldEqnNumber(int fieldID, int &eqnNumber) const
int binarySearch(const T &item, const T *list, int len)
void getFieldID(int eqnNumber, int &fieldID, int &offset_into_field) const
int listInsert(const T &item, int offset, T *&list, int &usedLength, int &allocatedLength, int allocChunkSize=200)