OGS
MeshLib::IO::NodePartitionedMeshReader Class Referencefinal

Detailed Description

Class for parallel reading of binary partitioned mesh files into a NodePartitionedMesh via MPI.

Definition at line 28 of file NodePartitionedMeshReader.h.

#include <NodePartitionedMeshReader.h>

Collaboration diagram for MeshLib::IO::NodePartitionedMeshReader:
[legend]

Classes

struct  PartitionedMeshInfo
 A collection of integers that configure the partitioned mesh data. More...

Public Member Functions

 NodePartitionedMeshReader (MPI_Comm comm)
 ~NodePartitionedMeshReader ()
MeshLib::NodePartitionedMeshread (const std::string &file_name_base)
 Create a NodePartitionedMesh object, read data to it, and return a pointer to it. Data files are in binary format.

Private Member Functions

void registerNodeDataMpiType ()
 Define MPI data type for NodeData struct.
MeshLib::NodePartitionedMeshnewMesh (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.
template<typename DATA>
bool readDataFromFile (std::string const &filename, MPI_Offset offset, MPI_Datatype type, DATA &data) const
MeshLib::NodePartitionedMeshreadMesh (const std::string &file_name_base)
 Create a NodePartitionedMesh object, read binary mesh data in the manner of parallel, and return a pointer to it. Four binary files have to been read in this function named as:
MeshLib::Properties readProperties (const std::string &file_name_base) const
void readProperties (const std::string &file_name_base, MeshLib::MeshItemType t, MeshLib::Properties &p) 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
template<typename T>
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
template<typename T>
void createSpecificPropertyVectorPart (std::istream &is, MeshLib::IO::PropertyVectorMetaData const &pvmd, MeshLib::MeshItemType t, unsigned long global_offset, MeshLib::Properties &p) const
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.
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.

Private Attributes

BaseLib::MPI::Mpi mpi_
 Pointer to MPI communicator, the rank and the size.
MPI_Datatype _mpi_node_type
 MPI data type for struct NodeData.
struct MeshLib::IO::NodePartitionedMeshReader::PartitionedMeshInfo _mesh_info

Constructor & Destructor Documentation

◆ NodePartitionedMeshReader()

MeshLib::IO::NodePartitionedMeshReader::NodePartitionedMeshReader ( MPI_Comm comm)
explicit
Parameters
commMPI communicator.

Definition at line 37 of file NodePartitionedMeshReader.cpp.

37 : mpi_(comm)
38{
40}
void registerNodeDataMpiType()
Define MPI data type for NodeData struct.
BaseLib::MPI::Mpi mpi_
Pointer to MPI communicator, the rank and the size.

References mpi_, and registerNodeDataMpiType().

◆ ~NodePartitionedMeshReader()

MeshLib::IO::NodePartitionedMeshReader::~NodePartitionedMeshReader ( )

Definition at line 42 of file NodePartitionedMeshReader.cpp.

43{
44 MPI_Type_free(&_mpi_node_type);
45}
MPI_Datatype _mpi_node_type
MPI data type for struct NodeData.

References _mpi_node_type.

Member Function Documentation

◆ createPropertyVectorPart()

template<typename T>
void MeshLib::IO::NodePartitionedMeshReader::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
inlineprivate

Definition at line 173 of file NodePartitionedMeshReader.h.

178 {
179 MeshLib::PropertyVector<T>* pv = p.createNewPropertyVector<T>(
180 pvmd.property_name, t, pvmd.number_of_components);
181 pv->resize(pvpmd.number_of_tuples * pvmd.number_of_components);
182
183 // Locate the start position of the data in the file for the current
184 // rank.
185 is.seekg(global_offset +
186 pvpmd.offset * pvmd.number_of_components * sizeof(T));
187 // read the values
188 if (!is.read(reinterpret_cast<char*>(pv->data()),
189 pv->size() * sizeof(T)))
190 OGS_FATAL(
191 "Error in NodePartitionedMeshReader::readProperties: "
192 "Could not read part {:d} of the PropertyVector.",
193 mpi_.rank);
194 }
#define OGS_FATAL(...)
Definition Error.h:19
PropertyVector< T > * createNewPropertyVector(std::string_view name, MeshItemType mesh_item_type, std::size_t n_components=1)
constexpr void resize(std::size_t const size)
constexpr std::size_t size() const
constexpr const PROP_VAL_TYPE * data() const

References MeshLib::Properties::createNewPropertyVector(), MeshLib::PropertyVector< PROP_VAL_TYPE >::data(), mpi_, MeshLib::IO::PropertyVectorMetaData::number_of_components, MeshLib::IO::PropertyVectorPartitionMetaData::number_of_tuples, MeshLib::IO::PropertyVectorPartitionMetaData::offset, OGS_FATAL, MeshLib::IO::PropertyVectorMetaData::property_name, MeshLib::PropertyVector< PROP_VAL_TYPE >::resize(), and MeshLib::PropertyVector< PROP_VAL_TYPE >::size().

Referenced by readDomainSpecificPartOfPropertyVectors().

◆ createSpecificPropertyVectorPart()

template<typename T>
void MeshLib::IO::NodePartitionedMeshReader::createSpecificPropertyVectorPart ( std::istream & is,
MeshLib::IO::PropertyVectorMetaData const & pvmd,
MeshLib::MeshItemType t,
unsigned long global_offset,
MeshLib::Properties & p ) const
inlineprivate

Read data for property OGS_VERSION or IntegrationPointMetaData, and create property vector for it.

Definition at line 199 of file NodePartitionedMeshReader.h.

203 {
204 MeshLib::PropertyVector<T>* pv = p.createNewPropertyVector<T>(
205 pvmd.property_name, t, pvmd.number_of_components);
206
207 std::size_t const property_vector_size =
208 pvmd.number_of_tuples / mpi_.size;
209 pv->resize(property_vector_size);
210
211 // Locate the start position of the data in the file for the current
212 // rank.
213 is.seekg(global_offset + property_vector_size * sizeof(T) * mpi_.rank);
214
215 // read the values
216 if (!is.read(reinterpret_cast<char*>(pv->data()),
217 pv->size() * sizeof(T)))
218 {
219 OGS_FATAL(
220 "Error in NodePartitionedMeshReader::readProperties: "
221 "Could not read part {:d} of the PropertyVector.",
222 mpi_.rank);
223 }
224 }

References MeshLib::Properties::createNewPropertyVector(), MeshLib::PropertyVector< PROP_VAL_TYPE >::data(), mpi_, MeshLib::IO::PropertyVectorMetaData::number_of_components, MeshLib::IO::PropertyVectorMetaData::number_of_tuples, OGS_FATAL, MeshLib::IO::PropertyVectorMetaData::property_name, MeshLib::PropertyVector< PROP_VAL_TYPE >::resize(), and MeshLib::PropertyVector< PROP_VAL_TYPE >::size().

Referenced by readDomainSpecificPartOfPropertyVectors().

◆ newMesh()

MeshLib::NodePartitionedMesh * MeshLib::IO::NodePartitionedMeshReader::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
private

Create a new mesh of NodePartitionedMesh after reading and processing the data.

Parameters
mesh_nameName assigned to the new mesh.
mesh_nodesNode data.
glb_node_idsGlobal IDs of nodes.
mesh_elemsElement data.
propertiesCollection of PropertyVector's assigned to the mesh.
Returns
Returns a pointer to a NodePartitionedMesh

Definition at line 387 of file NodePartitionedMeshReader.cpp.

393{
394 std::vector<std::size_t> const gathered_n_regular_base_nodes =
395 BaseLib::MPI::allgather(_mesh_info.number_of_regular_base_nodes, mpi_);
396
397 std::vector<std::size_t> n_regular_base_nodes_at_rank =
398 BaseLib::sizesToOffsets(gathered_n_regular_base_nodes);
399
400 std::size_t const n_regular_high_order_nodes =
401 _mesh_info.number_of_regular_nodes -
402 _mesh_info.number_of_regular_base_nodes;
403 std::vector<std::size_t> const gathered_n_regular_high_order_nodes =
404 BaseLib::MPI::allgather(n_regular_high_order_nodes, mpi_);
405
406 std::vector<std::size_t> n_regular_high_order_nodes_at_rank =
407 BaseLib::sizesToOffsets(gathered_n_regular_high_order_nodes);
408
409 return new MeshLib::NodePartitionedMesh(
410 mesh_name, mesh_nodes, glb_node_ids, mesh_elems, properties,
411 _mesh_info.number_of_global_base_nodes,
412 _mesh_info.number_of_global_nodes, _mesh_info.number_of_regular_nodes,
413 std::move(n_regular_base_nodes_at_rank),
414 std::move(n_regular_high_order_nodes_at_rank));
415}
struct MeshLib::IO::NodePartitionedMeshReader::PartitionedMeshInfo _mesh_info
static std::vector< T > allgather(T const &value, Mpi const &mpi)
Definition MPI.h:98
std::vector< ranges::range_value_t< R > > sizesToOffsets(R const &sizes)
Definition Algorithm.h:276

References _mesh_info, BaseLib::MPI::allgather(), mpi_, and BaseLib::sizesToOffsets().

Referenced by readMesh().

◆ read()

MeshLib::NodePartitionedMesh * MeshLib::IO::NodePartitionedMeshReader::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 binary format.

Parameters
file_name_baseName of file to be read, and it must be base name without name extension.
Returns
Pointer to Mesh object. If the creation of mesh object fails, it returns a null pointer.

Definition at line 59 of file NodePartitionedMeshReader.cpp.

61{
62 BaseLib::RunTime timer;
63 timer.start();
64
65 // Always try binary file first
66 std::string const fname_new = file_name_base + "_partitioned_msh_cfg" +
67 std::to_string(mpi_.size) + ".bin";
68
69 if (!BaseLib::IsFileExisting(fname_new)) // binary file does not exist.
70 {
71 std::string const fname_ascii = file_name_base +
72 "_partitioned_msh_cfg" +
73 std::to_string(mpi_.size) + ".msh";
74 if (BaseLib::IsFileExisting(fname_ascii))
75 {
76 ERR("Reading of ASCII mesh file {:s} is not supported since OGS "
77 "version 6.3.3.",
78 fname_ascii);
79 }
80 OGS_FATAL("Required binary file {:s} does not exist.\n", fname_new);
81 }
82
83 INFO("Reading corresponding part of mesh data from binary file {:s} ...",
84 file_name_base);
85
86 MeshLib::NodePartitionedMesh* mesh = readMesh(file_name_base);
87
88 INFO("[time] Reading the mesh took {:f} s.", timer.elapsed());
89
90 MPI_Barrier(mpi_.communicator);
91
92 return mesh;
93}
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:28
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
double elapsed() const
Get the elapsed time in seconds.
Definition RunTime.h:31
void start()
Start the timer.
Definition RunTime.h:21
MeshLib::NodePartitionedMesh * readMesh(const std::string &file_name_base)
Create a NodePartitionedMesh object, read binary mesh data in the manner of parallel,...
bool IsFileExisting(const std::string &strFilename)
Returns true if given file exists.
Definition FileTools.cpp:23

References BaseLib::RunTime::elapsed(), ERR(), INFO(), BaseLib::IsFileExisting(), mpi_, OGS_FATAL, readMesh(), and BaseLib::RunTime::start().

Referenced by MeshLib::IO::readMeshFromFile().

◆ readDataFromFile()

template<typename DATA>
bool MeshLib::IO::NodePartitionedMeshReader::readDataFromFile ( std::string const & filename,
MPI_Offset offset,
MPI_Datatype type,
DATA & data ) const
private

Parallel reading of a binary file via MPI_File_read, reading mesh data head, nodes, non-ghost elements and ghost elements.

Note
In case of failure during opening of the file, an error message is printed.
If the number of elements in container is larger than MPI_file_read() supports (maximum of current int type), an error is printed.
Parameters
filenameFile name containing data.
offsetDisplacement of the data accessible from the view. see MPI_File_set_view() documentation.
typeType of data.
dataA container to be filled with data. Its size is used to determine how many values should be read.
Template Parameters
DATAA homogeneous container type supporting data() and size().
Returns
True on success and false otherwise.

Definition at line 96 of file NodePartitionedMeshReader.cpp.

100{
101 // Check container size
103 {
104 ERR("The container size is too large for MPI_File_read() call.");
105 return false;
106 }
107
108 // Open file
109 MPI_File file;
110
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);
115
116 if (file_status != 0)
117 {
118 ERR("Error opening file {:s}. MPI error code {:d}", filename,
119 file_status);
120 return false;
121 }
122
123 // Read data
124 char file_mode[] = "native";
125 MPI_File_set_view(file, offset, type, type, file_mode, MPI_INFO_NULL);
126 // The static cast is checked above.
127 MPI_File_read(file, data.data(), static_cast<int>(data.size()), type,
128 MPI_STATUS_IGNORE);
129 MPI_File_close(&file);
130
131 return true;
132}
bool is_safely_convertable(VALUE const &value)

References ERR(), is_safely_convertable(), and mpi_.

Referenced by readMesh().

◆ readDomainSpecificPartOfPropertyVectors()

void MeshLib::IO::NodePartitionedMeshReader::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
private

Definition at line 284 of file NodePartitionedMeshReader.cpp.

291{
292 unsigned long global_offset = 0;
293 std::size_t const number_of_properties = vec_pvmd.size();
294 for (std::size_t i(0); i < number_of_properties; ++i)
295 {
296 DBUG("global offset: {:d}, offset within the PropertyVector: {:d}.",
297 global_offset,
298 global_offset + pvpmd.offset * vec_pvmd[i]->number_of_components *
299 vec_pvmd[i]->data_type_size_in_bytes);
300
301 // Special field data such as OGS_VERSION, IntegrationPointMetaData,
302 // etc., which are not "real" integration points, are copied "as is"
303 // (i.e. fully) for every partition.
304 if (vec_pvmd[i]->property_name.find("_ip") == std::string::npos &&
306 {
307 createSpecificPropertyVectorPart<char>(is, *vec_pvmd[i], t,
308 global_offset, p);
309
310 global_offset += vec_pvmd[i]->data_type_size_in_bytes *
311 vec_pvmd[i]->number_of_tuples;
312 continue;
313 }
314
315 if (vec_pvmd[i]->is_int_type)
316 {
317 if (vec_pvmd[i]->is_data_type_signed)
318 {
319 if (vec_pvmd[i]->data_type_size_in_bytes == sizeof(char))
320 {
321 createPropertyVectorPart<char>(is, *vec_pvmd[i], pvpmd, t,
322 global_offset, p);
323 }
324 else if (vec_pvmd[i]->data_type_size_in_bytes == sizeof(int))
325 {
326 createPropertyVectorPart<int>(is, *vec_pvmd[i], pvpmd, t,
327 global_offset, p);
328 }
329 else if (vec_pvmd[i]->data_type_size_in_bytes == sizeof(long))
330 createPropertyVectorPart<long>(is, *vec_pvmd[i], pvpmd, t,
331 global_offset, p);
332 else
333 {
334 WARN(
335 "Implementation for reading signed integer property "
336 "vector '{:s}' is not available.",
337 vec_pvmd[i]->property_name);
338 }
339 }
340 else
341 {
342 if (vec_pvmd[i]->data_type_size_in_bytes ==
343 sizeof(unsigned char))
344 {
346 is, *vec_pvmd[i], pvpmd, t, global_offset, p);
347 }
348 else if (vec_pvmd[i]->data_type_size_in_bytes ==
349 sizeof(unsigned int))
351 is, *vec_pvmd[i], pvpmd, t, global_offset, p);
352 else if (vec_pvmd[i]->data_type_size_in_bytes ==
353 sizeof(unsigned long))
355 is, *vec_pvmd[i], pvpmd, t, global_offset, p);
356 else
357 {
358 WARN(
359 "Implementation for reading unsigned property vector "
360 "'{:s}' is not available.",
361 vec_pvmd[i]->property_name);
362 }
363 }
364 }
365 else
366 {
367 if (vec_pvmd[i]->data_type_size_in_bytes == sizeof(float))
368 createPropertyVectorPart<float>(is, *vec_pvmd[i], pvpmd, t,
369 global_offset, p);
370 else if (vec_pvmd[i]->data_type_size_in_bytes == sizeof(double))
371 createPropertyVectorPart<double>(is, *vec_pvmd[i], pvpmd, t,
372 global_offset, p);
373 else
374 {
375 WARN(
376 "Implementation for reading floating point property vector "
377 "'{:s}' is not available.",
378 vec_pvmd[i]->property_name);
379 }
380 }
381 global_offset += vec_pvmd[i]->data_type_size_in_bytes *
382 vec_pvmd[i]->number_of_tuples *
383 vec_pvmd[i]->number_of_components;
384 }
385}
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:22
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:34
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 createSpecificPropertyVectorPart(std::istream &is, MeshLib::IO::PropertyVectorMetaData const &pvmd, MeshLib::MeshItemType t, unsigned long global_offset, MeshLib::Properties &p) const

References createPropertyVectorPart(), createSpecificPropertyVectorPart(), DBUG(), MeshLib::IntegrationPoint, MeshLib::IO::PropertyVectorPartitionMetaData::offset, and WARN().

Referenced by readProperties().

◆ readMesh()

MeshLib::NodePartitionedMesh * MeshLib::IO::NodePartitionedMeshReader::readMesh ( const std::string & file_name_base)
private

Create a NodePartitionedMesh object, read binary mesh data in the manner of parallel, and return a pointer to it. Four binary files have to been read in this function named as:

  • file_name_base+_partitioned_msh_cfg[number of partitions].bin
  • file_name_base+_partitioned_msh_nod[number of partitions].bin
  • file_name_base+_partitioned_msh_ele[number of partitions].bin
  • file_name_base+_partitioned_msh_ele_g[number of partitions].bin

in which, the first file contains an array of integers for the PartitionMeshInfo for all partitions, the second file contains a struct type (long, double double double) array of nodes information of global IDs and coordinates of all partitions, the third file contains a long type integer array of element information of material ID, element type and node IDs of each non-ghost element of all partitions, and the forth file contains a long type integer array of element information of material ID, element type and node IDs of each ghost element of all partitions.

Parameters
file_name_baseName of file to be read, which must be a name with the path to the file and without file extension.
Returns
Pointer to Mesh object.

Definition at line 134 of file NodePartitionedMeshReader.cpp.

136{
137 //----------------------------------------------------------------------------------
138 // Read headers
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";
141
142 // Read the config meta data from *cfg* file into struct PartitionedMeshInfo
143 // _mesh_info
144 if (!readDataFromFile(
145 fname_header + "cfg" + fname_num_p_ext,
146 static_cast<MPI_Offset>(static_cast<unsigned>(mpi_.rank) *
147 sizeof(_mesh_info)),
148 MPI_LONG, _mesh_info))
149 return nullptr;
150
151 //----------------------------------------------------------------------------------
152 // Read Nodes
153 std::vector<NodeData> nodes(_mesh_info.number_of_nodes);
154
155 if (!readDataFromFile(fname_header + "nod" + fname_num_p_ext,
156 static_cast<MPI_Offset>(_mesh_info.offset[2]),
157 _mpi_node_type, nodes))
158 return nullptr;
159
160 std::vector<MeshLib::Node*> mesh_nodes;
161 std::vector<unsigned long> glb_node_ids;
162 setNodes(nodes, mesh_nodes, glb_node_ids);
163
164 //----------------------------------------------------------------------------------
165 // Read non-ghost elements
166 std::vector<unsigned long> elem_data(_mesh_info.number_of_regular_elements +
167 _mesh_info.offset[0]);
168 if (!readDataFromFile(fname_header + "ele" + fname_num_p_ext,
169 static_cast<MPI_Offset>(_mesh_info.offset[3]),
170 MPI_LONG, elem_data))
171 return nullptr;
172
173 std::vector<MeshLib::Element*> mesh_elems(
174 _mesh_info.number_of_regular_elements +
175 _mesh_info.number_of_ghost_elements);
176 setElements(mesh_nodes, elem_data, mesh_elems);
177
178 //----------------------------------------------------------------------------------
179 // Read ghost element
180 std::vector<unsigned long> ghost_elem_data(
181 _mesh_info.number_of_ghost_elements + _mesh_info.offset[1]);
182
183 if (!readDataFromFile(fname_header + "ele_g" + fname_num_p_ext,
184 static_cast<MPI_Offset>(_mesh_info.offset[4]),
185 MPI_LONG, ghost_elem_data))
186 return nullptr;
187
188 const bool process_ghost = true;
189 setElements(mesh_nodes, ghost_elem_data, mesh_elems, process_ghost);
190
191 //----------------------------------------------------------------------------------
192 // read the properties
193 MeshLib::Properties p(readProperties(file_name_base));
194
195 return newMesh(BaseLib::extractBaseName(file_name_base), mesh_nodes,
196 glb_node_ids, mesh_elems, p);
197}
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 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.
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.
std::string extractBaseName(std::string const &pathname)

References _mesh_info, _mpi_node_type, BaseLib::extractBaseName(), mpi_, newMesh(), readDataFromFile(), readProperties(), setElements(), and setNodes().

Referenced by read().

◆ readProperties() [1/2]

MeshLib::Properties MeshLib::IO::NodePartitionedMeshReader::readProperties ( const std::string & file_name_base) const
private

Definition at line 199 of file NodePartitionedMeshReader.cpp.

201{
202 MeshLib::Properties p;
206 return p;
207}

References MeshLib::Cell, MeshLib::IntegrationPoint, MeshLib::Node, and readProperties().

Referenced by readMesh(), and readProperties().

◆ readProperties() [2/2]

void MeshLib::IO::NodePartitionedMeshReader::readProperties ( const std::string & file_name_base,
MeshLib::MeshItemType t,
MeshLib::Properties & p ) const
private

Definition at line 209 of file NodePartitionedMeshReader.cpp.

212{
213 const std::string item_type = MeshLib::toString(t);
214
215 const std::string fname_cfg = file_name_base + "_partitioned_" + item_type +
216 "_properties_cfg" +
217 std::to_string(mpi_.size) + ".bin";
218 std::ifstream is(fname_cfg.c_str(), std::ios::binary | std::ios::in);
219 if (!is)
220 {
221 WARN(
222 "Could not open file '{:s}'.\n"
223 "\tYou can ignore this warning if the mesh does not contain {:s}-"
224 "wise property data.",
225 fname_cfg, item_type.data());
226 return;
227 }
228 std::size_t number_of_properties = 0;
229 is.read(reinterpret_cast<char*>(&number_of_properties),
230 sizeof(std::size_t));
231 std::vector<std::optional<MeshLib::IO::PropertyVectorMetaData>> vec_pvmd(
232 number_of_properties);
233 for (std::size_t i(0); i < number_of_properties; ++i)
234 {
236 if (!vec_pvmd[i])
237 {
238 OGS_FATAL(
239 "Error in NodePartitionedMeshReader::readProperties: "
240 "Could not read the meta data for the PropertyVector {:d}",
241 i);
242 }
243 }
244 for (std::size_t i(0); i < number_of_properties; ++i)
245 {
247 }
248 auto pos = is.tellg();
249 auto offset =
250 static_cast<long>(pos) +
251 static_cast<long>(mpi_.rank *
252 sizeof(MeshLib::IO::PropertyVectorPartitionMetaData));
253 is.seekg(offset);
254 std::optional<MeshLib::IO::PropertyVectorPartitionMetaData> pvpmd(
256 bool const all_pvpmd_read_ok =
257 BaseLib::MPI::allreduce(static_cast<bool>(pvpmd), MPI_LOR, mpi_);
258 if (!all_pvpmd_read_ok)
259 {
260 OGS_FATAL(
261 "Error in NodePartitionedMeshReader::readProperties: "
262 "Could not read the partition meta data for the mpi process {:d}",
263 mpi_.rank);
264 }
265 DBUG("offset in the PropertyVector: {:d}", pvpmd->offset);
266 DBUG("{:d} tuples in partition.", pvpmd->number_of_tuples);
267 is.close();
268
269 const std::string fname_val = file_name_base + "_partitioned_" + item_type +
270 "_properties_val" +
271 std::to_string(mpi_.size) + ".bin";
272 is.open(fname_val.c_str(), std::ios::binary | std::ios::in);
273 if (!is)
274 {
275 ERR("Could not open file '{:s}'\n."
276 "\tYou can ignore this warning if the mesh does not contain {:s}-"
277 "wise property data.",
278 fname_val, item_type.data());
279 }
280
281 readDomainSpecificPartOfPropertyVectors(vec_pvmd, *pvpmd, t, is, p);
282}
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
static T allreduce(T const &value, MPI_Op const &mpi_op, Mpi const &mpi)
Definition MPI.h:122
void writePropertyVectorMetaData(std::ostream &os, PropertyVectorMetaData const &pvmd)
std::optional< PropertyVectorMetaData > readPropertyVectorMetaData(std::istream &is)
std::optional< PropertyVectorPartitionMetaData > readPropertyVectorPartitionMetaData(std::istream &is)
static constexpr char const * toString(const MeshItemType t)
Returns a char array for a specific MeshItemType.
Definition MeshEnums.h:25

References BaseLib::MPI::allreduce(), DBUG(), ERR(), mpi_, OGS_FATAL, readDomainSpecificPartOfPropertyVectors(), MeshLib::IO::readPropertyVectorMetaData(), MeshLib::IO::readPropertyVectorPartitionMetaData(), MeshLib::toString(), WARN(), and MeshLib::IO::writePropertyVectorMetaData().

◆ registerNodeDataMpiType()

void MeshLib::IO::NodePartitionedMeshReader::registerNodeDataMpiType ( )
private

Define MPI data type for NodeData struct.

Definition at line 47 of file NodePartitionedMeshReader.cpp.

48{
49 int const count = 2;
50 int blocks[count] = {1, 3};
51 MPI_Datatype types[count] = {MPI_UNSIGNED_LONG, MPI_DOUBLE};
52 MPI_Aint displacements[count] = {0, sizeof(NodeData::index)};
53
54 MPI_Type_create_struct(count, blocks, displacements, types,
56 MPI_Type_commit(&_mpi_node_type);
57}
std::size_t index
Global node index.
Definition NodeData.h:20

References _mpi_node_type, and MeshLib::IO::NodeData::index.

Referenced by NodePartitionedMeshReader().

◆ setElements()

void MeshLib::IO::NodePartitionedMeshReader::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
private

Set mesh elements from a temporary array containing node data read from file.

Parameters
mesh_nodesVector of mesh nodes used to set element nodes.
elem_dataVector containing element data read from file.
mesh_elemsVector of mesh elements to be set.
ghostFlag of processing ghost elements.

Definition at line 433 of file NodePartitionedMeshReader.cpp.

437{
438 // Number of elements, either ghost or regular
439 unsigned long const ne = ghost ? _mesh_info.number_of_ghost_elements
440 : _mesh_info.number_of_regular_elements;
441 unsigned long const id_offset_ghost =
442 ghost ? _mesh_info.number_of_regular_elements : 0;
443
444 for (unsigned long i = 0; i < ne; i++)
445 {
446 unsigned long id_offset_elem = elem_data[i];
447
448 // Unused for now, keep for elem_data documentation purpose here.
449 {
450 const unsigned mat_idx =
451 static_cast<unsigned>(elem_data[id_offset_elem++]);
452 (void)mat_idx;
453 }
454 const unsigned long e_type = elem_data[id_offset_elem++];
455 unsigned long const nnodes = elem_data[id_offset_elem++];
456
457 MeshLib::Node** elem_nodes = new MeshLib::Node*[nnodes];
458 for (unsigned long k = 0; k < nnodes; k++)
459 elem_nodes[k] = mesh_nodes[elem_data[id_offset_elem++]];
460
461 // The element types below are defined by the MeshLib::CellType.
462 switch (static_cast<CellType>(e_type))
463 {
464 case CellType::POINT1:
465 mesh_elems[i + id_offset_ghost] =
466 new MeshLib::Point(elem_nodes);
467 break;
468 case CellType::LINE2:
469 mesh_elems[i + id_offset_ghost] = new MeshLib::Line(elem_nodes);
470 break;
471 case CellType::LINE3:
472 mesh_elems[i + id_offset_ghost] =
473 new MeshLib::Line3(elem_nodes);
474 break;
475 case CellType::QUAD4:
476 mesh_elems[i + id_offset_ghost] = new MeshLib::Quad(elem_nodes);
477 break;
478 case CellType::QUAD8:
479 mesh_elems[i + id_offset_ghost] =
480 new MeshLib::Quad8(elem_nodes);
481 break;
482 case CellType::QUAD9:
483 mesh_elems[i + id_offset_ghost] =
484 new MeshLib::Quad9(elem_nodes);
485 break;
486 case CellType::HEX8:
487 mesh_elems[i + id_offset_ghost] = new MeshLib::Hex(elem_nodes);
488 break;
489 case CellType::HEX20:
490 mesh_elems[i + id_offset_ghost] =
491 new MeshLib::Hex20(elem_nodes);
492 break;
493 case CellType::HEX27:
494 OGS_FATAL(
495 "NodePartitionedMeshReader: construction of HEX27 element "
496 "with id {:d} is not implemented.",
497 i);
498 break;
499 case CellType::TRI3:
500 mesh_elems[i + id_offset_ghost] = new MeshLib::Tri(elem_nodes);
501 break;
502 case CellType::TRI6:
503 mesh_elems[i + id_offset_ghost] = new MeshLib::Tri6(elem_nodes);
504 break;
505 case CellType::TET4:
506 mesh_elems[i + id_offset_ghost] = new MeshLib::Tet(elem_nodes);
507 break;
508 case CellType::TET10:
509 mesh_elems[i + id_offset_ghost] =
510 new MeshLib::Tet10(elem_nodes);
511 break;
512 case CellType::PRISM6:
513 mesh_elems[i + id_offset_ghost] =
514 new MeshLib::Prism(elem_nodes);
515 break;
517 mesh_elems[i + id_offset_ghost] =
518 new MeshLib::Prism15(elem_nodes);
519 break;
521 mesh_elems[i + id_offset_ghost] =
522 new MeshLib::Pyramid(elem_nodes);
523 break;
525 mesh_elems[i + id_offset_ghost] =
526 new MeshLib::Pyramid13(elem_nodes);
527 break;
529 OGS_FATAL(
530 "NodePartitionedMeshReader: construction of INVALID "
531 "element type with id {:d} is not possible.",
532 i);
533 break;
534 default:
535 OGS_FATAL(
536 "NodePartitionedMeshReader: construction of element type "
537 "{:d} is not implemented.",
538 e_type);
539 }
540 }
541}
TemplateElement< MeshLib::QuadRule9 > Quad9
Definition Quad.h:19
TemplateElement< MeshLib::TetRule10 > Tet10
Definition Tet.h:15
CellType
Types of mesh elements supported by OpenGeoSys.
Definition MeshEnums.h:53
TemplateElement< MeshLib::HexRule20 > Hex20
Definition Hex.h:15
TemplateElement< MeshLib::TetRule4 > Tet
Definition Tet.h:14
TemplateElement< MeshLib::LineRule2 > Line
Definition Line.h:14
TemplateElement< MeshLib::QuadRule8 > Quad8
Definition Quad.h:18
TemplateElement< MeshLib::PyramidRule13 > Pyramid13
Definition Pyramid.h:15
TemplateElement< MeshLib::QuadRule4 > Quad
Definition Quad.h:17
TemplateElement< MeshLib::TriRule3 > Tri
Definition Tri.h:15
TemplateElement< MeshLib::PyramidRule5 > Pyramid
Definition Pyramid.h:14
TemplateElement< MeshLib::PrismRule6 > Prism
Definition Prism.h:14
TemplateElement< PointRule1 > Point
TemplateElement< MeshLib::PrismRule15 > Prism15
Definition Prism.h:15
TemplateElement< MeshLib::TriRule6 > Tri6
Definition Tri.h:16
TemplateElement< MeshLib::LineRule3 > Line3
Definition Line.h:15
TemplateElement< MeshLib::HexRule8 > Hex
Definition Hex.h:14

References _mesh_info, MeshLib::HEX20, MeshLib::HEX27, MeshLib::HEX8, MeshLib::INVALID, MeshLib::LINE2, MeshLib::LINE3, OGS_FATAL, MeshLib::POINT1, MeshLib::PRISM15, MeshLib::PRISM6, MeshLib::PYRAMID13, MeshLib::PYRAMID5, MeshLib::QUAD4, MeshLib::QUAD8, MeshLib::QUAD9, MeshLib::TET10, MeshLib::TET4, MeshLib::TRI3, and MeshLib::TRI6.

Referenced by readMesh().

◆ setNodes()

void MeshLib::IO::NodePartitionedMeshReader::setNodes ( const std::vector< NodeData > & node_data,
std::vector< MeshLib::Node * > & mesh_node,
std::vector< unsigned long > & glb_node_ids ) const
private

Set mesh nodes from a temporary array containing node data read from file.

Parameters
node_dataVector containing node data read from file.
mesh_nodeVector of mesh nodes to be set.
glb_node_idsGlobal IDs of nodes of a partition.

Definition at line 417 of file NodePartitionedMeshReader.cpp.

421{
422 mesh_node.resize(_mesh_info.number_of_nodes);
423 glb_node_ids.resize(_mesh_info.number_of_nodes);
424
425 for (std::size_t i = 0; i < mesh_node.size(); i++)
426 {
427 NodeData const& nd = node_data[i];
428 glb_node_ids[i] = nd.index;
429 mesh_node[i] = new MeshLib::Node(nd.x, nd.y, nd.z, i);
430 }
431}

References _mesh_info, MeshLib::IO::NodeData::index, MeshLib::Node, MeshLib::IO::NodeData::x, MeshLib::IO::NodeData::y, and MeshLib::IO::NodeData::z.

Referenced by readMesh().

Member Data Documentation

◆ _mesh_info

struct MeshLib::IO::NodePartitionedMeshReader::PartitionedMeshInfo MeshLib::IO::NodePartitionedMeshReader::_mesh_info
private

◆ _mpi_node_type

MPI_Datatype MeshLib::IO::NodePartitionedMeshReader::_mpi_node_type
private

MPI data type for struct NodeData.

Definition at line 51 of file NodePartitionedMeshReader.h.

Referenced by ~NodePartitionedMeshReader(), readMesh(), and registerNodeDataMpiType().

◆ mpi_

BaseLib::MPI::Mpi MeshLib::IO::NodePartitionedMeshReader::mpi_
private

Pointer to MPI communicator, the rank and the size.

Definition at line 48 of file NodePartitionedMeshReader.h.

Referenced by NodePartitionedMeshReader(), createPropertyVectorPart(), createSpecificPropertyVectorPart(), newMesh(), read(), readDataFromFile(), readMesh(), and readProperties().


The documentation for this class was generated from the following files: