DOLFINx
DOLFINx C++ interface
xdmf_meshtags.h
1 // Copyright (C) 2020 Michal Habera
2 //
3 // This file is part of DOLFINx (https://www.fenicsproject.org)
4 //
5 // SPDX-License-Identifier: LGPL-3.0-or-later
6 
7 #pragma once
8 
9 #include "xdmf_mesh.h"
10 #include "xdmf_utils.h"
11 #include <dolfinx/common/IndexMap.h>
12 #include <dolfinx/common/MPI.h>
13 #include <dolfinx/common/log.h>
14 #include <dolfinx/mesh/MeshTags.h>
15 #include <hdf5.h>
16 #include <pugixml.hpp>
17 #include <span>
18 #include <string>
19 #include <vector>
20 
21 namespace dolfinx
22 {
23 namespace io
24 {
25 namespace xdmf_meshtags
26 {
27 
29 template <typename T>
30 void add_meshtags(MPI_Comm comm, const mesh::MeshTags<T>& meshtags,
31  pugi::xml_node& xml_node, const hid_t h5_id,
32  const std::string name)
33 {
34  LOG(INFO) << "XDMF: add meshtags (" << name << ")";
35  // Get mesh
36  assert(meshtags.mesh());
37  std::shared_ptr<const mesh::Mesh> mesh = meshtags.mesh();
38  const int dim = meshtags.dim();
39  std::shared_ptr<const common::IndexMap> entity_map
40  = mesh->topology().index_map(dim);
41  if (!entity_map)
42  {
43  throw std::runtime_error("Missing entities. Did you forget to call "
44  "dolfinx::mesh::Topology::create_entities?");
45  }
46  const std::int32_t num_local_entities = entity_map->size_local();
47 
48  // Find number of tagged entities in local range
49  auto it = std::lower_bound(meshtags.indices().begin(),
50  meshtags.indices().end(), num_local_entities);
51  const int num_active_entities = std::distance(meshtags.indices().begin(), it);
52 
53  const std::string path_prefix = "/MeshTags/" + name;
55  comm, xml_node, h5_id, path_prefix, mesh->topology(), mesh->geometry(),
56  dim,
57  std::span<const std::int32_t>(meshtags.indices().data(),
58  num_active_entities));
59 
60  // Add attribute node with values
61  pugi::xml_node attribute_node = xml_node.append_child("Attribute");
62  assert(attribute_node);
63  attribute_node.append_attribute("Name") = name.c_str();
64  attribute_node.append_attribute("AttributeType") = "Scalar";
65  attribute_node.append_attribute("Center") = "Cell";
66 
67  std::int64_t global_num_values = 0;
68  const std::int64_t local_num_values = num_active_entities;
69  MPI_Allreduce(&local_num_values, &global_num_values, 1, MPI_INT64_T, MPI_SUM,
70  comm);
71  const std::int64_t num_local = num_active_entities;
72  std::int64_t offset = 0;
73  MPI_Exscan(&num_local, &offset, 1, MPI_INT64_T, MPI_SUM, comm);
74  const bool use_mpi_io = (dolfinx::MPI::size(comm) > 1);
75  xdmf_utils::add_data_item(
76  attribute_node, h5_id, path_prefix + std::string("/Values"),
77  std::span<const T>(meshtags.values().data(), num_active_entities), offset,
78  {global_num_values, 1}, "", use_mpi_io);
79 }
80 
81 } // namespace xdmf_meshtags
82 } // namespace io
83 } // namespace dolfinx
int size(MPI_Comm comm)
Return size of the group (number of processes) associated with the communicator.
Definition: MPI.cpp:83
void add_topology_data(MPI_Comm comm, pugi::xml_node &xml_node, const hid_t h5_id, const std::string path_prefix, const mesh::Topology &topology, const mesh::Geometry &geometry, int cell_dim, const std::span< const std::int32_t > &entities)
Add Topology xml node.
Definition: xdmf_mesh.cpp:20