31 template <
typename VALUE,
typename TYPE>
34 bool const result = value <= std::numeric_limits<TYPE>::max();
37 ERR(
"The value {:d} is too large for conversion.", value);
38 ERR(
"Maximum available size is {:d}.",
39 std::numeric_limits<TYPE>::max());
65 int blocks[count] = {1, 3};
66 MPI_Datatype types[count] = {MPI_UNSIGNED_LONG, MPI_DOUBLE};
69 MPI_Type_create_struct(count, blocks, displacements, types,
75 const std::string& file_name_base)
83 std::string
const fname_new = file_name_base +
"_partitioned_msh_cfg" +
89 "Required binary file {:s} does not exist.\n"
90 "Reading of ASCII mesh file is not supported since OGS version "
95 INFO(
"Reading corresponding part of mesh data from binary file {:s} ...",
99 INFO(
"[time] Reading the mesh took {:f} s.", timer.
elapsed());
106 template <
typename DATA>
113 if (!is_safely_convertable<std::size_t, int>(data.size()))
115 ERR(
"The container size is too large for MPI_File_read() call.");
122 char* filename_char =
const_cast<char*
>(filename.data());
123 int const file_status = MPI_File_open(
124 _mpi_comm, filename_char, MPI_MODE_RDONLY, MPI_INFO_NULL, &file);
126 if (file_status != 0)
128 ERR(
"Error opening file {:s}. MPI error code {:d}", filename,
134 char file_mode[] =
"native";
135 MPI_File_set_view(file, offset, type, type, file_mode, MPI_INFO_NULL);
137 MPI_File_read(file, data.data(),
static_cast<int>(data.size()), type,
139 MPI_File_close(&file);
145 const std::string& file_name_base)
149 const std::string fname_header = file_name_base +
"_partitioned_msh_";
150 const std::string fname_num_p_ext = std::to_string(
_mpi_comm_size) +
".bin";
153 fname_header +
"cfg" + fname_num_p_ext,
154 static_cast<MPI_Offset
>(
static_cast<unsigned>(
_mpi_rank) *
168 std::vector<MeshLib::Node*> mesh_nodes;
169 std::vector<unsigned long> glb_node_ids;
170 setNodes(nodes, mesh_nodes, glb_node_ids);
178 MPI_LONG, elem_data))
192 MPI_LONG, ghost_elem_data))
195 const bool process_ghost =
true;
196 setElements(mesh_nodes, ghost_elem_data, mesh_elems, process_ghost);
203 glb_node_ids, mesh_elems, p);
207 const std::string& file_name_base)
const
219 std::string
const item_type =
221 const std::string fname_cfg = file_name_base +
"_partitioned_" + item_type +
224 std::ifstream is(fname_cfg.c_str(), std::ios::binary | std::ios::in);
228 "Could not open file '{:s}'.\n"
229 "\tYou can ignore this warning if the mesh does not contain {:s}-"
230 "wise property data.",
231 fname_cfg, item_type.data());
236 sizeof(std::size_t));
237 std::vector<std::optional<MeshLib::IO::PropertyVectorMetaData>> vec_pvmd(
245 "Error in NodePartitionedMeshReader::readProperties: "
246 "Could not read the meta data for the PropertyVector {:d}",
254 auto pos = is.tellg();
256 static_cast<long>(pos) +
260 std::optional<MeshLib::IO::PropertyVectorPartitionMetaData> pvpmd(
262 bool pvpmd_read_ok =
static_cast<bool>(pvpmd);
263 bool all_pvpmd_read_ok;
264 MPI_Allreduce(&pvpmd_read_ok, &all_pvpmd_read_ok, 1, MPI_C_BOOL, MPI_LOR,
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(
"[{:d}] offset in the PropertyVector: {:d}",
_mpi_rank, pvpmd->offset);
275 pvpmd->number_of_tuples);
278 const std::string fname_val = file_name_base +
"_partitioned_" + item_type +
281 is.open(fname_val.c_str(), std::ios::binary | std::ios::in);
284 ERR(
"Could not open file '{:s}'\n."
285 "\tYou can ignore this warning if the mesh does not contain {:s}-"
286 "wise property data.",
287 fname_val, item_type.data());
294 std::vector<std::optional<MeshLib::IO::PropertyVectorMetaData>>
const&
301 unsigned long global_offset = 0;
306 "[{:d}] global offset: {:d}, offset within the PropertyVector: "
309 global_offset + pvpmd.
offset * vec_pvmd[i]->number_of_components *
310 vec_pvmd[i]->data_type_size_in_bytes);
311 if (vec_pvmd[i]->is_int_type)
313 if (vec_pvmd[i]->is_data_type_signed)
315 if (vec_pvmd[i]->data_type_size_in_bytes ==
sizeof(
char))
316 createPropertyVectorPart<char>(is, *vec_pvmd[i], pvpmd, t,
318 else if (vec_pvmd[i]->data_type_size_in_bytes ==
sizeof(
int))
319 createPropertyVectorPart<int>(is, *vec_pvmd[i], pvpmd, t,
321 else if (vec_pvmd[i]->data_type_size_in_bytes ==
sizeof(
long))
322 createPropertyVectorPart<long>(is, *vec_pvmd[i], pvpmd, t,
327 "Implementation for reading signed integer property "
328 "vector '{:s}' is not available.",
329 vec_pvmd[i]->property_name);
334 if (vec_pvmd[i]->data_type_size_in_bytes ==
335 sizeof(
unsigned char))
336 createPropertyVectorPart<unsigned char>(
337 is, *vec_pvmd[i], pvpmd, t, global_offset, p);
338 else if (vec_pvmd[i]->data_type_size_in_bytes ==
339 sizeof(
unsigned int))
340 createPropertyVectorPart<unsigned int>(
341 is, *vec_pvmd[i], pvpmd, t, global_offset, p);
342 else if (vec_pvmd[i]->data_type_size_in_bytes ==
343 sizeof(
unsigned long))
344 createPropertyVectorPart<unsigned long>(
345 is, *vec_pvmd[i], pvpmd, t, global_offset, p);
349 "Implementation for reading unsigned property vector "
350 "'{:s}' is not available.",
351 vec_pvmd[i]->property_name);
357 if (vec_pvmd[i]->data_type_size_in_bytes ==
sizeof(
float))
358 createPropertyVectorPart<float>(is, *vec_pvmd[i], pvpmd, t,
360 else if (vec_pvmd[i]->data_type_size_in_bytes ==
sizeof(
double))
361 createPropertyVectorPart<double>(is, *vec_pvmd[i], pvpmd, t,
366 "Implementation for reading floating point property vector "
367 "'{:s}' is not available.",
368 vec_pvmd[i]->property_name);
371 global_offset += vec_pvmd[i]->data_type_size_in_bytes *
372 vec_pvmd[i]->number_of_tuples *
373 vec_pvmd[i]->number_of_components;
378 std::string
const& mesh_name,
379 std::vector<MeshLib::Node*>
const& mesh_nodes,
380 std::vector<unsigned long>
const& glb_node_ids,
381 std::vector<MeshLib::Element*>
const& mesh_elems,
385 mesh_name, mesh_nodes, glb_node_ids, mesh_elems, properties,
391 const std::vector<NodeData>& node_data,
392 std::vector<MeshLib::Node*>& mesh_node,
393 std::vector<unsigned long>& glb_node_ids)
const
398 for (std::size_t i = 0; i < mesh_node.size(); i++)
401 glb_node_ids[i] = nd.
index;
407 const std::vector<MeshLib::Node*>& mesh_nodes,
408 const std::vector<unsigned long>& elem_data,
409 std::vector<MeshLib::Element*>& mesh_elems,
const bool ghost)
const
412 unsigned long const ne =
414 unsigned long const id_offset_ghost =
417 for (
unsigned long i = 0; i < ne; i++)
419 unsigned long id_offset_elem = elem_data[i];
423 const unsigned mat_idx =
424 static_cast<unsigned>(elem_data[id_offset_elem++]);
427 const unsigned long e_type = elem_data[id_offset_elem++];
428 unsigned long const nnodes = elem_data[id_offset_elem++];
431 for (
unsigned long k = 0; k < nnodes; k++)
432 elem_nodes[k] = mesh_nodes[elem_data[id_offset_elem++]];
435 switch (
static_cast<CellType>(e_type))
438 mesh_elems[i + id_offset_ghost] =
442 mesh_elems[i + id_offset_ghost] =
new MeshLib::Line(elem_nodes);
445 mesh_elems[i + id_offset_ghost] =
449 mesh_elems[i + id_offset_ghost] =
new MeshLib::Quad(elem_nodes);
452 mesh_elems[i + id_offset_ghost] =
456 mesh_elems[i + id_offset_ghost] =
460 mesh_elems[i + id_offset_ghost] =
new MeshLib::Hex(elem_nodes);
463 mesh_elems[i + id_offset_ghost] =
468 "NodePartitionedMeshReader: construction of HEX27 element "
469 "with id {:d} is not implemented.",
473 mesh_elems[i + id_offset_ghost] =
new MeshLib::Tri(elem_nodes);
476 mesh_elems[i + id_offset_ghost] =
new MeshLib::Tri6(elem_nodes);
479 mesh_elems[i + id_offset_ghost] =
new MeshLib::Tet(elem_nodes);
482 mesh_elems[i + id_offset_ghost] =
486 mesh_elems[i + id_offset_ghost] =
490 mesh_elems[i + id_offset_ghost] =
494 mesh_elems[i + id_offset_ghost] =
498 mesh_elems[i + id_offset_ghost] =
503 "NodePartitionedMeshReader: construction of INVALID "
504 "element type with id {:d} is not possible.",
509 "NodePartitionedMeshReader: construction of element type "
510 "{:d} is not implemented.",
void INFO(char const *fmt, Args const &... args)
void ERR(char const *fmt, Args const &... args)
void DBUG(char const *fmt, Args const &... args)
void WARN(char const *fmt, Args const &... args)
Definition of mesh-related Enumerations.
Definition of the class Properties that implements a container of properties.
bool is_safely_convertable(VALUE const &value)
Declare a class to read node-wise partitioned mesh with MPI functions.
Definition of the RunTime class.
double elapsed() const
Get the elapsed time in seconds.
void start()
Start the timer.
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
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
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.
int _mpi_comm_size
Number of processes in the communicator: _mpi_comm.
NodePartitionedMeshReader(MPI_Comm comm)
MPI_Comm _mpi_comm
Pointer to MPI communicator.
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
int _mpi_rank
Rank of compute core.
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.
Property manager on mesh items. Class Properties manages scalar, vector or matrix properties....
bool IsFileExisting(const std::string &strFilename)
Returns true if given file exists.
std::string extractBaseName(std::string const &pathname)
std::optional< PropertyVectorPartitionMetaData > readPropertyVectorPartitionMetaData(std::istream &is)
void writePropertyVectorMetaData(std::ostream &os, PropertyVectorMetaData const &pvmd)
std::optional< PropertyVectorMetaData > readPropertyVectorMetaData(std::istream &is)
TemplateElement< MeshLib::PyramidRule13 > Pyramid13
CellType
Types of mesh elements supported by OpenGeoSys.
TemplateElement< MeshLib::QuadRule8 > Quad8
TemplateElement< MeshLib::TetRule4 > Tet
TemplateElement< MeshLib::LineRule2 > Line
TemplateElement< MeshLib::LineRule3 > Line3
TemplateElement< MeshLib::TriRule3 > Tri
TemplateElement< MeshLib::QuadRule9 > Quad9
TemplateElement< MeshLib::PrismRule6 > Prism
TemplateElement< MeshLib::PyramidRule5 > Pyramid
TemplateElement< PointRule1 > Point
TemplateElement< MeshLib::HexRule20 > Hex20
TemplateElement< MeshLib::TriRule6 > Tri6
TemplateElement< MeshLib::TetRule10 > Tet10
TemplateElement< MeshLib::PrismRule15 > Prism15
TemplateElement< MeshLib::HexRule8 > Hex
TemplateElement< MeshLib::QuadRule4 > Quad
Node data only for parallel reading.
std::size_t index
Global node index.
unsigned long active_base_nodes
unsigned long regular_elements
unsigned long active_nodes
5: Number of all active nodes a partition,
unsigned long ghost_elements
3: Number of ghost element of a partition,
unsigned long nodes
0: Number of all nodes of a partition,
unsigned long global_nodes
7: Number of all nodes of global mesh,