Line data Source code
1 : /*
2 : * Copyright (c) 2017: G-CSC, Goethe University Frankfurt
3 : * Author: Sebastian Reiter
4 : *
5 : * This file is part of UG4.
6 : *
7 : * UG4 is free software: you can redistribute it and/or modify it under the
8 : * terms of the GNU Lesser General Public License version 3 (as published by the
9 : * Free Software Foundation) with the following additional attribution
10 : * requirements (according to LGPL/GPL v3 §7):
11 : *
12 : * (1) The following notice must be displayed in the Appropriate Legal Notices
13 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 : *
15 : * (2) The following notice must be displayed at a prominent place in the
16 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 : *
18 : * (3) The following bibliography is recommended for citation and must be
19 : * preserved in all covered files:
20 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 : * parallel geometric multigrid solver on hierarchically distributed grids.
22 : * Computing and visualization in science 16, 4 (2013), 151-164"
23 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 : * flexible software system for simulating pde based models on high performance
25 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 : *
27 : * This program is distributed in the hope that it will be useful,
28 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 : * GNU Lesser General Public License for more details.
31 : */
32 :
33 : #include "file_io_2df.h"
34 : #include <fstream>
35 : #include <vector>
36 : #include "../lg_base.h"
37 : #include "common/util/string_util.h"
38 :
39 : using namespace std;
40 :
41 : namespace ug {
42 :
43 0 : static inline std::string NextValid2DFLine(ifstream& in)
44 : {
45 : string line;
46 0 : while(!in.eof()){
47 0 : getline(in, line);
48 0 : size_t pos = line.find('#');
49 0 : if(pos != string::npos)
50 0 : line.erase(pos);
51 :
52 0 : line = TrimString(line);
53 0 : if(!line.empty()){
54 0 : return line;
55 : }
56 : }
57 : return string();
58 : }
59 :
60 0 : bool LoadGridFrom2DF(Grid& grid, const char* filename, ISubsetHandler* psh, AVector3& aPos)
61 : {
62 0 : ifstream file(filename);
63 :
64 0 : if(!file)
65 : return false;
66 :
67 : int numVrts, numTris;
68 : {
69 0 : stringstream in (NextValid2DFLine(file));
70 0 : in >> numVrts;
71 0 : in >> numTris;
72 0 : }
73 :
74 :
75 : // create points
76 : // store pointers to the vertices on the fly in a vector.
77 : vector<Vertex*> vVrts;
78 0 : vVrts.resize(numVrts);
79 :
80 : vector<Face*> vTris;
81 0 : vTris.reserve(numTris);
82 :
83 0 : for(int i = 0; i < numVrts; ++i)
84 0 : vVrts[i] = *grid.create<RegularVertex>();
85 :
86 0 : if(!grid.has_vertex_attachment(aPos))
87 0 : grid.attach_to_vertices(aPos);
88 : Grid::VertexAttachmentAccessor<APosition> aaPos(grid, aPos);
89 :
90 :
91 : // read the points
92 : {
93 0 : for(size_t i = 0; i < vVrts.size(); ++i)
94 : {
95 0 : stringstream in (NextValid2DFLine(file));
96 0 : Vertex* vrt = vVrts[i];
97 : double x, y;
98 : in >> x;
99 : in >> y;
100 0 : if(!in.fail())
101 0 : aaPos[vrt] = vector3(x, y, 0);
102 0 : }
103 : }
104 :
105 : // read the triangles
106 : {
107 0 : for(int i = 0; i < numTris; ++i)
108 : {
109 0 : stringstream in (NextValid2DFLine(file));
110 : int i1, i2, i3;
111 0 : in >> i1;
112 0 : in >> i2;
113 0 : in >> i3;
114 0 : if(!in.fail()){
115 0 : Face* t = *grid.create<Triangle>(TriangleDescriptor(vVrts[i1], vVrts[i2], vVrts[i3]));
116 0 : vTris.push_back(t);
117 : }
118 0 : }
119 : }
120 :
121 0 : if(psh){
122 0 : for(size_t i = 0; i < vVrts.size(); ++i)
123 : {
124 0 : stringstream in (NextValid2DFLine(file));
125 : int mark;
126 0 : in >> mark;
127 0 : if(!in.fail())
128 0 : psh->assign_subset(vVrts[i], mark);
129 : else
130 0 : psh->assign_subset(vVrts[i], 0);
131 0 : }
132 :
133 0 : for(size_t i = 0; i < vTris.size(); ++i)
134 : {
135 0 : stringstream in (NextValid2DFLine(file));
136 : int mark;
137 0 : in >> mark;
138 0 : if(!in.fail())
139 0 : psh->assign_subset(vTris[i], mark);
140 : else
141 0 : psh->assign_subset(vTris[i], 0);
142 0 : }
143 : }
144 :
145 0 : file.close();
146 : return true;
147 0 : }
148 :
149 :
150 0 : bool SaveGridTo2DF(Grid& grid, const char* filename, ISubsetHandler* psh, AVector3& aPos)
151 : {
152 0 : if(!grid.has_vertex_attachment(aPos))
153 : return false;
154 :
155 0 : ofstream out(filename);
156 :
157 0 : if(!out)
158 : return false;
159 :
160 : // write the header
161 : out << grid.num_vertices() << " " << grid.num<Triangle>() << endl;
162 :
163 : // write the vertices
164 : // store in each vertex at which position it has been written to the file.
165 : AInt aInt;
166 : grid.attach_to_vertices(aInt);
167 : Grid::VertexAttachmentAccessor<AVector3> aaPos(grid, aPos);
168 : Grid::VertexAttachmentAccessor<AInt> aaInt(grid, aInt);
169 :
170 : {
171 0 : out << "\n# vertices\n";
172 : int counter = 0;
173 :
174 0 : for(VertexIterator iter = grid.vertices_begin(); iter != grid.vertices_end(); iter++)
175 : {
176 0 : out << aaPos[*iter].x() << " "
177 0 : << aaPos[*iter].y() << endl;
178 :
179 0 : aaInt[*iter] = counter++;
180 : }
181 : }
182 :
183 : // write the faces.
184 : {
185 0 : out << "\n# triangles\n";
186 0 : for(TriangleIterator iter = grid.begin<Triangle>(); iter != grid.end<Triangle>(); ++iter)
187 : {
188 : Triangle* t = *iter;
189 0 : out << aaInt[t->vertex(0)] << " "
190 0 : << aaInt[t->vertex(1)] << " "
191 0 : << aaInt[t->vertex(2)] << endl;
192 : }
193 : }
194 :
195 0 : if(psh){
196 : // write vertex subset indices
197 0 : out << "\n# vertex marks\n";
198 0 : for(VertexIterator iter = grid.vertices_begin(); iter != grid.vertices_end(); iter++)
199 : {
200 0 : out << psh->get_subset_index(*iter) << endl;
201 : }
202 :
203 : // write triangle subset indices
204 0 : out << "\n# triangle marks\n";
205 0 : for(TriangleIterator iter = grid.begin<Triangle>(); iter != grid.end<Triangle>(); ++iter)
206 : {
207 0 : out << psh->get_subset_index(*iter) << endl;
208 : }
209 : }
210 :
211 : grid.detach_from_vertices(aInt);
212 : return true;
213 0 : }
214 :
215 : }// end of namespace
|