Chaste Commit::1fd4e48e3990e67db148bc1bc4cf6991a0049d0c
CmguiDeformedSolutionsWriter.cpp
1/*
2
3Copyright (c) 2005-2024, University of Oxford.
4All rights reserved.
5
6University of Oxford means the Chancellor, Masters and Scholars of the
7University of Oxford, having an administrative office at Wellington
8Square, Oxford OX1 2JD, UK.
9
10This file is part of Chaste.
11
12Redistribution and use in source and binary forms, with or without
13modification, 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
23THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32OF 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
39template<unsigned DIM>
41 std::string baseName,
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
125template<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 }
137 this->WriteFilesUsingMesh(*mpQuadraticMesh);
138 this->mBaseName = saved_base_name;
139}
140
141template<unsigned DIM>
142void 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
172template<unsigned DIM>
173void 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
211template<unsigned DIM>
213 std::string inputFileBaseName,
214 unsigned finalCounter)
215{
216 // write the mesh to <inputFileBaseName>_0.exnode and <inputFileBaseName>_0.exelem
217 WriteInitialMesh();
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
255 WriteCmguiScript();
256}
257
258
#define EXCEPTION(message)
#define NEVER_REACHED
virtual unsigned GetNumNodes() const
virtual unsigned GetNumVertices() const
AbstractTetrahedralMesh< DIM, DIM > * mpQuadraticMesh
void WriteCmguiScript(std::string fieldBaseName="", std::string undeformedBaseName="")
void ConvertOutput(std::string inputDirectory, std::string inputFileBaseName, unsigned finalCounter)
void WriteDeformationPositions(std::vector< c_vector< double, DIM > > &rDeformedPositions, unsigned counter)
void WriteInitialMesh(std::string fileName="")
CmguiDeformedSolutionsWriter(std::string outputDirectory, std::string baseName, AbstractTetrahedralMesh< DIM, DIM > &rQuadraticMesh, CmguiMeshWriteType writeType)
std::vector< unsigned > mReordering