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 172 of file NodePartitionedMeshReader.h.

177 {
178 MeshLib::PropertyVector<T>* pv = p.createNewPropertyVector<T>(
179 pvmd.property_name, t, pvmd.number_of_components);
180 pv->resize(pvpmd.number_of_tuples * pvmd.number_of_components);
181
182 // Locate the start position of the data in the file for the current
183 // rank.
184 is.seekg(global_offset +
185 pvpmd.offset * pvmd.number_of_components * sizeof(T));
186 // read the values
187 if (!is.read(reinterpret_cast<char*>(pv->data()),
188 pv->size() * sizeof(T)))
189 OGS_FATAL(
190 "Error in NodePartitionedMeshReader::readProperties: "
191 "Could not read part {:d} of the PropertyVector.",
192 mpi_.rank);
193 }
#define OGS_FATAL(...)
Definition Error.h:10
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 198 of file NodePartitionedMeshReader.h.

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

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 395 of file NodePartitionedMeshReader.cpp.

401{
402 std::vector<std::size_t> const gathered_n_regular_base_nodes =
403 BaseLib::MPI::allgather(_mesh_info.number_of_regular_base_nodes, mpi_);
404
405 std::vector<std::size_t> n_regular_base_nodes_at_rank =
406 BaseLib::sizesToOffsets(gathered_n_regular_base_nodes);
407
408 std::size_t const n_regular_high_order_nodes =
409 _mesh_info.number_of_regular_nodes -
410 _mesh_info.number_of_regular_base_nodes;
411 std::vector<std::size_t> const gathered_n_regular_high_order_nodes =
412 BaseLib::MPI::allgather(n_regular_high_order_nodes, mpi_);
413
414 std::vector<std::size_t> n_regular_high_order_nodes_at_rank =
415 BaseLib::sizesToOffsets(gathered_n_regular_high_order_nodes);
416
417 return new MeshLib::NodePartitionedMesh(
418 mesh_name, mesh_nodes, glb_node_ids, mesh_elems, properties,
419 _mesh_info.number_of_global_base_nodes,
420 _mesh_info.number_of_global_nodes, _mesh_info.number_of_regular_nodes,
421 std::move(n_regular_base_nodes_at_rank),
422 std::move(n_regular_high_order_nodes_at_rank));
423}
struct MeshLib::IO::NodePartitionedMeshReader::PartitionedMeshInfo _mesh_info
static std::vector< T > allgather(T const &value, Mpi const &mpi)
Definition MPI.h:87
std::vector< ranges::range_value_t< R > > sizesToOffsets(R const &sizes)
Definition Algorithm.h:301

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, 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 292 of file NodePartitionedMeshReader.cpp.

299{
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)
303 {
304 DBUG("global offset: {:d}, offset within the PropertyVector: {:d}.",
305 global_offset,
306 global_offset + pvpmd.offset * vec_pvmd[i]->number_of_components *
307 vec_pvmd[i]->data_type_size_in_bytes);
308
309 // Special field data such as OGS_VERSION, IntegrationPointMetaData,
310 // etc., which are not "real" integration points, are copied "as is"
311 // (i.e. fully) for every partition.
312 if (vec_pvmd[i]->property_name.find("_ip") == std::string::npos &&
314 {
315 createSpecificPropertyVectorPart<char>(is, *vec_pvmd[i], t,
316 global_offset, p);
317
318 global_offset += vec_pvmd[i]->data_type_size_in_bytes *
319 vec_pvmd[i]->number_of_tuples;
320 continue;
321 }
322
323 if (vec_pvmd[i]->is_int_type)
324 {
325 if (vec_pvmd[i]->is_data_type_signed)
326 {
327 if (vec_pvmd[i]->data_type_size_in_bytes == sizeof(char))
328 {
329 createPropertyVectorPart<char>(is, *vec_pvmd[i], pvpmd, t,
330 global_offset, p);
331 }
332 else if (vec_pvmd[i]->data_type_size_in_bytes == sizeof(int))
333 {
334 createPropertyVectorPart<int>(is, *vec_pvmd[i], pvpmd, t,
335 global_offset, p);
336 }
337 else if (vec_pvmd[i]->data_type_size_in_bytes == sizeof(long))
338 createPropertyVectorPart<long>(is, *vec_pvmd[i], pvpmd, t,
339 global_offset, p);
340 else
341 {
342 WARN(
343 "Implementation for reading signed integer property "
344 "vector '{:s}' is not available.",
345 vec_pvmd[i]->property_name);
346 }
347 }
348 else
349 {
350 if (vec_pvmd[i]->data_type_size_in_bytes ==
351 sizeof(unsigned char))
352 {
354 is, *vec_pvmd[i], pvpmd, t, global_offset, p);
355 }
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);
364 else
365 {
366 WARN(
367 "Implementation for reading unsigned property vector "
368 "'{:s}' is not available.",
369 vec_pvmd[i]->property_name);
370 }
371 }
372 }
373 else
374 {
375 if (vec_pvmd[i]->data_type_size_in_bytes == sizeof(float))
376 createPropertyVectorPart<float>(is, *vec_pvmd[i], pvpmd, t,
377 global_offset, p);
378 else if (vec_pvmd[i]->data_type_size_in_bytes == sizeof(double))
379 createPropertyVectorPart<double>(is, *vec_pvmd[i], pvpmd, t,
380 global_offset, p);
381 else
382 {
383 WARN(
384 "Implementation for reading floating point property vector "
385 "'{:s}' is not available.",
386 vec_pvmd[i]->property_name);
387 }
388 }
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;
392 }
393}
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 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 elements
166 std::vector<unsigned long> elem_data(_mesh_info.number_of_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_elements + _mesh_info.number_of_ghost_elements);
175 setElements(mesh_nodes, elem_data, mesh_elems);
176
177 //----------------------------------------------------------------------------------
178 // Read ghost element
179 if (_mesh_info.number_of_ghost_elements > 0)
180 {
181 WARN(
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 "
185 "partitioned mesh.",
186 _mesh_info.number_of_ghost_elements);
187 }
188 std::vector<unsigned long> ghost_elem_data(
189 _mesh_info.number_of_ghost_elements + _mesh_info.offset[1]);
190
191 if (!readDataFromFile(fname_header + "ele_g" + fname_num_p_ext,
192 static_cast<MPI_Offset>(_mesh_info.offset[4]),
193 MPI_LONG, ghost_elem_data))
194 return nullptr;
195
196 const bool process_ghost = true;
197 setElements(mesh_nodes, ghost_elem_data, mesh_elems, process_ghost);
198
199 //----------------------------------------------------------------------------------
200 // read the properties
201 MeshLib::Properties p(readProperties(file_name_base));
202
203 return newMesh(BaseLib::extractBaseName(file_name_base), mesh_nodes,
204 glb_node_ids, mesh_elems, p);
205}
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(), setNodes(), and WARN().

Referenced by read().

◆ readProperties() [1/2]

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

Definition at line 207 of file NodePartitionedMeshReader.cpp.

209{
210 MeshLib::Properties p;
214 return p;
215}

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 217 of file NodePartitionedMeshReader.cpp.

220{
221 const std::string item_type = MeshLib::toString(t);
222
223 const std::string fname_cfg = file_name_base + "_partitioned_" + item_type +
224 "_properties_cfg" +
225 std::to_string(mpi_.size) + ".bin";
226 std::ifstream is(fname_cfg.c_str(), std::ios::binary | std::ios::in);
227 if (!is)
228 {
229 WARN(
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());
234 return;
235 }
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)
242 {
244 if (!vec_pvmd[i])
245 {
246 OGS_FATAL(
247 "Error in NodePartitionedMeshReader::readProperties: "
248 "Could not read the meta data for the PropertyVector {:d}",
249 i);
250 }
251 }
252 for (std::size_t i(0); i < number_of_properties; ++i)
253 {
255 }
256 auto pos = is.tellg();
257 auto offset =
258 static_cast<long>(pos) +
259 static_cast<long>(mpi_.rank *
260 sizeof(MeshLib::IO::PropertyVectorPartitionMetaData));
261 is.seekg(offset);
262 std::optional<MeshLib::IO::PropertyVectorPartitionMetaData> pvpmd(
264 bool const all_pvpmd_read_ok =
265 BaseLib::MPI::allreduce(static_cast<bool>(pvpmd), MPI_LOR, mpi_);
266 if (!all_pvpmd_read_ok)
267 {
268 OGS_FATAL(
269 "Error in NodePartitionedMeshReader::readProperties: "
270 "Could not read the partition meta data for the mpi process {:d}",
271 mpi_.rank);
272 }
273 DBUG("offset in the PropertyVector: {:d}", pvpmd->offset);
274 DBUG("{:d} tuples in partition.", pvpmd->number_of_tuples);
275 is.close();
276
277 const std::string fname_val = file_name_base + "_partitioned_" + item_type +
278 "_properties_val" +
279 std::to_string(mpi_.size) + ".bin";
280 is.open(fname_val.c_str(), std::ios::binary | std::ios::in);
281 if (!is)
282 {
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());
287 }
288
289 readDomainSpecificPartOfPropertyVectors(vec_pvmd, *pvpmd, t, is, p);
290}
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:111
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:26

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 441 of file NodePartitionedMeshReader.cpp.

445{
446 // Number of elements, either ghost or regular
447 unsigned long const ne = ghost ? _mesh_info.number_of_ghost_elements
448 : _mesh_info.number_of_elements;
449 unsigned long const id_offset_ghost =
450 ghost ? _mesh_info.number_of_elements : 0;
451
452 for (unsigned long i = 0; i < ne; i++)
453 {
454 unsigned long id_offset_elem = elem_data[i];
455
456 // Unused for now, keep for elem_data documentation purpose here.
457 {
458 const unsigned mat_idx =
459 static_cast<unsigned>(elem_data[id_offset_elem++]);
460 (void)mat_idx;
461 }
462 const unsigned long e_type = elem_data[id_offset_elem++];
463 unsigned long const nnodes = elem_data[id_offset_elem++];
464
465 MeshLib::Node** elem_nodes = new MeshLib::Node*[nnodes];
466 for (unsigned long k = 0; k < nnodes; k++)
467 elem_nodes[k] = mesh_nodes[elem_data[id_offset_elem++]];
468
469 // The element types below are defined by the MeshLib::CellType.
470 switch (static_cast<CellType>(e_type))
471 {
472 case CellType::POINT1:
473 mesh_elems[i + id_offset_ghost] =
474 new MeshLib::Point(elem_nodes);
475 break;
476 case CellType::LINE2:
477 mesh_elems[i + id_offset_ghost] = new MeshLib::Line(elem_nodes);
478 break;
479 case CellType::LINE3:
480 mesh_elems[i + id_offset_ghost] =
481 new MeshLib::Line3(elem_nodes);
482 break;
483 case CellType::QUAD4:
484 mesh_elems[i + id_offset_ghost] = new MeshLib::Quad(elem_nodes);
485 break;
486 case CellType::QUAD8:
487 mesh_elems[i + id_offset_ghost] =
488 new MeshLib::Quad8(elem_nodes);
489 break;
490 case CellType::QUAD9:
491 mesh_elems[i + id_offset_ghost] =
492 new MeshLib::Quad9(elem_nodes);
493 break;
494 case CellType::HEX8:
495 mesh_elems[i + id_offset_ghost] = new MeshLib::Hex(elem_nodes);
496 break;
497 case CellType::HEX20:
498 mesh_elems[i + id_offset_ghost] =
499 new MeshLib::Hex20(elem_nodes);
500 break;
501 case CellType::HEX27:
502 OGS_FATAL(
503 "NodePartitionedMeshReader: construction of HEX27 element "
504 "with id {:d} is not implemented.",
505 i);
506 break;
507 case CellType::TRI3:
508 mesh_elems[i + id_offset_ghost] = new MeshLib::Tri(elem_nodes);
509 break;
510 case CellType::TRI6:
511 mesh_elems[i + id_offset_ghost] = new MeshLib::Tri6(elem_nodes);
512 break;
513 case CellType::TET4:
514 mesh_elems[i + id_offset_ghost] = new MeshLib::Tet(elem_nodes);
515 break;
516 case CellType::TET10:
517 mesh_elems[i + id_offset_ghost] =
518 new MeshLib::Tet10(elem_nodes);
519 break;
520 case CellType::PRISM6:
521 mesh_elems[i + id_offset_ghost] =
522 new MeshLib::Prism(elem_nodes);
523 break;
525 mesh_elems[i + id_offset_ghost] =
526 new MeshLib::Prism15(elem_nodes);
527 break;
529 mesh_elems[i + id_offset_ghost] =
530 new MeshLib::Pyramid(elem_nodes);
531 break;
533 mesh_elems[i + id_offset_ghost] =
534 new MeshLib::Pyramid13(elem_nodes);
535 break;
537 OGS_FATAL(
538 "NodePartitionedMeshReader: construction of INVALID "
539 "element type with id {:d} is not possible.",
540 i);
541 break;
542 default:
543 OGS_FATAL(
544 "NodePartitionedMeshReader: construction of element type "
545 "{:d} is not implemented.",
546 e_type);
547 }
548 }
549}
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:58
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 425 of file NodePartitionedMeshReader.cpp.

429{
430 mesh_node.resize(_mesh_info.number_of_nodes);
431 glb_node_ids.resize(_mesh_info.number_of_nodes);
432
433 for (std::size_t i = 0; i < mesh_node.size(); i++)
434 {
435 NodeData const& nd = node_data[i];
436 glb_node_ids[i] = nd.index;
437 mesh_node[i] = new MeshLib::Node(nd.x, nd.y, nd.z, i);
438 }
439}

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: