Chaste  Release::3.4
CmguiDeformedSolutionsWriter.cpp
1 /*
2 
3 Copyright (c) 2005-2016, 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 
49  QuadraticMesh<DIM>* p_quad_mesh = dynamic_cast<QuadraticMesh<DIM>* >(&rQuadraticMesh);
50 
51  if(p_quad_mesh == NULL)
52  {
53  EXCEPTION("CmguiDeformedSolutionsWriter only supports use of a QuadraticMesh");
54  }
55 
57 
58  if (writeType==WRITE_QUADRATIC_MESH)
59  {
61 
62  switch (DIM)
63  {
64  //WriteCmguiScript Commented as CmguiDeformedSolutionsWriter is meant to correspond to
65  // output of nonlinear elasticity problems - 2d or 3d only, and there is
66  // no explicit instantiation of this class in 1d.
67  //case 1:
68  //{
69  // this->mElementFileHeader = CmguiElementFileHeader1DQuadratic;
70  // this->mCoordinatesFileHeader = CmguiCoordinatesFileHeader1DQuadratic;
71  // this->mAdditionalFieldHeader = CmguiAdditionalFieldHeader1DQuadratic;
72  // this->mNumNodesPerElement = 3;
73  // this->mReordering.resize(this->mNumNodesPerElement);
74  // unsigned reordering[6] = {0,2,1};
75  // for (unsigned i=0; i<3; i++)
76  // {
77  // this->mReordering[i] = reordering[i];
78  // }
79  // break;
80  //};
81 
82  case 2:
83  {
84  this->mElementFileHeader = CmguiElementFileHeader2DQuadratic;
85  this->mCoordinatesFileHeader = CmguiCoordinatesFileHeader2DQuadratic;
86  this->mAdditionalFieldHeader = CmguiAdditionalFieldHeader2DQuadratic;
87  this->mNumNodesPerElement = 6;
88  this->mReordering.resize(this->mNumNodesPerElement);
89 
90  // Go from Chaste(tetgen ordering) (see example comments in
91  // QuadraticBasisFunction::ComputeBasisFunction() to CMGUI ordering
92  // ("psi1 increasing, then psi1 increasing")
93  unsigned reordering[6] = {0,5,1,4,3,2};
94  for (unsigned i=0; i<6; i++)
95  {
96  this->mReordering[i] = reordering[i];
97  }
98  break;
99  }
100  case 3:
101  {
102  this->mElementFileHeader = CmguiElementFileHeader3DQuadratic;
103  this->mCoordinatesFileHeader = CmguiCoordinatesFileHeader3DQuadratic;
104  this->mAdditionalFieldHeader = CmguiAdditionalFieldHeader3DQuadratic;
105  this->mNumNodesPerElement = 10;
106  this->mReordering.resize(this->mNumNodesPerElement);
107 
108  // Go from Chaste(tetgen ordering) (see example comments in
109  // QuadraticBasisFunction::ComputeBasisFunction() to CMGUI ordering
110  // ("psi1 increasing, then psi2 increasing, then psi3 increasing")
111  unsigned reordering[10] = {0,4,1,6,5,2,7,8,9,3};
112  for (unsigned i=0; i<10; i++)
113  {
114  this->mReordering[i] = reordering[i];
115  }
116  break;
117  }
118  default:
119  {
121  }
122  }
123  }
124 }
125 
126 template<unsigned DIM>
128 {
129  std::string saved_base_name = this->mBaseName;
130  if(fileName == "")
131  {
132  this->mBaseName = this->mBaseName + "_0";
133  }
134  else
135  {
136  this->mBaseName = fileName;
137  }
138  this->WriteFilesUsingMesh(*mpQuadraticMesh);
139  this->mBaseName = saved_base_name;
140 }
141 
142 template<unsigned DIM>
143 void CmguiDeformedSolutionsWriter<DIM>::WriteDeformationPositions(std::vector<c_vector<double,DIM> >& rDeformedPositions,
144  unsigned counter)
145 {
146  if (mpQuadraticMesh->GetNumNodes() != rDeformedPositions.size() )
147  {
148  EXCEPTION("The size of rDeformedPositions does not match the number of nodes in the mesh");
149  }
150 
151  mFinalCounter = counter;
152  std::stringstream node_file_name_stringstream;
153  node_file_name_stringstream << this->mBaseName << "_" << counter << ".exnode";
154 
155  out_stream p_node_file = this->mpOutputFileHandler->OpenOutputFile(node_file_name_stringstream.str());
156 
157  this->WriteNodeFileHeader(p_node_file);
158 
159  // Write each node's data
160  for (unsigned index=0; index<this->GetNumNodes(); index++)
161  {
162  *p_node_file << "Node:\t" << index+1 << "\t";
163 
164  for (unsigned i=0; i<DIM; i++)
165  {
166  *p_node_file << rDeformedPositions[index](i) << "\t";
167  }
168  *p_node_file << "\n";
169  }
170  p_node_file->close();
171 }
172 
173 template<unsigned DIM>
174 void CmguiDeformedSolutionsWriter<DIM>::WriteCmguiScript(std::string fieldBaseName, std::string undeformedBaseName)
175 {
176  std::string field_string = "";
177  if (fieldBaseName != "")
178  {
179  field_string = " gfx read node " + fieldBaseName + "_$i time $i\n";
180  }
181 
182  out_stream p_script_file = this->mpOutputFileHandler->OpenOutputFile("LoadSolutions.com");
183  *p_script_file << "#\n# Cmgui script automatically generated by Chaste\n#\n";
184 
185  if(undeformedBaseName != "")
186  {
187  *p_script_file << "gfx read node " << undeformedBaseName << " time -1\n";
188  }
189 
190  *p_script_file << "for ($i=0; $i<=" << mFinalCounter << "; $i++) { \n"
191  << " gfx read node " << this->mBaseName << "_$i time $i\n"
192  << field_string
193  << "}\n";
194 
195  if(undeformedBaseName != "")
196  {
197  for (unsigned region_index=0; region_index<this->mRegionNames.size(); region_index++)
198  {
199  *p_script_file << "gfx read ele " << this->mRegionNames[region_index] << "\n";
200  }
201  }
202  else
203  {
204  *p_script_file << "gfx read ele " << this->mBaseName << "_0\n";
205  }
206  *p_script_file << "gfx define faces egroup "<<this->mBaseName<<"\n";
207  *p_script_file << "gfx modify g_element "<<this->mBaseName<<" lines select_on material default spectrum default selected_material default_selected;\n";
208  *p_script_file << "gfx cr win\n\n";
209  p_script_file->close();
210 }
211 
212 template<unsigned DIM>
213 void CmguiDeformedSolutionsWriter<DIM>::ConvertOutput(std::string inputDirectory,
214  std::string inputFileBaseName,
215  unsigned finalCounter)
216 {
217  // write the mesh to <inputFileBaseName>_0.exnode and <inputFileBaseName>_0.exelem
218  WriteInitialMesh();
219 
220  std::vector<c_vector<double,DIM> > deformed_position(mpQuadraticMesh->GetNumNodes(), zero_vector<double>(DIM));
221 
222  for (unsigned i=1; i<=finalCounter; i++) //not i=0
223  {
224  std::stringstream in_file_stream;
225  in_file_stream << inputDirectory << "/" << inputFileBaseName << "_" << i << ".nodes";
226 
227  std::ifstream ifs(in_file_stream.str().c_str());
228  if (!ifs.is_open())
229  {
230  EXCEPTION("Could not open file: " + in_file_stream.str());
231  }
232 
233  // the file into deformed_position
234  double data;
235  for (unsigned index=0; index<mpQuadraticMesh->GetNumNodes(); index++)
236  {
237  for (unsigned j=0; j<DIM; j++)
238  {
239  ifs >> data;
240  if (ifs.fail())
241  {
242  EXCEPTION("Error occurred when reading file " << in_file_stream.str()
243  << ". Expected " << mpQuadraticMesh->GetNumNodes() << " rows and "
244  << DIM << " columns");
245  }
246  deformed_position[index](j) = data;
247  }
248  }
249 
250  ifs.close();
251 
252  // convert
253  WriteDeformationPositions(deformed_position, i);
254  }
255 
256  WriteCmguiScript();
257 }
258 
259 
260 template class CmguiDeformedSolutionsWriter<2>;
261 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)
virtual unsigned GetNumNodes() const
#define NEVER_REACHED
Definition: Exception.hpp:206
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)