CylindricalHoneycombVertexMeshGenerator.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 "CylindricalHoneycombVertexMeshGenerator.hpp"
00030 
00031 
00032 CylindricalHoneycombVertexMeshGenerator::CylindricalHoneycombVertexMeshGenerator(unsigned numElementsAcross,
00033                                                            unsigned numElementsUp,
00034                                                            bool isFlatBottom,
00035                                                            double cellRearrangementThreshold,
00036                                                            double t2Threshold)
00037 {
00038     assert(numElementsAcross > 0);
00039     assert(numElementsUp > 0);
00040     assert(cellRearrangementThreshold > 0.0);
00041     assert(t2Threshold > 0.0);
00042 
00043     std::vector<Node<2>*> nodes;
00044     std::vector<VertexElement<2,2>*>  elements;
00045 
00046     unsigned node_index = 0;
00047     unsigned node_indices[6];
00048     unsigned element_index;
00049 
00050     assert(numElementsAcross > 1);
00051     assert(numElementsAcross%2==0); // numElementsAcross must be even for cylindrical meshes
00052 
00053     // Create the nodes
00054     for (unsigned j=0; j<=2*numElementsUp+1; j++)
00055     {
00056         if (isFlatBottom && (j==1))
00057         {
00058             // Flat bottom to cylindrical mesh
00059             for (unsigned i=0; i<=numElementsAcross-1; i++)
00060             {
00061                 Node<2>* p_node = new Node<2>(node_index, true, i, 0.0);
00062                 nodes.push_back(p_node);
00063                 node_index++;
00064             }
00065         }
00066         /*
00067          * On each interior row we have numElementsAcross+1 nodes. On the first second, penultimate,
00068          *  and last rows all nodes are boundary nodes. On other rows no nodes are boundary nodes.
00069          */
00070         else
00071         {
00072             for (unsigned i=0; i<=numElementsAcross-1; i++)
00073             {
00074                 double x_coord = ((j%4 == 0)||(j%4 == 3)) ? i+0.5 : i;
00075                 double y_coord = (1.5*j - 0.5*(j%2))*0.5/sqrt(3);
00076                 bool is_boundary_node = (j==0 || j==1 || j==2*numElementsUp || j==2*numElementsUp+1) ? true : false;
00077 
00078                 Node<2>* p_node = new Node<2>(node_index, is_boundary_node , x_coord, y_coord);
00079                 nodes.push_back(p_node);
00080                 node_index++;
00081             }
00082         }
00083     }
00084 
00085     /*
00086      * Create the elements. The array node_indices contains the
00087      * global node indices from bottom, going anticlockwise.
00088      */
00089     for (unsigned j=0; j<numElementsUp; j++)
00090     {
00091         for (unsigned i=0; i<numElementsAcross; i++)
00092         {
00093             element_index = j*numElementsAcross + i;
00094 
00095             node_indices[0] = 2*j*(numElementsAcross) + i + 1*(j%2==1);
00096             node_indices[1] = node_indices[0] + numElementsAcross + 1*(j%2==0);
00097             node_indices[2] = node_indices[0] + 2*numElementsAcross + 1*(j%2==0);
00098             node_indices[3] = node_indices[0] + 3*numElementsAcross;
00099             node_indices[4] = node_indices[0] + 2*numElementsAcross - 1*(j%2==1);
00100             node_indices[5] = node_indices[0] + numElementsAcross - 1*(j%2==1);
00101 
00102             if (i==numElementsAcross-1) // on far right
00103             {
00104                 node_indices[0] -= numElementsAcross*(j%2==1);
00105                 node_indices[1] -= numElementsAcross;
00106                 node_indices[2] -= numElementsAcross;
00107                 node_indices[3] -= numElementsAcross*(j%2==1);
00108             }
00109 
00110             std::vector<Node<2>*> element_nodes;
00111             for (unsigned k=0; k<6; k++)
00112             {
00113                element_nodes.push_back(nodes[node_indices[k]]);
00114             }
00115             VertexElement<2,2>* p_element = new VertexElement<2,2>(element_index, element_nodes);
00116             elements.push_back(p_element);
00117         }
00118     }
00119 
00120     // If the mesh has an imposed flat bottom delete unnessesary nodes
00121     if (isFlatBottom)
00122     {
00123         for (unsigned i=0; i<numElementsAcross; i++)
00124         {
00125             // Move node 0 to the same position as node 5 then merge the nodes
00126             nodes[i]->SetPoint(nodes[i+numElementsAcross]->GetPoint());
00127 //                SetNode(i, nodes[i+numElementsAcross]->GetPoint());
00128 //                PerformNodeMerge(mNodes[i], mNodes[i+numElementsAcross]);
00129         }
00130     }
00131     mpMesh = new Cylindrical2dVertexMesh(numElementsAcross, nodes, elements, cellRearrangementThreshold, t2Threshold);
00132 }
00133 
00134 
00135 VertexMesh<2,2>* CylindricalHoneycombVertexMeshGenerator::GetMesh()
00136 {
00137     EXCEPTION("A cylindrical mesh was created but a normal mesh is being requested.");
00138     return mpMesh; //Not really
00139 }
00140 
00141 
00142 Cylindrical2dVertexMesh* CylindricalHoneycombVertexMeshGenerator::GetCylindricalMesh()
00143 {
00144     return (Cylindrical2dVertexMesh*) mpMesh;
00145 }

Generated on Mon Nov 1 12:35:16 2010 for Chaste by  doxygen 1.5.5