MixedDimensionMesh.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2011
00004 
00005 University of Oxford means the Chancellor, Masters and Scholars of the
00006 University of Oxford, having an administrative office at Wellington
00007 Square, Oxford OX1 2JD, UK.
00008 
00009 This file is part of Chaste.
00010 
00011 Chaste is free software: you can redistribute it and/or modify it
00012 under the terms of the GNU Lesser General Public License as published
00013 by the Free Software Foundation, either version 2.1 of the License, or
00014 (at your option) any later version.
00015 
00016 Chaste is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00019 License for more details. The offer of Chaste under the terms of the
00020 License is subject to the License being interpreted in accordance with
00021 English Law and subject to any action against the University of Oxford
00022 being under the jurisdiction of the English Courts.
00023 
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>.
00026 
00027 */
00028 
00029 #include "MixedDimensionMesh.hpp"
00030 
00031 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00032 MixedDimensionMesh<ELEMENT_DIM, SPACE_DIM>::MixedDimensionMesh(DistributedTetrahedralMeshPartitionType::type partitioningMethod)
00033     : DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::DistributedTetrahedralMesh(partitioningMethod)
00034 {
00035 }
00036 
00037 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00038 MixedDimensionMesh<ELEMENT_DIM, SPACE_DIM>::~MixedDimensionMesh()
00039 {
00040     for (unsigned i=0; i<mCableElements.size(); i++)
00041     {
00042         delete mCableElements[i];
00043     }
00044 }
00045 
00046 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00047 void MixedDimensionMesh<ELEMENT_DIM, SPACE_DIM>::ConstructFromMeshReader(AbstractMeshReader<ELEMENT_DIM,SPACE_DIM>& rMeshReader)
00048 {
00049     DistributedTetrahedralMesh<ELEMENT_DIM,SPACE_DIM>::ConstructFromMeshReader(rMeshReader);
00050     
00051     // Add cable elements
00052     mNumCableElements = rMeshReader.GetNumCableElements();
00053     //this->mCableElements.reserve(mNumCableElements);
00054     
00055     for (unsigned element_index=0; element_index < mNumCableElements; element_index++)
00056     {
00057         ElementData element_data = rMeshReader.GetNextCableElementData();
00058 
00059         //Determine if we own any nodes on this cable element
00060         bool node_owned = false;
00061         for (unsigned j=0; j<2; j++) // cables are always 1d
00062         {
00063             try
00064             {
00065                 this->SolveNodeMapping(element_data.NodeIndices[j]);
00066                 node_owned = true;
00067                 break;
00068             }
00069             catch (Exception &e)
00070             {
00071                 //We deal with non-owned nodes in the next part
00072             }
00073         }
00074         
00075         //If we don't locally own either node, then we don't construct the cable      
00076         if (node_owned)
00077         {           
00078             std::vector<Node<SPACE_DIM>*> nodes;
00079             nodes.reserve(2u);
00080     
00081             for (unsigned j=0; j<2; j++) // cables are always 1d
00082             {
00083                 //Note that if we own one node on a cable element then we are likely to own the other.
00084                 //If not, we are likely to have a halo.
00085                 //If not, (free-running Purkinje with monodomain mesh?), then this will terminate.
00086                 try
00087                 {
00088                     nodes.push_back(this->GetNodeOrHaloNode(element_data.NodeIndices[j]) );
00089                 }
00090                 catch (Exception& e)
00091                 {
00092                     NEVER_REACHED;
00093                 }
00094             }
00095     
00096             Element<1u, SPACE_DIM>* p_element = new Element<1u,SPACE_DIM>(element_index, nodes);
00097             RegisterCableElement(element_index);
00098             this->mCableElements.push_back(p_element);
00099     
00100             if (rMeshReader.GetNumCableElementAttributes() > 0)
00101             {
00102                 assert(rMeshReader.GetNumCableElementAttributes() == 1);
00103                 unsigned attribute_value = element_data.AttributeValue;
00104                 p_element->SetRegion(attribute_value);
00105             }
00106         }
00107     }
00108 
00109     rMeshReader.Reset();
00110 }
00111 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00112 void MixedDimensionMesh<ELEMENT_DIM, SPACE_DIM>::RegisterCableElement(unsigned index)
00113 {
00114     mCableElementsMapping[index] = this->mCableElements.size();
00115 }
00116 
00117 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00118 unsigned MixedDimensionMesh<ELEMENT_DIM, SPACE_DIM>::GetNumCableElements() const
00119 {
00120    return mNumCableElements;
00121 }
00122 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00123 unsigned MixedDimensionMesh<ELEMENT_DIM, SPACE_DIM>::GetNumLocalCableElements() const
00124 {
00125    return mCableElements.size();
00126 }
00127     
00128 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00129 Element<1u, SPACE_DIM>* MixedDimensionMesh<ELEMENT_DIM, SPACE_DIM>::GetCableElement(unsigned globalElementIndex) const
00130 {
00131     std::map<unsigned, unsigned>::const_iterator element_position = mCableElementsMapping.find(globalElementIndex);
00132 
00133     if (element_position == mCableElementsMapping.end())
00134     {
00135         std::stringstream message;
00136         message << "Requested cable element " << globalElementIndex << " does not belong to processor " << PetscTools::GetMyRank();
00137         EXCEPTION(message.str().c_str());
00138     }
00139 
00140     unsigned index = element_position->second;
00141 
00142     return mCableElements[index];
00143 }
00144 
00145 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00146 bool MixedDimensionMesh<ELEMENT_DIM, SPACE_DIM>::CalculateDesignatedOwnershipOfCableElement( unsigned elementIndex )
00147 {
00148     //This should not throw in the distributed parallel case
00149     try
00150     {
00151         unsigned tie_break_index = this->GetCableElement(elementIndex)->GetNodeGlobalIndex(0);
00152 
00153         //if it is in my range
00154         if (this->GetDistributedVectorFactory()->IsGlobalIndexLocal(tie_break_index))
00155         {
00156             return true;
00157         }
00158         else
00159         {
00160             return false;
00161         }
00162     }
00163     catch (Exception &e)
00164     {
00165         //We don't own this cable element
00166         return false;
00167     }
00168 }
00169 
00170 
00171 
00172 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00173 typename MixedDimensionMesh<ELEMENT_DIM, SPACE_DIM>::CableElementIterator MixedDimensionMesh<ELEMENT_DIM, SPACE_DIM>::GetCableElementIteratorBegin() const
00174 {
00175     return mCableElements.begin();
00176 }
00177 
00178 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00179 typename MixedDimensionMesh<ELEMENT_DIM, SPACE_DIM>::CableElementIterator MixedDimensionMesh<ELEMENT_DIM, SPACE_DIM>::GetCableElementIteratorEnd() const
00180 {
00181     return mCableElements.end();
00182 }
00183 
00184 
00185 
00187 // Explicit instantiation
00189 
00190 template class MixedDimensionMesh<1,1>;
00191 template class MixedDimensionMesh<1,2>;
00192 template class MixedDimensionMesh<1,3>;
00193 template class MixedDimensionMesh<2,2>;
00194 template class MixedDimensionMesh<2,3>;
00195 template class MixedDimensionMesh<3,3>;

Generated on Tue May 31 14:31:48 2011 for Chaste by  doxygen 1.5.5