Line data Source code
1 : /*
2 : * Copyright (c) 2010-2015: 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 <fstream>
34 : #include "lib_grid/lg_base.h"
35 : #include "lib_grid/algorithms/attachment_util.h"
36 : #include "file_io_ncdf.h"
37 :
38 : using namespace std;
39 :
40 : namespace ug
41 : {
42 :
43 0 : bool SaveGridToNCDF(Grid& grid, const char* filename,
44 : ISubsetHandler* pSH,
45 : APosition aPos)
46 : {
47 : // open the file to which we'll write
48 0 : ofstream out(filename);
49 0 : if(!out)
50 : return false;
51 :
52 : // access subset-handler
53 0 : if(!pSH){
54 : UG_LOG("ERROR: SubsetHandler required for NCDF (Exodus) export.\n");
55 : return false;
56 : }
57 :
58 : ISubsetHandler& sh = *pSH;
59 :
60 : // access the position attachment
61 0 : if(!grid.has_vertex_attachment(aPos))
62 : return false;
63 :
64 0 : if(grid.num_volumes() != grid.num<Tetrahedron>()){
65 : UG_LOG("Saving grid to EXODUS-format.\n"
66 : << " WARNING: only Tetrahedrons exported in the moment.\n");
67 : }
68 :
69 : Grid::VertexAttachmentAccessor<APosition> aaPos(grid, aPos);
70 :
71 : // assign vertex indices
72 : AInt aInt;
73 : grid.attach_to_vertices(aInt);
74 : Grid::VertexAttachmentAccessor<AInt> aaInt(grid, aInt);
75 : AssignIndices(grid.vertices_begin(), grid.vertices_end(), aaInt, 1);
76 :
77 : // write exodus header
78 : int var4 = 4;
79 : out << "netcdf object {" << endl;
80 : out << "dimensions:" << endl;
81 : out << "\tlen_string = 33 ;" << endl;
82 : out << "\tlen_line = 81 ;" << endl;
83 0 : out << "\tfour = " << var4 << " ;" << endl;
84 : out << "\ttime_step = UNLIMITED ;" << endl;
85 : out << "\tnum_dim = 3 ;" << endl;
86 : out << "\tnum_nodes = " << grid.num_vertices() << " ;" << endl;
87 : out << "\tnum_elem = " << grid.num<Tetrahedron>() << " ;" << endl;
88 0 : out << "\tnum_el_blk = " << sh.num_subsets() << " ;" << endl;
89 :
90 0 : for(int i = 0; i < sh.num_subsets(); ++i){
91 0 : GridObjectCollection goc = sh.get_grid_objects_in_subset(i);
92 0 : out << "\tnum_el_in_blk" << i+1 << " = " << goc.num<Tetrahedron>() << " ;" << endl;
93 0 : out << "\tnum_nod_per_el" << i+1 << " = 4 ;" << endl;
94 : }
95 :
96 : out << "\tnum_qa_rec = 1 ;" << endl;
97 :
98 : // write variables
99 : out << endl;
100 : out << "variables:" << endl;
101 : out << "\tdouble time_whole(time_step) ;" << endl;
102 : out << "\tint eb_status(num_el_blk) ;" << endl;
103 : out << "\tint eb_prop1(num_el_blk) ;" << endl;
104 : out << "\t\teb_prop1:name = \"ID\" ;" << endl;
105 :
106 0 : for(int i = 0; i < sh.num_subsets(); ++i){
107 : out << "\tint connect" << i+1
108 0 : << "(num_el_in_blk" << i+1
109 0 : << ", num_nod_per_el" << i+1 << ") ;" << endl;
110 0 : out << "\t\tconnect" << i+1 << ":elem_type = \"TETRA4\" ;" << endl;
111 : }
112 :
113 : out << "\tdouble coord(num_dim, num_nodes) ;" << endl;
114 : out << "\tchar qa_records(num_qa_rec, four, len_string) ;" << endl;
115 : out << "\tchar coor_names(num_dim, len_string) ;" << endl;
116 : out << "\tint elem_map(num_elem) ;" << endl;
117 : out << "\tint elem_num_map(num_elem) ;" << endl;
118 : out << "\tint node_num_map(num_nodes) ;" << endl;
119 :
120 : out << "// global attributes:" << endl;
121 : out << "\t:api_version = 4.01f ;" << endl;
122 : out << "\t:version = 3.01f ;" << endl;
123 : out << "\t:floating_point_word_size = " << sizeof(number) << " ;" << endl;
124 : out << "\t:file_size = 0 ;" << endl;
125 : out << "\t:title = \"Exported from lib_grid.\" ;" << endl;
126 :
127 : // write data
128 : out << endl;
129 : out << "data:" << endl;
130 :
131 0 : out << "eb_status = ";
132 0 : for(int i = 0; i < sh.num_subsets(); ++i){
133 0 : out << "1";
134 0 : if(i + 1 < sh.num_subsets())
135 0 : out << ", ";
136 : }
137 : out << " ;" << endl << endl;
138 :
139 0 : out << "eb_prop1 = ";
140 0 : for(int i = 0; i < sh.num_subsets(); ++i){
141 0 : out << i+1;
142 0 : if(i + 1 < sh.num_subsets())
143 0 : out << ", ";
144 : }
145 : out << " ;" << endl << endl;
146 :
147 : // write elements
148 0 : for(int i = 0; i < sh.num_subsets(); ++i){
149 : // get the goc for this subset
150 0 : GridObjectCollection goc = sh.get_grid_objects_in_subset(i);
151 :
152 0 : out << "connect" << i+1 << " =" << endl;
153 0 : for(size_t lvl = 0; lvl < goc.num_levels(); ++lvl){
154 : for(TetrahedronIterator iter = goc.begin<Tetrahedron>(lvl);
155 0 : iter != goc.end<Tetrahedron>(lvl); ++iter)
156 : {
157 : // last comma in each row
158 0 : if(iter != goc.begin<Tetrahedron>(lvl))
159 : out << "," << endl;
160 :
161 : Tetrahedron* tet = *iter;
162 0 : out << " ";
163 0 : out << aaInt[tet->vertex(0)] << ", ";
164 0 : out << aaInt[tet->vertex(1)] << ", ";
165 0 : out << aaInt[tet->vertex(2)] << ", ";
166 0 : out << aaInt[tet->vertex(3)];
167 : }
168 : }
169 : out << " ;" << endl << endl;
170 : }
171 :
172 : // write coords
173 : // x
174 0 : out << "coord =" << endl << " ";
175 : size_t endlCounter = 1;
176 : for(VertexIterator iter = grid.vertices_begin();
177 0 : iter != grid.vertices_end(); ++iter, ++endlCounter)
178 : {
179 0 : if(endlCounter > 5){
180 : endlCounter = 1;
181 0 : out << endl << " ";
182 : }
183 :
184 0 : out << " " << aaPos[*iter].x() << ",";
185 : }
186 :
187 : // y
188 : for(VertexIterator iter = grid.vertices_begin();
189 0 : iter != grid.vertices_end(); ++iter, ++endlCounter)
190 : {
191 0 : if(endlCounter > 5){
192 : endlCounter = 1;
193 0 : out << endl << " ";
194 : }
195 0 : out << " " << aaPos[*iter].y() << ",";
196 : }
197 :
198 : // z
199 : for(VertexIterator iter = grid.vertices_begin();
200 0 : iter != grid.vertices_end(); ++iter, ++endlCounter)
201 : {
202 0 : if(iter != grid.vertices_begin()){
203 0 : out << ",";
204 0 : if(endlCounter > 5){
205 : endlCounter = 1;
206 0 : out << endl << " ";
207 : }
208 : }
209 :
210 0 : out << " " << aaPos[*iter].z();
211 : }
212 : out << " ;" << endl << endl;
213 :
214 : // write qa_records
215 : out << "qa_records =" << endl;
216 : out << " \"lib_grid\"," << endl;
217 : out << " \"...\"," << endl;
218 : out << " \"...\"," << endl;
219 : out << " \"...\" ;" << endl;
220 :
221 : // write coor_names
222 : out << endl;
223 : out << "coor_names =" << endl;
224 : out << " \"x\"," << endl;
225 : out << " \"y\"," << endl;
226 : out << " \"z\" ;" << endl;
227 :
228 : // write elem_map
229 : out << endl;
230 0 : out << "elem_map = ";
231 : endlCounter = 1;
232 0 : for(size_t i = 0; i < grid.num<Tetrahedron>(); ++i, ++endlCounter)
233 : {
234 0 : out << i+1;
235 0 : if(i+1 < grid.num<Tetrahedron>()){
236 0 : out << ", ";
237 :
238 0 : if(endlCounter > 4){
239 : endlCounter = 0;
240 0 : out << endl << " ";
241 : }
242 : }
243 : }
244 : out << " ;" << endl;
245 :
246 : // write elem_num_map
247 : out << endl;
248 0 : out << "elem_num_map = ";
249 : endlCounter = 1;
250 0 : for(size_t i = 0; i < grid.num<Tetrahedron>(); ++i, ++endlCounter)
251 : {
252 0 : out << i+1;
253 0 : if(i+1 < grid.num<Tetrahedron>()){
254 0 : out << ", ";
255 :
256 0 : if(endlCounter > 4){
257 : endlCounter = 0;
258 0 : out << endl << " ";
259 : }
260 : }
261 : }
262 : out << " ;" << endl;
263 :
264 : // write node_num_map
265 : out << endl;
266 0 : out << "node_num_map = ";
267 : endlCounter = 1;
268 0 : for(size_t i = 0; i < grid.num<Vertex>(); ++i, ++endlCounter)
269 : {
270 0 : out << i+1;
271 0 : if(i+1 < grid.num<Vertex>()){
272 0 : out << ", ";
273 :
274 0 : if(endlCounter > 4){
275 : endlCounter = 0;
276 0 : out << endl << " ";
277 : }
278 : }
279 : }
280 : out << " ;" << endl;
281 :
282 : // close object
283 : out << "}" << endl;
284 : // remove vertex indices
285 : grid.detach_from_vertices(aInt);
286 :
287 : // done
288 : return true;
289 0 : }
290 :
291 : }// end of namespace
|