Commit 0667c53a authored by GILLES Sebastien's avatar GILLES Sebastien

#1421 Output directory now will be written into a subdirectory named "Rank_*"...

#1421 Output directory now will be written into a subdirectory named "Rank_*" (except for very global files).

Therefore, the files with names such as ****_proc*n*_  have been renamed to remove the now unneeded part specifying the rank involved.

All the tests have been adapted accordingly, and the way the time iteration file is written has been modified as well.
parent aa1d42a3
......@@ -1592,6 +1592,9 @@
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 */; };
BEF4A6E022E1BF0400CD4A6E /* OutputDirectoryStorage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BEF4A6DD22E1BF0400CD4A6E /* OutputDirectoryStorage.cpp */; };
BEF4A6E122E1BF0400CD4A6E /* OutputDirectoryStorage.hxx in Headers */ = {isa = PBXBuildFile; fileRef = BEF4A6DE22E1BF0400CD4A6E /* OutputDirectoryStorage.hxx */; };
BEF4A6E222E1BF0400CD4A6E /* OutputDirectoryStorage.hpp in Headers */ = {isa = PBXBuildFile; fileRef = BEF4A6DF22E1BF0400CD4A6E /* OutputDirectoryStorage.hpp */; };
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 */; };
......@@ -3962,8 +3965,8 @@
BE6E4EDE1B2ABE8B0049BB2D /* AccessGhostContent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessGhostContent.cpp; sourceTree = "<group>"; };
BE6E4EDF1B2ABE8B0049BB2D /* AccessGhostContent.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = AccessGhostContent.hpp; sourceTree = "<group>"; };
BE6E4EE01B2ABE8B0049BB2D /* AccessGhostContent.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = AccessGhostContent.hxx; sourceTree = "<group>"; };
BE6EA61E1EC32FFB0085E651 /* demo_input_elasticity_3d.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = demo_input_elasticity_3d.lua; sourceTree = "<group>"; };
BE6EA61F1EC32FFB0085E651 /* demo_input_elasticity.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = demo_input_elasticity.lua; sourceTree = "<group>"; };
BE6EA61E1EC32FFB0085E651 /* demo_3d.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = demo_3d.lua; sourceTree = "<group>"; };
BE6EA61F1EC32FFB0085E651 /* demo_2d.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = demo_2d.lua; sourceTree = "<group>"; };
BE6EA6201EC330820085E651 /* demo_input_hyperelasticity.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = demo_input_hyperelasticity.lua; sourceTree = "<group>"; };
BE6EA6211EC331BC0085E651 /* demo_input_heat_1d.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = demo_input_heat_1d.lua; sourceTree = "<group>"; };
BE6EA6221EC331BC0085E651 /* demo_input_heat.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = demo_input_heat.lua; sourceTree = "<group>"; };
......@@ -4030,8 +4033,8 @@
BE7ABCD522DCADAD00238C51 /* WritePrepartitionedData.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = WritePrepartitionedData.cpp; path = Advanced/WritePrepartitionedData.cpp; sourceTree = "<group>"; };
BE7ABCD722DCADAD00238C51 /* WritePrepartitionedData.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = WritePrepartitionedData.hpp; path = Advanced/WritePrepartitionedData.hpp; sourceTree = "<group>"; };
BE7ABCDC22DCC16400238C51 /* WritePrepartitionedData.hxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = WritePrepartitionedData.hxx; path = Advanced/WritePrepartitionedData.hxx; sourceTree = "<group>"; };
BE7ABCE822DCDF0100238C51 /* demo_input_elasticity_3d_binary.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = demo_input_elasticity_3d_binary.lua; sourceTree = "<group>"; };
BE7ABCE922DCDF0100238C51 /* demo_input_elasticity_binary.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = demo_input_elasticity_binary.lua; sourceTree = "<group>"; };
BE7ABCE822DCDF0100238C51 /* demo_3d_binary.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = demo_3d_binary.lua; sourceTree = "<group>"; };
BE7ABCE922DCDF0100238C51 /* demo_2d_binary.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = demo_2d_binary.lua; sourceTree = "<group>"; };
BE7C1D0B1F4F2C8C000403E7 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
BE7C1D0D1F4F2E8B000403E7 /* demo_input_parameter_movemesh.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = demo_input_parameter_movemesh.lua; sourceTree = "<group>"; };
BE7C942C1F5FE614003D2C52 /* InputData.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = InputData.hpp; sourceTree = "<group>"; };
......@@ -4783,6 +4786,9 @@
BEF3B486212DB17F00807965 /* ForUnknownList.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ForUnknownList.hpp; sourceTree = "<group>"; };
BEF3B487212DB17F00807965 /* ForUnknownList.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ForUnknownList.hxx; sourceTree = "<group>"; };
BEF3B488212DB17F00807965 /* ForUnknownList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ForUnknownList.cpp; sourceTree = "<group>"; };
BEF4A6DD22E1BF0400CD4A6E /* OutputDirectoryStorage.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = OutputDirectoryStorage.cpp; sourceTree = "<group>"; };
BEF4A6DE22E1BF0400CD4A6E /* OutputDirectoryStorage.hxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = OutputDirectoryStorage.hxx; sourceTree = "<group>"; };
BEF4A6DF22E1BF0400CD4A6E /* OutputDirectoryStorage.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = OutputDirectoryStorage.hpp; 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>"; };
......@@ -8136,10 +8142,10 @@
children = (
BE964C7D206E8E3B00B9ED1E /* CMakeLists.txt */,
BEB0C6161EC304EF00D62905 /* README */,
BE6EA61E1EC32FFB0085E651 /* demo_input_elasticity_3d.lua */,
BE6EA61F1EC32FFB0085E651 /* demo_input_elasticity.lua */,
BE7ABCE822DCDF0100238C51 /* demo_input_elasticity_3d_binary.lua */,
BE7ABCE922DCDF0100238C51 /* demo_input_elasticity_binary.lua */,
BE6EA61E1EC32FFB0085E651 /* demo_3d.lua */,
BE6EA61F1EC32FFB0085E651 /* demo_2d.lua */,
BE7ABCE822DCDF0100238C51 /* demo_3d_binary.lua */,
BE7ABCE922DCDF0100238C51 /* demo_2d_binary.lua */,
BE4478861AA740F800665010 /* main.cpp */,
BE3B35FB1D91792500DB81A3 /* main_ensight_output.cpp */,
BE8E21C8207E9D3000E24E6D /* test_results.cpp */,
......@@ -9778,6 +9784,9 @@
BE4A09BA1C6B46E6002799C0 /* MovemeshHelper.cpp */,
BE4A09BB1C6B46E6002799C0 /* MovemeshHelper.hpp */,
BE4A09BC1C6B46E6002799C0 /* MovemeshHelper.hxx */,
BEF4A6DD22E1BF0400CD4A6E /* OutputDirectoryStorage.cpp */,
BEF4A6DF22E1BF0400CD4A6E /* OutputDirectoryStorage.hpp */,
BEF4A6DE22E1BF0400CD4A6E /* OutputDirectoryStorage.hxx */,
BEBEB21D19C849C200E4EA1D /* Impl */,
);
path = Internal;
......@@ -11100,6 +11109,7 @@
BE90E1311A2491AE00CCAFDE /* Dof.hpp in Headers */,
BE2B66361A2778C700E80864 /* BasicRefFElt.hpp in Headers */,
BE9B82871D81881E00BA174F /* TetrahedronP1Bubble.hpp in Headers */,
BEF4A6E122E1BF0400CD4A6E /* OutputDirectoryStorage.hxx in Headers */,
BE2B663E1A2778C700E80864 /* GeometryBasedBasicRefFElt.hxx in Headers */,
BE90E1291A2491AE00CCAFDE /* Node.hxx in Headers */,
BE510D8C1CB3D44900E953FE /* Comp2.hpp in Headers */,
......@@ -11165,6 +11175,7 @@
BE2B66631A2778C700E80864 /* RefLocalFEltSpace.hpp in Headers */,
BE3E664E1ACEB94E00A3F7E2 /* Connectivity.hpp in Headers */,
BE63C1511B21876B00978D05 /* SegmentP0.hpp in Headers */,
BEF4A6E222E1BF0400CD4A6E /* OutputDirectoryStorage.hpp in Headers */,
BE2B66581A2778C700E80864 /* BasicRefFEltFactory.hpp in Headers */,
BEDEB9521C3C0A4F00B1C71B /* DofProgramWiseIndexListPerVertexCoordIndexList.hpp in Headers */,
BE2B66451A2778C700E80864 /* Spectral.hpp in Headers */,
......@@ -12632,6 +12643,7 @@
BE90E06C1A2491AE00CCAFDE /* ComputeMatrixPattern.cpp in Sources */,
BE90E1091A2491AE00CCAFDE /* Segment.cpp in Sources */,
BE63C1501B21876B00978D05 /* SegmentP0.cpp in Sources */,
BEF4A6E022E1BF0400CD4A6E /* OutputDirectoryStorage.cpp in Sources */,
BE90E0701A2491AE00CCAFDE /* CreateNodeListHelper.cpp in Sources */,
BE2B664F1A2778C700E80864 /* BasicRefFEltFactory.cpp in Sources */,
BE2B66621A2778C700E80864 /* RefLocalFEltSpace.cpp in Sources */,
......@@ -74,7 +74,7 @@
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument
argument = "-i ${HOME}/Codes/MoReFEM/CoreLibrary/Sources/ModelInstances/Elasticity/demo_input_elasticity.lua"
argument = "-i ${HOME}/Codes/MoReFEM/CoreLibrary/Sources/ModelInstances/Elasticity/demo_2d.lua"
isEnabled = "YES">
</CommandLineArgument>
</CommandLineArguments>
......
......@@ -63,11 +63,11 @@
</BuildableProductRunnable>
<CommandLineArguments>
<CommandLineArgument
argument = "-i ${HOME}/Codes/MoReFEM/CoreLibrary/Sources/ModelInstances/Elasticity/demo_input_elasticity.lua"
argument = "-i ${HOME}/Codes/MoReFEM/CoreLibrary/Sources/ModelInstances/Elasticity/demo_2d.lua"
isEnabled = "NO">
</CommandLineArgument>
<CommandLineArgument
argument = "-i ${HOME}/Codes/MoReFEM/CoreLibrary/Sources/ModelInstances/Elasticity/demo_input_elasticity_3d.lua"
argument = "-i ${HOME}/Codes/MoReFEM/CoreLibrary/Sources/ModelInstances/Elasticity/demo_3d.lua"
isEnabled = "YES">
</CommandLineArgument>
</CommandLineArguments>
......
......@@ -19,14 +19,13 @@ namespace MoReFEM
{
void InitTimeKeepLog(const Wrappers::Mpi& mpi,
const std::string& result_directory)
void InitTimeKeepLog(const std::string& result_directory)
{
std::string time_log_filename;
{
std::ostringstream oconv;
oconv << result_directory << "/time_log." << mpi.template GetRank<int>() << ".hhdata";
oconv << result_directory << "/time_log.hhdata";
time_log_filename = oconv.str();
}
......
......@@ -37,12 +37,10 @@ namespace MoReFEM
*
* This function is to be called early in your main if you want to time keep some information lines.
*
* \copydetails doxygen_hide_mpi_param
* \param[in] result_directory Directory into which all outputs should be written. It is assumed to exist when
* it is given to this function.
*/
void InitTimeKeepLog(const Wrappers::Mpi& mpi,
const std::string& result_directory);
void InitTimeKeepLog(const std::string& result_directory);
......
......@@ -26,7 +26,7 @@
# include "Utilities/Mpi/Mpi.hpp"
# include "Core/MoReFEMData/MoReFEMData.hpp" // not used here directly, but all models which include current header
// nedd this one at the same time.
// needs this one at the same time.
namespace MoReFEM
......
......@@ -17,6 +17,7 @@
# include "ThirdParty/Wrappers/Mpi/Mpi.hpp"
# include "ThirdParty/Wrappers/Mpi/MpiScale.hpp"
# include "ThirdParty/Wrappers/Petsc/Petsc.hpp"
# include "ThirdParty/Wrappers/Petsc/Print.hpp"
# include "ThirdParty/Wrappers/Tclap/StringPair.hpp"
......@@ -46,6 +47,7 @@ namespace MoReFEM
{ };
/*!
* \brief Init MoReFEM: initialize mpi and read the input data file.
*
......@@ -111,13 +113,20 @@ namespace MoReFEM
///@}
//! Accessor to underlying mpi object.
const Wrappers::Mpi& GetMpi() const;
const Wrappers::Mpi& GetMpi() const noexcept;
//! Accessor to underlying InputData object.
const InputDataT& GetInputData() const;
const InputDataT& GetInputData() const noexcept;
//! Accessor to the result directory, in which all the outputs of MoReFEM should be written.
const std::string& GetResultDirectory() const;
/*!
* \brief Accessor to the result directory, in which all the outputs of MoReFEM should be written.
*
* \tparam MpiScaleT If MpiScale::processor-wise, return the subdirectory which also specifies the rank.
* If MpiScale::program_wise, returns the
* result directory. The latter is expected to be used mostly on the root processor.
*/
template<MpiScale MpiScaleT>
const std::string& GetResultDirectory() const noexcept;
private:
......@@ -130,9 +139,13 @@ namespace MoReFEM
//! Holds InputData.
typename InputDataT::const_unique_ptr input_data_ = nullptr;
//! Result directory, in which all the outputs of MoReFEM should be written.
//! Directory into which model results will be written (with a folder hierarchy)
std::string result_directory_;
//! Subdirectory of \a result_directory_ in which informations related to current rank are written.
std::string result_directory_with_rank_;
};
......
......@@ -192,8 +192,13 @@ namespace MoReFEM
result_directory_ = ipl::Extract<Result::OutputDirectory>::Folder(*input_data_);
InitTimeKeepLog(mpi, result_directory_);
result_directory_with_rank_ = result_directory_ + "/Rank_" + std::to_string(mpi.template GetRank<int>());
if (!FilesystemNS::Folder::DoExist(result_directory_with_rank_))
FilesystemNS::Folder::Create(result_directory_with_rank_, __FILE__, __LINE__);
InitTimeKeepLog(result_directory_);
const auto& binary_output = ipl::Extract<Result::BinaryOutput>::Value(*input_data_);
Utilities::OutputFormat::CreateOrGetInstance(__FILE__, __LINE__, binary_output);
}
......@@ -241,7 +246,7 @@ namespace MoReFEM
>
inline const Wrappers::Mpi&
MoReFEMData<InputDataT, DoTrackUnusedFieldsT, AdditionalCommandLineArgumentsPolicyT>
::GetMpi() const
::GetMpi() const noexcept
{
assert(!(!mpi_));
return *mpi_;
......@@ -254,7 +259,8 @@ namespace MoReFEM
Utilities::InputDataNS::DoTrackUnusedFields DoTrackUnusedFieldsT,
class AdditionalCommandLineArgumentsPolicyT
>
const InputDataT& MoReFEMData<InputDataT, DoTrackUnusedFieldsT, AdditionalCommandLineArgumentsPolicyT>::GetInputData() const
const InputDataT& MoReFEMData<InputDataT, DoTrackUnusedFieldsT, AdditionalCommandLineArgumentsPolicyT>
::GetInputData() const noexcept
{
assert(!(!input_data_));
return *input_data_;
......@@ -267,10 +273,14 @@ namespace MoReFEM
Utilities::InputDataNS::DoTrackUnusedFields DoTrackUnusedFieldsT,
class AdditionalCommandLineArgumentsPolicyT
>
template<MpiScale MpiScaleT>
const std::string& MoReFEMData<InputDataT, DoTrackUnusedFieldsT, AdditionalCommandLineArgumentsPolicyT>
::GetResultDirectory() const
::GetResultDirectory() const noexcept
{
return result_directory_;
if constexpr (MpiScaleT == MpiScale::processor_wise)
return result_directory_with_rank_;
else
return result_directory_;
}
......
......@@ -71,10 +71,10 @@ namespace MoReFEM
/*!
* \brief Constructor.
*
* \copydoc doxygen_hide_input_data_arg
* \copydoc doxygen_hide_morefem_data_param
*/
template<class InputDataT>
explicit TimeManager(const InputDataT& input_data);
template<class MoReFEMDataT>
explicit TimeManager(const MoReFEMDataT& morefem_data);
//! Destructor.
virtual ~TimeManager();
......@@ -193,6 +193,9 @@ namespace MoReFEM
//! \copydoc doxygen_hide_time_manager_reset_time_manager_at_initial_time
virtual void ResetTimeManagerAtInitialTime() = 0;
//! Path to the time iteration file in which the files written are recorded with their time index.
const std::string& GetTimeIterationFile() const noexcept;
protected:
//! Current time (in seconds).
......@@ -207,6 +210,9 @@ namespace MoReFEM
private:
//! Path to the time iteration file in which the files written are recorded with their time index.
std::string time_iteration_file_;
//! Current time (in seconds).
double time_ = 0.;
......
......@@ -20,13 +20,33 @@ namespace MoReFEM
{
template<class InputDataT>
TimeManager::TimeManager(const InputDataT& input_data)
template<class MoReFEMDataT>
TimeManager::TimeManager(const MoReFEMDataT& morefem_data)
{
namespace IPL = Utilities::InputDataNS;
using TimeManager = InputDataNS::TimeManager;
time_ = IPL::Extract<TimeManager::TimeInit>::Value(input_data);
time_iteration_file_ = morefem_data.template GetResultDirectory<MpiScale::program_wise>() +
"/time_iteration.hhdata";
decltype(auto) mpi = morefem_data.GetMpi();
if (mpi.IsRootProcessor())
{
if (FilesystemNS::File::DoExist(time_iteration_file_))
{
std::cerr << "[WARNING] A file named " << time_iteration_file_ << " already existed; it has been removed "
"and recreated from scratch. Please consider using ${MOREFEM_START_TIME} in your result directory path "
"to guarantee each run gets its outputs written in an empty directory." << std::endl;
FilesystemNS::File::Remove(time_iteration_file_, __FILE__, __LINE__);
}
std::ofstream stream;
FilesystemNS::File::Create(stream, time_iteration_file_, __FILE__, __LINE__);
stream << "# Time iteration; time; numbering subset id; filename" << std::endl;
}
time_ = IPL::Extract<TimeManager::TimeInit>::Value(morefem_data.GetInputData());
}
......@@ -81,6 +101,14 @@ namespace MoReFEM
}
inline const std::string& TimeManager::GetTimeIterationFile() const noexcept
{
assert(!time_iteration_file_.empty());
assert(FilesystemNS::File::DoExist(time_iteration_file_));
return time_iteration_file_;
}
} // namespace MoReFEM
......
......@@ -52,10 +52,10 @@ namespace MoReFEM
/*!
* \brief Constructor.
*
* \copydoc doxygen_hide_input_data_arg
* \copydoc doxygen_hide_morefem_data_param
*/
template<class InputDataT>
explicit TimeManagerInstance(const InputDataT& input_data);
template<class MoReFEMDataT>
explicit TimeManagerInstance(const MoReFEMDataT& morefem_data);
//! Destructor.
~TimeManagerInstance() override = default;
......
......@@ -17,15 +17,14 @@
namespace MoReFEM
{
{
template<class EvolutionPolicyT>
template<class InputDataT>
TimeManagerInstance<EvolutionPolicyT>::TimeManagerInstance(const InputDataT& input_data)
: TimeManager(input_data),
EvolutionPolicyT(input_data)
template<class MoReFEMDataT>
TimeManagerInstance<EvolutionPolicyT>::TimeManagerInstance(const MoReFEMDataT& morefem_data)
: TimeManager(morefem_data),
EvolutionPolicyT(morefem_data.GetInputData())
{ }
......
......@@ -80,7 +80,8 @@ namespace MoReFEM
}
void GodOfDof::Init1(FEltSpace::vector_unique_ptr&& a_felt_space_list,
void GodOfDof::Init1(std::string&& output_directory,
FEltSpace::vector_unique_ptr&& a_felt_space_list,
std::map<unsigned int, std::vector<unsigned int>>& dof_list_per_felt_space)
{
assert(!HasInitBeenCalled() && "Must be called only once per GodOfDof!");
......@@ -98,7 +99,16 @@ namespace MoReFEM
ComputeNumberingSubsetList();
SetOutputDirectoryPerNumberingSubset();
decltype(auto) numbering_subset_list = GetNumberingSubsetList();
output_directory_storage_ =
std::make_unique<Internal::GodOfDofNS::OutputDirectoryStorage>(output_directory,
numbering_subset_list);
output_directory_wildcard_storage_ =
std::make_unique<Internal::GodOfDofNS::OutputDirectoryStorage>(output_directory,
numbering_subset_list,
Internal::GodOfDofNS::wildcard_for_rank::yes);
const auto& mpi = GetMpi();
const auto rank = mpi.GetRank<unsigned int>();
......@@ -132,9 +142,6 @@ namespace MoReFEM
}
}
const auto& numbering_subset_list = GetNumberingSubsetList();
// Give each dof its program-wise index for each numbering subset.
{
for (const auto& numbering_subset_ptr : numbering_subset_list)
......@@ -829,22 +836,7 @@ namespace MoReFEM
const auto& mpi = GetMpi();
{
time_iteration_file_ = GetOutputDirectory() + "/time_iteration.hhdata";
if (mpi.IsRootProcessor())
{
if (!FilesystemNS::File::DoExist(time_iteration_file_))
{
std::ofstream stream;
FilesystemNS::File::Create(stream, time_iteration_file_, __FILE__, __LINE__);
stream << "# Time iteration; time; numbering subset id; filename" << std::endl;
}
}
}
// First create all the relevant folders; make sure this is done before any processor attempts to create a file.
if (mpi.IsRootProcessor())
{
for (const auto& numbering_subset_ptr : numbering_subset_list)
{
......@@ -876,7 +868,7 @@ namespace MoReFEM
// Report the dof informations.
std::ostringstream oconv;
oconv << subfolder << "/dof_information_proc_" << mpi.GetRank<int>() << ".hhdata";
oconv << subfolder << "/dof_information.hhdata";
std::ofstream out;
FilesystemNS::File::Create(out, oconv.str(), __FILE__, __LINE__);
PrintDofInformation(numbering_subset, out);
......@@ -884,21 +876,6 @@ namespace MoReFEM
}
const std::string& GodOfDof::GetOutputDirectoryForNumberingSubset(const NumberingSubset& numbering_subset) const
{
const auto id = numbering_subset.GetUniqueId();
decltype(auto) output_directory_per_numbering_subset = GetOutputDirectoryPerNumberingSubset();
const auto it = output_directory_per_numbering_subset.find(id);
assert(it != output_directory_per_numbering_subset.cend() &&
"All relevant numbering subsets should have been loaded into the map.");
return it->second;
}
bool GodOfDof::IsGhosted(const Dof& dof) const
{
const auto& ghosted_dof_list = GetGhostedDofList();
......@@ -1043,8 +1020,6 @@ namespace MoReFEM
assert(!(!felt_ptr));
felt_ptr->ClearTemporaryData();
}
}
......@@ -1306,31 +1281,6 @@ namespace MoReFEM
}
void GodOfDof::SetOutputDirectoryPerNumberingSubset()
{
decltype(auto) numbering_subset_list = GetNumberingSubsetList();
std::ostringstream oconv;
output_directory_per_numbering_subset_.max_load_factor(Utilities::DefaultMaxLoadFactor());
for (const auto& numbering_subset_ptr : numbering_subset_list)
{
assert(!(!numbering_subset_ptr));
const auto& numbering_subset = *numbering_subset_ptr;
const auto numbering_subset_id = numbering_subset.GetUniqueId();
oconv.str("");
oconv << GetOutputDirectory() << "/NumberingSubset_" << numbering_subset_id;
auto check = output_directory_per_numbering_subset_.insert(std::make_pair(numbering_subset_id, oconv.str()));
assert(check.second);
}
}
} // namespace MoReFEM
......
......@@ -31,6 +31,7 @@
# include "FiniteElement/FiniteElementSpace/Internal/MatrixPattern.hpp"
# include "FiniteElement/FiniteElementSpace/Internal/ComputeMatrixPattern.hpp"
# include "FiniteElement/FiniteElementSpace/Internal/DofProgramWiseIndexListPerVertexCoordIndexListManager.hpp"
# include "FiniteElement/FiniteElementSpace/Internal/OutputDirectoryStorage.hpp"
# include "FiniteElement/BoundaryConditions/DirichletBoundaryCondition.hpp"
......@@ -302,6 +303,7 @@ namespace MoReFEM
const NumberingSubset::const_shared_ptr& GetNumberingSubsetPtr(unsigned int unique_id) const;
//! Get the output directory.
template<Internal::GodOfDofNS::wildcard_for_rank is_wildcard = Internal::GodOfDofNS::wildcard_for_rank::no>
const std::string& GetOutputDirectory() const noexcept;
......@@ -320,12 +322,9 @@ namespace MoReFEM
*
* \return Name of the subfolder related to a given numbering subset.
*/
template<Internal::GodOfDofNS::wildcard_for_rank is_wildcard = Internal::GodOfDofNS::wildcard_for_rank::no>
const std::string& GetOutputDirectoryForNumberingSubset(const NumberingSubset& numbering_subset) const;
//! Get the path of the time iteration file.
const std::string& GetTimeIterationFile() const noexcept;
//! Clear the temporary data used to build properly the Internal::FEltNS::Local2GlobalStorage objects.
void ClearTemporaryData() const noexcept;
......@@ -502,10 +501,11 @@ namespace MoReFEM
*
* \param[in] felt_space_list List of all \a FEltSpace to consider in the \a GodOfDof.
* \param[out] \copydetails doxygen_hide_dof_list_per_felt_space_arg
*
* \param[in] output_directory Output directory for data specific to the mesh covered by the \a GodOfDof.
*
*/
void Init1(FEltSpace::vector_unique_ptr&& felt_space_list,
void Init1(std::string&& output_directory,
FEltSpace::vector_unique_ptr&& felt_space_list,
std::map<unsigned int, std::vector<unsigned int>>& dof_list_per_felt_space);
......@@ -547,14 +547,6 @@ namespace MoReFEM
*/
DoConsiderProcessorWiseLocal2Global GetDoConsiderProcessorWiseLocal2Global() const;
private:
//! Set the values of \a output_directory_per_numbering_subset_.
void SetOutputDirectoryPerNumberingSubset();
//! For each \a NumberingSubset id, keep the associated output directory path.
const std::unordered_map<unsigned int, std::string>& GetOutputDirectoryPerNumberingSubset() const noexcept;
private:
//! List of all finite element spaces related to the mesh covered by GodOfDof.
......@@ -575,6 +567,12 @@ namespace MoReFEM
//! Objects that counts the number of dofs in several configurations.
Internal::FEltSpaceNS::NdofHolder::const_unique_ptr Ndof_holder_ = nullptr;
//! Object in charge of storing output directories.
Internal::GodOfDofNS::OutputDirectoryStorage::const_unique_ptr output_directory_storage_ = nullptr;
//! Object in charge of storing output directories with wildcarfs instead of rank id (for use in output files).
Internal::GodOfDofNS::OutputDirectoryStorage::const_unique_ptr output_directory_wildcard_storage_ = nullptr;
/*!
* \brief List of processor-wise dofs.
*
......@@ -596,15 +594,9 @@ namespace MoReFEM
//! CSR Pattern of the matrix.
Internal::FEltSpaceNS::MatrixPattern::vector_const_unique_ptr matrix_pattern_per_numbering_subset_;
//! Path to the output directory into which god of dof data are written.
std::string output_directory_;
//! Path of the file listing the time iterations and the related files.
std::string time_iteration_file_;
//! For each \a NumberingSubset id, keep the associated output directory path.
std::unordered_map<unsigned int, std::string> output_directory_per_numbering_subset_;
# ifndef NDEBUG
/*!
* \brief Whether Init() has already been called or not.
......
......@@ -27,12 +27,14 @@ namespace MoReFEM
DoConsiderProcessorWiseLocal2Global do_consider_proc_wise_local_2_global,
std::string&& output_directory)
{
output_directory_ = std::move(output_directory);
std::map<unsigned int, std::vector<unsigned int>> dof_list_per_felt_space;