| 238 | //----------------------------------------------------------------------------- |
| 239 | template <dolfinx::scalar T, std::floating_point U> |
| 240 | void XDMFFile::write_function(const fem::Function<T, U>& u, double t, |
| 241 | std::string mesh_xpath) |
| 242 | { |
| 243 | assert(_xml_doc); |
| 244 | |
| 245 | std::string timegrid_xpath |
| 246 | = "/Xdmf/Domain/Grid[@GridType='Collection'][@Name='" + u.name + "']"; |
| 247 | pugi::xml_node timegrid_node |
| 248 | = _xml_doc->select_node(timegrid_xpath.c_str()).node(); |
| 249 | |
| 250 | if (!timegrid_node) |
| 251 | { |
| 252 | pugi::xml_node domain_node = _xml_doc->select_node("/Xdmf/Domain").node(); |
| 253 | timegrid_node = domain_node.append_child("Grid"); |
| 254 | timegrid_node.append_attribute("Name") = u.name.c_str(); |
| 255 | timegrid_node.append_attribute("GridType") = "Collection"; |
| 256 | timegrid_node.append_attribute("CollectionType") = "Temporal"; |
| 257 | } |
| 258 | |
| 259 | assert(timegrid_node); |
| 260 | |
| 261 | pugi::xml_node grid_node = timegrid_node.append_child("Grid"); |
| 262 | assert(grid_node); |
| 263 | grid_node.append_attribute("Name") = u.name.c_str(); |
| 264 | grid_node.append_attribute("GridType") = "Uniform"; |
| 265 | |
| 266 | pugi::xml_node mesh_node = _xml_doc->select_node(mesh_xpath.c_str()).node(); |
| 267 | if (!mesh_node) |
| 268 | { |
| 269 | spdlog::warn("No mesh found at '{}'. Write mesh before function!", |
| 270 | mesh_xpath); |
| 271 | } |
| 272 | |
| 273 | const std::string ref_path |
| 274 | = "xpointer(" + mesh_xpath + "/*[self::Topology or self::Geometry])"; |
| 275 | |
| 276 | pugi::xml_node topo_geo_ref = grid_node.append_child("xi:include"); |
| 277 | topo_geo_ref.append_attribute("xpointer") = ref_path.c_str(); |
| 278 | assert(topo_geo_ref); |
| 279 | |
| 280 | std::string t_str = boost::lexical_cast<std::string>(t); |
| 281 | pugi::xml_node time_node = grid_node.append_child("Time"); |
| 282 | time_node.append_attribute("Value") = t_str.c_str(); |
| 283 | assert(time_node); |
| 284 | |
| 285 | // Add the mesh Grid to the domain |
| 286 | xdmf_function::add_function(_comm.comm(), u, t, grid_node, _h5_id); |
| 287 | |
| 288 | // Save XML file (on process 0 only) |
| 289 | if (dolfinx::MPI::rank(_comm.comm()) == 0) |
| 290 | _xml_doc->save_file(_filename.c_str(), " "); |
| 291 | } |
| 292 | //----------------------------------------------------------------------------- |
| 293 | // Instantiation for different types |
| 294 | /// @cond |