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