1
// Copyright (C) 2003-2008 Johan Hoffman and Anders Logg.
2
// Licensed under the GNU LGPL Version 2.1.
4
// Modified by Minh Do-Quang 2006
6
// First added: 2003-07-15
7
// Last changed: 2008-02-11
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>
18
using namespace dolfin;
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.")
30
//-�---------------------------------------------------------------------------
31
OpenDXFile::~OpenDXFile()
35
//-�---------------------------------------------------------------------------
36
void OpenDXFile::operator<<(Mesh& mesh)
41
FILE* fp = fopen(filename.c_str(), "r+");
42
fseek(fp, 0L, SEEK_END);
44
// Write header first time
52
writeMeshData(fp, mesh);
57
//-�---------------------------------------------------------------------------
58
void OpenDXFile::operator<<(Function& u)
60
error("Function output in OpenDX format not implemented for new Function.");
63
event_saving_function();
66
FILE* fp = fopen(filename.c_str(), "r+");
67
fseek(fp, 0L, SEEK_END);
69
// Remove previous time series
70
if ( frames.size() > 0 )
73
// Write header first time
78
if ( frames.size() == 0 || save_each_mesh )
79
writeMesh(fp, u.mesh());
91
//-�---------------------------------------------------------------------------
92
void OpenDXFile::writeHeader(FILE* fp)
94
fprintf(fp,"# Output from DOLFIN version %s.\n", DOLFIN_VERSION);
95
fprintf(fp,"# Format intended for use with OpenDX (Data Explorer).\n");
99
//-�---------------------------------------------------------------------------
100
void OpenDXFile::writeMesh(FILE* fp, Mesh& mesh)
102
int meshdim, celldim;
103
if( mesh.type().cellType() == CellType::tetrahedron ) {
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());
116
for (VertexIterator n(mesh); !n.end(); ++n)
118
Point p = n->point();
120
float x = (float) p.x();
121
float y = (float) p.y();
122
float z = (float) p.z();
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);
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());
136
for (CellIterator c(mesh); !c.end(); ++c)
138
for (VertexIterator n(*c); !n.end(); ++n)
141
fwrite(&id, sizeof(int), 1, fp);
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");
152
//-�---------------------------------------------------------------------------
153
void OpenDXFile::writeMeshData(FILE* fp, Mesh& mesh)
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.
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.");
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",
169
for (CellIterator c(mesh); !c.end(); ++c)
171
float value = static_cast<float>(c->diameter());
172
fwrite(&value, sizeof(float), 1, fp);
175
fprintf(fp, "attribute \"dep\" string \"connections\"\n");
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");
185
//-�---------------------------------------------------------------------------
186
void OpenDXFile::writeFunction(FILE* fp, Function& u)
188
error("Function output in OpenDX format not implemented for new Function.");
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());
196
for (VertexIterator n(u.mesh()); !n.end(); ++n)
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);
204
fprintf(fp,"attribute \"dep\" string \"positions\"\n\n");
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());
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());
216
fprintf(fp,"component \"connections\" value \"cells 0\"\n");
217
fprintf(fp,"component \"data\" value \"data %d\"\n\n", (int)frames.size());
220
Frame frame(u.time());
221
frames.push_back(frame);
224
//-�---------------------------------------------------------------------------
225
void OpenDXFile::writeSeries(FILE* fp, Function& u)
227
// Get position in file at start of series
228
series_pos = ftell(fp);
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");
234
for (unsigned int i = 0; i < frames.size(); i++)
236
fprintf(fp,"member %u value \"field %u\" position %f\n",
237
i, i, frames[i].time);
242
//-�---------------------------------------------------------------------------
243
void OpenDXFile::removeSeries(FILE* fp)
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.
250
fseek(fp, series_pos, SEEK_SET);
253
//-�---------------------------------------------------------------------------
255
//-�---------------------------------------------------------------------------
256
OpenDXFile::Frame::Frame(real time) : time(time)
260
//-�---------------------------------------------------------------------------
261
OpenDXFile::Frame::~Frame()
265
//-�---------------------------------------------------------------------------