FEI Version of the Day
Loading...
Searching...
No Matches
fei_DirichletBCManager.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_sstream.hpp>
11#include <fei_DirichletBCManager.hpp>
12#include <fei_DirichletBCRecord.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
22typedef std::vector<fei::DirichletBCRecord> DBCvec;
23
24#undef fei_file
25#define fei_file "fei_DirichletBCManager.cpp"
26#include <fei_ErrMacros.hpp>
27
28namespace fei {
29
30int
31DirichletBCManager::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 }
42 NodeDatabase& nodeDB = structure_->getNodeDatabase();
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
63void
64DirichletBCManager::addBCRecords(int numBCs,
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
84void
85DirichletBCManager::addBCRecords(int numBCs,
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
105int
106DirichletBCManager::finalizeBCEqns(fei::Matrix& matrix,
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
145int
146DirichletBCManager::finalizeBCEqns(EqnBuffer& bcEqns)
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
163size_t
164DirichletBCManager::getNumBCRecords() const
165{
166 return bcs_.size();
167}
168
169void
170DirichletBCManager::clearAllBCs()
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 getNodeWithID(GlobalID nodeID, const NodeDescriptor *&node) const
bool getFieldEqnNumber(int fieldID, int &eqnNumber) const
virtual fei::SharedPtr< fei::Reducer > getReducer()=0
virtual fei::SharedPtr< fei::MatrixGraph > getMatrixGraph() const =0
virtual int copyIn(int numRows, const int *rows, int numCols, const int *cols, const double *const *values, int format=0)=0
T * get() const
std::ostream & console_out()