dolfin team mailing list archive
-
dolfin team
-
Mailing list archive
-
Message #24024
Re: [Branch ~dolfin-core/dolfin/main] Rev 6015: merge
Hurray!
--
Marie
On 2. juli 2011, at 13:12, noreply@xxxxxxxxxxxxx wrote:
> Merge authors:
> Garth Wells (garth-wells)
> ------------------------------------------------------------
> revno: 6015 [merge]
> committer: Garth N. Wells <gnw20@xxxxxxxxx>
> branch nick: dolfin-main
> timestamp: Sat 2011-07-02 12:11:14 +0100
> message:
> merge
> modified:
> dolfin/io/GenericFile.cpp
> dolfin/io/GenericFile.h
> dolfin/io/XMLFile.cpp
> dolfin/io/XMLFile.h
> dolfin/io/XMLIndent.cpp
> dolfin/io/XMLIndent.h
> dolfin/io/XMLMesh.cpp
> dolfin/io/XMLMesh.h
> dolfin/io/XMLVector.cpp
> dolfin/io/XMLVector.h
> dolfin/la/GenericMatrix.h
> dolfin/mesh/Mesh.h
> test/unit/io/python/xml_vector.py
>
>
> --
> lp:dolfin
> https://code.launchpad.net/~dolfin-core/dolfin/main
>
> Your team DOLFIN Core Team is subscribed to branch lp:dolfin.
> To unsubscribe from this branch go to https://code.launchpad.net/~dolfin-core/dolfin/main/+edit-subscription
> === modified file 'dolfin/io/GenericFile.cpp' --- dolfin/io/GenericFile.cpp 2011-06-21 00:01:06 +0000 +++ dolfin/io/GenericFile.cpp 2011-07-02 09:11:13 +0000 @@ -42,6 +42,11 @@ // Do nothing } //----------------------------------------------------------------------------- +GenericFile::~GenericFile() +{ + // Do nothing +} +//----------------------------------------------------------------------------- void GenericFile::operator>> (Mesh& mesh) { read_not_impl("Mesh"); === modified file 'dolfin/io/GenericFile.h' --- dolfin/io/GenericFile.h 2011-06-21 00:01:06 +0000 +++ dolfin/io/GenericFile.h 2011-07-02 09:11:13 +0000 @@ -48,6 +48,9 @@ /// Constructor GenericFile(const std::string filename); + /// Destructor + virtual ~GenericFile(); + // Input virtual void operator>> (Mesh& mesh); virtual void operator>> (GenericVector& x); === modified file 'dolfin/io/XMLFile.cpp' --- dolfin/io/XMLFile.cpp 2011-07-01 21:55:17 +0000 +++ dolfin/io/XMLFile.cpp 2011-07-02 11:11:14 +0000 @@ -57,6 +57,11 @@ // Do nothing } //----------------------------------------------------------------------------- +XMLFile::~XMLFile() +{ + // Do nothing +} +//----------------------------------------------------------------------------- void XMLFile::operator>> (Mesh& input_mesh) { // Create XML doc and get DOLFIN node @@ -72,16 +77,12 @@ if (MPI::num_processes() > 1) error("Mesh XML output in parallel not yet supported"); - // Open file on process 0 for distributed objects and on all processes - // for local objects - open_file(); - - // Note: 'write' is being called on all processes since collective MPI - // calls might be used. - XMLMesh::write(output_mesh, *outstream, 1); - - // Close file - close_file(); + pugi::xml_document doc; + pugi::xml_node node = write_dolfin(doc); + XMLMesh::write(output_mesh, node); + + // FIXME: Implement copy to stream + doc.save_file(filename.c_str(), " "); } //----------------------------------------------------------------------------- void XMLFile::operator>> (LocalMeshData& input_data) @@ -148,15 +149,19 @@ // Open file on process 0 for distributed objects and on all processes // for local objects if (MPI::process_number() == 0) - open_file(); - - // Note: 'write' is being called on all processes since collective MPI - // calls might be used. - XMLVector::write(output, *outstream, 1); - - // Close file - if (MPI::process_number() == 0) - close_file(); + { + pugi::xml_document doc; + pugi::xml_node node = write_dolfin(doc); + XMLVector::write(output, node, true); + + // FIXME: Implement copy to stream + doc.save_file(filename.c_str(), " "); + } + else + { + pugi::xml_node node(0); + XMLVector::write(output, node, false); + } } //----------------------------------------------------------------------------- void XMLFile::operator>> (Parameters& input) @@ -172,12 +177,13 @@ void XMLFile::operator<< (const Parameters& output) { if (MPI::process_number() == 0) - open_file(); - - XMLParameters::write(output, *outstream, 1); - - if (MPI::process_number() == 0) - close_file(); + { + open_write_file(); + XMLParameters::write(output, *outstream, 1); + close_write_file(); + } + else + XMLParameters::write(output, *outstream, 1); } //----------------------------------------------------------------------------- void XMLFile::operator>> (FunctionPlotData& input) @@ -193,12 +199,13 @@ void XMLFile::operator<< (const FunctionPlotData& output) { if (MPI::process_number() == 0) - open_file(); - - XMLFunctionPlotData::write(output, *outstream, 1); - - if (MPI::process_number() == 0) - close_file(); + { + open_write_file(); + XMLFunctionPlotData::write(output, *outstream, 1); + close_write_file(); + } + else + XMLFunctionPlotData::write(output, *outstream, 1); } //----------------------------------------------------------------------------- void XMLFile::write_start(std::ostream& outfile, uint indentation_level) @@ -229,12 +236,13 @@ const std::string type) { if (MPI::process_number() == 0) - open_file(); - - XMLMeshFunction::write(t, type, *outstream, 1); - - if (MPI::process_number() == 0) - close_file(); + { + open_write_file(); + XMLMeshFunction::write(t, type, *outstream, 1); + close_write_file(); + } + else + XMLMeshFunction::write(t, type, *outstream, 1); } //----------------------------------------------------------------------------- const pugi::xml_node XMLFile::get_dolfin_xml_node(pugi::xml_document& xml_doc, @@ -273,27 +281,38 @@ // Check that we have a DOLFIN XML file const pugi::xml_node dolfin_node = xml_doc.child("dolfin"); if (!dolfin_node) - error("Not a DOLFIN XML file"); + error("XMLFile::get_dolfin_xml_node: not a DOLFIN XML file"); return dolfin_node; } //----------------------------------------------------------------------------- -void XMLFile::open_file() +pugi::xml_node XMLFile::write_dolfin(pugi::xml_document& xml_doc) +{ + pugi::xml_node node = xml_doc.append_child("dolfin"); + node.append_attribute("xmlns:dolfin") = "http://www.fenicsproject.org"; + return node; +} +//----------------------------------------------------------------------------- +void XMLFile::open_write_file() { // Convert to ofstream std::ofstream* outfile = dynamic_cast(outstream.get()); if (outfile) { - // Open file - outfile->open(filename.c_str()); + // Open file (erase contents) + outfile->open(filename.c_str(), std::ios::out | std::ios::trunc); + + if (!outfile->is_open()) + error("Error opening XML file."); // Go to end of file - outfile->seekp(0, std::ios::end); + //outfile->seekp(0, std::ios::end); } + assert(outstream); XMLFile::write_start(*outstream); } //----------------------------------------------------------------------------- -void XMLFile::close_file() +void XMLFile::close_write_file() { XMLFile::write_end(*outstream); @@ -301,15 +320,9 @@ const boost::filesystem::path path(filename); const std::string extension = boost::filesystem::extension(path); if (extension == ".gz") - { error("Compressed XML output not yet supported."); - } - else - { - // Convert to ofstream - std::ofstream* outfile = dynamic_cast(outstream.get()); - if (outfile) - outfile->close(); - } + + // Finalise (closes file is stream is a file stream) + outstream.reset(); } //----------------------------------------------------------------------------- === modified file 'dolfin/io/XMLFile.h' --- dolfin/io/XMLFile.h 2011-06-30 12:57:51 +0000 +++ dolfin/io/XMLFile.h 2011-07-02 11:09:24 +0000 @@ -53,6 +53,8 @@ /// Constructor from a stream XMLFile(std::ostream& s); + ~XMLFile(); + // Mesh void operator>> (Mesh& input); void operator<< (const Mesh& output); @@ -111,9 +113,11 @@ const pugi::xml_node get_dolfin_xml_node(pugi::xml_document& xml_doc, const std::string filename) const; + static pugi::xml_node write_dolfin(pugi::xml_document& doc); + // Open/close files - void open_file(); - void close_file(); + void open_write_file(); + void close_write_file(); boost::shared_ptr outstream; === modified file 'dolfin/io/XMLIndent.cpp' --- dolfin/io/XMLIndent.cpp 2011-06-30 12:57:51 +0000 +++ dolfin/io/XMLIndent.cpp 2011-07-02 09:11:13 +0000 @@ -45,10 +45,8 @@ -- indentation_level; } //----------------------------------------------------------------------------- -std::string XMLIndent::operator()() +std::string XMLIndent::operator()() const { - std::ostringstream ss; - ss << std::setw(indentation_level*step_size) << ""; - return ss.str(); + return std::string(indentation_level*step_size, ' '); } //----------------------------------------------------------------------------- === modified file 'dolfin/io/XMLIndent.h' --- dolfin/io/XMLIndent.h 2011-06-30 12:57:51 +0000 +++ dolfin/io/XMLIndent.h 2011-07-02 09:11:13 +0000 @@ -44,7 +44,7 @@ void operator--(); - std::string operator() (); + std::string operator() () const; dolfin::uint level() { return indentation_level; } === modified file 'dolfin/io/XMLMesh.cpp' --- dolfin/io/XMLMesh.cpp 2011-06-30 12:57:51 +0000 +++ dolfin/io/XMLMesh.cpp 2011-07-02 11:09:24 +0000 @@ -143,6 +143,85 @@ outfile << indent() << "" << std::endl; } //----------------------------------------------------------------------------- +void XMLMesh::write(const Mesh& mesh, pugi::xml_node xml_node) +{ + // Add mesh node + pugi::xml_node mesh_node = xml_node.append_child("mesh"); + + // Add mesh attributes + const CellType::Type _cell_type = mesh.type().cell_type(); + const std::string cell_type = CellType::type2string(_cell_type); + mesh_node.append_attribute("celltype") = cell_type.c_str(); + mesh_node.append_attribute("dim") = mesh.geometry().dim(); + + // Add vertices node + pugi::xml_node vertices_node = mesh_node.append_child("vertices"); + vertices_node.append_attribute("size") = mesh.num_vertices(); + + // Write each vertex + for(VertexIterator v(mesh); !v.end(); ++v) + { + pugi::xml_node vertex_node = vertices_node.append_child("vertex"); + vertex_node.append_attribute("index") = v->index(); + + const Point p = v->point(); + switch (mesh.geometry().dim()) + { + case 1: + vertex_node.append_attribute("x") = p.x(); + break; + case 2: + vertex_node.append_attribute("x") = p.x(); + vertex_node.append_attribute("y") = p.y(); + break; + case 3: + vertex_node.append_attribute("x") = p.x(); + vertex_node.append_attribute("y") = p.y(); + vertex_node.append_attribute("z") = p.z(); + break; + default: + error("The XML mesh file format only supports 1D, 2D and 3D meshes."); + } + } + + // Add cells node + pugi::xml_node cells_node = mesh_node.append_child("cells"); + cells_node.append_attribute("size") = mesh.num_cells(); + + // Add each cell + for (CellIterator c(mesh); !c.end(); ++c) + { + pugi::xml_node cell_node = cells_node.append_child(cell_type.c_str()); + cell_node.append_attribute("index") = c->index(); + + const uint* vertices = c->entities(0); + assert(vertices); + + switch (_cell_type) + { + case CellType::interval: + cell_node.append_attribute("v0") = vertices[0]; + cell_node.append_attribute("v1") = vertices[1]; + break; + case CellType::triangle: + cell_node.append_attribute("v0") = vertices[0]; + cell_node.append_attribute("v1") = vertices[1]; + cell_node.append_attribute("v2") = vertices[2]; + break; + case CellType::tetrahedron: + cell_node.append_attribute("v0") = vertices[0]; + cell_node.append_attribute("v1") = vertices[1]; + cell_node.append_attribute("v2") = vertices[2]; + cell_node.append_attribute("v3") = vertices[3]; + break; + default: + error("Unknown cell type: %u.", _cell_type); + } + } + + // FIXME: Write mesh data +} +//----------------------------------------------------------------------------- void XMLMesh::read_mesh(Mesh& mesh, const pugi::xml_node xml_mesh) { // Get cell type and geometric dimension === modified file 'dolfin/io/XMLMesh.h' --- dolfin/io/XMLMesh.h 2011-06-30 12:57:51 +0000 +++ dolfin/io/XMLMesh.h 2011-07-02 11:09:24 +0000 @@ -47,6 +47,8 @@ static void write(const Mesh& mesh, std::ostream& outfile, unsigned int indentation_level=0); + /// Write the XML file + static void write(const Mesh& mesh, pugi::xml_node xml_node); private: === modified file 'dolfin/io/XMLVector.cpp' --- dolfin/io/XMLVector.cpp 2011-06-30 13:30:14 +0000 +++ dolfin/io/XMLVector.cpp 2011-07-02 11:09:24 +0000 @@ -37,12 +37,12 @@ // Check that we have a XML Vector const pugi::xml_node xml_vector_node = xml_dolfin.child("vector"); if (!xml_vector_node) - error("Not a DOLFIN Vector file."); + error("XMLVector::read: not a DOLFIN Vector file."); // Get type and size const pugi::xml_node array = xml_vector_node.child("array"); if (!array) - error("Not a DOLFIN array inside Vector XML file."); + error("XMLVector::read: not a DOLFIN array inside Vector XML file."); const unsigned int size = array.attribute("size").as_uint(); const std::string type = array.attribute("type").value(); @@ -68,37 +68,72 @@ // Check that we have a XML Vector const pugi::xml_node xml_vector_node = xml_dolfin.child("vector"); if (!xml_vector_node) - error("Not a DOLFIN Vector file."); + error("XMLVector::read_size: not a DOLFIN Vector file."); // Get size const pugi::xml_node array = xml_vector_node.child("array"); if (!array) - std::cout << "Not a DOLFIN Array" << std::endl; + std::cout << "XMLVector::read_size: not a DOLFIN Array" << std::endl; return array.attribute("size").as_uint(); } //----------------------------------------------------------------------------- void XMLVector::write(const GenericVector& vector, std::ostream& outfile, - unsigned int indentation_level) + bool write_to_stream, unsigned int indentation_level) { - bool write_to_stream = false; + // Gather entries from process i on process 0 + Array x; + if (MPI::num_processes() > 1) + vector.gather_on_zero(x); + else + vector.get_local(x); + + const uint size = vector.size(); if (MPI::process_number() == 0) - write_to_stream = true; - - XMLIndent indent(indentation_level); - - // Write vector header + assert(size == x.size()); + if (write_to_stream) { - outfile << indent() << "" << std::endl; - ++indent; - - // Write array header - outfile << indent() << "<< vector.size() - << "\">" << std::endl; - ++indent; + XMLIndent indent(indentation_level); + + // Write vector header + if (write_to_stream) + { + outfile << indent() << "" << std::endl; + ++indent; + + // Write array header + outfile << indent() << "<< size + << "\">" << std::endl; + ++indent; + } + + + // Write vector entries + if (write_to_stream) + { + for (uint i = 0; i < x.size(); ++i) + { + outfile << indent() + << "<< i +