fei_DirichletBCManager.cpp

00001 /*--------------------------------------------------------------------*/
00002 /*    Copyright 2005 Sandia Corporation.                              */
00003 /*    Under the terms of Contract DE-AC04-94AL85000, there is a       */
00004 /*    non-exclusive license for use of this work by or on behalf      */
00005 /*    of the U.S. Government.  Export of this program may require     */
00006 /*    a license from the United States Government.                    */
00007 /*--------------------------------------------------------------------*/
00008 
00009 #include <fei_iostream.hpp>
00010 #include <fei_sstream.hpp>
00011 #include <fei_DirichletBCManager.hpp>
00012 #include <fei_DirichletBCRecord.hpp>
00013 #include <fei_NodeDatabase.hpp>
00014 #include <fei_EqnBuffer.hpp>
00015 #include <fei_SharedPtr.hpp>
00016 #include <fei_VectorSpace.hpp>
00017 #include <fei_Matrix.hpp>
00018 
00019 #include <algorithm>
00020 #include <vector>
00021 
00022 typedef std::vector<fei::DirichletBCRecord> DBCvec;
00023 
00024 #undef fei_file
00025 #define fei_file "fei_DirichletBCManager.cpp"
00026 #include <fei_ErrMacros.hpp>
00027 
00028 namespace fei {
00029 
00030 int
00031 DirichletBCManager::getEqnNumber(int IDType, int ID, int fieldID, int offsetIntoField)
00032 {
00033   int eqn = -1;
00034   try {
00035     if (vecSpace_.get() != NULL) {
00036       vecSpace_->getGlobalIndex(IDType, ID, fieldID, eqn);
00037     }
00038     else {
00039       if (structure_ == NULL) {
00040         throw std::runtime_error("fei::DirichletBCManager has NULL SNL_FEI_Structure.");
00041       }
00042       NodeDatabase& nodeDB = structure_->getNodeDatabase();
00043       const NodeDescriptor* node = NULL;
00044       nodeDB.getNodeWithID(ID, node);
00045       if (node == NULL) {
00046         throw std::runtime_error("fei::DirichletBCManager::getEqnNumber failed to get node.");
00047       }
00048       node->getFieldEqnNumber(fieldID, eqn);
00049     }
00050   }
00051   catch(std::runtime_error& exc) {
00052     FEI_OSTRINGSTREAM osstr;
00053     osstr << "fei::DirichletBCManager::finalizeBCEqns caught exception: "
00054        << exc.what() << " BC IDType="<<IDType<<", ID="<<ID
00055        << ", fieldID="<<fieldID;
00056     FEI_CERR << osstr.str() << FEI_ENDL;
00057     ERReturn(-1);
00058   }
00059 
00060   return eqn + offsetIntoField;
00061 }
00062 
00063 void
00064 DirichletBCManager::addBCRecords(int numBCs,
00065                                  int IDType,
00066                                  int fieldID,
00067                                  int offsetIntoField,
00068                                  const int* IDs,
00069                                  const double* prescribedValues)
00070 {
00071   for(int i=0; i<numBCs; ++i) {
00072     int eqn = getEqnNumber(IDType, IDs[i], fieldID, offsetIntoField);
00073 
00074     bc_map::iterator iter = bcs_.lower_bound(eqn);
00075 
00076     if (iter == bcs_.end() || iter->first != eqn) {
00077       bcs_.insert(iter, std::make_pair(eqn, prescribedValues[i]));
00078       continue;
00079     }
00080     else iter->second = prescribedValues[i];
00081   }
00082 }
00083 
00084 void
00085 DirichletBCManager::addBCRecords(int numBCs,
00086                                  int IDType,
00087                                  int fieldID,
00088                                  const int* IDs,
00089                                  const int* offsetsIntoField,
00090                                  const double* prescribedValues)
00091 {
00092   for(int i=0; i<numBCs; ++i) {
00093     int eqn = getEqnNumber(IDType, IDs[i], fieldID, offsetsIntoField[i]);
00094 
00095     bc_map::iterator iter = bcs_.lower_bound(eqn);
00096 
00097     if (iter == bcs_.end() || iter->first != eqn) {
00098       bcs_.insert(iter, std::make_pair(eqn, prescribedValues[i]));
00099       continue;
00100     }
00101     else iter->second = prescribedValues[i];
00102   }
00103 }
00104 
00105 int
00106 DirichletBCManager::finalizeBCEqns(fei::Matrix& matrix,
00107                                    bool throw_if_bc_slave_conflict)
00108 {
00109   fei::SharedPtr<fei::Reducer> reducer = matrix.getMatrixGraph()->getReducer();
00110   bool haveSlaves = reducer.get()!=NULL;
00111 
00112   //copy the boundary-condition prescribed values into the matrix, in
00113   //an equation-number obtained by using the matrix' VectorSpace to map
00114   //from the BC's idtype,id,fieldID,component to an equation-number. The
00115   //bc values will go on the diagonal of the matrix, i.e., column-index
00116   //will be the same equation-number.
00117 
00118   bc_map::iterator iter = bcs_.begin(), iter_end = bcs_.end();
00119 
00120   for(; iter!=iter_end; ++iter) {
00121 
00122     int eqn = iter->first;
00123 
00124     if (haveSlaves) {
00125       if (reducer->isSlaveEqn(eqn)) {
00126         if (throw_if_bc_slave_conflict) {
00127           FEI_OSTRINGSTREAM osstr;
00128           osstr << "fei BCManager::finalizeBCeqns ERROR, eqn="<<eqn
00129             << " is both a BC eqn and slave-constraint eqn.";
00130           throw std::runtime_error(osstr.str());
00131         }
00132         continue;
00133       }
00134     }
00135 
00136     double* ptr = &iter->second;
00137 
00138     CHK_ERR( matrix.copyIn(1, &eqn, 1, &eqn, &ptr) );
00139   }
00140 
00141   bcs_.clear();
00142   return(0);
00143 }
00144 
00145 int
00146 DirichletBCManager::finalizeBCEqns(EqnBuffer& bcEqns)
00147 {
00148   //copy the boundary-condition prescribed values into bcEqns.
00149 
00150   bc_map::iterator iter = bcs_.begin(), iter_end = bcs_.end();
00151 
00152   for(; iter!=iter_end; ++iter) {
00153     int eqn = iter->first;
00154     double coef = iter->second;
00155 
00156     CHK_ERR( bcEqns.addEqn(eqn, &coef, &eqn, 1, false) );
00157   }
00158 
00159   bcs_.clear();
00160   return(0);
00161 }
00162 
00163 size_t
00164 DirichletBCManager::getNumBCRecords() const
00165 {
00166   return bcs_.size();
00167 }
00168 
00169 void
00170 DirichletBCManager::clearAllBCs()
00171 {
00172   bcs_.clear();
00173 }
00174 
00175 }//namespace fei
00176 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends
Generated on Wed Apr 13 10:08:23 2011 for FEI by  doxygen 1.6.3