FEI Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
fei_DirichletBCManager.cpp
Go to the documentation of this file.
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_sstream.hpp>
13 #include <fei_NodeDatabase.hpp>
14 #include <fei_EqnBuffer.hpp>
15 #include <fei_SharedPtr.hpp>
16 #include <fei_VectorSpace.hpp>
17 #include <fei_Matrix.hpp>
18 
19 #include <algorithm>
20 #include <vector>
21 
22 typedef std::vector<fei::DirichletBCRecord> DBCvec;
23 
24 #undef fei_file
25 #define fei_file "fei_DirichletBCManager.cpp"
26 #include <fei_ErrMacros.hpp>
27 
28 namespace fei {
29 
30 int
31 DirichletBCManager::getEqnNumber(int IDType, int ID, int fieldID, int offsetIntoField)
32 {
33  int eqn = -1;
34  try {
35  if (vecSpace_.get() != NULL) {
36  vecSpace_->getGlobalIndex(IDType, ID, fieldID, eqn);
37  }
38  else {
39  if (structure_ == NULL) {
40  throw std::runtime_error("fei::DirichletBCManager has NULL SNL_FEI_Structure.");
41  }
43  const NodeDescriptor* node = NULL;
44  nodeDB.getNodeWithID(ID, node);
45  if (node == NULL) {
46  throw std::runtime_error("fei::DirichletBCManager::getEqnNumber failed to get node.");
47  }
48  node->getFieldEqnNumber(fieldID, eqn);
49  }
50  }
51  catch(std::runtime_error& exc) {
52  FEI_OSTRINGSTREAM osstr;
53  osstr << "fei::DirichletBCManager::finalizeBCEqns caught exception: "
54  << exc.what() << " BC IDType="<<IDType<<", ID="<<ID
55  << ", fieldID="<<fieldID;
56  fei::console_out() << osstr.str() << FEI_ENDL;
57  ERReturn(-1);
58  }
59 
60  return eqn + offsetIntoField;
61 }
62 
63 void
65  int IDType,
66  int fieldID,
67  int offsetIntoField,
68  const int* IDs,
69  const double* prescribedValues)
70 {
71  for(int i=0; i<numBCs; ++i) {
72  int eqn = getEqnNumber(IDType, IDs[i], fieldID, offsetIntoField);
73 
74  bc_map::iterator iter = bcs_.lower_bound(eqn);
75 
76  if (iter == bcs_.end() || iter->first != eqn) {
77  bcs_.insert(iter, std::make_pair(eqn, prescribedValues[i]));
78  continue;
79  }
80  else iter->second = prescribedValues[i];
81  }
82 }
83 
84 void
86  int IDType,
87  int fieldID,
88  const int* IDs,
89  const int* offsetsIntoField,
90  const double* prescribedValues)
91 {
92  for(int i=0; i<numBCs; ++i) {
93  int eqn = getEqnNumber(IDType, IDs[i], fieldID, offsetsIntoField[i]);
94 
95  bc_map::iterator iter = bcs_.lower_bound(eqn);
96 
97  if (iter == bcs_.end() || iter->first != eqn) {
98  bcs_.insert(iter, std::make_pair(eqn, prescribedValues[i]));
99  continue;
100  }
101  else iter->second = prescribedValues[i];
102  }
103 }
104 
105 int
107  bool throw_if_bc_slave_conflict)
108 {
110  bool haveSlaves = reducer.get()!=NULL;
111 
112  //copy the boundary-condition prescribed values into the matrix, in
113  //an equation-number obtained by using the matrix' VectorSpace to map
114  //from the BC's idtype,id,fieldID,component to an equation-number. The
115  //bc values will go on the diagonal of the matrix, i.e., column-index
116  //will be the same equation-number.
117 
118  bc_map::iterator iter = bcs_.begin(), iter_end = bcs_.end();
119 
120  for(; iter!=iter_end; ++iter) {
121 
122  int eqn = iter->first;
123 
124  if (haveSlaves) {
125  if (reducer->isSlaveEqn(eqn)) {
126  if (throw_if_bc_slave_conflict) {
127  FEI_OSTRINGSTREAM osstr;
128  osstr << "fei BCManager::finalizeBCeqns ERROR, eqn="<<eqn
129  << " is both a BC eqn and slave-constraint eqn.";
130  throw std::runtime_error(osstr.str());
131  }
132  continue;
133  }
134  }
135 
136  double* ptr = &iter->second;
137 
138  CHK_ERR( matrix.copyIn(1, &eqn, 1, &eqn, &ptr) );
139  }
140 
141  bcs_.clear();
142  return(0);
143 }
144 
145 int
147 {
148  //copy the boundary-condition prescribed values into bcEqns.
149 
150  bc_map::iterator iter = bcs_.begin(), iter_end = bcs_.end();
151 
152  for(; iter!=iter_end; ++iter) {
153  int eqn = iter->first;
154  double coef = iter->second;
155 
156  CHK_ERR( bcEqns.addEqn(eqn, &coef, &eqn, 1, false) );
157  }
158 
159  bcs_.clear();
160  return(0);
161 }
162 
163 size_t
165 {
166  return bcs_.size();
167 }
168 
169 void
171 {
172  bcs_.clear();
173 }
174 
175 }//namespace fei
176 
int addEqn(int eqnNumber, const double *coefs, const int *indices, int len, bool accumulate, bool create_indices_union=false)
int getEqnNumber(int IDType, int ID, int fieldID, int offsetIntoField)
std::vector< fei::DirichletBCRecord > DBCvec
virtual fei::SharedPtr< fei::Reducer > getReducer()=0
NodeDatabase & getNodeDatabase()
bool getFieldEqnNumber(int fieldID, int &eqnNumber) const
int getGlobalIndex(int idType, int ID, int fieldID, int fieldOffset, int whichComponentOfField, int &globalIndex)
void addBCRecords(int numBCs, int IDType, int fieldID, int offsetIntoField, const int *IDs, const double *prescribedValues)
int finalizeBCEqns(fei::Matrix &matrix, bool throw_if_bc_slave_conflict=false)
#define ERReturn(a)
T * get() const
virtual fei::SharedPtr< fei::MatrixGraph > getMatrixGraph() const =0
#define FEI_ENDL
std::ostream & console_out()
virtual int copyIn(int numRows, const int *rows, int numCols, const int *cols, const double *const *values, int format=0)=0
bool isSlaveEqn(int unreducedEqn) const
#define CHK_ERR(a)
int getNodeWithID(GlobalID nodeID, const NodeDescriptor *&node) const
#define FEI_OSTRINGSTREAM
Definition: fei_sstream.hpp:32
fei::SharedPtr< fei::VectorSpace > vecSpace_