← Back to team overview

dolfin team mailing list archive

Re: Update OpenDXFile

 

On Fri, Feb 15, 2008 at 02:34:35PM +0100, Minh Do Quang wrote:
> 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

But isn't the point of the DX format that you write everything as a
time series to one file?

It also looks like values are not written in binary anymore, which is
also an important point of the DX format.

-- 
Anders


> // 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

> _______________________________________________
> DOLFIN-dev mailing list
> DOLFIN-dev@xxxxxxxxxx
> http://www.fenics.org/mailman/listinfo/dolfin-dev



References