Commit 7a093211 authored by GILLES Sebastien's avatar GILLES Sebastien

#1422 Introduce a new test to check binary output behaves exactly as intended.

parent 50c5f296
......@@ -1587,6 +1587,7 @@
BEF3B489212DB18000807965 /* ForUnknownList.hpp in Headers */ = {isa = PBXBuildFile; fileRef = BEF3B486212DB17F00807965 /* ForUnknownList.hpp */; };
BEF3B48A212DB18000807965 /* ForUnknownList.hxx in Headers */ = {isa = PBXBuildFile; fileRef = BEF3B487212DB17F00807965 /* ForUnknownList.hxx */; };
BEF3B48B212DB18000807965 /* ForUnknownList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BEF3B488212DB17F00807965 /* ForUnknownList.cpp */; };
BEF795E022DDDE430054B192 /* BinaryOrAscii.hpp in Headers */ = {isa = PBXBuildFile; fileRef = BEF795DD22DDDE430054B192 /* BinaryOrAscii.hpp */; };
BEFC32DF1CB53C3B00C8903C /* RefFEltInLocalOperator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BEFC32DC1CB53C3B00C8903C /* RefFEltInLocalOperator.cpp */; };
BEFC32E01CB53C3B00C8903C /* RefFEltInLocalOperator.hpp in Headers */ = {isa = PBXBuildFile; fileRef = BEFC32DD1CB53C3B00C8903C /* RefFEltInLocalOperator.hpp */; };
BEFC32E11CB53C3B00C8903C /* RefFEltInLocalOperator.hxx in Headers */ = {isa = PBXBuildFile; fileRef = BEFC32DE1CB53C3B00C8903C /* RefFEltInLocalOperator.hxx */; };
......@@ -4774,6 +4775,15 @@
BEF3B488212DB17F00807965 /* ForUnknownList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ForUnknownList.cpp; sourceTree = "<group>"; };
BEF553162083963E00CA8A50 /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
BEF5531A2084C47C00CA8A50 /* test.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = test.cpp; sourceTree = "<group>"; };
BEF795D322DDBDB20054B192 /* CMakeLists.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
BEF795D422DDBE540054B192 /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
BEF795D522DDBE550054B192 /* CMakeLists.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
BEF795D622DDBFCD0054B192 /* Model.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Model.cpp; sourceTree = "<group>"; };
BEF795D722DDBFCD0054B192 /* InputData.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = InputData.hpp; sourceTree = "<group>"; };
BEF795D822DDBFCD0054B192 /* Model.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Model.hpp; sourceTree = "<group>"; };
BEF795D922DDBFCD0054B192 /* demo.lua */ = {isa = PBXFileReference; lastKnownFileType = text; path = demo.lua; sourceTree = "<group>"; };
BEF795DA22DDBFCD0054B192 /* Model.hxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Model.hxx; sourceTree = "<group>"; };
BEF795DD22DDDE430054B192 /* BinaryOrAscii.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = BinaryOrAscii.hpp; sourceTree = "<group>"; };
BEF9835B180451CF00E7905D /* Factory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Factory.cpp; sourceTree = "<group>"; };
BEF9835C180451CF00E7905D /* Factory.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Factory.hpp; sourceTree = "<group>"; };
BEFC32DC1CB53C3B00C8903C /* RefFEltInLocalOperator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RefFEltInLocalOperator.cpp; sourceTree = "<group>"; };
......@@ -9965,6 +9975,7 @@
BE8B5F8D207792B600DC005E /* Tclap */,
BEE79C672136F43000388FED /* NanOrInf */,
BEC5CFB41F4DBF9B00A2863B /* Mpi */,
BEF795CE22DDBD640054B192 /* PETSc */,
);
path = ThirdParty;
sourceTree = "<group>";
......@@ -10327,6 +10338,7 @@
BE6E4EDE1B2ABE8B0049BB2D /* AccessGhostContent.cpp */,
BE6E4EDF1B2ABE8B0049BB2D /* AccessGhostContent.hpp */,
BE6E4EE01B2ABE8B0049BB2D /* AccessGhostContent.hxx */,
BEF795DD22DDDE430054B192 /* BinaryOrAscii.hpp */,
BE110E9A1E11514200D2D2C8 /* Internal */,
);
path = Vector;
......@@ -10405,6 +10417,29 @@
path = InformationsAtQuadraturePoint;
sourceTree = "<group>";
};
BEF795CE22DDBD640054B192 /* PETSc */ = {
isa = PBXGroup;
children = (
BEF795D322DDBDB20054B192 /* CMakeLists.txt */,
BEF795CF22DDBD7A0054B192 /* Binary */,
);
path = PETSc;
sourceTree = "<group>";
};
BEF795CF22DDBD7A0054B192 /* Binary */ = {
isa = PBXGroup;
children = (
BEF795D522DDBE550054B192 /* CMakeLists.txt */,
BEF795D922DDBFCD0054B192 /* demo.lua */,
BEF795D722DDBFCD0054B192 /* InputData.hpp */,
BEF795D422DDBE540054B192 /* main.cpp */,
BEF795D622DDBFCD0054B192 /* Model.cpp */,
BEF795D822DDBFCD0054B192 /* Model.hpp */,
BEF795DA22DDBFCD0054B192 /* Model.hxx */,
);
path = Binary;
sourceTree = "<group>";
};
BEFC32DB1CB53C3B00C8903C /* Advanced */ = {
isa = PBXGroup;
children = (
......@@ -11218,6 +11253,7 @@
BE90E1AE1A24929A00CCAFDE /* MatrixPattern.hxx in Headers */,
BE168EB11CC96F120090AC88 /* Triangle6.hxx in Headers */,
BE110E911E11512100D2D2C8 /* Datatype.hpp in Headers */,
BEF795E022DDDE430054B192 /* BinaryOrAscii.hpp in Headers */,
BE53FC271E0D81A000C5D6F5 /* Traits.hxx in Headers */,
BE90E1C21A2492AA00CCAFDE /* SeldonFunctions.hxx in Headers */,
BE90E1A81A24929A00CCAFDE /* Parmetis.hpp in Headers */,
......@@ -54,9 +54,7 @@ namespace MoReFEM
return mesh_manager.GetMesh<10>();
}
} // namespace LoadPrepartitionedMeshNS
......
include(${CMAKE_CURRENT_LIST_DIR}/Mpi/CMakeLists.txt)
include(${CMAKE_CURRENT_LIST_DIR}/Tclap/CMakeLists.txt)
include(${CMAKE_CURRENT_LIST_DIR}/NanOrInf/CMakeLists.txt)
include(${CMAKE_CURRENT_LIST_DIR}/PETSc/CMakeLists.txt)
add_executable(MoReFEMTestPetscVectorBinary
${CMAKE_CURRENT_LIST_DIR}/main.cpp
${CMAKE_CURRENT_LIST_DIR}/InputData.hpp
${CMAKE_CURRENT_LIST_DIR}/Model.cpp
${CMAKE_CURRENT_LIST_DIR}/Model.hpp
${CMAKE_CURRENT_LIST_DIR}/Model.hxx
)
target_link_libraries(MoReFEMTestPetscVectorBinary
${MOREFEM_TEST_TOOLS}
)
add_test(PetscVectorBinary
${OPEN_MPI_INCL_DIR}/../bin/mpirun
--oversubscribe
-np 4
MoReFEMTestPetscVectorBinary
--
${MOREFEM_ROOT}
${MOREFEM_TEST_OUTPUT_DIR})
/*!
// \file
//
//
// Created by Sebastien Gilles <sebastien.gilles@inria.fr> on the Sun, 18 Nov 2018 22:29:38 +0100
// Copyright (c) Inria. All rights reserved.
//
*/
#ifndef MOREFEM_x_TEST_x_THIRD_PARTY_x_P_E_T_SC_x_BINARY_x_INPUT_DATA_HPP_
# define MOREFEM_x_TEST_x_THIRD_PARTY_x_P_E_T_SC_x_BINARY_x_INPUT_DATA_HPP_
# include "Utilities/Containers/EnumClass.hpp"
# include "Core/InputData/InputData.hpp"
# include "Core/InputData/Instances/TimeManager/TimeManager.hpp"
# include "Core/InputData/Instances/Geometry/Domain.hpp"
# include "Core/InputData/Instances/Geometry/Mesh.hpp"
# include "Core/InputData/Instances/Solver/Petsc.hpp"
# include "Core/InputData/Instances/FElt/Unknown.hpp"
# include "Core/InputData/Instances/FElt/NumberingSubset.hpp"
# include "Core/InputData/Instances/FElt/FEltSpace.hpp"
# include "Core/InputData/Instances/Result.hpp"
# include "Core/InputData/Instances/PrepartitionedData.hpp"
namespace MoReFEM::TestNS::PetscNS::VectorBinaryNS
{
//! Sole index used for this very simple model.
constexpr auto sole = 1;
//! \copydoc doxygen_hide_input_data_tuple
using InputDataTuple = std::tuple
<
InputDataNS::TimeManager,
InputDataNS::Mesh<sole>,
InputDataNS::Unknown<sole>,
InputDataNS::Domain<sole>,
InputDataNS::NumberingSubset<sole>,
InputDataNS::FEltSpace<sole>,
InputDataNS::Petsc<sole>,
InputDataNS::Result
>;
//! \copydoc doxygen_hide_model_specific_input_data
using InputData = InputData<InputDataTuple>;
//! \copydoc doxygen_hide_morefem_data_type
using morefem_data_type = MoReFEMData<InputData>;
} // namespace MoReFEM::TestNS::PetscNS::VectorBinaryNS
#endif // MOREFEM_x_TEST_x_THIRD_PARTY_x_P_E_T_SC_x_BINARY_x_INPUT_DATA_HPP_
/*!
// \file
//
//
// Created by Gautier Bureau <gautier.bureau@inria.fr> on the Fri, 28 Jul 2017 12:12:25 +0200
// Copyright (c) Inria. All rights reserved.
//
*/
#include <fstream>
#include <sstream>
#include "Utilities/Filesystem/File.hpp"
#include "Utilities/Filesystem/Folder.hpp"
#include "ThirdParty/Wrappers/Petsc/Vector/AccessVectorContent.hpp"
#include "ThirdParty/IncludeWithoutWarning/Boost/Test.hpp"
#include "Test/ThirdParty/PETSc/Binary/Model.hpp"
namespace MoReFEM::TestNS::PetscNS::VectorBinaryNS
{
namespace // anonymous
{
std::string ComputeAsciiFile(const Model& model)
{
std::ostringstream oconv;
oconv << model.GetOutputDirectory() << "/vector_" << model.GetMpi().GetRank<int>() << ".hhdata";
return oconv.str();
}
std::string ComputeBinaryFile(const Model& model)
{
std::ostringstream oconv;
oconv << model.GetOutputDirectory() << "/vector_" << model.GetMpi().GetRank<int>() << ".bin";
return oconv.str();
}
} // namespace anonymous
Model::Model(const morefem_data_type& morefem_data)
: parent(morefem_data)
{ }
const std::string& Model::GetBinaryFile() const noexcept
{
static auto ret = ComputeBinaryFile(*this);
return ret;
}
const std::string& Model::GetAsciiFile() const noexcept
{
static auto ret = ComputeAsciiFile(*this);
return ret;
}
void Model::SupplInitialize()
{
decltype(auto) god_of_dof_manager = GodOfDofManager::GetInstance(__FILE__, __LINE__);
decltype(auto) god_of_dof = god_of_dof_manager.GetGodOfDof(1);
decltype(auto) numbering_subset = god_of_dof.GetNumberingSubset(1);
decltype(auto) mpi = god_of_dof.GetMpi();
vector_ = std::make_unique<GlobalVector>(numbering_subset);
auto& vector = *vector_;
AllocateGlobalVector(god_of_dof, vector);
{
Wrappers::Petsc::AccessVectorContent<Utilities::Access::read_and_write> content(vector,
__FILE__, __LINE__);
const auto size = content.GetSize(__FILE__, __LINE__);
const auto rank_plus_one = static_cast<double>(1 + mpi.GetRank<int>());
for (auto i = 0u; i < size; ++i)
content[i] = rank_plus_one * std::sqrt(i); // completely arbitrary value with no redundancy!
}
{
const auto binary_file = GetBinaryFile();
if (FilesystemNS::File::DoExist(binary_file))
FilesystemNS::File::Remove(binary_file, __FILE__, __LINE__);
}
{
const auto ascii_file = GetAsciiFile();
if (FilesystemNS::File::DoExist(ascii_file))
FilesystemNS::File::Remove(ascii_file, __FILE__, __LINE__);
}
}
void Model::Forward()
{ }
void Model::SupplFinalizeStep()
{ }
void Model::SupplFinalize()
{ }
} // namespace MoReFEM::TestNS::PetscNS::VectorBinaryNS
/*!
// \file
//
//
// Created by Sebastien Gilles <sebastien.gilles@inria.fr> on the Fri, 14 Apr 2017 16:21:23 +0200
// Copyright (c) Inria. All rights reserved.
//
*/
#ifndef MOREFEM_x_TEST_x_THIRD_PARTY_x_P_E_T_SC_x_BINARY_x_MODEL_HPP_
# define MOREFEM_x_TEST_x_THIRD_PARTY_x_P_E_T_SC_x_BINARY_x_MODEL_HPP_
# include <memory>
# include <vector>
# include "Core/InputData/Instances/Result.hpp"
# include "Model/Model.hpp"
# include "Test/ThirdParty/PETSc/Binary/InputData.hpp"
namespace MoReFEM
{
namespace TestNS::PetscNS::VectorBinaryNS
{
/*!
* \brief Toy model used to perform tests about reconstruction of a \a Mesh from pre-partitioned data.
*
* This test must be run in parallel; its principle is to:
* - Initialize the model normally (including separating the mesh among all mpi processors and reducing it).
* - Write the data related to the partition of said mesh.
* - Load from the data written a new mesh.
* - Check both mesh are indistinguishable.
*/
//! \copydoc doxygen_hide_model_4_test
class Model : public MoReFEM::Model<Model, morefem_data_type, DoConsiderProcessorWiseLocal2Global::no>
{
private:
//! \copydoc doxygen_hide_alias_self
using self = Model;
//! Convenient alias.
using parent = MoReFEM::Model<self, morefem_data_type, DoConsiderProcessorWiseLocal2Global::no>;
public:
//! Return the name of the model.
static const std::string& ClassName();
//! Friendship granted to the base class so this one can manipulates private methods.
friend parent;
public:
/// \name Special members.
///@{
/*!
* \brief Constructor.
*
* \copydoc doxygen_hide_morefem_data_param
*/
Model(const morefem_data_type& morefem_data);
//! Destructor.
~Model() = default;
//! \copydoc doxygen_hide_copy_constructor
Model(const Model& rhs) = delete;
//! \copydoc doxygen_hide_move_constructor
Model(Model&& rhs) = delete;
//! \copydoc doxygen_hide_copy_affectation
Model& operator=(const Model& rhs) = delete;
//! \copydoc doxygen_hide_move_affectation
Model& operator=(Model&& rhs) = delete;
///@}
/// \name Crtp-required methods.
///@{
/*!
* \brief Initialise the problem.
*
* This initialisation includes the resolution of the static problem.
*/
void SupplInitialize();
//! Manage time iteration.
void Forward();
/*!
* \brief Additional operations to finalize a dynamic step.
*
* Base class already update the time for next time iterations.
*/
void SupplFinalizeStep();
/*!
* \brief Initialise a dynamic step.
*
*/
void SupplFinalize();
//! Accessor to the vector used for tests.
const GlobalVector& GetVector() const noexcept;
//! Accessor to the path to the binary file for current rank.
const std::string& GetBinaryFile() const noexcept;
//! Accessor to the path to the ascii file for current rank.
const std::string& GetAsciiFile() const noexcept;
private:
//! \copydoc doxygen_hide_model_SupplHasFinishedConditions_always_true
bool SupplHasFinishedConditions() const;
/*!
* \brief Part of InitializedStep() specific to Elastic model.
*
* As there are none, the body of this method is empty.
*/
void SupplInitializeStep();
///@}
private:
//! Global vector which is used in the tests.
GlobalVector::unique_ptr vector_ = nullptr;
};
} // namespace TestNS::PetscNS::VectorBinaryNS
} // namespace MoReFEM
#include "Test/ThirdParty/PETSc/Binary/Model.hxx"
#endif // MOREFEM_x_TEST_x_THIRD_PARTY_x_P_E_T_SC_x_BINARY_x_MODEL_HPP_
/*!
// \file
//
//
// Created by Sebastien Gilles <sebastien.gilles@inria.fr> on the Mon, 21 Mar 2016 23:31:12 +0100
// Copyright (c) Inria. All rights reserved.
//
*/
#ifndef MOREFEM_x_TEST_x_THIRD_PARTY_x_P_E_T_SC_x_BINARY_x_MODEL_HXX_
# define MOREFEM_x_TEST_x_THIRD_PARTY_x_P_E_T_SC_x_BINARY_x_MODEL_HXX_
namespace MoReFEM
{
namespace TestNS::PetscNS::VectorBinaryNS
{
inline const std::string& Model::ClassName()
{
static std::string ret("Test Petsc Vector Binary");
return ret;
}
inline bool Model::SupplHasFinishedConditions() const
{
return false; // ie no additional condition
}
inline void Model::SupplInitializeStep()
{ }
inline const GlobalVector& Model::GetVector() const noexcept
{
assert(!(!vector_));
return *vector_;
}
} // namespace TestNS::PetscNS::VectorBinaryNS
} // namespace MoReFEM
#endif // MOREFEM_x_TEST_x_THIRD_PARTY_x_P_E_T_SC_x_BINARY_x_MODEL_HXX_
-- Comment lines are introduced by "--".
-- In a section (i.e. within braces), all entries must be separated by a comma.
transient = {
-- Time at the beginning of the code (in seconds).
-- Expected format: VALUE
-- Constraint: v >= 0.
init_time = 0.,
-- Time step between two iterations, in seconds.
-- Expected format: VALUE
-- Constraint: v > 0.
timeStep = 0.1,
-- Maximum time, if set to zero run a static case.
-- Expected format: VALUE
-- Constraint: v >= 0.
timeMax = .1
} -- transient
Mesh1 = {
-- Path of the mesh file to use.
-- Expected format: "VALUE"
mesh = "${MOREFEM_ROOT}/Data/Mesh/elasticity_Nx50_Ny20_force_label.mesh",
-- Format of the input mesh.
-- Expected format: "VALUE"
-- Constraint: value_in(v, {'Ensight', 'Medit'})
format = "Medit",
-- Highest dimension of the input mesh. This dimension might be lower than the one effectively read in the
-- mesh file; in which case Coords will be reduced provided all the dropped values are 0. If not, an
-- exception is thrown.
-- Expected format: VALUE
-- Constraint: v <= 3 and v > 0
dimension = 2,
-- Space unit of the mesh.
-- Expected format: VALUE
space_unit = 1.
} -- Mesh1
Domain1 = {
-- Index of the geometric mesh upon which the domain is defined (as defined in the present file). Might be
-- left empty if domain not limited to one mesh; at most one value is expected here.
-- Expected format: {VALUE1, VALUE2, ...}
mesh_index = { 1 },
-- List of dimensions encompassed by the domain. Might be left empty if no restriction at all upon
-- dimensions.
-- Expected format: {VALUE1, VALUE2, ...}
-- Constraint: value_in(v, {0, 1, 2, 3})
dimension_list = { 2 },
-- List of mesh labels encompassed by the domain. Might be left empty if no restriction at all upon mesh
-- labels. This parameter does not make sense if no mesh is defined for the domain.
-- Expected format: {VALUE1, VALUE2, ...}
mesh_label_list = {},
-- List of geometric element types considered in the domain. Might be left empty if no restriction upon
-- these. No constraint is applied at LuaOptionFile level, as some geometric element types could be added after
-- generation of current input data file. Current list is below; if an incorrect value is put there it
-- will be detected a bit later when the domain object is built.
-- The known types when this file was generated are:
-- . Point1
-- . Segment2, Segment3
-- . Triangle3, Triangle6
-- . Quadrangle4, Quadrangle8, Quadrangle9
-- . Tetrahedron4, Tetrahedron10
-- . Hexahedron8, Hexahedron20, Hexahedron27.
-- Expected format: {"VALUE1", "VALUE2", ...}
geometric_element_type_list = {}
} -- Domain1
Unknown1 = {
-- Name of the unknown (used for displays in output).
-- Expected format: "VALUE"
name = "sole",
-- Index of the god of dof into which the finite element space is defined.
-- Expected format: "VALUE"
-- Constraint: value_in(v, {'scalar', 'vectorial'})
nature = "scalar"
} -- Unknown1
NumberingSubset1 = {
-- Name of the numbering subset (not really used; at the moment I just need one input parameter to ground
-- the possible values to choose elsewhere).
-- Expected format: "VALUE"
name = "sole",
-- Whether a vector defined on this numbering subset might be used to compute a movemesh. If true, a
-- FEltSpace featuring this numbering subset will compute additional quantities to enable fast computation.
-- This should be false for most numbering subsets, and when it's true the sole unknown involved should be a
-- displacement.
-- Expected format: 'true' or 'false' (without the quote)