Chaste  Release::2017.1
CmguiDeformedSolutionsWriter.cpp
1 /*
2 
3 Copyright (c) 2005-2017, University of Oxford.
4 All rights reserved.
5 
6 University of Oxford means the Chancellor, Masters and Scholars of the
7 University of Oxford, having an administrative office at Wellington
8 Square, Oxford OX1 2JD, UK.
9 
10 This file is part of Chaste.
11 
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions are met:
14  * Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16  * Redistributions in binary form must reproduce the above copyright notice,
17  this list of conditions and the following disclaimer in the documentation
18  and/or other materials provided with the distribution.
19  * Neither the name of the University of Oxford nor the names of its
20  contributors may be used to endorse or promote products derived from this
21  software without specific prior written permission.
22 
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 
34 */
35 
36 #include "CmguiDeformedSolutionsWriter.hpp"
37 #include "Exception.hpp"
38 
39 template<unsigned DIM>
41  std::string baseName,
42  AbstractTetrahedralMesh<DIM,DIM>& rQuadraticMesh,
43  CmguiMeshWriteType writeType)
44  : CmguiMeshWriter<DIM, DIM>(outputDirectory, baseName),
45  mpQuadraticMesh(&rQuadraticMesh),
46  mFinalCounter(0)
47 {
48  QuadraticMesh<DIM>* p_quad_mesh = dynamic_cast<QuadraticMesh<DIM>* >(&rQuadraticMesh);
49 
50  if (p_quad_mesh == nullptr)
51  {
52  EXCEPTION("CmguiDeformedSolutionsWriter only supports use of a QuadraticMesh");
53  }
54 
56 
57  if (writeType == WRITE_QUADRATIC_MESH)
58  {
60 
61  switch (DIM)
62  {
63  //WriteCmguiScript Commented as CmguiDeformedSolutionsWriter is meant to correspond to
64  // output of nonlinear elasticity problems - 2d or 3d only, and there is
65  // no explicit instantiation of this class in 1d.
66  //case 1:
67  //{
68  // this->mElementFileHeader = CmguiElementFileHeader1DQuadratic;
69  // this->mCoordinatesFileHeader = CmguiCoordinatesFileHeader1DQuadratic;
70  // this->mAdditionalFieldHeader = CmguiAdditionalFieldHeader1DQuadratic;
71  // this->mNumNodesPerElement = 3;
72  // this->mReordering.resize(this->mNumNodesPerElement);
73  // unsigned reordering[6] = {0,2,1};
74  // for (unsigned i=0; i<3; i++)
75  // {
76  // this->mReordering[i] = reordering[i];
77  // }
78  // break;
79  //};
80 
81  case 2:
82  {
83  this->mElementFileHeader = CmguiElementFileHeader2DQuadratic;
84  this->mCoordinatesFileHeader = CmguiCoordinatesFileHeader2DQuadratic;
85  this->mAdditionalFieldHeader = CmguiAdditionalFieldHeader2DQuadratic;
86  this->mNumNodesPerElement = 6;
87  this->mReordering.resize(this->mNumNodesPerElement);
88 
89  // Go from Chaste(tetgen ordering) (see example comments in
90  // QuadraticBasisFunction::ComputeBasisFunction() to CMGUI ordering
91  // ("psi1 increasing, then psi1 increasing")
92  unsigned reordering[6] = {0,5,1,4,3,2};
93  for (unsigned i=0; i<6; i++)
94  {
95  this->mReordering[i] = reordering[i];
96  }
97  break;
98  }
99  case 3:
100  {
101  this->mElementFileHeader = CmguiElementFileHeader3DQuadratic;
102  this->mCoordinatesFileHeader = CmguiCoordinatesFileHeader3DQuadratic;
103  this->mAdditionalFieldHeader = CmguiAdditionalFieldHeader3DQuadratic;
104  this->mNumNodesPerElement = 10;
105  this->mReordering.resize(this->mNumNodesPerElement);
106 
107  // Go from Chaste(tetgen ordering) (see example comments in
108  // QuadraticBasisFunction::ComputeBasisFunction() to CMGUI ordering
109  // ("psi1 increasing, then psi2 increasing, then psi3 increasing")
110  unsigned reordering[10] = {0,4,1,6,5,2,7,8,9,3};
111  for (unsigned i=0; i<10; i++)
112  {
113  this->mReordering[i] = reordering[i];
114  }
115  break;
116  }
117  default:
118  {
120  }
121  }
122  }
123 }
124 
125 template<unsigned DIM>
127 {
128  std::string saved_base_name = this->mBaseName;
129  if (fileName == "")
130  {
131  this->mBaseName = this->mBaseName + "_0";
132  }
133  else
134  {
135  this->mBaseName = fileName;
136  }
138  this->mBaseName = saved_base_name;
139 }
140 
141 template<unsigned DIM>
142 void CmguiDeformedSolutionsWriter<DIM>::WriteDeformationPositions(std::vector<c_vector<double,DIM> >& rDeformedPositions,
143  unsigned counter)
144 {
145  if (mpQuadraticMesh->GetNumNodes() != rDeformedPositions.size() )
146  {
147  EXCEPTION("The size of rDeformedPositions does not match the number of nodes in the mesh");
148  }
149 
150  mFinalCounter = counter;
151  std::stringstream node_file_name_stringstream;
152  node_file_name_stringstream << this->mBaseName << "_" << counter << ".exnode";
153 
154  out_stream p_node_file = this->mpOutputFileHandler->OpenOutputFile(node_file_name_stringstream.str());
155 
156  this->WriteNodeFileHeader(p_node_file);
157 
158  // Write each node's data
159  for (unsigned index=0; index<this->GetNumNodes(); index++)
160  {
161  *p_node_file << "Node:\t" << index+1 << "\t";
162 
163  for (unsigned i=0; i<DIM; i++)
164  {
165  *p_node_file << rDeformedPositions[index](i) << "\t";
166  }
167  *p_node_file << "\n";
168  }
169  p_node_file->close();
170 }
171 
172 template<unsigned DIM>
173 void CmguiDeformedSolutionsWriter<DIM>::WriteCmguiScript(std::string fieldBaseName, std::string undeformedBaseName)
174 {
175  std::string field_string = "";
176  if (fieldBaseName != "")
177  {
178  field_string = " gfx read node " + fieldBaseName + "_$i time $i\n";
179  }
180 
181  out_stream p_script_file = this->mpOutputFileHandler->OpenOutputFile("LoadSolutions.com");
182  *p_script_file << "#\n# Cmgui script automatically generated by Chaste\n#\n";
183 
184  if (undeformedBaseName != "")
185  {
186  *p_script_file << "gfx read node " << undeformedBaseName << " time -1\n";
187  }
188 
189  *p_script_file << "for ($i=0; $i<=" << mFinalCounter << "; $i++) { \n"
190  << " gfx read node " << this->mBaseName << "_$i time $i\n"
191  << field_string
192  << "}\n";
193 
194  if (undeformedBaseName != "")
195  {
196  for (unsigned region_index=0; region_index<this->mRegionNames.size(); region_index++)
197  {
198  *p_script_file << "gfx read ele " << this->mRegionNames[region_index] << "\n";
199  }
200  }
201  else
202  {
203  *p_script_file << "gfx read ele " << this->mBaseName << "_0\n";
204  }
205  *p_script_file << "gfx define faces egroup "<<this->mBaseName<<"\n";
206  *p_script_file << "gfx modify g_element "<<this->mBaseName<<" lines select_on material default spectrum default selected_material default_selected;\n";
207  *p_script_file << "gfx cr win\n\n";
208  p_script_file->close();
209 }
210 
211 template<unsigned DIM>
212 void CmguiDeformedSolutionsWriter<DIM>::ConvertOutput(std::string inputDirectory,
213  std::string inputFileBaseName,
214  unsigned finalCounter)
215 {
216  // write the mesh to <inputFileBaseName>_0.exnode and <inputFileBaseName>_0.exelem
218 
219  std::vector<c_vector<double,DIM> > deformed_position(mpQuadraticMesh->GetNumNodes(), zero_vector<double>(DIM));
220 
221  for (unsigned i=1; i<=finalCounter; i++) //not i=0
222  {
223  std::stringstream in_file_stream;
224  in_file_stream << inputDirectory << "/" << inputFileBaseName << "_" << i << ".nodes";
225 
226  std::ifstream ifs(in_file_stream.str().c_str());
227  if (!ifs.is_open())
228  {
229  EXCEPTION("Could not open file: " + in_file_stream.str());
230  }
231 
232  // the file into deformed_position
233  double data;
234  for (unsigned index=0; index<mpQuadraticMesh->GetNumNodes(); index++)
235  {
236  for (unsigned j=0; j<DIM; j++)
237  {
238  ifs >> data;
239  if (ifs.fail())
240  {
241  EXCEPTION("Error occurred when reading file " << in_file_stream.str()
242  << ". Expected " << mpQuadraticMesh->GetNumNodes() << " rows and "
243  << DIM << " columns");
244  }
245  deformed_position[index](j) = data;
246  }
247  }
248 
249  ifs.close();
250 
251  // convert
252  WriteDeformationPositions(deformed_position, i);
253  }
254 
256 }
257 
258 
259 template class CmguiDeformedSolutionsWriter<2>;
260 template class CmguiDeformedSolutionsWriter<3>;
void WriteInitialMesh(std::string fileName="")
#define EXCEPTION(message)
Definition: Exception.hpp:143
CmguiDeformedSolutionsWriter(std::string outputDirectory, std::string baseName, AbstractTetrahedralMesh< DIM, DIM > &rQuadraticMesh, CmguiMeshWriteType writeType)
OutputFileHandler * mpOutputFileHandler
virtual unsigned GetNumNodes() const
#define NEVER_REACHED
Definition: Exception.hpp:206
std::vector< std::string > mRegionNames
out_stream OpenOutputFile(const std::string &rFileName, std::ios_base::openmode mode=std::ios::out|std::ios::trunc) const
void WriteDeformationPositions(std::vector< c_vector< double, DIM > > &rDeformedPositions, unsigned counter)
virtual unsigned GetNumVertices() const
AbstractTetrahedralMesh< DIM, DIM > * mpQuadraticMesh
std::vector< unsigned > mReordering
void WriteCmguiScript(std::string fieldBaseName="", std::string undeformedBaseName="")
void ConvertOutput(std::string inputDirectory, std::string inputFileBaseName, unsigned finalCounter)
virtual void WriteFilesUsingMesh(AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > &rMesh, bool keepOriginalElementIndexing=true)
void WriteNodeFileHeader(out_stream &rpNodeFile)