FEI Version of the Day
fei_NodeDescriptor.cpp
00001 /*
00002 // @HEADER
00003 // ************************************************************************
00004 //             FEI: Finite Element Interface to Linear Solvers
00005 //                  Copyright (2005) Sandia Corporation.
00006 //
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the
00008 // U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Alan Williams (william@sandia.gov) 
00038 //
00039 // ************************************************************************
00040 // @HEADER
00041 */
00042 
00043 
00044 #include <string>
00045 #include <fei_macros.hpp>
00046 #include <fei_defs.h>
00047 
00048 #include <fei_NodeDescriptor.hpp>
00049 
00050 //======Constructor=============================================================
00051 NodeDescriptor::NodeDescriptor()
00052  : nodeID_((GlobalID)-1),
00053    nodeNumber_(-1),
00054    numNodalDOF_(0),
00055    fieldIDList_(NULL),
00056    fieldEqnNumbers_(NULL),
00057    numFields_(0),
00058    blkEqnNumber_(0),
00059    ownerProc_(-1),
00060    blockList_()
00061 {
00062    //There's nothing for this constructor to do, apart from the
00063    //above initializations.
00064 }
00065 
00066 //======Destructor==============================================================
00067 NodeDescriptor::~NodeDescriptor() {
00068   delete [] fieldIDList_;
00069   delete [] fieldEqnNumbers_;
00070   numFields_ = 0;
00071 }
00072 
00073 //==============================================================================
00074 void NodeDescriptor::addField(int fieldID) {
00075 //
00076 //Add a field identifier to this node, ONLY if that field identifier
00077 //is not already present.
00078 //
00079 //If fieldID is added, lengthen the corresponding list for equation numbers.
00080 //
00081 
00082    int tmp = numFields_;
00083    int allocLen = numFields_;
00084    int index = fei::sortedListInsert(fieldID, fieldIDList_, numFields_,
00085                                          allocLen);
00086 
00087    //index is the position at which fieldID was inserted, or found
00088 
00089    //if tmp < numFields_ then fieldID wasn't already present
00090    if (tmp < numFields_) {
00091       //
00092       //if the length of fieldIDList_ changed, let's lengthen the 
00093       //fieldEqnNumbers_ list.
00094       //fieldEqnNumbers_ will have an empty position 'index', which we'll set to
00095       //-99 for now. The calling code (BASE_FEI) will set the fieldEqnNumber for
00096       //this fieldID using setFieldEqnNumber(...).
00097       //
00098 
00099       allocLen = numFields_ - 1;
00100       fei::listInsert(-99, index, fieldEqnNumbers_, tmp, allocLen);
00101    }
00102 }
00103 
00104 //==============================================================================
00105 void NodeDescriptor::setFieldEqnNumber(int fieldID, int eqn) {
00106 //
00107 //Set the equation number corresponding to fieldID. fieldID must
00108 //already have been added to this node using the addField function.
00109 //If it was already added, then the fieldEqnNumbers_ list was lengthened
00110 //appropriately, with an empty spot left for this eqn number.
00111 //
00112    int insert = -1;
00113    int index = fei::binarySearch(fieldID, fieldIDList_,
00114               numFields_, insert);
00115 
00116    if (index < 0) {
00117       return;
00118    }
00119 
00120    fieldEqnNumbers_[index] = eqn;
00121 }
00122 
00123 //==============================================================================
00124 bool NodeDescriptor::getFieldEqnNumber(int fieldID, int& eqnNumber) const
00125 {
00126    int insert = -1;
00127    int index = fei::binarySearch(fieldID, fieldIDList_,
00128               numFields_, insert);
00129 
00130    if (index < 0) {
00131       return(false);
00132    }
00133 
00134    eqnNumber = fieldEqnNumbers_[index];
00135    return(true);
00136 }
00137 
00138 //==============================================================================
00139 void NodeDescriptor::getFieldID(int eqnNumber, int& fieldID, int& offset_into_field) const
00140 {
00141   if (numFields_ < 1) {
00142     throw std::runtime_error("fei::NodeDescriptor::getFieldID ERROR, no nodal dofs on this node.");
00143   }
00144 
00145   int firstNodalEqn = fieldEqnNumbers_[0];
00146   if (eqnNumber - firstNodalEqn > numNodalDOF_) {
00147     throw std::runtime_error("fei::NodeDescriptor::getFieldID ERROR, eqnNumber out of range.");
00148   }
00149 
00150   bool found_field = false;
00151   for(int i=numFields_-1; i>=0; --i) {
00152     if (fieldEqnNumbers_[i] <= eqnNumber) {
00153       fieldID = fieldIDList_[i];
00154       offset_into_field = eqnNumber - fieldEqnNumbers_[i];
00155       found_field = true;
00156       break;
00157     }
00158   }
00159 
00160   if (!found_field) {
00161     throw std::runtime_error("fei::NodeDescriptor::getFieldID ERROR, fieldID not found for eqnNumber.");
00162   }
00163 }
00164 
00165 //==============================================================================
00166 bool NodeDescriptor::hasBlockIndex(unsigned blk_idx) const
00167 {
00168   //return true if this node is contained in element-block-index 'blk_idx'.
00169 
00170    int index = fei::binarySearch(blk_idx, &blockList_[0], blockList_.size());
00171    if (index >= 0) return(true);
00172    else return(false);
00173 }
00174 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends