Commit 13e3adc9 authored by GILLES Sebastien's avatar GILLES Sebastien

#1478 MoReFEMData: use helper functions to make the constructor clearer

parent 73412706
......@@ -575,6 +575,9 @@
BE3B36831D9183FD00DB81A3 /* libGeometry.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BE05B4DD16D23573000E248D /* libGeometry.a */; };
BE3B36841D9183FD00DB81A3 /* libUtilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BEA8A379177AD4FE009436C9 /* libUtilities.a */; };
BE3B36861D9183FD00DB81A3 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BEC37E0617DDC0210021BFB7 /* Accelerate.framework */; };
BE3B7E2F22F0A20200F76A79 /* Helper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BE3B7E2C22F0A20200F76A79 /* Helper.cpp */; };
BE3B7E3022F0A20200F76A79 /* Helper.hxx in Headers */ = {isa = PBXBuildFile; fileRef = BE3B7E2D22F0A20200F76A79 /* Helper.hxx */; };
BE3B7E3122F0A20200F76A79 /* Helper.hpp in Headers */ = {isa = PBXBuildFile; fileRef = BE3B7E2E22F0A20200F76A79 /* Helper.hpp */; };
BE3D12BF1D9B1FFB00F900F5 /* KspConvergenceReason.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BE3D12B91D9B1FFB00F900F5 /* KspConvergenceReason.cpp */; };
BE3D12C01D9B1FFB00F900F5 /* KspConvergenceReason.hpp in Headers */ = {isa = PBXBuildFile; fileRef = BE3D12BA1D9B1FFB00F900F5 /* KspConvergenceReason.hpp */; };
BE3D12C11D9B1FFB00F900F5 /* KspConvergenceReason.hxx in Headers */ = {isa = PBXBuildFile; fileRef = BE3D12BB1D9B1FFB00F900F5 /* KspConvergenceReason.hxx */; };
......@@ -3474,6 +3477,9 @@
BE3B366D1D9183C200DB81A3 /* Ensight4Heat */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Ensight4Heat; sourceTree = BUILT_PRODUCTS_DIR; };
BE3B368B1D9183FD00DB81A3 /* Ensight4RivlinCube */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Ensight4RivlinCube; sourceTree = BUILT_PRODUCTS_DIR; };
BE3B7E2822F02AFE00F76A79 /* demo_test.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = demo_test.lua; sourceTree = "<group>"; };
BE3B7E2C22F0A20200F76A79 /* Helper.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Helper.cpp; sourceTree = "<group>"; };
BE3B7E2D22F0A20200F76A79 /* Helper.hxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Helper.hxx; sourceTree = "<group>"; };
BE3B7E2E22F0A20200F76A79 /* Helper.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Helper.hpp; sourceTree = "<group>"; };
BE3D12B91D9B1FFB00F900F5 /* KspConvergenceReason.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KspConvergenceReason.cpp; sourceTree = "<group>"; };
BE3D12BA1D9B1FFB00F900F5 /* KspConvergenceReason.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = KspConvergenceReason.hpp; sourceTree = "<group>"; };
BE3D12BB1D9B1FFB00F900F5 /* KspConvergenceReason.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = KspConvergenceReason.hxx; sourceTree = "<group>"; };
......@@ -8660,6 +8666,9 @@
children = (
BE7E555222EF507A00BEA053 /* Parallelism.hpp */,
BE7E555122EF507A00BEA053 /* Parallelism.hxx */,
BE3B7E2C22F0A20200F76A79 /* Helper.cpp */,
BE3B7E2E22F0A20200F76A79 /* Helper.hpp */,
BE3B7E2D22F0A20200F76A79 /* Helper.hxx */,
);
path = Internal;
sourceTree = "<group>";
......@@ -10955,6 +10964,7 @@
BE4D0D2821A2E4F900E0D4E7 /* NumberingSubset.hpp in Headers */,
BE4D0D7521A2E4F900E0D4E7 /* SpatialFunction.hpp in Headers */,
BE6462341AEE1AE100D5162A /* GlobalMatrix.hpp in Headers */,
BE3B7E3122F0A20200F76A79 /* Helper.hpp in Headers */,
BE4D0D5221A2E4F900E0D4E7 /* AnalyticalPrestress.hxx in Headers */,
BE64623A1AEE1AEF00D5162A /* GlobalVector.hpp in Headers */,
BE4D0D3621A2E4F900E0D4E7 /* Petsc.hxx in Headers */,
......@@ -10971,6 +10981,7 @@
BE8B67401CC0EA9100312399 /* FindFunctor.hxx in Headers */,
BEBE35B71C58FECD00392CCC /* GlobalDiagonalMatrix.hxx in Headers */,
BE4D0D6921A2E4F900E0D4E7 /* VolumicMass.hpp in Headers */,
BE3B7E3022F0A20200F76A79 /* Helper.hxx in Headers */,
BE7E552822EF280E00BEA053 /* Parallelism.hpp in Headers */,
BE4D0D8A21A2E4F900E0D4E7 /* Domain.hxx in Headers */,
BE4D0D6A21A2E4F900E0D4E7 /* VolumicMass.hxx in Headers */,
......@@ -12603,6 +12614,7 @@
BE7818791E82BD5F00FF503D /* EnsightCaseReader.cpp in Sources */,
BE4D0D4321A2E4F900E0D4E7 /* Heart.cpp in Sources */,
BE4D0D7121A2E4F900E0D4E7 /* Fiber.cpp in Sources */,
BE3B7E2F22F0A20200F76A79 /* Helper.cpp in Sources */,
BE6462391AEE1AEF00D5162A /* GlobalVector.cpp in Sources */,
BE4D0D7F21A2E4F900E0D4E7 /* PseudoNormals.cpp in Sources */,
BE4D0D6021A2E4F900E0D4E7 /* Kappa2.cpp in Sources */,
//! \file
//
//
// Helper.cpp
// MoReFEM
//
// Created by sebastien on 30/07/2019.
//Copyright © 2019 Inria. All rights reserved.
//
#include "ThirdParty/Wrappers/Mpi/Mpi.hpp"
#include "Utilities/Datetime/Now.hpp"
#include "Utilities/Filesystem/Folder.hpp"
#include "Core/MoReFEMData/Internal/Helper.hpp"
namespace MoReFEM::Internal::MoReFEMDataNS
{
void DefineEnvironmentVariable(const ::MoReFEM::Wrappers::Mpi& mpi)
{
const char* const result_dir = "MOREFEM_RESULT_DIR";
auto& environment = Utilities::Environment::CreateOrGetInstance(__FILE__, __LINE__);
if (!environment.DoExist(result_dir))
{
const char* const default_value("/Volumes/Data/${USER}/MoReFEM/Results");
environment.SetEnvironmentVariable(std::make_pair("MOREFEM_RESULT_DIR", default_value),
__FILE__, __LINE__);
std::cout << "[WARNING] Environment variable '" << result_dir << "' was not defined; default value '"
<< default_value << "' has therefore be provided. This environment variable may appear in mesh "
"directory defined in input data file; if not it is in fact unused." << std::endl;
}
const char* const morefem_dir = "MOREFEM_ROOT";
if (!environment.DoExist(morefem_dir))
{
const char* const default_value("${HOME}/Codes/MoReFEM/CoreLibrary");
environment.SetEnvironmentVariable(std::make_pair("MOREFEM_ROOT", default_value),
__FILE__, __LINE__);
std::cout << "[WARNING] Environment variable '" << morefem_dir << "' was not defined; default value '"
<< default_value << "' has therefore be provided. This environment variable may appear in output "
"directory defined in input data file; if not it is in fact unused." << std::endl;
}
std::string start_time = "MOREFEM_START_TIME";
if (!environment.DoExist(start_time))
{
environment.SetEnvironmentVariable(std::make_pair(start_time, ::MoReFEM::Utilities::Now(mpi)),
__FILE__, __LINE__);
mpi.Barrier();
}
}
void CheckExistingForAllRank(const ::MoReFEM::Wrappers::Mpi& mpi,
const std::string& input_data_file)
{
// Check the input data file can be found on each processor.
const bool do_file_exist_for_rank = FilesystemNS::File::DoExist(input_data_file) ;
std::vector<bool> sent_data { do_file_exist_for_rank };
std::vector<bool> gathered_data;
mpi.Gather(sent_data, gathered_data);
// Root processor sent true if all files exist for all ranks, false otherwise.
// Beware (#461): it doesn't check here the file is consistent!
std::vector<bool> do_file_exist_for_all_ranks { true };
std::vector<std::size_t> rank_without_file;
if (mpi.IsRootProcessor())
{
for (std::size_t i = 0ul, Nproc = gathered_data.size(); i < Nproc; ++i)
{
if (!gathered_data[i])
rank_without_file.push_back(i);
}
if (!rank_without_file.empty())
do_file_exist_for_all_ranks.back() = false;
}
mpi.Broadcast(do_file_exist_for_all_ranks);
if (mpi.IsRootProcessor())
{
if (!rank_without_file.empty())
{
std::ostringstream oconv;
oconv << "The following ranks couldn't find the input data file: ";
Utilities::PrintContainer<>::Do(rank_without_file, oconv, ", ", "", ".\n");
throw Exception(oconv.str(), __FILE__, __LINE__);
}
}
else
{
if (do_file_exist_for_all_ranks.back() == false)
throw Exception("Input data file not found for one or more rank; see root processor "
"exception for more details!", __FILE__, __LINE__);
}
}
void AskResultDirectoryRemoval(const std::string& directory)
{
if (FilesystemNS::Folder::DoExist(directory))
{
std::string answer;
while (answer != "y" || answer != "n")
{
do
{
std::cin.clear(); // clear the states of std::cin, putting it back to `goodbit`.
std::cin.ignore(10000, '\n'); // clean-up what might remain in std::cin before using it again.
std::cout << "Directory '" << directory << "' already exists. Do you want to remove it? "
"[y/n]" << std::endl;
std::cin >> answer;
} while (!std::cin);
}
if (answer == "n")
{
std::cout << "The program will therefore exit here." << std::endl;
exit(EXIT_SUCCESS);
}
FilesystemNS::Folder::Remove(directory, __FILE__, __LINE__);
}
}
} // namespace MoReFEM::Internal::MoReFEMDataNS
//! \file
//
//
// Helper.hpp
// MoReFEM
//
// Created by sebastien on 30/07/2019.
//Copyright © 2019 Inria. All rights reserved.
//
#ifndef MOREFEM_x_CORE_x_MO_RE_F_E_M_DATA_x_INTERNAL_x_HELPER_HPP_
# define MOREFEM_x_CORE_x_MO_RE_F_E_M_DATA_x_INTERNAL_x_HELPER_HPP_
# include <cassert>
# include <string>
# include "Utilities/InputData/Base.hpp"
# include "Utilities/Exceptions/Exception.hpp"
# include "Utilities/Environment/Environment.hpp"
# include "Utilities/InputData/Base.hpp"
# include "ThirdParty/Wrappers/Tclap/StringPair.hpp"
# include "ThirdParty/IncludeWithoutWarning/Tclap/Tclap.hpp"
namespace MoReFEM
{
// ============================
//! \cond IGNORE_BLOCK_IN_DOXYGEN
// Forward declarations.
// ============================
namespace Wrappers
{
class Mpi;
} // namespace Wrappers
// ============================
// End of forward declarations.
//! \endcond IGNORE_BLOCK_IN_DOXYGEN
// ============================
}
namespace MoReFEM::Internal::MoReFEMDataNS
{
/*!
* \brief Parse the command line and extract its informations.
*
* \tparam AdditionalCommandLineArgumentsPolicyT Policy if you need additional arguments on the command line.
* To see a concrete example of this possibility, have a look at Test/Core/MoReFEMData/test_command_line_options.cpp
* which demonstrate the possibility. If none, use std::false_type.
* \param[in] argc Number of argument in the command line (including the program name).
* \param[in] argv List of arguments read.
* \param[in] additional If AdditionalCommandLineArgumentsPolicyT is not nullptr, give it the this pointer of
* MoReFEMData
*
* \return Path of the input data file.
*/
template<class AdditionalCommandLineArgumentsPolicyT>
std::string ParseCommandLine(int argc, char** argv,
AdditionalCommandLineArgumentsPolicyT* additional = nullptr);
/*!
* \brief Define the few environment variables required to make MoReEM work properly.
*
* \copydetails doxygen_hide_mpi_param
*/
void DefineEnvironmentVariable(const ::MoReFEM::Wrappers::Mpi& mpi);
/*!
* \brief Create of not already existing the input data file, with the fields given in \a TupleT.
*
* This function is intended to be run only on root processor (once the file is done it's up to the user to
* propagate it on all ranks - if the same filesystem is not used for all ranks).
*
* \tparam TupleT The type of the tuple which defines the structure of the input data.
*
* \param[in] input_data_file Path to the input data file to be created.
*/
template<class TupleT>
void CreateIfNotExisting(const std::string& input_data_file);
/*!
* \brief Check the input data file was properly found for all ranks.
*
* If not, an exception is thrown.
*
* \copydetails doxygen_hide_mpi_param
* \param[in] input_data_file Path to the input data file to be created.
*/
void CheckExistingForAllRank(const ::MoReFEM::Wrappers::Mpi& mpi,
const std::string& input_data_file);
/*!
* \brief If \a directory already exists, ask the user whereas he wants to remove it or stop the program.
*
* \param[in] directory Directory which existence is checked.
*/
void AskResultDirectoryRemoval(const std::string& directory);
} // namespace MoReFEM::Internal::MoReFEMDataNS
# include "Core/MoReFEMData/Internal/Helper.hxx"
#endif // MOREFEM_x_CORE_x_MO_RE_F_E_M_DATA_x_INTERNAL_x_HELPER_HPP_
//! \file
//
//
// Helper.hxx
// MoReFEM
//
// Created by sebastien on 30/07/2019.
//Copyright © 2019 Inria. All rights reserved.
//
#ifndef MOREFEM_x_CORE_x_MO_RE_F_E_M_DATA_x_INTERNAL_x_HELPER_HXX_
# define MOREFEM_x_CORE_x_MO_RE_F_E_M_DATA_x_INTERNAL_x_HELPER_HXX_
namespace MoReFEM::Internal::MoReFEMDataNS
{
template<class AdditionalCommandLineArgumentsPolicyT>
std::string ParseCommandLine(int argc, char** argv,
AdditionalCommandLineArgumentsPolicyT* additional)
{
std::string ret;
try
{
TCLAP::CmdLine cmd("Command description message");
cmd.setExceptionHandling(false);
TCLAP::ValueArg<std::string> input_data_file_arg("i",
"input_data",
"Input data file (Lua)",
true,
"",
"string",
cmd);
TCLAP::MultiArg<::MoReFEM::Wrappers::Tclap::StringPair> env_arg("e",
"env",
"environment_variable",
false,
"string=string",
cmd);
if constexpr (!std::is_same<AdditionalCommandLineArgumentsPolicyT, std::false_type>())
{
assert(!(!additional));
additional->Add(cmd);
}
cmd.parse(argc, argv);
decltype(auto) env_var_list = env_arg.getValue();
auto& environment = Utilities::Environment::CreateOrGetInstance(__FILE__, __LINE__);
for (const auto& pair : env_var_list)
environment.SetEnvironmentVariable(pair.GetValue(), __FILE__, __LINE__);
ret = input_data_file_arg.getValue();
return ret;
}
catch (TCLAP::ArgException &e) // catch any exceptions
{
std::ostringstream oconv;
oconv << "Caught command line exception " << e.error() << " for argument " << e.argId() << std::endl;
throw Exception(oconv.str(), __FILE__, __LINE__);
}
}
template<class TupleT>
void CreateIfNotExisting(const std::string& input_data_file)
{
if (!FilesystemNS::File::DoExist(input_data_file))
{
::MoReFEM::Utilities::InputDataNS::CreateDefaultInputFile<TupleT>(input_data_file);
std::cout << '\n' << input_data_file << " wasn't existing and has just been created on root processor; "
"please edit it and then copy it onto all machines intended to run the code in parallel." << std::endl;
throw Exception("Input data file to edit and complete!", __FILE__, __LINE__);
}
}
} // namespace MoReFEM::Internal::MoReFEMDataNS
#endif // MOREFEM_x_CORE_x_MO_RE_F_E_M_DATA_x_INTERNAL_x_HELPER_HXX_
......@@ -10,6 +10,11 @@
target_sources(${MOREFEM_CORE}
PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/Helper.cpp"
PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/Helper.hpp"
"${CMAKE_CURRENT_LIST_DIR}/Helper.hxx"
"${CMAKE_CURRENT_LIST_DIR}/Parallelism.hpp"
"${CMAKE_CURRENT_LIST_DIR}/Parallelism.hxx"
)
......
......@@ -15,18 +15,13 @@
#ifndef MOREFEM_x_CORE_x_MO_RE_F_E_M_DATA_x_MO_RE_F_E_M_DATA_HPP_
# define MOREFEM_x_CORE_x_MO_RE_F_E_M_DATA_x_MO_RE_F_E_M_DATA_HPP_
# include "ThirdParty/Wrappers/Mpi/Mpi.hpp"
# include "ThirdParty/Wrappers/Mpi/MpiScale.hpp"
# include "ThirdParty/Wrappers/Petsc/Print.hpp"
# include "ThirdParty/Wrappers/Petsc/Internal/RAII.hpp"
# include "ThirdParty/Wrappers/Tclap/StringPair.hpp"
# include "ThirdParty/IncludeWithoutWarning/Tclap/Tclap.hpp"
# include "Utilities/Filesystem/File.hpp"
# include "Utilities/InputData/Base.hpp"
# include "Utilities/TimeKeep/TimeKeep.hpp"
# include "Utilities/Environment/Environment.hpp"
# include "Utilities/OutputFormat/OutputFormat.hpp"
# include "Utilities/Datetime/Now.hpp"
......@@ -34,6 +29,7 @@
# include "Core/InitTimeKeepLog.hpp"
# include "Core/InputData/Instances/Parallelism/Parallelism.hpp"
# include "Core/MoReFEMData/Internal/Parallelism.hpp"
# include "Core/MoReFEMData/Internal/Helper.hpp"
namespace MoReFEM
......@@ -44,10 +40,6 @@ namespace MoReFEM
///@{
//! Empty shell when no additional command line argument are required in the model for which \a MoReFEMData is built.
struct NoAdditionalCommandLineArgument
{ };
//! Whether a model, a test or a post-processing program is run.
enum class program_type { model, test, post_processing };
......@@ -65,7 +57,7 @@ namespace MoReFEM
* existing result directory, contrary to what happens in model run.
* \tparam AdditionalCommandLineArgumentsPolicyT Policy if you need additional arguments on the command line.
* To see a concrete example of this possibility, have a look at Test/Core/MoReFEMData/test_command_line_options.cpp
* which demonstrate the possibility.
* which demonstrate the possibility. If none, use std::false_type.
*
* http://tclap.sourceforge.net gives a nice manual of how to add additional argument on the command lines.
* By default, there is one mandatory argument (--input_data *lua file*) and one optional that might be
......@@ -76,7 +68,7 @@ namespace MoReFEM
class InputDataT,
program_type ProgramTypeT,
Utilities::InputDataNS::DoTrackUnusedFields DoTrackUnusedFieldsT = Utilities::InputDataNS::DoTrackUnusedFields::yes,
class AdditionalCommandLineArgumentsPolicyT = NoAdditionalCommandLineArgument
class AdditionalCommandLineArgumentsPolicyT = std::false_type
>
class MoReFEMData : public AdditionalCommandLineArgumentsPolicyT
{
......
......@@ -32,147 +32,22 @@ namespace MoReFEM
{
Internal::PetscNS::RAII::CreateOrGetInstance(__FILE__, __LINE__, argc, argv);
auto& environment = Utilities::Environment::CreateOrGetInstance(__FILE__, __LINE__);
const auto ptr = std::is_same<AdditionalCommandLineArgumentsPolicyT, std::nullptr_t>()
? nullptr
: this;
std::string input_data_file;
std::string input_data_file =
Internal::MoReFEMDataNS::ParseCommandLine<AdditionalCommandLineArgumentsPolicyT>(argc, argv, ptr);
try
{
TCLAP::CmdLine cmd("Command description message");
cmd.setExceptionHandling(false);
TCLAP::ValueArg<std::string> input_data_file_arg("i",
"input_data",
"Input data file (Lua)",
true,
"",
"string",
cmd);
TCLAP::MultiArg<Wrappers::Tclap::StringPair> env_arg("e",
"env",
"environment_variable",
false,
"string=string",
cmd);
if constexpr (!std::is_same<AdditionalCommandLineArgumentsPolicyT, NoAdditionalCommandLineArgument>())
AdditionalCommandLineArgumentsPolicyT::Add(cmd);
cmd.parse(argc, argv);
decltype(auto) env_var_list = env_arg.getValue();
for (const auto& pair : env_var_list)
environment.SetEnvironmentVariable(pair.GetValue(), __FILE__, __LINE__);
input_data_file = input_data_file_arg.getValue();
}
catch (TCLAP::ArgException &e) // catch any exceptions
{
std::ostringstream oconv;
oconv << "Caught command line exception " << e.error() << " for argument " << e.argId() << std::endl;
throw Exception(oconv.str(), __FILE__, __LINE__);
}
const auto& mpi = GetMpi();
{
const char* const result_dir = "MOREFEM_RESULT_DIR";
if (!environment.DoExist(result_dir))
{
const char* const default_value("/Volumes/Data/${USER}/MoReFEM/Results");
environment.SetEnvironmentVariable(std::make_pair("MOREFEM_RESULT_DIR", default_value),
__FILE__, __LINE__);
std::cout << "[WARNING] Environment variable '" << result_dir << "' was not defined; default value '"
<< default_value << "' has therefore be provided. This environment variable may appear in mesh "
"directory defined in input data file; if not it is in fact unused." << std::endl;
}
const char* const morefem_dir = "MOREFEM_ROOT";
if (!environment.DoExist(morefem_dir))
{
const char* const default_value("${HOME}/Codes/MoReFEM/CoreLibrary");
decltype(auto) mpi = GetMpi();
environment.SetEnvironmentVariable(std::make_pair("MOREFEM_ROOT", default_value),
__FILE__, __LINE__);
std::cout << "[WARNING] Environment variable '" << morefem_dir << "' was not defined; default value '"
<< default_value << "' has therefore be provided. This environment variable may appear in output "
"directory defined in input data file; if not it is in fact unused." << std::endl;
}
std::string start_time = "MOREFEM_START_TIME";
if (!environment.DoExist(start_time))
{
environment.SetEnvironmentVariable(std::make_pair(start_time, Utilities::Now(mpi)),
__FILE__, __LINE__);
mpi.Barrier();
}
}
// Check the input data file can be found on each processor.
const bool do_file_exist_for_rank = FilesystemNS::File::DoExist(input_data_file) ;
std::vector<bool> sent_data { do_file_exist_for_rank };
std::vector<bool> gathered_data;
mpi.Gather(sent_data, gathered_data);
// Root processor sent true if all files exist for all ranks, false otherwise.
// Beware (#461): it doesn't check here the file is consistent!
std::vector<bool> do_file_exist_for_all_ranks { true };
std::vector<std::size_t> rank_without_file;
Internal::MoReFEMDataNS::DefineEnvironmentVariable(mpi);
if (mpi.IsRootProcessor())
{
for (std::size_t i = 0ul, Nproc = gathered_data.size(); i < Nproc; ++i)
{
if (!gathered_data[i])
rank_without_file.push_back(i);
}
if (!rank_without_file.empty())
do_file_exist_for_all_ranks.back() = false;
}
// Stops the program after creating it for root processor.
Internal::MoReFEMDataNS::CreateIfNotExisting<typename InputDataT::Tuple>(input_data_file);
mpi.Broadcast(do_file_exist_for_all_ranks);
if (mpi.IsRootProcessor())
{
if (!do_file_exist_for_rank)
{
Utilities::InputDataNS::CreateDefaultInputFile<typename InputDataT::Tuple>(input_data_file);
std::cout << '\n' << input_data_file << " wasn't existing and has just been created on root processor; "
"please edit it and then copy it onto all machines intended to run the code in parallel." << std::endl;
throw Exception("Input data file to edit and complete!", __FILE__, __LINE__);
}
if (!rank_without_file.empty())
{
std::ostringstream oconv;
oconv << "The following ranks couldn't find the input data file: ";
Utilities::PrintContainer<>::Do(rank_without_file, oconv, ", ", "", ".\n");
throw Exception(oconv.str(), __FILE__, __LINE__);
}
}
else
{
if (do_file_exist_for_all_ranks.back() == false)
throw Exception("Input data file not found for one or more rank; see root processor "
"exception for more details!", __FILE__, __LINE__);
}
Internal::MoReFEMDataNS::CheckExistingForAllRank(mpi, input_data_file);
// We can be here only if the file exists...
input_data_ = std::make_unique<InputDataT>(input_data_file,
......@@ -189,6 +64,14 @@ namespace MoReFEM
result_directory_ = ipl::Extract<Result::OutputDirectory>::Folder(*input_data_);
if constexpr(ProgramTypeT == program_type::model)
Internal::MoReFEMDataNS::AskResultDirectoryRemoval(result_directory_);
else if constexpr(ProgramTypeT == program_type::test)
{
if (FilesystemNS::Folder::DoExist(result_directory_))
FilesystemNS::Folder::Remove(result_directory_, __FILE__, __LINE__);
}
result_directory_with_rank_ = result_directory_ + "/Rank_" + std::to_string(mpi.template GetRank<int>());
if (!FilesystemNS::Folder::DoExist(result_directory_with_rank_))
......
......@@ -535,7 +535,7 @@ Parallelism = {
-- If Policy is 'RunFromPreprocessed', path to the directory which contains the pre-processed data.
-- Expected format: "VALUE"
-- Expected format: "VALUE"y
path = ''
} -- Parallelism
......@@ -550,7 +550,7 @@ Result = {
-- YYYY_MM_DD_HH_MM_SS.Please do not read the value directly from this Lua file: whenever you need the path
-- to the result directory, use instead MoReFEMData::GetResultDirectory().
-- Expected format: "VALUE"
output_directory = '${MOREFEM_RESULT_DIR}/MidpointHyperelasticity/${MOREFEM_START_TIME}',
output_directory = '${MOREFEM_RESULT_DIR}/MidpointHyperelasticity', -- /${MOREFEM_START_TIME}',
-- Enables to skip some printing in the console. Can be used to WriteSolution every n time.
......
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