Commit ca698493 authored by GILLES Sebastien's avatar GILLES Sebastien

#1453 PetscVector: ad a method to load parallel vector from ascii files.

parent 2bb3755c
......@@ -95,17 +95,27 @@ BOOST_FIXTURE_TEST_SUITE(processor_wise, fixture_type)
BOOST_CHECK(FilesystemNS::File::DoExist(binary_file) == true); // created in previous test!
decltype(auto) vector = model.GetVector();
std::vector<PetscInt> ghost_padding;
if (mpi.Nprocessor<int>() > 1)
ghost_padding = vector.GetGhostPadding();
Wrappers::Petsc::Vector from_file;
from_file.InitParallelFromProcessorWiseAsciiFile(mpi,
static_cast<unsigned int>(vector.GetProcessorWiseSize(__FILE__, __LINE__)),
static_cast<unsigned int>(vector.GetProgramWiseSize(__FILE__, __LINE__)),
ghost_padding,
binary_file,
__FILE__, __LINE__);
std::string inequality_description;
Wrappers::Petsc::AreEqual(from_file,
vector,
NumericNS::DefaultEpsilon<double>(),
inequality_description,
__FILE__, __LINE__);
//
//
// std::string inequality_description;
// Wrappers::Petsc::AreEqual(from_file,
// vector,
// NumericNS::DefaultEpsilon<double>(),
// inequality_description,
// __FILE__, __LINE__);
//
// BOOST_CHECK_EQUAL(inequality_description, "");
BOOST_CHECK_EQUAL(inequality_description, "");
}
BOOST_AUTO_TEST_CASE(load_binary)
......@@ -189,6 +199,51 @@ BOOST_FIXTURE_TEST_SUITE(program_wise, fixture_type)
BOOST_AUTO_TEST_SUITE_END()
BOOST_FIXTURE_TEST_SUITE(sequential_only, fixture_type)
BOOST_AUTO_TEST_CASE(load_ascii)
{
decltype(auto) model = GetModel();
decltype(auto) mpi = model.GetMpi();
if (mpi.Nprocessor<int>() == 1)
{
std::string ascii_file = model.GetProgramWiseAsciiFile();
std::cout << "ASC II FILE = " << ascii_file << std::endl;
BOOST_CHECK(FilesystemNS::File::DoExist(ascii_file) == true); // created in previous test!
decltype(auto) vector = model.GetVector();
Wrappers::Petsc::Vector from_file;
std::vector<PetscInt> ghost_padding;
BOOST_CHECK_EQUAL(vector.GetProcessorWiseSize(__FILE__, __LINE__),
vector.GetProgramWiseSize(__FILE__, __LINE__));
from_file.InitSequentialFromFile(mpi,
ascii_file,
__FILE__, __LINE__);
std::string inequality_description;
Wrappers::Petsc::AreEqual(from_file,
vector,
NumericNS::DefaultEpsilon<double>(),
inequality_description,
__FILE__, __LINE__);
BOOST_CHECK_EQUAL(inequality_description, "");
}
}
BOOST_AUTO_TEST_CASE(load_binary)
{
}
BOOST_AUTO_TEST_SUITE_END()
PRAGMA_DIAGNOSTIC(pop)
......
......@@ -43,8 +43,6 @@ namespace MoReFEM
const char* invoking_file, int invoking_line,
binary_or_ascii binary_or_ascii_choice)
{
::MoReFEM::Wrappers::Petsc
::AccessVectorContent<Utilities::Access::read_only> content(vector,
invoking_file, invoking_line);
......
......@@ -219,8 +219,6 @@ namespace MoReFEM
*
* This file is assumed to have been created with Print() method for a sequential vector.
*
* Parallel case is not handled at all at the moment!
*
* \param[in] file File from which vector content is read.
* \copydoc doxygen_hide_invoking_file_and_line
* \copydetails doxygen_hide_mpi_param
......@@ -229,6 +227,27 @@ namespace MoReFEM
const std::string& file,
const char* invoking_file, int invoking_line);
/*!
* \brief Init a vector from the data read in the file.
*
* This file is assumed to have been created with Print() method.
*
* Current method is in fact able to create a sequential vector as well, but use rather
* InitSequentialFromFile() with its more friendly API if you need only the sequential case.
*
* \param[in] file File from which vector content is read.
* \copydetails doxygen_hide_parallel_with_ghosts_arg
* \copydoc doxygen_hide_invoking_file_and_line
* \copydetails doxygen_hide_mpi_param
*/
void InitParallelFromProcessorWiseAsciiFile(const Mpi& mpi,
unsigned int processor_wise_size,
unsigned int program_wise_size,
const std::vector<PetscInt>& ghost_padding,
const std::string& file,
const char* invoking_file, int invoking_line);
/*!
* \brief Init from a program-wise binary file: load a vector dumped with View() method.
*
......
......@@ -26,16 +26,24 @@
#include "ThirdParty/Wrappers/Petsc/Print.hpp"
namespace MoReFEM
namespace MoReFEM::Wrappers::Petsc
{
namespace Wrappers
namespace // anonymous
{
namespace Petsc
{
//! Basic function to read content of a simple file and stores the values into a vector of double.
//! Two different types of files are processable by this function:
//! - Ad hoc files generated by Internal::Wrappers::Petsc::PrintPerProcessor()
//! - Matlab files generated directly by Petsc.
std::vector<double> ReadAsciiFileContent(const std::string& file,
const char* invoking_file, int invoking_line);
} // namespace anonymous
Vector::Vector()
......@@ -190,11 +198,68 @@ namespace MoReFEM
assert(petsc_vector_ == PETSC_NULL && "Should not be initialized when this method is called!");
assert(mpi.Nprocessor<int>() == 1 && "This method assumes sequential case!");
std::vector<double> value_list = ReadAsciiFileContent(file,
invoking_file, invoking_line);
// Now Init the vector with the appropriate size.
const unsigned int Nvalue = static_cast<unsigned int>(value_list.size());
InitSequentialVector(mpi, Nvalue, invoking_file, invoking_line);
// And fill it with the values.
AccessVectorContent<Utilities::Access::read_and_write> content(*this, invoking_file, invoking_line);
for (auto i = 0u; i < Nvalue; ++i)
content[i] = value_list[static_cast<std::size_t>(i)];
}
void Vector::InitParallelFromProcessorWiseAsciiFile(const Mpi& mpi,
unsigned int processor_wise_size,
unsigned int program_wise_size,
const std::vector<PetscInt>& ghost_padding,
const std::string& file,
const char* invoking_file, int invoking_line)
{
assert(processor_wise_size <= program_wise_size);
InitMpiVectorWithGhost(mpi,
processor_wise_size,
program_wise_size,
ghost_padding,
invoking_file, invoking_line);
const auto value_list = ReadAsciiFileContent(file, invoking_file, invoking_line);
assert(value_list.size() == static_cast<std::size_t>(processor_wise_size));
{
AccessVectorContent<Utilities::Access::read_and_write> content(*this, invoking_file, invoking_line);
const auto size = content.GetSize(invoking_file, invoking_line);
assert(size == processor_wise_size);
for (auto i = 0u; i < size; ++i)
content[i] = value_list[i];
}
mpi.Barrier();
UpdateGhosts(invoking_file, invoking_line);
}
namespace // anonymous
{
std::vector<double> ReadAsciiFileContent(const std::string& file, const char* invoking_file, int invoking_line)
{
std::ifstream stream;
FilesystemNS::File::Read(stream, file, invoking_file, invoking_line);
std::string line;
std::vector<double> value_list;
std::vector<double> ret;
while (getline(stream, line))
{
......@@ -205,29 +270,18 @@ namespace MoReFEM
continue;
// All lines are expected to be one value.
value_list.push_back(std::stod(line));
ret.push_back(std::stod(line));
}
// Now Init the vector with the appropriate size.
const unsigned int Nvalue = static_cast<unsigned int>(value_list.size());
InitSequentialVector(mpi, Nvalue, invoking_file, invoking_line);
// And fill it with the values.
AccessVectorContent<Utilities::Access::read_and_write> content(*this, invoking_file, invoking_line);
for (auto i = 0u; i < Nvalue; ++i)
content[i] = value_list[static_cast<std::size_t>(i)];
return ret;
}
} // namespace Petsc
} // namespace Wrappers
} // namespace anonymous
} // namespace MoReFEM
} // namespace MoReFEM::Wrappers::Petsc
/// @} // addtogroup ThirdPartyGroup
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment