PottsMeshWriter.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 "PottsMeshWriter.hpp"
00030 #include "Version.hpp"
00031 
00035 template<unsigned SPACE_DIM>
00036 struct MeshPottsWriterIterators
00037 {
00039     typename AbstractMesh<SPACE_DIM,SPACE_DIM>::NodeIterator* pNodeIter;
00041     typename PottsMesh<SPACE_DIM>::PottsElementIterator* pElemIter;
00042 };
00043 
00045 // Implementation
00047 
00048 template<unsigned SPACE_DIM>
00049 PottsMeshWriter<SPACE_DIM>::PottsMeshWriter(const std::string& rDirectory,
00050                                                            const std::string& rBaseName,
00051                                                            const bool clearOutputDir)
00052     : AbstractMeshWriter<SPACE_DIM, SPACE_DIM>(rDirectory, rBaseName, clearOutputDir),
00053       mpMesh(NULL),
00054       mpIters(new MeshPottsWriterIterators<SPACE_DIM>),
00055       mpNodeMap(NULL),
00056       mNodeMapCurrentIndex(0)
00057 {
00058     mpIters->pNodeIter = NULL;
00059     mpIters->pElemIter = NULL;
00060 }
00061 
00062 template<unsigned SPACE_DIM>
00063 PottsMeshWriter<SPACE_DIM>::~PottsMeshWriter()
00064 {
00065     if (mpIters->pNodeIter)
00066     {
00067         delete mpIters->pNodeIter;
00068         delete mpIters->pElemIter;
00069     }
00070 
00071     delete mpIters;
00072 
00073     if (mpNodeMap)
00074     {
00075         delete mpNodeMap;
00076     }
00077 }
00078 
00079 template<unsigned SPACE_DIM>
00080 std::vector<double> PottsMeshWriter<SPACE_DIM>::GetNextNode()
00081 {
00082     if (mpMesh)
00083     {
00084         // Sanity check
00085         assert(this->mNumNodes == mpMesh->GetNumNodes());
00086 
00087         std::vector<double> coordinates(SPACE_DIM+1);
00088 
00089         // Get the node coordinates using the node iterator (thus skipping deleted nodes)
00090         for (unsigned j=0; j<SPACE_DIM; j++)
00091         {
00092             coordinates[j] = (*(mpIters->pNodeIter))->GetPoint()[j];
00093         }
00094         coordinates[SPACE_DIM] = (*(mpIters->pNodeIter))->IsBoundaryNode();
00095 
00096         ++(*(mpIters->pNodeIter));
00097 
00098         return coordinates;
00099     }
00100     else
00101     {
00102         return AbstractMeshWriter<SPACE_DIM,SPACE_DIM>::GetNextNode();
00103     }
00104 }
00105 
00106 template<unsigned SPACE_DIM>
00107 ElementData PottsMeshWriter<SPACE_DIM>::GetNextElement()
00108 {
00109     if (mpMesh)
00110     {
00111         assert(this->mNumElements == mpMesh->GetNumElements());
00112 
00113         ElementData elem_data;
00114         elem_data.NodeIndices.resize((*(mpIters->pElemIter))->GetNumNodes());
00115         for (unsigned j=0; j<elem_data.NodeIndices.size(); j++)
00116         {
00117             unsigned old_index = (*(mpIters->pElemIter))->GetNodeGlobalIndex(j);
00118             elem_data.NodeIndices[j] = mpMesh->IsMeshChanging() ? mpNodeMap->GetNewIndex(old_index) : old_index;
00119         }
00120 
00121         // Set attribute
00122         elem_data.AttributeValue = (*(mpIters->pElemIter))->GetRegion();
00123         ++(*(mpIters->pElemIter));
00124 
00125         return elem_data;
00126     }
00127     else
00128     {
00129         return AbstractMeshWriter<SPACE_DIM, SPACE_DIM>::GetNextElement();
00130     }
00131 }
00132 
00134 template<unsigned SPACE_DIM>
00135 void PottsMeshWriter<SPACE_DIM>::WriteFilesUsingMesh(PottsMesh<SPACE_DIM>& rMesh)
00136 {
00137     this->mpMeshReader = NULL;
00138     mpMesh = &rMesh;
00139 
00140     this->mNumNodes = mpMesh->GetNumNodes();
00141     this->mNumElements = mpMesh->GetNumElements();
00142 
00143     typedef typename AbstractMesh<SPACE_DIM,SPACE_DIM>::NodeIterator NodeIterType;
00144     mpIters->pNodeIter = new NodeIterType(mpMesh->GetNodeIteratorBegin());
00145 
00146     typedef typename PottsMesh<SPACE_DIM>::PottsElementIterator ElemIterType;
00147     mpIters->pElemIter = new ElemIterType(mpMesh->GetElementIteratorBegin());
00148 
00149     // Set up node map if we might have deleted nodes
00150     mNodeMapCurrentIndex = 0;
00151     if (mpMesh->IsMeshChanging())
00152     {
00153         mpNodeMap = new NodeMap(mpMesh->GetNumAllNodes());
00154         for (NodeIterType it = mpMesh->GetNodeIteratorBegin(); it != mpMesh->GetNodeIteratorEnd(); ++it)
00155         {
00156             mpNodeMap->SetNewIndex(it->GetIndex(), mNodeMapCurrentIndex++);
00157         }
00158     }
00159     WriteFiles();
00160 }
00161 
00162 template<unsigned SPACE_DIM>
00163 void PottsMeshWriter<SPACE_DIM>::WriteFiles()
00164 {
00165     std::string comment = "# " + ChasteBuildInfo::GetProvenanceString();
00166 
00167     // Write node file
00168     std::string node_file_name = this->mBaseName + ".node";
00169     out_stream p_node_file = this->mpOutputFileHandler->OpenOutputFile(node_file_name);
00170 
00171     // Write the node header
00172     unsigned num_attr = 0;
00173     unsigned max_bdy_marker = 1; // as we include boundary node information in the node file
00174     unsigned num_nodes = this->GetNumNodes();
00175 
00176     *p_node_file << num_nodes << "\t";
00177     *p_node_file << SPACE_DIM << "\t";
00178     *p_node_file << num_attr << "\t";
00179     *p_node_file << max_bdy_marker << "\n";
00180     *p_node_file << std::setprecision(6);
00181 
00182     // Write each node's data
00183     for (unsigned item_num=0; item_num<num_nodes; item_num++)
00184     {
00185         std::vector<double> current_item = this->GetNextNode();
00186         *p_node_file << item_num;
00187         for (unsigned i=0; i<SPACE_DIM+1; i++)
00188         {
00189             *p_node_file << "\t" << current_item[i];
00190         }
00191         *p_node_file << "\n";
00192     }
00193     *p_node_file << comment << "\n";
00194     p_node_file->close();
00195 
00196     // Write element file
00197     std::string element_file_name = this->mBaseName + ".cell";
00198     out_stream p_element_file = this->mpOutputFileHandler->OpenOutputFile(element_file_name);
00199 
00200     // Write the element header
00201     unsigned num_elements = this->GetNumElements();
00202 
00203     unsigned first_elem_attribute_value = (*(mpIters->pElemIter))->GetRegion();
00204     if (first_elem_attribute_value != 0)
00205     {
00206         num_attr = 1;
00207     }
00208 
00209     *p_element_file << num_elements << "\t";
00210     *p_element_file << num_attr << "\n";
00211 
00212     // Write each element's data
00213     for (unsigned item_num=0; item_num<num_elements; item_num++)
00214     {
00215         // Get data for this element
00216         ElementData elem_data = this->GetNextElement();
00217 
00218         // Get the node indices owned by this element
00219         std::vector<unsigned> node_indices = elem_data.NodeIndices;
00220 
00221         // Write this element's index and the number of nodes owned by it to file
00222         *p_element_file << item_num <<  "\t" << node_indices.size();
00223 
00224         // Write the node indices owned by this element to file
00225         for (unsigned i=0; i<node_indices.size(); i++)
00226         {
00227             *p_element_file << "\t" << node_indices[i];
00228         }
00229 
00230         // Write the element attribute if necessary
00231         if (elem_data.AttributeValue != 0)
00232         {
00233             *p_element_file << "\t" << elem_data.AttributeValue;
00234         }
00235 
00236         // New line
00237         *p_element_file << "\n";
00238     }
00239 
00240     *p_element_file << comment << "\n";
00241     p_element_file->close();
00242 }
00243 
00245 // Explicit instantiation
00247 
00248 template class PottsMeshWriter<1>;
00249 template class PottsMeshWriter<2>;
00250 template class PottsMeshWriter<3>;
Generated on Thu Dec 22 13:00:04 2011 for Chaste by  doxygen 1.6.3