Chaste Release::3.1
AbstractElement.cpp
00001 /*
00002 
00003 Copyright (c) 2005-2012, University of Oxford.
00004 All rights reserved.
00005 
00006 University of Oxford means the Chancellor, Masters and Scholars of the
00007 University of Oxford, having an administrative office at Wellington
00008 Square, Oxford OX1 2JD, UK.
00009 
00010 This file is part of Chaste.
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided that the following conditions are met:
00014  * Redistributions of source code must retain the above copyright notice,
00015    this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright notice,
00017    this list of conditions and the following disclaimer in the documentation
00018    and/or other materials provided with the distribution.
00019  * Neither the name of the University of Oxford nor the names of its
00020    contributors may be used to endorse or promote products derived from this
00021    software without specific prior written permission.
00022 
00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 
00034 */
00035 
00036 #include "AbstractElement.hpp"
00037 
00038 #include "Exception.hpp"
00039 
00040 #include <cassert>
00041 
00043 // Implementation
00045 
00046 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00047 AbstractElement<ELEMENT_DIM, SPACE_DIM>::AbstractElement(unsigned index, const std::vector<Node<SPACE_DIM>*>& rNodes)
00048     : mNodes(rNodes),
00049       mIndex(index),
00050       mAttribute(0.0),
00051       mIsDeleted(false),
00052       mOwnership(true),
00053       mFlag(false)
00054 {
00055     // Sanity checking
00056     assert(ELEMENT_DIM <= SPACE_DIM);
00057 
00058     // Flags must be initialised before the Jacobian calculations, or assertions trip
00059 }
00060 
00061 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00062 AbstractElement<ELEMENT_DIM, SPACE_DIM>::AbstractElement(unsigned index)
00063     : mIndex(index),
00064       mAttribute(0.0),
00065       mIsDeleted(false),
00066       mOwnership(true),
00067       mFlag(false)
00068 {}
00069 
00070 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00071 void AbstractElement<ELEMENT_DIM, SPACE_DIM>::ReplaceNode(Node<SPACE_DIM>* pOldNode, Node<SPACE_DIM>* pNewNode)
00072 {
00073     assert(pOldNode != pNewNode);
00074     for (unsigned i=0; i<this->mNodes.size(); i++)
00075     {
00076         if (this->mNodes[i] == pOldNode)
00077         {
00078             UpdateNode(i, pNewNode);
00079             return;
00080         }
00081     }
00082     EXCEPTION("You didn't have that node to start with.");
00083 }
00084 
00085 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00086 double AbstractElement<ELEMENT_DIM, SPACE_DIM>::GetNodeLocation(unsigned localIndex, unsigned dimension) const
00087 {
00088     assert(dimension < SPACE_DIM);
00089     assert((unsigned)localIndex < mNodes.size());
00090     return mNodes[localIndex]->rGetLocation()[dimension];
00091 }
00092 
00093 /*
00094  * Note for future reference: this used to return a reference to a c_vector, in which case a
00095  * weird error arose where it compiled, ran and passed on some machines but failed the tests
00096  * (bad_size errors) on another machine.  So be careful if you think about changing it!
00097  */
00098 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00099 c_vector<double, SPACE_DIM> AbstractElement<ELEMENT_DIM, SPACE_DIM>::GetNodeLocation(unsigned localIndex) const
00100 {
00101     assert((unsigned)localIndex < mNodes.size());
00102     return mNodes[localIndex]->rGetLocation();
00103 }
00104 
00105 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00106 unsigned AbstractElement<ELEMENT_DIM, SPACE_DIM>::GetNodeGlobalIndex(unsigned localIndex) const
00107 {
00108     assert((unsigned)localIndex < mNodes.size());
00109     return mNodes[localIndex]->GetIndex();
00110 }
00111 
00112 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00113 Node<SPACE_DIM>* AbstractElement<ELEMENT_DIM, SPACE_DIM>::GetNode(unsigned localIndex) const
00114 {
00115     assert((unsigned)localIndex < mNodes.size());
00116     return mNodes[localIndex];
00117 }
00118 
00119 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00120 unsigned AbstractElement<ELEMENT_DIM, SPACE_DIM>::GetNumNodes() const
00121 {
00122     return mNodes.size();
00123 }
00124 
00125 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00126 void AbstractElement<ELEMENT_DIM, SPACE_DIM>::AddNode(Node<SPACE_DIM>* pNode)
00127 {
00128     mNodes.push_back(pNode);
00129 }
00130 
00131 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00132 bool AbstractElement<ELEMENT_DIM, SPACE_DIM>::IsDeleted() const
00133 {
00134     return mIsDeleted;
00135 }
00136 
00137 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00138 unsigned AbstractElement<ELEMENT_DIM, SPACE_DIM>::GetIndex() const
00139 {
00140     return mIndex;
00141 }
00142 
00143 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00144 void AbstractElement<ELEMENT_DIM, SPACE_DIM>::SetIndex(unsigned index)
00145 {
00146     mIndex = index;
00147 }
00148 
00149 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00150 bool AbstractElement<ELEMENT_DIM, SPACE_DIM>::GetOwnership() const
00151 {
00152     return mOwnership;
00153 }
00154 
00155 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00156 void AbstractElement<ELEMENT_DIM, SPACE_DIM>::SetOwnership(bool ownership)
00157 {
00158     mOwnership = ownership;
00159 }
00160 
00161 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00162 void AbstractElement<ELEMENT_DIM, SPACE_DIM>::Flag()
00163 {
00164     mFlag = true;
00165 }
00166 
00167 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00168 void AbstractElement<ELEMENT_DIM, SPACE_DIM>::Unflag()
00169 {
00170     mFlag = false;
00171 }
00172 
00173 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00174 bool AbstractElement<ELEMENT_DIM, SPACE_DIM>::IsFlagged() const
00175 {
00176     return mFlag;
00177 }
00178 
00179 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00180 void AbstractElement<ELEMENT_DIM, SPACE_DIM>::SetAttribute(double attribute)
00181 {
00182     mAttribute = attribute;
00183 }
00184 
00185 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00186 double AbstractElement<ELEMENT_DIM, SPACE_DIM>::GetAttribute()
00187 {
00188     return mAttribute;
00189 }
00190 
00191 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00192 unsigned AbstractElement<ELEMENT_DIM, SPACE_DIM>::GetUnsignedAttribute()
00193 {
00194     double double_attr = GetAttribute();
00195     unsigned unsigned_attr = (unsigned) double_attr;
00196     if (fabs(double_attr-((double)(unsigned_attr)))>1e-9)
00197     {
00198         EXCEPTION("Element attribute '"<< double_attr <<"' cannot be converted to an unsigned.");
00199     }
00200     return unsigned_attr;
00201 }
00202 
00203 
00205 // Explicit instantiation
00207 
00208 template class AbstractElement<0,1>;
00209 template class AbstractElement<1,1>;
00210 template class AbstractElement<0,2>;
00211 template class AbstractElement<1,2>;
00212 template class AbstractElement<2,2>;
00213 template class AbstractElement<0,3>;
00214 template class AbstractElement<1,3>;
00215 template class AbstractElement<2,3>;
00216 template class AbstractElement<3,3>;