dolfin team mailing list archive
-
dolfin team
-
Mailing list archive
-
Message #06226
Update OpenDXFile
Hi,
I just tried to wake up the function OpenDXFile. It now can handle the
discrete functions as in VTK. Each time it will write to a separate
files instead of writing all together as before.
/ Minh
// Copyright (C) 2003-2006 Johan Hoffman and Anders Logg.
// Licensed under the GNU LGPL Version 2.1.
//
// Modified by Minh Do-Quang 2006-2008
//
// First added: 2003-07-15
// Last changed: 2008-02-15
#include <stdio.h>
#include <dolfin/log.h>
#include <dolfin/parameters.h>
#include <dolfin/Cell.h>
#include <dolfin/Function.h>
#include <dolfin/Mesh.h>
#include <dolfin/Vertex.h>
#include <dolfin/OpenDXFile.h>
using namespace dolfin;
//-�---------------------------------------------------------------------------
OpenDXFile::OpenDXFile(const std::string filename) : GenericFile(filename)
{
type = "OpenDX";
}
//-�---------------------------------------------------------------------------
OpenDXFile::~OpenDXFile()
{
// Do nothing
}
//-�---------------------------------------------------------------------------
void OpenDXFile::operator<<(Mesh& mesh)
{
// Update dx file name and clear file
dxNameUpdate(counter);
// Open file
FILE* fp = fopen(dx_filename.c_str(), "w");
// Write header first time
writeHeader(fp);
// Write mesh
writeMesh(fp, mesh);
// Close headers
writeMeshData(fp, mesh);
// Increase the number of times we have saved the mesh
counter++;
message(1, "Saved mesh %s (%s) to file %s in OpenDX format.",
mesh.name().c_str(), mesh.label().c_str(), filename.c_str());
// Close file
fclose(fp);
}
//-�---------------------------------------------------------------------------
void OpenDXFile::operator<<(Function& u)
{
// Can only save discrete functions
if ( u.type() != Function::discrete )
error("Only discrete functions can be saved in OpenDX format.");
// Update dx file name and clear file
dxNameUpdate(counter);
FILE* fp = fopen(dx_filename.c_str(), "w");
fseek(fp, 0L, SEEK_END);
// Write header first time
if ( ftell(fp) == 0 )
writeHeader(fp);
// Write mesh
if ( save_each_mesh )
writeMesh(fp, u.mesh());
// Write function
writeFunction(fp, u);
// Close headers
writeHeaderClose(fp);
// Close file
fclose(fp);
// Increase the number of times we have saved the function
counter++;
cout << "Saved function " << u.name() << " (" << u.label()
<< ") to file " << filename << " in OpenDX format." << endl;
}
//-�---------------------------------------------------------------------------
void OpenDXFile::writeHeader(FILE* fp)
{
fprintf(fp,"# Output from DOLFIN version %s.\n", DOLFIN_VERSION);
fprintf(fp,"# Format intended for use with OpenDX (Data Explorer).\n");
fprintf(fp,"#\n");
fprintf(fp,"\n");
}
//-�---------------------------------------------------------------------------
void OpenDXFile::writeHeaderClose(FILE* fp)
{
fprintf(fp,"#\n");
fprintf(fp,"#\n");
fprintf(fp,"object \"maindata\" class field\n");
fprintf(fp,"component \"positions\" \"vertex\"\n");
fprintf(fp,"component \"connections\" \"cells\"\n");
fprintf(fp,"component \"data\" \"data\"\n");
fprintf(fp,"end\n");
fprintf(fp,"\n");
}
//-�---------------------------------------------------------------------------
void OpenDXFile::writeMesh(FILE* fp, Mesh& mesh)
{
int meshdim, celldim;
if( mesh.type().cellType() == CellType::tetrahedron ) {
meshdim = 3;
celldim = 4;
} else {
meshdim = 2;
celldim = 3;
}
// Write vertices
fprintf(fp, "# A list of all vertex positions\n");
fprintf(fp, "object \"vertex\" class array type float rank 1 shape %d items %u data follows\n",
meshdim, mesh.numVertices());
for (VertexIterator n(mesh); !n.end(); ++n)
{
Point p = n->point();
float x = (float) p.x();
float y = (float) p.y();
float z = (float) p.z();
if ( mesh.type().cellType() == CellType::tetrahedron )
fprintf(fp, "%g %g %g\n", p.x(), p.y(), p.z());
else if ( mesh.type().cellType() == CellType::triangle )
fprintf(fp, "%g %g\n", p.x(), p.y());
}
fprintf(fp,"#\n");
// Write cells
fprintf(fp, "# A list of all cells (connections)\n");
fprintf(fp, "object \"cells\" class array type int rank 1 shape %d items %u data follows\n",
celldim, mesh.numCells());
for (CellIterator c(mesh); !c.end(); ++c)
{
for (VertexIterator n(*c); !n.end(); ++n)
fprintf(fp, " %8u ", n->index());
fprintf(fp, "\n");
}
fprintf(fp, "#\n");
if ( mesh.type().cellType() == CellType::tetrahedron )
fprintf(fp, "attribute \"element type\" string \"tetrahedra\"\n");
else if ( mesh.type().cellType() == CellType::triangle )
fprintf(fp, "attribute \"element type\" string \"triangles\"\n");
fprintf(fp, "attribute \"ref\" string \"positions\"\n");
fprintf(fp, "\n");
}
//-�---------------------------------------------------------------------------
void OpenDXFile::writeMeshData(FILE* fp, Mesh& mesh)
{
// Write data for a given mesh to create an object that can be visualized
// when no data is associated with the mesh. This is necessary when we only
// want to save the mesh.
// Check that we don't try to write mesh data at the same time as we
// write a time series
fprintf(fp,"# Cell diameter\n");
fprintf(fp,"object \"diameter\" class array type float rank 0 items %u data follows\n",
mesh.numCells());
for (CellIterator c(mesh); !c.end(); ++c)
{
float value = static_cast<float>(c->diameter());
fprintf(fp, "%g\n", value);
}
fprintf(fp, "\n");
fprintf(fp, "attribute \"dep\" string \"connections\"\n");
fprintf(fp, "\n");
// Write the mesh
fprintf(fp, "# The mesh\n");
fprintf(fp, "object \"Mesh\" class field\n");
fprintf(fp, "component \"positions\" value \"vertex\"\n");
fprintf(fp, "component \"connections\" value \"cells\"\n");
fprintf(fp, "component \"data\" value \"diameter\"\n");
}
//-�---------------------------------------------------------------------------
void OpenDXFile::writeFunction(FILE* fp, Function& u)
{
Mesh& mesh = u.mesh();
const uint rank = u.rank();
if(rank > 1)
error("Only scalar and vectors functions can be saved in VTK format.");
// Get number of components
const uint dim = u.dim(0);
// Allocate memory for function values at vertices
uint size = mesh.numVertices();
for (uint i = 0; i < u.rank(); i++)
size *= u.dim(i);
real* values = new real[size];
// Write header for object
fprintf(fp,"# Values for [%s] at nodal points\n", u.label().c_str());
fprintf(fp,"object \"data\" class array type float rank 1 shape %u items %u data follows\n",
dim, mesh.numVertices());
// Get function values at vertices
u.interpolate(values);
// Write function data at mesh vertices
if ( rank <=1 )
{
for (VertexIterator vertex(mesh); !vertex.end(); ++vertex)
{
for(unsigned int i=0; i<dim; i++)
fprintf(fp, " %e ", values[vertex->index()+i*mesh.numVertices()]);
fprintf(fp, "\n");
}
}
fprintf(fp,"\n");
fprintf(fp,"attribute \"dep\" string \"positions\"\n\n");
}
//----------------------------------------------------------------------------
void OpenDXFile::dxNameUpdate(const int counter)
{
std::string filestart, extension;
std::ostringstream fileid, newfilename;
fileid.fill('0');
fileid.width(6);
filestart.assign(filename, 0, filename.find("."));
extension.assign(filename, filename.find("."), filename.size());
fileid << counter;
newfilename << filestart << fileid.str() << ".dx";
dx_filename = newfilename.str();
}
// Copyright (C) 2003-2005 Johan Hoffman and Anders Logg.
// Licensed under the GNU LGPL Version 2.1.
//
// Modified by Minh Do-Quang 2008.
//
// First added: 2003-07-15
// Last changed: 2008
#ifndef __OPEN_DX_FILE_H
#define __OPEN_DX_FILE_H
#include <string>
#include <stdio.h>
#include <dolfin/constants.h>
#include <dolfin/Event.h>
#include <dolfin/Array.h>
#include <dolfin/GenericFile.h>
namespace dolfin
{
class OpenDXFile : public GenericFile
{
public:
OpenDXFile(const std::string filename);
~OpenDXFile();
void operator<< (Mesh& mesh);
void operator<< (Function& u);
private:
void writeHeader (FILE* fp);
void writeHeaderClose(FILE* fp);
void writeMesh (FILE* fp, Mesh& mesh);
void writeMeshData (FILE* fp, Mesh& mesh);
void writeFunction (FILE* fp, Function& u);
void dxNameUpdate(const int counter);
// dx filename
std::string dx_filename;
// Check if we should save each mesh
bool save_each_mesh;
};
}
#endif
Follow ups