DOLFIN
DOLFIN C++ interface
XMLMeshFunction.h
1 // Copyright (C) 2011 Garth N. Wells
2 //
3 // This file is part of DOLFIN.
4 //
5 // DOLFIN is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // DOLFIN is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // Modified by Anders Logg 2011
19 //
20 // First added: 2011-06-30
21 // Last changed: 2011-11-14
22 
23 #ifndef __XML_MESH_FUNCTION_H
24 #define __XML_MESH_FUNCTION_H
25 
26 #include <iomanip>
27 #include <iostream>
28 #include <ostream>
29 #include <string>
30 
31 #include "pugixml.hpp"
32 #include <dolfin/mesh/LocalMeshValueCollection.h>
33 #include <dolfin/mesh/Mesh.h>
34 #include <dolfin/mesh/MeshFunction.h>
35 #include <dolfin/mesh/MeshValueCollection.h>
36 #include "XMLMesh.h"
37 #include "XMLMeshValueCollection.h"
38 
39 #include <dolfin/common/Timer.h>
40 
41 namespace dolfin
42 {
43 
45 
47  {
48  public:
49 
51  template <typename T>
52  static void read(MeshFunction<T>& mesh_function, const std::string type,
53  const pugi::xml_node xml_mesh);
54 
56  template <typename T>
57  static void read(MeshValueCollection<T>& mesh_value_collection,
58  const std::string type, const pugi::xml_node xml_mesh);
59 
61  template<typename T>
62  static void write(const MeshFunction<T>& mesh_function,
63  const std::string type, pugi::xml_node xml_node,
64  bool write_mesh=true);
65 
66  };
67 
68  //---------------------------------------------------------------------------
69  template <typename T>
70  inline void XMLMeshFunction::read(MeshFunction<T>& mesh_function,
71  const std::string type,
72  const pugi::xml_node xml_mesh)
73  {
74  bool new_format = false;
75  pugi::xml_node xml_meshfunction;
76  if (std::string(xml_mesh.name()) == "mesh_function")
77  {
78  // XML node is a mesh function
79  new_format = true;
80  xml_meshfunction = xml_mesh;
81  }
82  else
83  {
84  // Tag
85  std::string tag_name = "mesh_function";
86 
87  // Check for old tag
88  if (xml_mesh.child("meshfunction"))
89  {
90  warning("The XML tag <meshfunction> has been changed to <mesh_function>. "
91  "I'll be nice and read your XML data anyway, for now, but you will "
92  "need to update your XML files (a simple search and replace) to use "
93  "future versions of DOLFIN.");
94  tag_name = "meshfunction";
95  }
96 
97  // Get XML node
98  xml_meshfunction = xml_mesh.child(tag_name.c_str());
99 
100  // Read main tag
101  if (!xml_meshfunction)
102  std::cout << "Not a DOLFIN MeshFunction XML file." << std::endl;
103 
104  if (xml_meshfunction.attributes_begin() == xml_meshfunction.attributes_end())
105  new_format = true;
106  }
107 
108  // Check for new (MeshValueCollection) / old storage
109  if (new_format)
110  {
111  // Read new-style MeshFunction
112  MeshValueCollection<T> mesh_value_collection(mesh_function.mesh());
113  XMLMeshValueCollection::read<T>(mesh_value_collection, type,
114  xml_meshfunction);
115 
116  // Assign collection to mesh function (this is a local
117  // operation) and attach name
118  mesh_function = mesh_value_collection;
119  mesh_function.rename(mesh_value_collection.name(),
120  mesh_value_collection.label());
121  }
122  else
123  {
124  // Get type and size
125  const std::string file_data_type = xml_meshfunction.attribute("type").value();
126  const std::size_t dim = xml_meshfunction.attribute("dim").as_uint();
127  const std::size_t size = xml_meshfunction.attribute("size").as_uint();
128 
129  // Check that types match
130  if (type != file_data_type)
131  {
132  dolfin_error("XMLMeshFunction.h",
133  "read mesh function from XML file",
134  "Type mismatch reading XML MeshFunction. MeshFunction type is \"%s\", but file type is \"%s\"",
135  type.c_str(), file_data_type.c_str());
136  }
137 
138  // Initialise MeshFunction
139  mesh_function.init(dim, size);
140 
141  // Iterate over entries (choose data type)
142  if (type == "uint")
143  {
144  for (pugi::xml_node_iterator it = xml_meshfunction.begin();
145  it != xml_meshfunction.end(); ++it)
146  {
147  const std::size_t index = it->attribute("index").as_uint();
148  dolfin_assert(index < size);
149  mesh_function[index] = it->attribute("value").as_uint();
150  }
151  }
152  else if (type == "int")
153  {
154  for (pugi::xml_node_iterator it = xml_meshfunction.begin();
155  it != xml_meshfunction.end(); ++it)
156  {
157  const std::size_t index = it->attribute("index").as_uint();
158  dolfin_assert(index < size);
159  mesh_function[index] = it->attribute("value").as_int();
160  }
161  }
162  else if (type == "double")
163  {
164  for (pugi::xml_node_iterator it = xml_meshfunction.begin();
165  it != xml_meshfunction.end(); ++it)
166  {
167  const std::size_t index = it->attribute("index").as_uint();
168  dolfin_assert(index < size);
169  mesh_function[index] = it->attribute("value").as_double();
170  }
171  }
172  else if (type == "bool")
173  {
174  for (pugi::xml_node_iterator it = xml_meshfunction.begin();
175  it != xml_meshfunction.end(); ++it)
176  {
177  const std::size_t index = it->attribute("index").as_uint();
178  dolfin_assert(index < size);
179  mesh_function[index] = it->attribute("value").as_bool();
180  }
181  }
182  else
183  {
184  dolfin_error("XMLMeshFunction.h",
185  "read mesh function from XML file",
186  "Unknown value type (\"%s\")", type.c_str());
187  }
188  }
189  }
190  //---------------------------------------------------------------------------
191  template <typename T>
192  inline void XMLMeshFunction::read(MeshValueCollection<T>& mesh_value_collection,
193  const std::string type,
194  const pugi::xml_node xml_mesh)
195  {
196  // Check for old tag
197  std::string tag_name("mesh_function");
198  if (xml_mesh.child("meshfunction"))
199  {
200  warning("The XML tag <meshfunction> has been changed to <mesh_function>. "
201  "I'll be nice and read your XML data anyway, for now, but you will "
202  "need to update your XML files (a simple search and replace) to use "
203  "future versions of DOLFIN.");
204  tag_name = "meshfunction";
205  }
206 
207  // Read main tag
208  const pugi::xml_node xml_meshfunction = xml_mesh.child(tag_name.c_str());
209  if (!xml_meshfunction)
210  std::cout << "Not a DOLFIN MeshFunction XML file." << std::endl;
211 
212  // Check for new (MeshValueCollection) / old storage
213  if (xml_meshfunction.attributes_begin() == xml_meshfunction.attributes_end())
214  {
215  // Read new-style MeshFunction
216  XMLMeshValueCollection::read<T>(mesh_value_collection, type,
217  xml_meshfunction);
218  }
219  else
220  {
221  dolfin_error("XMLMeshFunction.h",
222  "read mesh function from XML file",
223  "Cannot read old-style MeshFunction XML files as a MeshValueCollection");
224  }
225  }
226  //---------------------------------------------------------------------------
227  template<typename T>
228  void XMLMeshFunction::write(const MeshFunction<T>& mesh_function,
229  const std::string type, pugi::xml_node xml_node,
230  bool write_mesh)
231  {
232  not_working_in_parallel("MeshFunction XML output");
233 
234  // Write mesh if requested
235  if (write_mesh)
236  XMLMesh::write(*mesh_function.mesh(), xml_node);
237 
238  // Add mesh function node and attributes
239  pugi::xml_node mf_node = xml_node.append_child("mesh_function");
240 
241  // Create MeshValueCollection for output
242  MeshValueCollection<T> mesh_value_collection(mesh_function);
243  mesh_value_collection.rename(mesh_function.name(), mesh_function.label());
244 
245  // Write MeshValueCollection
246  XMLMeshValueCollection::write(mesh_value_collection, type, mf_node);
247  }
248  //---------------------------------------------------------------------------
249 
250 }
251 #endif
Definition: adapt.h:41
static void write(const MeshValueCollection< T > &mesh_value_collection, const std::string type, pugi::xml_node xml_node)
Write mesh value collection to XML file.
Definition: XMLMeshValueCollection.h:146
void warning(std::string msg,...)
Print warning.
Definition: log.cpp:115
Definition: adapt.h:29
void init(std::size_t dim)
Definition: MeshFunction.h:572
void rename(const std::string name, const std::string label)
Rename variable.
Definition: Variable.cpp:65
std::string label() const
Return label (description)
Definition: Variable.cpp:76
static void write(const Mesh &mesh, pugi::xml_node mesh_node)
Write mesh to XML.
Definition: XMLMesh.cpp:73
static void read(MeshFunction< T > &mesh_function, const std::string type, const pugi::xml_node xml_mesh)
Read XML MeshFunction.
Definition: XMLMeshFunction.h:70
I/O of XML representation of MeshFunction.
Definition: XMLMeshFunction.h:46
Definition: GenericFile.h:38
std::string name() const
Return name.
Definition: Variable.cpp:71
std::shared_ptr< const Mesh > mesh() const
Definition: MeshFunction.h:491
void dolfin_error(std::string location, std::string task, std::string reason,...)
Definition: log.cpp:129
void not_working_in_parallel(std::string what)
Definition: log.cpp:205
static void write(const MeshFunction< T > &mesh_function, const std::string type, pugi::xml_node xml_node, bool write_mesh=true)
Write the XML file.
Definition: XMLMeshFunction.h:228