FEI  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
fei_BlockDescriptor.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_iostream.hpp>
10 #include <fei_defs.h>
11 
12 #include <fei_BlockDescriptor.hpp>
13 
14 //====Constructor===============================================================
15 BlockDescriptor::BlockDescriptor()
16  : blockID_(-1),
17  numNodesPerElement_(0),
18  numFieldsPerNode_(NULL),
19  nodalFieldIDs_(NULL),
20  fieldIDsAllocated_(false),
21  numDistinctFields_(0),
22  elemDofFieldIDs_(),
23  interleaveStrategy_(0),
24  lumpingStrategy_(0),
25  numElements_(0),
26  numElemDOFPerElement_(0),
27  elemDOFEqnNumbers_(),
28  numEqnsPerElement_(0),
29  numBlkEqnsPerElement_(0),
30  numActiveNodes_(0),
31  totalNumEqns_(0)
32 {
33  //There's nothing else for this constructor to do.
34 }
35 
36 //====Destructor================================================================
37 BlockDescriptor::~BlockDescriptor() {
38 
39  destroyFieldArrays();
40 
41  numElemDOFPerElement_ = 0;
42 }
43 
44 //==============================================================================
45 void BlockDescriptor::destroyFieldArrays() {
46  if (numNodesPerElement_ == 0) return;
47 
48  for(int i=0; i<numNodesPerElement_; i++) {
49  delete [] nodalFieldIDs_[i];
50  }
51 
52  delete [] nodalFieldIDs_;
53  nodalFieldIDs_ = NULL;
54  delete [] numFieldsPerNode_;
55  numFieldsPerNode_ = NULL;
56  numNodesPerElement_ = 0;
57 }
58 
59 //==============================================================================
61 {
62  if (numNodes < 1) {
63  return(-1);
64  }
65 
66  destroyFieldArrays();
67 
68  numNodesPerElement_ = numNodes;
69 
70  numFieldsPerNode_ = new int[numNodesPerElement_];
71 
72  for(int i=0; i<numNodesPerElement_; i++) {
73  numFieldsPerNode_[i] = 0;
74  }
75  return(0);
76 }
77 
78 //==============================================================================
79 int* BlockDescriptor::fieldsPerNodePtr() {
80 
81  return(numFieldsPerNode_);
82 }
83 
84 //==============================================================================
85 int BlockDescriptor::allocateFieldIDsTable()
86 {
87  nodalFieldIDs_ = new int*[numNodesPerElement_];
88  bool rowsAllZeroLength = true;
89 
90  for(int i=0; i<numNodesPerElement_; i++) {
91  if (numFieldsPerNode_[i] > 0) {
92  nodalFieldIDs_[i] = new int[numFieldsPerNode_[i]];
93  rowsAllZeroLength = false;
94  }
95  else nodalFieldIDs_[i] = NULL;
96  }
97 
98  if (rowsAllZeroLength || numNodesPerElement_ == 0) {
99  fei::console_out() << "BlockDescriptor::allocateFieldIDsTable: ERROR, all rows of"
100  << " fieldIDs table have zero length. Set fieldsPerNode entries"
101  << " first." << FEI_ENDL;
102  return(-1);
103  }
104 
105  fieldIDsAllocated_ = true;
106  return(0);
107 }
108 
109 //==============================================================================
110 bool BlockDescriptor::containsField(int fieldID) {
111 //
112 //This function will mostly be called by the BASE_FEI function for
113 //getting solutions to return to the user.
114 //
115 //For cases where each of the nodes in an element have the same fields,
116 //this function will be quite fast.
117 //
118 //It will be slow for cases where there are quite a few nodes per element
119 //and the different nodes have different solution fields. (i.e., the search
120 //below has to step through most of the fieldIDs table before finding the
121 //fieldID in question.
122 //
123 //In general though, this function won't be called if the fieldID isn't
124 //associated with ANY node in this block, because the calling code can first
125 //query the node to find out if IT is associated with this block. And if the
126 //node is associated with this block, then the node's fields usually will be
127 //also, unless the node lies on a block boundary and 'fieldID' is only in
128 //the other block.
129 //
130  for(int i=0; i<numNodesPerElement_; i++) {
131  for(int j=0; j<numFieldsPerNode_[i]; j++) {
132  if (nodalFieldIDs_[i][j] == fieldID) return(true);
133  }
134  }
135 
136  return(false);
137 }
138 
139 //==============================================================================
140 int BlockDescriptor::setElemDofFieldIDs(int numFields, const int* fieldIDs)
141 {
142  if (numFields <= 0) {
143  elemDOFEqnNumbers_.resize(0);
144  return(0);
145  }
146 
147  for(int i=0; i<numFields; i++) elemDofFieldIDs_.push_back(fieldIDs[i]);
148 
149  elemDOFEqnNumbers_.resize(numElements_);
150 
151  for(int j=0; j<numElements_; j++) {
152  elemDOFEqnNumbers_[j] = -1;
153  }
154 
155  return(0);
156 }
std::ostream & console_out()
int setNumNodesPerElement(int numNodes)