AbstractTetrahedralMesh.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2010
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 "AbstractTetrahedralMesh.hpp"
00030 
00032 // Implementation
00034 
00035 
00036 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00037 void AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::SetElementOwnerships(unsigned lo, unsigned hi)
00038 {
00039     assert(hi >= lo);
00040     for (unsigned element_index=0; element_index<mElements.size(); element_index++)
00041     {
00042         Element<ELEMENT_DIM, SPACE_DIM>* p_element = mElements[element_index];
00043         p_element->SetOwnership(false);
00044         for (unsigned local_node_index=0; local_node_index< p_element->GetNumNodes(); local_node_index++)
00045         {
00046             unsigned global_node_index = p_element->GetNodeGlobalIndex(local_node_index);
00047             if (lo<=global_node_index && global_node_index<hi)
00048             {
00049                 p_element->SetOwnership(true);
00050                 break;
00051             }
00052         }
00053     }
00054 }
00055 
00056 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00057 AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::AbstractTetrahedralMesh()
00058     : mMeshIsLinear(true)
00059 {
00060 }
00061 
00062 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00063 AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::~AbstractTetrahedralMesh()
00064 {
00065     // Iterate over elements and free the memory
00066     for (unsigned i=0; i<mElements.size(); i++)
00067     {
00068         delete mElements[i];
00069     }
00070     // Iterate over boundary elements and free the memory
00071     for (unsigned i=0; i<mBoundaryElements.size(); i++)
00072     {
00073         delete mBoundaryElements[i];
00074     }
00075 }
00076 
00077 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00078 unsigned AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetNumElements() const
00079 {
00080     return mElements.size();
00081 }
00082 
00083 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00084 unsigned AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetNumAllElements() const
00085 {
00086     return mElements.size();
00087 }
00088 
00089 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00090 unsigned AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetNumAllBoundaryElements() const
00091 {
00092     return mBoundaryElements.size();
00093 }
00094 
00095 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00096 unsigned AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetNumBoundaryElements() const
00097 {
00098     return mBoundaryElements.size();
00099 }
00100 
00101 
00102 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00103 Element<ELEMENT_DIM, SPACE_DIM>* AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetElement(unsigned index) const
00104 {
00105     unsigned local_index = SolveElementMapping(index);
00106     return mElements[local_index];
00107 }
00108 
00109 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00110 BoundaryElement<ELEMENT_DIM-1, SPACE_DIM>* AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetBoundaryElement(unsigned index) const
00111 {
00112     unsigned local_index = SolveBoundaryElementMapping(index);
00113     return mBoundaryElements[local_index];
00114 }
00115 
00116 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00117 typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::BoundaryElementIterator AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetBoundaryElementIteratorBegin() const
00118 {
00119     return mBoundaryElements.begin();
00120 }
00121 
00122 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00123 typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::BoundaryElementIterator AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetBoundaryElementIteratorEnd() const
00124 {
00125     return mBoundaryElements.end();
00126 }
00127 
00128 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00129 void AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetInverseJacobianForElement(
00130         unsigned elementIndex,
00131         c_matrix<double, SPACE_DIM, ELEMENT_DIM>& rJacobian,
00132         double& rJacobianDeterminant,
00133         c_matrix<double, ELEMENT_DIM, SPACE_DIM>& rInverseJacobian) const
00134 {
00135     mElements[SolveElementMapping(elementIndex)]->CalculateInverseJacobian(rJacobian, rJacobianDeterminant, rInverseJacobian);
00136 }
00137 
00138 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00139 void AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetWeightedDirectionForBoundaryElement(
00140         unsigned elementIndex,
00141         c_vector<double, SPACE_DIM>& rWeightedDirection,
00142         double& rJacobianDeterminant) const
00143 {
00144     mBoundaryElements[SolveBoundaryElementMapping(elementIndex)]->CalculateWeightedDirection(rWeightedDirection, rJacobianDeterminant );
00145 }
00146 
00147 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00148 void AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ConstructLinearMesh(unsigned width)
00149 {
00150     assert(ELEMENT_DIM == 1);
00151 
00152     for (unsigned node_index=0; node_index<=width; node_index++)
00153     {
00154         Node<SPACE_DIM>* p_node = new Node<SPACE_DIM>(node_index, node_index==0 || node_index==width, node_index);
00155         this->mNodes.push_back(p_node); // create node
00156         if (node_index==0) // create left boundary node and boundary element
00157         {
00158             this->mBoundaryNodes.push_back(p_node);
00159             this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(0, p_node) );
00160         }
00161         if (node_index==width) // create right boundary node and boundary element
00162         {
00163             this->mBoundaryNodes.push_back(p_node);
00164             this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(1, p_node) );
00165         }
00166         if (node_index>0) // create element
00167         {
00168             std::vector<Node<SPACE_DIM>*> nodes;
00169             nodes.push_back(this->mNodes[node_index-1]);
00170             nodes.push_back(this->mNodes[node_index]);
00171             this->mElements.push_back(new Element<ELEMENT_DIM,SPACE_DIM>(node_index-1, nodes) );
00172         }
00173     }
00174 
00175     this->RefreshMesh();
00176 }
00177 
00178 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00179 void AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ConstructRectangularMesh(unsigned width, unsigned height, bool stagger)
00180 {
00181     assert(SPACE_DIM == 2);
00182     assert(ELEMENT_DIM == 2);
00183 
00184     //Construct the nodes
00185     unsigned node_index=0;
00186     for (unsigned j=0; j<height+1; j++)
00187     {
00188         for (unsigned i=0; i<width+1; i++)
00189         {
00190             bool is_boundary=false;
00191             if (i==0 || j==0 || i==width || j==height)
00192             {
00193                 is_boundary=true;
00194             }
00195             //Check in place for parallel
00196             assert(node_index==(width+1)*(j) + i);
00197             Node<SPACE_DIM>* p_node = new Node<SPACE_DIM>(node_index++, is_boundary, i, j);
00198             this->mNodes.push_back(p_node);
00199             if (is_boundary)
00200             {
00201                 this->mBoundaryNodes.push_back(p_node);
00202             }
00203         }
00204     }
00205 
00206     //Construct the boundary elements
00207     unsigned belem_index=0;
00208     //Top
00209     for (unsigned i=0; i<width; i++)
00210     {
00211         std::vector<Node<SPACE_DIM>*> nodes;
00212         nodes.push_back(this->mNodes[height*(width+1)+i]);
00213         nodes.push_back(this->mNodes[height*(width+1)+i+1]);
00214         assert(belem_index==i);
00215         this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,nodes));
00216     }
00217     //Right
00218     for (unsigned j=1; j<=height; j++)
00219     {
00220         std::vector<Node<SPACE_DIM>*> nodes;
00221         nodes.push_back(this->mNodes[(width+1)*(j+1)-1]);
00222         nodes.push_back(this->mNodes[(width+1)*j-1]);
00223         assert(belem_index==width+j-1);
00224         this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,nodes));
00225     }
00226     //Bottom
00227     for (unsigned i=0; i<width; i++)
00228     {
00229         std::vector<Node<SPACE_DIM>*> nodes;
00230         nodes.push_back(this->mNodes[i+1]);
00231         nodes.push_back(this->mNodes[i]);
00232         assert(belem_index==width+height+i);
00233         this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,nodes));
00234     }
00235     //Left
00236     for (unsigned j=0; j<height; j++)
00237     {
00238         std::vector<Node<SPACE_DIM>*> nodes;
00239         nodes.push_back(this->mNodes[(width+1)*(j+1)]);
00240         nodes.push_back(this->mNodes[(width+1)*(j)]);
00241         assert(belem_index==2*width+height+j);
00242         this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,nodes));
00243     }
00244 
00245     //Construct the elements
00246     unsigned elem_index = 0;
00247     for (unsigned j=0; j<height; j++)
00248     {
00249         for (unsigned i=0; i<width; i++)
00250         {
00251             unsigned parity=(i+(height-j))%2;//Note that parity is measured from the top-left (not bottom left) for historical reasons
00252             unsigned nw=(j+1)*(width+1)+i; //ne=nw+1
00253             unsigned sw=(j)*(width+1)+i;   //se=sw+1
00254             std::vector<Node<SPACE_DIM>*> upper_nodes;
00255             upper_nodes.push_back(this->mNodes[nw]);
00256             upper_nodes.push_back(this->mNodes[nw+1]);
00257             if (stagger==false  || parity == 1)
00258             {
00259                 upper_nodes.push_back(this->mNodes[sw+1]);
00260             }
00261             else
00262             {
00263                 upper_nodes.push_back(this->mNodes[sw]);
00264             }
00265             assert(elem_index==2*(j*width+i));
00266             this->mElements.push_back(new Element<ELEMENT_DIM,SPACE_DIM>(elem_index++,upper_nodes));
00267             std::vector<Node<SPACE_DIM>*> lower_nodes;
00268             lower_nodes.push_back(this->mNodes[sw+1]);
00269             lower_nodes.push_back(this->mNodes[sw]);
00270             if (stagger==false  ||parity == 1)
00271             {
00272                 lower_nodes.push_back(this->mNodes[nw]);
00273             }
00274             else
00275             {
00276                 lower_nodes.push_back(this->mNodes[nw+1]);
00277             }
00278             this->mElements.push_back(new Element<ELEMENT_DIM,SPACE_DIM>(elem_index++,lower_nodes));
00279         }
00280     }
00281 
00282     this->RefreshMesh();
00283 }
00284 
00285 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00286 void AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ConstructCuboid(unsigned width,
00287         unsigned height,
00288         unsigned depth)
00289 {
00290     assert(SPACE_DIM == 3);
00291     assert(ELEMENT_DIM == 3);
00292     //Construct the nodes
00293 
00294     unsigned node_index = 0;
00295     for (unsigned k=0; k<depth+1; k++)
00296     {
00297         for (unsigned j=0; j<height+1; j++)
00298         {
00299             for (unsigned i=0; i<width+1; i++)
00300             {
00301                 bool is_boundary = false;
00302                 if (i==0 || j==0 || k==0 || i==width || j==height || k==depth)
00303                 {
00304                     is_boundary = true;
00305                 }
00306                 assert(node_index == (k*(height+1)+j)*(width+1)+i);
00307                 Node<SPACE_DIM>* p_node = new Node<SPACE_DIM>(node_index++, is_boundary, i, j, k);
00308 
00309                 this->mNodes.push_back(p_node);
00310                 if (is_boundary)
00311                 {
00312                     this->mBoundaryNodes.push_back(p_node);
00313                 }
00314             }
00315         }
00316     }
00317 
00318     // Construct the elements
00319 
00320     unsigned elem_index = 0;
00321     unsigned belem_index = 0;
00322     unsigned element_nodes[6][4] = {{0, 1, 5, 7}, {0, 1, 3, 7},
00323                                         {0, 2, 3, 7}, {0, 2, 6, 7},
00324                                         {0, 4, 6, 7}, {0, 4, 5, 7}};
00325 /* Alternative tessellation - (gerardus)
00326  * Note that our method (above) has a bias that all tetrahedra share a
00327  * common edge (the diagonal 0 - 7).  In the following method the cube is
00328  * split along the "face diagonal" 1-2-5-6 into two prisms.  This also has a bias.
00329  *
00330     unsigned element_nodes[6][4] = {{ 0, 6, 5, 4},
00331                                     { 0, 2, 6, 1},
00332                                     { 0, 1, 6, 5},
00333                                     { 1, 2, 3, 7},
00334                                     { 1, 2, 6, 7},
00335                                     { 1, 6, 7, 5 }};
00336 */
00337     std::vector<Node<SPACE_DIM>*> tetrahedra_nodes;
00338 
00339     for (unsigned k=0; k<depth; k++)
00340     {
00341         if (k!=0)
00342         {
00343             // height*width squares on upper face, k layers of 2*height+2*width square aroun
00344             assert(belem_index ==   2*(height*width+k*2*(height+width)) );
00345         }
00346         for (unsigned j=0; j<height; j++)
00347         {
00348             for (unsigned i=0; i<width; i++)
00349             {
00350                 // Compute the nodes' index
00351                 unsigned global_node_indices[8];
00352                 unsigned local_node_index = 0;
00353 
00354                 for (unsigned z = 0; z < 2; z++)
00355                 {
00356                     for (unsigned y = 0; y < 2; y++)
00357                     {
00358                         for (unsigned x = 0; x < 2; x++)
00359                         {
00360                             global_node_indices[local_node_index] = i+x+(width+1)*(j+y+(height+1)*(k+z));
00361 
00362                             local_node_index++;
00363                         }
00364                     }
00365                 }
00366 
00367                 for (unsigned m = 0; m < 6; m++)
00368                 {
00369                     // Tetrahedra #m
00370 
00371                     tetrahedra_nodes.clear();
00372 
00373                     for (unsigned n = 0; n < 4; n++)
00374                     {
00375                         tetrahedra_nodes.push_back(this->mNodes[global_node_indices[element_nodes[m][n]]]);
00376                     }
00377 
00378                     assert(elem_index == 6 * ((k*height+j)*width+i)+m );
00379                     this->mElements.push_back(new Element<ELEMENT_DIM,SPACE_DIM>(elem_index++, tetrahedra_nodes));
00380                 }
00381 
00382                 //Are we at a boundary?
00383                 std::vector<Node<SPACE_DIM>*> triangle_nodes;
00384 
00385                 if (i == 0) //low face at x==0
00386                 {
00387                     triangle_nodes.clear();
00388                     triangle_nodes.push_back(this->mNodes[global_node_indices[0]]);
00389                     triangle_nodes.push_back(this->mNodes[global_node_indices[2]]);
00390                     triangle_nodes.push_back(this->mNodes[global_node_indices[6]]);
00391                     this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,triangle_nodes));
00392                     triangle_nodes.clear();
00393                     triangle_nodes.push_back(this->mNodes[global_node_indices[0]]);
00394                     triangle_nodes.push_back(this->mNodes[global_node_indices[6]]);
00395                     triangle_nodes.push_back(this->mNodes[global_node_indices[4]]);
00396                     this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,triangle_nodes));
00397                 }
00398                 if (i == width-1) //high face at x=width
00399                 {
00400                     triangle_nodes.clear();
00401                     triangle_nodes.push_back(this->mNodes[global_node_indices[1]]);
00402                     triangle_nodes.push_back(this->mNodes[global_node_indices[5]]);
00403                     triangle_nodes.push_back(this->mNodes[global_node_indices[7]]);
00404                     this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,triangle_nodes));
00405                     triangle_nodes.clear();
00406                     triangle_nodes.push_back(this->mNodes[global_node_indices[1]]);
00407                     triangle_nodes.push_back(this->mNodes[global_node_indices[7]]);
00408                     triangle_nodes.push_back(this->mNodes[global_node_indices[3]]);
00409                     this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,triangle_nodes));
00410                 }
00411                 if (j == 0) //low face at y==0
00412                 {
00413                     triangle_nodes.clear();
00414                     triangle_nodes.push_back(this->mNodes[global_node_indices[0]]);
00415                     triangle_nodes.push_back(this->mNodes[global_node_indices[5]]);
00416                     triangle_nodes.push_back(this->mNodes[global_node_indices[1]]);
00417                     this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,triangle_nodes));
00418                     triangle_nodes.clear();
00419                     triangle_nodes.push_back(this->mNodes[global_node_indices[0]]);
00420                     triangle_nodes.push_back(this->mNodes[global_node_indices[4]]);
00421                     triangle_nodes.push_back(this->mNodes[global_node_indices[5]]);
00422                     this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,triangle_nodes));
00423                 }
00424                 if (j == height-1) //high face at y=height
00425                 {
00426                     triangle_nodes.clear();
00427                     triangle_nodes.push_back(this->mNodes[global_node_indices[2]]);
00428                     triangle_nodes.push_back(this->mNodes[global_node_indices[3]]);
00429                     triangle_nodes.push_back(this->mNodes[global_node_indices[7]]);
00430                     this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,triangle_nodes));
00431                     triangle_nodes.clear();
00432                     triangle_nodes.push_back(this->mNodes[global_node_indices[2]]);
00433                     triangle_nodes.push_back(this->mNodes[global_node_indices[7]]);
00434                     triangle_nodes.push_back(this->mNodes[global_node_indices[6]]);
00435                     this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,triangle_nodes));
00436                 }
00437                 if (k == 0) //low face at z==0
00438                 {
00439                     triangle_nodes.clear();
00440                     triangle_nodes.push_back(this->mNodes[global_node_indices[0]]);
00441                     triangle_nodes.push_back(this->mNodes[global_node_indices[3]]);
00442                     triangle_nodes.push_back(this->mNodes[global_node_indices[2]]);
00443                     this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,triangle_nodes));
00444                     triangle_nodes.clear();
00445                     triangle_nodes.push_back(this->mNodes[global_node_indices[0]]);
00446                     triangle_nodes.push_back(this->mNodes[global_node_indices[1]]);
00447                     triangle_nodes.push_back(this->mNodes[global_node_indices[3]]);
00448                     this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,triangle_nodes));
00449                 }
00450                 if (k == depth-1) //high face at z=depth
00451                 {
00452                     triangle_nodes.clear();
00453                     triangle_nodes.push_back(this->mNodes[global_node_indices[4]]);
00454                     triangle_nodes.push_back(this->mNodes[global_node_indices[7]]);
00455                     triangle_nodes.push_back(this->mNodes[global_node_indices[5]]);
00456                     this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,triangle_nodes));
00457                     triangle_nodes.clear();
00458                     triangle_nodes.push_back(this->mNodes[global_node_indices[4]]);
00459                     triangle_nodes.push_back(this->mNodes[global_node_indices[6]]);
00460                     triangle_nodes.push_back(this->mNodes[global_node_indices[7]]);
00461                     this->mBoundaryElements.push_back(new BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>(belem_index++,triangle_nodes));
00462                 }
00463             }//i
00464         }//j
00465     }//k
00466 
00467     this->RefreshMesh();
00468 }
00469 
00470 
00471 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00472 bool AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::CalculateDesignatedOwnershipOfBoundaryElement( unsigned faceIndex )
00473 {
00474         //This may throw in the distributed parallel case
00475         unsigned tie_break_index = this->GetBoundaryElement(faceIndex)->GetNodeGlobalIndex(0);
00476 
00477         //if it is in my range
00478         if (this->GetDistributedVectorFactory()->IsGlobalIndexLocal(tie_break_index))
00479         {
00480             return true;
00481         }
00482         else
00483         {
00484             return false;
00485         }
00486 }
00487 
00488 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00489 bool AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::CalculateDesignatedOwnershipOfElement( unsigned elementIndex )
00490 {
00491         //This may throw in the distributed parallel case
00492         unsigned tie_break_index = this->GetElement(elementIndex)->GetNodeGlobalIndex(0);
00493 
00494         //if it is in my range
00495         if (this->GetDistributedVectorFactory()->IsGlobalIndexLocal(tie_break_index))
00496         {
00497             return true;
00498         }
00499         else
00500         {
00501             return false;
00502         }
00503 }
00504 
00505 
00507 // Explicit instantiation
00509 
00510 template class AbstractTetrahedralMesh<1,1>;
00511 template class AbstractTetrahedralMesh<1,2>;
00512 template class AbstractTetrahedralMesh<1,3>;
00513 template class AbstractTetrahedralMesh<2,2>;
00514 template class AbstractTetrahedralMesh<2,3>;
00515 template class AbstractTetrahedralMesh<3,3>;

Generated by  doxygen 1.6.2