20template <
typename VALUE,
typename TYPE>
23 bool const result = value <= std::numeric_limits<TYPE>::max();
26 ERR(
"The value {:d} is too large for conversion.", value);
27 ERR(
"Maximum available size is {:d}.",
28 std::numeric_limits<TYPE>::max());
50 int blocks[count] = {1, 3};
51 MPI_Datatype types[count] = {MPI_UNSIGNED_LONG, MPI_DOUBLE};
54 MPI_Type_create_struct(count, blocks, displacements, types,
60 const std::string& file_name_base)
66 std::string
const fname_new = file_name_base +
"_partitioned_msh_cfg" +
67 std::to_string(
mpi_.size) +
".bin";
71 std::string
const fname_ascii = file_name_base +
72 "_partitioned_msh_cfg" +
73 std::to_string(
mpi_.size) +
".msh";
76 ERR(
"Reading of ASCII mesh file {:s} is not supported since OGS "
80 OGS_FATAL(
"Required binary file {:s} does not exist.\n", fname_new);
83 INFO(
"Reading corresponding part of mesh data from binary file {:s} ...",
88 INFO(
"[time] Reading the mesh took {:f} s.", timer.
elapsed());
90 MPI_Barrier(
mpi_.communicator);
95template <
typename DATA>
104 ERR(
"The container size is too large for MPI_File_read() call.");
111 char* filename_char =
const_cast<char*
>(filename.data());
112 int const file_status =
113 MPI_File_open(
mpi_.communicator, filename_char, MPI_MODE_RDONLY,
114 MPI_INFO_NULL, &file);
116 if (file_status != 0)
118 ERR(
"Error opening file {:s}. MPI error code {:d}", filename,
124 char file_mode[] =
"native";
125 MPI_File_set_view(file, offset, type, type, file_mode, MPI_INFO_NULL);
127 MPI_File_read(file, data.data(),
static_cast<int>(data.size()), type,
129 MPI_File_close(&file);
135 const std::string& file_name_base)
139 const std::string fname_header = file_name_base +
"_partitioned_msh_";
140 const std::string fname_num_p_ext = std::to_string(
mpi_.size) +
".bin";
145 fname_header +
"cfg" + fname_num_p_ext,
146 static_cast<MPI_Offset
>(
static_cast<unsigned>(
mpi_.rank) *
153 std::vector<NodeData> nodes(
_mesh_info.number_of_nodes);
156 static_cast<MPI_Offset
>(
_mesh_info.offset[2]),
160 std::vector<MeshLib::Node*> mesh_nodes;
161 std::vector<unsigned long> glb_node_ids;
162 setNodes(nodes, mesh_nodes, glb_node_ids);
166 std::vector<unsigned long> elem_data(
_mesh_info.number_of_elements +
169 static_cast<MPI_Offset
>(
_mesh_info.offset[3]),
170 MPI_LONG, elem_data))
173 std::vector<MeshLib::Element*> mesh_elems(
182 "The mesh partition contains {:d} ghost elements. Reading ghost "
183 "elements is deprecated: the current mesh partitioner no longer "
184 "writes them. Please re-run the mesh partitioner to regenerate the "
188 std::vector<unsigned long> ghost_elem_data(
192 static_cast<MPI_Offset
>(
_mesh_info.offset[4]),
193 MPI_LONG, ghost_elem_data))
196 const bool process_ghost =
true;
197 setElements(mesh_nodes, ghost_elem_data, mesh_elems, process_ghost);
204 glb_node_ids, mesh_elems, p);
208 const std::string& file_name_base)
const
223 const std::string fname_cfg = file_name_base +
"_partitioned_" + item_type +
225 std::to_string(
mpi_.size) +
".bin";
226 std::ifstream is(fname_cfg.c_str(), std::ios::binary | std::ios::in);
230 "Could not open file '{:s}'.\n"
231 "\tYou can ignore this warning if the mesh does not contain {:s}-"
232 "wise property data.",
233 fname_cfg, item_type.data());
236 std::size_t number_of_properties = 0;
237 is.read(
reinterpret_cast<char*
>(&number_of_properties),
238 sizeof(std::size_t));
239 std::vector<std::optional<MeshLib::IO::PropertyVectorMetaData>> vec_pvmd(
240 number_of_properties);
241 for (std::size_t i(0); i < number_of_properties; ++i)
247 "Error in NodePartitionedMeshReader::readProperties: "
248 "Could not read the meta data for the PropertyVector {:d}",
252 for (std::size_t i(0); i < number_of_properties; ++i)
256 auto pos = is.tellg();
258 static_cast<long>(pos) +
259 static_cast<long>(
mpi_.rank *
262 std::optional<MeshLib::IO::PropertyVectorPartitionMetaData> pvpmd(
264 bool const all_pvpmd_read_ok =
266 if (!all_pvpmd_read_ok)
269 "Error in NodePartitionedMeshReader::readProperties: "
270 "Could not read the partition meta data for the mpi process {:d}",
273 DBUG(
"offset in the PropertyVector: {:d}", pvpmd->offset);
274 DBUG(
"{:d} tuples in partition.", pvpmd->number_of_tuples);
277 const std::string fname_val = file_name_base +
"_partitioned_" + item_type +
279 std::to_string(
mpi_.size) +
".bin";
280 is.open(fname_val.c_str(), std::ios::binary | std::ios::in);
283 ERR(
"Could not open file '{:s}'\n."
284 "\tYou can ignore this warning if the mesh does not contain {:s}-"
285 "wise property data.",
286 fname_val, item_type.data());
293 std::vector<std::optional<MeshLib::IO::PropertyVectorMetaData>>
const&
300 unsigned long global_offset = 0;
301 std::size_t
const number_of_properties = vec_pvmd.size();
302 for (std::size_t i(0); i < number_of_properties; ++i)
304 DBUG(
"global offset: {:d}, offset within the PropertyVector: {:d}.",
306 global_offset + pvpmd.
offset * vec_pvmd[i]->number_of_components *
307 vec_pvmd[i]->data_type_size_in_bytes);
312 if (vec_pvmd[i]->property_name.find(
"_ip") == std::string::npos &&
318 global_offset += vec_pvmd[i]->data_type_size_in_bytes *
319 vec_pvmd[i]->number_of_tuples;
323 if (vec_pvmd[i]->is_int_type)
325 if (vec_pvmd[i]->is_data_type_signed)
327 if (vec_pvmd[i]->data_type_size_in_bytes ==
sizeof(
char))
332 else if (vec_pvmd[i]->data_type_size_in_bytes ==
sizeof(
int))
337 else if (vec_pvmd[i]->data_type_size_in_bytes ==
sizeof(
long))
343 "Implementation for reading signed integer property "
344 "vector '{:s}' is not available.",
345 vec_pvmd[i]->property_name);
350 if (vec_pvmd[i]->data_type_size_in_bytes ==
351 sizeof(
unsigned char))
354 is, *vec_pvmd[i], pvpmd, t, global_offset, p);
356 else if (vec_pvmd[i]->data_type_size_in_bytes ==
357 sizeof(
unsigned int))
359 is, *vec_pvmd[i], pvpmd, t, global_offset, p);
360 else if (vec_pvmd[i]->data_type_size_in_bytes ==
361 sizeof(
unsigned long))
363 is, *vec_pvmd[i], pvpmd, t, global_offset, p);
367 "Implementation for reading unsigned property vector "
368 "'{:s}' is not available.",
369 vec_pvmd[i]->property_name);
375 if (vec_pvmd[i]->data_type_size_in_bytes ==
sizeof(
float))
378 else if (vec_pvmd[i]->data_type_size_in_bytes ==
sizeof(
double))
384 "Implementation for reading floating point property vector "
385 "'{:s}' is not available.",
386 vec_pvmd[i]->property_name);
389 global_offset += vec_pvmd[i]->data_type_size_in_bytes *
390 vec_pvmd[i]->number_of_tuples *
391 vec_pvmd[i]->number_of_components;
396 std::string
const& mesh_name,
397 std::vector<MeshLib::Node*>
const& mesh_nodes,
398 std::vector<unsigned long>
const& glb_node_ids,
399 std::vector<MeshLib::Element*>
const& mesh_elems,
402 std::vector<std::size_t>
const gathered_n_regular_base_nodes =
405 std::vector<std::size_t> n_regular_base_nodes_at_rank =
408 std::size_t
const n_regular_high_order_nodes =
411 std::vector<std::size_t>
const gathered_n_regular_high_order_nodes =
414 std::vector<std::size_t> n_regular_high_order_nodes_at_rank =
418 mesh_name, mesh_nodes, glb_node_ids, mesh_elems, properties,
421 std::move(n_regular_base_nodes_at_rank),
422 std::move(n_regular_high_order_nodes_at_rank));
426 const std::vector<NodeData>& node_data,
427 std::vector<MeshLib::Node*>& mesh_node,
428 std::vector<unsigned long>& glb_node_ids)
const
431 glb_node_ids.resize(
_mesh_info.number_of_nodes);
433 for (std::size_t i = 0; i < mesh_node.size(); i++)
436 glb_node_ids[i] = nd.
index;
442 const std::vector<MeshLib::Node*>& mesh_nodes,
443 const std::vector<unsigned long>& elem_data,
444 std::vector<MeshLib::Element*>& mesh_elems,
const bool ghost)
const
447 unsigned long const ne = ghost ?
_mesh_info.number_of_ghost_elements
449 unsigned long const id_offset_ghost =
452 for (
unsigned long i = 0; i < ne; i++)
454 unsigned long id_offset_elem = elem_data[i];
458 const unsigned mat_idx =
459 static_cast<unsigned>(elem_data[id_offset_elem++]);
462 const unsigned long e_type = elem_data[id_offset_elem++];
463 unsigned long const nnodes = elem_data[id_offset_elem++];
466 for (
unsigned long k = 0; k < nnodes; k++)
467 elem_nodes[k] = mesh_nodes[elem_data[id_offset_elem++]];
470 switch (
static_cast<CellType>(e_type))
473 mesh_elems[i + id_offset_ghost] =
477 mesh_elems[i + id_offset_ghost] =
new MeshLib::Line(elem_nodes);
480 mesh_elems[i + id_offset_ghost] =
484 mesh_elems[i + id_offset_ghost] =
new MeshLib::Quad(elem_nodes);
487 mesh_elems[i + id_offset_ghost] =
491 mesh_elems[i + id_offset_ghost] =
495 mesh_elems[i + id_offset_ghost] =
new MeshLib::Hex(elem_nodes);
498 mesh_elems[i + id_offset_ghost] =
503 "NodePartitionedMeshReader: construction of HEX27 element "
504 "with id {:d} is not implemented.",
508 mesh_elems[i + id_offset_ghost] =
new MeshLib::Tri(elem_nodes);
511 mesh_elems[i + id_offset_ghost] =
new MeshLib::Tri6(elem_nodes);
514 mesh_elems[i + id_offset_ghost] =
new MeshLib::Tet(elem_nodes);
517 mesh_elems[i + id_offset_ghost] =
521 mesh_elems[i + id_offset_ghost] =
525 mesh_elems[i + id_offset_ghost] =
529 mesh_elems[i + id_offset_ghost] =
533 mesh_elems[i + id_offset_ghost] =
538 "NodePartitionedMeshReader: construction of INVALID "
539 "element type with id {:d} is not possible.",
544 "NodePartitionedMeshReader: construction of element type "
545 "{:d} is not implemented.",
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
bool is_safely_convertable(VALUE const &value)
double elapsed() const
Get the elapsed time in seconds.
void start()
Start the timer.
void createPropertyVectorPart(std::istream &is, MeshLib::IO::PropertyVectorMetaData const &pvmd, MeshLib::IO::PropertyVectorPartitionMetaData const &pvpmd, MeshLib::MeshItemType t, unsigned long global_offset, MeshLib::Properties &p) const
void setElements(const std::vector< MeshLib::Node * > &mesh_nodes, const std::vector< unsigned long > &elem_data, std::vector< MeshLib::Element * > &mesh_elems, const bool ghost=false) const
Set mesh elements from a temporary array containing node data read from file.
bool readDataFromFile(std::string const &filename, MPI_Offset offset, MPI_Datatype type, DATA &data) const
MeshLib::NodePartitionedMesh * readMesh(const std::string &file_name_base)
Create a NodePartitionedMesh object, read binary mesh data in the manner of parallel,...
MeshLib::NodePartitionedMesh * read(const std::string &file_name_base)
Create a NodePartitionedMesh object, read data to it, and return a pointer to it. Data files are in b...
void setNodes(const std::vector< NodeData > &node_data, std::vector< MeshLib::Node * > &mesh_node, std::vector< unsigned long > &glb_node_ids) const
Set mesh nodes from a temporary array containing node data read from file.
NodePartitionedMeshReader(MPI_Comm comm)
void createSpecificPropertyVectorPart(std::istream &is, MeshLib::IO::PropertyVectorMetaData const &pvmd, MeshLib::MeshItemType t, unsigned long global_offset, MeshLib::Properties &p) const
MPI_Datatype _mpi_node_type
MPI data type for struct NodeData.
void registerNodeDataMpiType()
Define MPI data type for NodeData struct.
~NodePartitionedMeshReader()
struct MeshLib::IO::NodePartitionedMeshReader::PartitionedMeshInfo _mesh_info
MeshLib::Properties readProperties(const std::string &file_name_base) const
MeshLib::NodePartitionedMesh * newMesh(std::string const &mesh_name, std::vector< MeshLib::Node * > const &mesh_nodes, std::vector< unsigned long > const &glb_node_ids, std::vector< MeshLib::Element * > const &mesh_elems, MeshLib::Properties const &properties) const
Create a new mesh of NodePartitionedMesh after reading and processing the data.
BaseLib::MPI::Mpi mpi_
Pointer to MPI communicator, the rank and the size.
void readDomainSpecificPartOfPropertyVectors(std::vector< std::optional< MeshLib::IO::PropertyVectorMetaData > > const &vec_pvmd, MeshLib::IO::PropertyVectorPartitionMetaData const &pvpmd, MeshLib::MeshItemType t, std::istream &is, MeshLib::Properties &p) const
Property manager on mesh items. Class Properties manages scalar, vector or matrix properties....
static T allreduce(T const &value, MPI_Op const &mpi_op, Mpi const &mpi)
static std::vector< T > allgather(T const &value, Mpi const &mpi)
bool IsFileExisting(const std::string &strFilename)
Returns true if given file exists.
std::vector< ranges::range_value_t< R > > sizesToOffsets(R const &sizes)
std::string extractBaseName(std::string const &pathname)
void writePropertyVectorMetaData(std::ostream &os, PropertyVectorMetaData const &pvmd)
std::optional< PropertyVectorMetaData > readPropertyVectorMetaData(std::istream &is)
std::optional< PropertyVectorPartitionMetaData > readPropertyVectorPartitionMetaData(std::istream &is)
TemplateElement< MeshLib::QuadRule9 > Quad9
TemplateElement< MeshLib::TetRule10 > Tet10
CellType
Types of mesh elements supported by OpenGeoSys.
TemplateElement< MeshLib::HexRule20 > Hex20
TemplateElement< MeshLib::TetRule4 > Tet
TemplateElement< MeshLib::LineRule2 > Line
TemplateElement< MeshLib::QuadRule8 > Quad8
TemplateElement< MeshLib::PyramidRule13 > Pyramid13
TemplateElement< MeshLib::QuadRule4 > Quad
TemplateElement< MeshLib::TriRule3 > Tri
TemplateElement< MeshLib::PyramidRule5 > Pyramid
TemplateElement< MeshLib::PrismRule6 > Prism
TemplateElement< PointRule1 > Point
TemplateElement< MeshLib::PrismRule15 > Prism15
TemplateElement< MeshLib::TriRule6 > Tri6
static constexpr char const * toString(const MeshItemType t)
Returns a char array for a specific MeshItemType.
TemplateElement< MeshLib::LineRule3 > Line3
TemplateElement< MeshLib::HexRule8 > Hex
struct NodeData used for parallel reading and also partitioning
std::size_t index
Global node index.