~njansson/dolfin/hpc

« back to all changes in this revision

Viewing changes to src/kernel/io/OpenDXFile.cpp

  • Committer: Johannes Ring
  • Date: 2008-03-05 22:43:06 UTC
  • Revision ID: johannr@simula.no-20080305224306-2npsdyhfdpl2esji
The BIG commit!

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright (C) 2003-2008 Johan Hoffman and Anders Logg.
2
 
// Licensed under the GNU LGPL Version 2.1.
3
 
//
4
 
// Modified by Minh Do-Quang 2006
5
 
//
6
 
// First added:  2003-07-15
7
 
// Last changed: 2008-02-11
8
 
 
9
 
#include <stdio.h>
10
 
#include <dolfin/log.h>
11
 
#include <dolfin/parameters.h>
12
 
#include <dolfin/Cell.h>
13
 
#include <dolfin/Function.h>
14
 
#include <dolfin/Mesh.h>
15
 
#include <dolfin/Vertex.h>
16
 
#include <dolfin/OpenDXFile.h>
17
 
 
18
 
using namespace dolfin;
19
 
 
20
 
//-�---------------------------------------------------------------------------
21
 
OpenDXFile::OpenDXFile(const std::string filename) : 
22
 
  GenericFile(filename),
23
 
  save_each_mesh(dolfin_get("save each mesh")),
24
 
  event_saving_mesh("Saving mesh to OpenDX file."),
25
 
  event_saving_function("Saving function to OpenDX file.")
26
 
{
27
 
  type = "OpenDX";
28
 
  series_pos = 0;
29
 
}
30
 
//-�---------------------------------------------------------------------------
31
 
OpenDXFile::~OpenDXFile()
32
 
{
33
 
  // Do nothing
34
 
}
35
 
//-�---------------------------------------------------------------------------
36
 
void OpenDXFile::operator<<(Mesh& mesh)
37
 
{
38
 
  event_saving_mesh();
39
 
  
40
 
  // Open file
41
 
  FILE* fp = fopen(filename.c_str(), "r+");
42
 
  fseek(fp, 0L, SEEK_END);
43
 
  
44
 
  // Write header first time
45
 
  if ( ftell(fp) == 0 )
46
 
    writeHeader(fp);
47
 
 
48
 
  // Write mesh
49
 
  writeMesh(fp, mesh);
50
 
 
51
 
  // Write mesh data
52
 
  writeMeshData(fp, mesh);
53
 
  
54
 
  // Close file
55
 
  fclose(fp);
56
 
}
57
 
//-�---------------------------------------------------------------------------
58
 
void OpenDXFile::operator<<(Function& u)
59
 
{
60
 
  error("Function output in OpenDX format not implemented for new Function.");
61
 
 
62
 
/*
63
 
  event_saving_function();
64
 
 
65
 
  // Open file
66
 
  FILE* fp = fopen(filename.c_str(), "r+");
67
 
  fseek(fp, 0L, SEEK_END);
68
 
 
69
 
  // Remove previous time series 
70
 
  if ( frames.size() > 0 )
71
 
    removeSeries(fp);
72
 
 
73
 
  // Write header first time
74
 
  if ( ftell(fp) == 0 )
75
 
    writeHeader(fp);
76
 
 
77
 
  // Write mesh
78
 
  if ( frames.size() == 0 || save_each_mesh )
79
 
    writeMesh(fp, u.mesh());
80
 
 
81
 
  // Write function
82
 
  writeFunction(fp, u);
83
 
 
84
 
  // Write time series
85
 
  writeSeries(fp, u);
86
 
 
87
 
  // Close file
88
 
  fclose(fp);
89
 
*/
90
 
}
91
 
//-�---------------------------------------------------------------------------
92
 
void OpenDXFile::writeHeader(FILE* fp)
93
 
{
94
 
  fprintf(fp,"# Output from DOLFIN version %s.\n", DOLFIN_VERSION);
95
 
  fprintf(fp,"# Format intended for use with OpenDX (Data Explorer).\n");
96
 
  fprintf(fp,"#\n");
97
 
  fprintf(fp,"\n");
98
 
}
99
 
//-�---------------------------------------------------------------------------
100
 
void OpenDXFile::writeMesh(FILE* fp, Mesh& mesh)
101
 
{
102
 
  int meshdim, celldim;
103
 
  if( mesh.type().cellType() == CellType::tetrahedron ) {
104
 
    meshdim = 3;
105
 
    celldim = 4;
106
 
  } else {
107
 
    meshdim = 2;
108
 
    celldim = 3;
109
 
  }
110
 
 
111
 
  // Write vertices
112
 
  fprintf(fp, "# A list of all vertex positions\n");
113
 
  fprintf(fp, "object \"vertices %d\" class array type float rank 1 shape %d items %u lsb binary data follows\n", 
114
 
            (int)frames.size(), meshdim, mesh.numVertices());
115
 
 
116
 
  for (VertexIterator n(mesh); !n.end(); ++n)
117
 
  {
118
 
    Point p = n->point();
119
 
    
120
 
    float x = (float) p.x();
121
 
    float y = (float) p.y();
122
 
    float z = (float) p.z();
123
 
    
124
 
    fwrite(&x, sizeof(float), 1, fp);
125
 
    fwrite(&y, sizeof(float), 1, fp);
126
 
    if ( mesh.type().cellType() == CellType::tetrahedron )
127
 
      fwrite(&z, sizeof(float), 1, fp);
128
 
  }
129
 
  fprintf(fp,"\n\n");
130
 
 
131
 
  // Write cells
132
 
  fprintf(fp, "# A list of all cells (connections)\n");
133
 
  fprintf(fp, "object \"cells %d\" class array type int rank 1 shape %d items %u lsb binary data follows\n",
134
 
          (int)frames.size(), celldim, mesh.numCells());
135
 
 
136
 
  for (CellIterator c(mesh); !c.end(); ++c)
137
 
  {  
138
 
    for (VertexIterator n(*c); !n.end(); ++n)
139
 
    {
140
 
      int id  = n->index();
141
 
      fwrite(&id, sizeof(int), 1, fp);
142
 
    }
143
 
  }
144
 
  fprintf(fp, "\n");
145
 
  if ( mesh.type().cellType() == CellType::tetrahedron )
146
 
    fprintf(fp, "attribute \"element type\" string \"tetrahedra\"\n");
147
 
  else if ( mesh.type().cellType() == CellType::triangle )
148
 
    fprintf(fp, "attribute \"element type\" string \"triangles\"\n");
149
 
  fprintf(fp, "attribute \"ref\" string \"positions\"\n");
150
 
  fprintf(fp, "\n");
151
 
}
152
 
//-�---------------------------------------------------------------------------
153
 
void OpenDXFile::writeMeshData(FILE* fp, Mesh& mesh)
154
 
{
155
 
  // Write data for a given mesh to create an object that can be visualized
156
 
  // when no data is associated with the mesh. This is necessary when we only
157
 
  // want to save the mesh.
158
 
 
159
 
  // Check that we don't try to write mesh data at the same time as we
160
 
  // write a time series
161
 
  if ( frames.size() > 0 )
162
 
    error("Mesh data and time series cannot be mixed for OpenDX file format.");
163
 
 
164
 
  // Write data (cell diameter)
165
 
  fprintf(fp,"# Cell diameter\n");
166
 
  fprintf(fp,"object \"diameter\" class array type float rank 0 items %u lsb binary data follows\n",
167
 
          mesh.numCells());
168
 
  
169
 
  for (CellIterator c(mesh); !c.end(); ++c)
170
 
  {
171
 
    float value = static_cast<float>(c->diameter());
172
 
    fwrite(&value, sizeof(float), 1, fp);
173
 
  }
174
 
  fprintf(fp, "\n");
175
 
  fprintf(fp, "attribute \"dep\" string \"connections\"\n");
176
 
  fprintf(fp, "\n");  
177
 
 
178
 
  // Write the mesh
179
 
  fprintf(fp, "# The mesh\n");
180
 
  fprintf(fp, "object \"Mesh\" class field\n");
181
 
  fprintf(fp, "component \"positions\" value \"vertices 0\"\n");
182
 
  fprintf(fp, "component \"connections\" value \"cells 0\"\n");
183
 
  fprintf(fp, "component \"data\" value \"diameter\"\n");
184
 
}
185
 
//-�---------------------------------------------------------------------------
186
 
void OpenDXFile::writeFunction(FILE* fp, Function& u)
187
 
{
188
 
  error("Function output in OpenDX format not implemented for new Function.");
189
 
/*
190
 
  // Write header for object
191
 
  fprintf(fp,"# Values for [%s] at nodal points, frame %d\n", u.label().c_str(), (int)frames.size());
192
 
  fprintf(fp,"object \"data %d\" class array type float rank 1 shape %u items %u lsb binary data follows\n",
193
 
          (int)frames.size(), u.vectordim(), u.mesh().numVertices());
194
 
  
195
 
  // Write data
196
 
  for (VertexIterator n(u.mesh()); !n.end(); ++n)
197
 
  {
198
 
    for(unsigned int i=0; i<u.vectordim(); i++) {
199
 
      float value = static_cast<float>(u(*n, i));
200
 
      fwrite(&value, sizeof(float), 1, fp);
201
 
    }
202
 
  }
203
 
  fprintf(fp,"\n");
204
 
  fprintf(fp,"attribute \"dep\" string \"positions\"\n\n");
205
 
  
206
 
  // Write field
207
 
  fprintf(fp,"# Field for [%s], frame %d\n", u.label().c_str(), (int)frames.size());
208
 
  fprintf(fp,"object \"field %d\" class field\n", (int)frames.size());
209
 
  if ( save_each_mesh )
210
 
    fprintf(fp,"component \"positions\" value \"vertices %d\"\n", (int)frames.size());
211
 
  else
212
 
    fprintf(fp,"component \"positions\" value \"vertices 0\"\n");
213
 
  if ( save_each_mesh )
214
 
    fprintf(fp,"component \"connections\" value \"cells %d\"\n", (int)frames.size());
215
 
  else
216
 
    fprintf(fp,"component \"connections\" value \"cells 0\"\n");
217
 
  fprintf(fp,"component \"data\" value \"data %d\"\n\n", (int)frames.size());
218
 
  
219
 
  // Add the new frame
220
 
  Frame frame(u.time());
221
 
  frames.push_back(frame);
222
 
*/
223
 
}
224
 
//-�---------------------------------------------------------------------------
225
 
void OpenDXFile::writeSeries(FILE* fp, Function& u)
226
 
{
227
 
  // Get position in file at start of series
228
 
  series_pos = ftell(fp);
229
 
 
230
 
  // Write the time series
231
 
  fprintf(fp,"# Time series for [%s]\n", u.label().c_str());
232
 
  fprintf(fp,"object \"Time series\" class series\n");
233
 
  
234
 
  for (unsigned int i = 0; i < frames.size(); i++)
235
 
  {
236
 
    fprintf(fp,"member %u value \"field %u\" position %f\n",
237
 
            i, i, frames[i].time);
238
 
  }
239
 
  
240
 
  fprintf(fp,"\n");
241
 
}
242
 
//-�---------------------------------------------------------------------------
243
 
void OpenDXFile::removeSeries(FILE* fp)
244
 
{
245
 
  // Remove the previous series (the new one will be placed at the end).
246
 
  // This makes sure that we have a valid dx-file even if we kill the
247
 
  // program after a few frames. Note that if someone puts a "#"
248
 
  // inside a comment we are in trouble.
249
 
 
250
 
  fseek(fp, series_pos, SEEK_SET);
251
 
  fflush(fp);
252
 
}
253
 
//-�---------------------------------------------------------------------------
254
 
// OpenDXFile::Frame
255
 
//-�---------------------------------------------------------------------------
256
 
OpenDXFile::Frame::Frame(real time) : time(time)
257
 
{
258
 
  // Do nothing
259
 
}
260
 
//-�---------------------------------------------------------------------------
261
 
OpenDXFile::Frame::~Frame()
262
 
{
263
 
  // Do nothing
264
 
}
265
 
//-�---------------------------------------------------------------------------