Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ four_c_configure_dependency(Backtrace DEFAULT OFF)
four_c_configure_dependency(ryml REQUIRED)
four_c_configure_dependency(magic_enum REQUIRED)
four_c_configure_dependency(ZLIB REQUIRED)
four_c_configure_dependency(CLI11 REQUIRED)
four_c_configure_dependency(Python DEFAULT ON) # not required but useful for most developers
four_c_configure_dependency(pybind11 DEFAULT OFF)

Expand Down
213 changes: 12 additions & 201 deletions apps/global_full/4C_global_full_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,17 @@

#include "4C_global_full_io.hpp"

#include "4C_comm_utils.hpp"
#include "4C_global_data_read.hpp"
#include "4C_global_legacy_module.hpp"
#include "4C_io_pstream.hpp"
#include "4C_utils_exceptions.hpp"

#include <Teuchos_StandardParameterEntryValidators.hpp>
#include <Teuchos_TimeMonitor.hpp>

FOUR_C_NAMESPACE_OPEN


Core::IO::InputFile setup_input_file(const MPI_Comm comm)
{
return Global::set_up_input_file(comm);
Expand All @@ -33,7 +34,8 @@ void emit_general_metadata(const Core::IO::YamlNodeRef& root_ref)
/**
* \brief Sets up the parallel output environment.
*/
void setup_parallel_output(const CommandlineArguments& arguments)
void setup_parallel_output(
const CommandlineArguments& arguments, const Core::Communication::Communicators& communicators)
{
using namespace FourC;

Expand All @@ -45,21 +47,22 @@ void setup_parallel_output(const CommandlineArguments& arguments)
int oproc = io.get<int>("LIMIT_OUTP_TO_PROC");
auto level = Teuchos::getIntegralValue<Core::IO::Verbositylevel>(io, "VERBOSITY");

Core::IO::cout.setup(screen, file, preGrpID, level, std::move(arguments.comms.local_comm()),
oproc, arguments.comms.group_id(), arguments.output_file_identifier);
Core::IO::cout.setup(screen, file, preGrpID, level, communicators.local_comm(), oproc,
communicators.group_id(), arguments.output_file_identifier);
}

void setup_global_problem(Core::IO::InputFile& input_file, const CommandlineArguments& arguments)
void setup_global_problem(Core::IO::InputFile& input_file, const CommandlineArguments& arguments,
Core::Communication::Communicators& communicators)
{
Global::Problem* problem = Global::Problem::instance();
problem->set_restart_step(arguments.restart_step);
problem->set_communicators(arguments.comms);
problem->set_restart_step(arguments.restart);
problem->set_communicators(communicators);
Global::read_parameter(*problem, input_file);

setup_parallel_output(arguments);
setup_parallel_output(arguments, communicators);

// create control file for output and read restart data if required
problem->open_control_file(arguments.comms.local_comm(), arguments.input_file_name,
problem->open_control_file(communicators.local_comm(), arguments.input_file_name,
arguments.output_file_identifier, arguments.restart_file_identifier);

// input of materials
Expand Down Expand Up @@ -108,203 +111,11 @@ double walltime_in_seconds()
1.0e-3;
}

void parse_commandline_arguments(CommandlineArguments& arguments)
{
int group = arguments.comms.group_id();

int restart_group = 0;
int my_rank = Core::Communication::my_mpi_rank(arguments.comms.local_comm());

std::vector<std::string> inout =
parse_input_output_files(arguments.argc, arguments.argv, my_rank);

// number of input/output arguments specified by the user
auto inout_args = int(inout.size());

std::string input_filename;
std::string output_file_identifier;
std::string restart_file_identifier;
// set input file name in each group
switch (arguments.comms.np_type())
{
case Core::Communication::NestedParallelismType::no_nested_parallelism:
input_filename = inout[0];
output_file_identifier = inout[1];
restart_group = 0;
break;
case Core::Communication::NestedParallelismType::every_group_read_input_file:
{
if (inout_args > 4)
FOUR_C_THROW(
"You specified too many arguments ({}). A maximum of four args is allowed", inout_args);

input_filename = inout[0];
// check whether output_file_identifier includes a dash and in case separate the number at the
// end
size_t pos = inout[1].rfind('-');
if (pos != std::string::npos)
{
int number = atoi(inout[1].substr(pos + 1).c_str());
inout[1] = inout[1].substr(0, pos);
output_file_identifier = std::format("{}_group_{}_{}", inout[1], group, number);
}
else
{
output_file_identifier = std::format("{}_group_{}", inout[1], group);
}
restart_group = 0;
}
break;
case Core::Communication::NestedParallelismType::separate_input_files:
if (inout_args % arguments.comms.num_groups() != 0)
FOUR_C_THROW("Each group needs the same number of arguments for input/output.");
inout_args /= arguments.comms.num_groups();
input_filename = inout[group * inout_args];
output_file_identifier = inout[group * inout_args + 1];
restart_group = group;
break;
default:
FOUR_C_THROW(
"-nptype is not correct. Only everyGroupReadInputFile and separateInputFiles "
"are available");
break;
}

if (my_rank == 0)
{
std::cout << "input is read from " << input_filename << std::endl;
}
parse_restart_definition(
inout, inout_args, restart_file_identifier, output_file_identifier, restart_group, arguments);

/// set IO file names and identifiers
arguments.input_file_name = input_filename;
arguments.output_file_identifier = output_file_identifier;
arguments.restart_file_identifier = restart_file_identifier;
}


std::vector<std::string> parse_input_output_files(const int argc, char** argv, const int my_rank)
{
if (argc <= 1)
{
if (my_rank == 0)
{
printf("You forgot to give the input and output file names!\n");
printf("Try again!\n");
}
MPI_Finalize();
exit(EXIT_FAILURE);
}
else if (argc <= 2)
{
if (my_rank == 0)
{
printf("You forgot to give the output file name!\n");
printf("Try again!\n");
}
MPI_Finalize();
exit(EXIT_FAILURE);
}


// parse command line and separate input/output arguments
std::vector<std::string> inout;
for (int i = 1; i < argc; i++)
{
std::string temp = argv[i];
if (temp.substr(0, 1) != "-") inout.push_back(temp);
}
return inout;
}

void parse_restart_definition(const std::vector<std::string>& inout, const int in_out_args,
std::string& restart_file_identifier, const std::string& outfile_identifier,
const int restart_group, CommandlineArguments& arguments)
{
// Global::Problem* problem = Global::Problem::instance();
// bool parameter defining if input argument is given
bool restartIsGiven = false;
bool restartfromIsGiven = false;

// default case is an identical restartfile_identifier and outputfile_identifier
restart_file_identifier = outfile_identifier;
for (int i = 2; i < in_out_args; i++)
{
std::string restart = inout[restart_group * in_out_args + i];

if (restart.substr(0, 8) == "restart=")
{
const std::string option = restart.substr(8, std::string::npos);
int r;
if (option.compare("last_possible") == 0)
{
r = -1; // here we use a negative value to trigger the search in the control file in
// the later step. It does not mean a restart from a negative number is allowed
// from the user point of view.
}
else
{
r = atoi(option.c_str());
if (r < 0) FOUR_C_THROW("Restart number must be a positive value");
}
// tell the global problem about the restart step given in the command line
arguments.restart_step = r;
restartIsGiven = true;
}
else if (restart.substr(0, 12) == "restartfrom=")
{
restart_file_identifier = (restart.substr(12, std::string::npos).c_str());

switch (arguments.comms.np_type())
{
case Core::Communication::NestedParallelismType::no_nested_parallelism:
case Core::Communication::NestedParallelismType::separate_input_files:
// nothing to add to restartfileidentifier
break;
case Core::Communication::NestedParallelismType::every_group_read_input_file:
{
// check whether restartfileidentifier includes a dash and in case separate the number
// at the end
size_t pos = restart_file_identifier.rfind('-');
if (pos != std::string::npos)
{
int number = atoi(restart_file_identifier.substr(pos + 1).c_str());
std::string identifier = restart_file_identifier.substr(0, pos);
restart_file_identifier =
std::format("{}_group_{}_-{}", identifier, arguments.comms.group_id(), number);
}
else
{
restart_file_identifier =
std::format("{}_group_{}", restart_file_identifier, arguments.comms.group_id());
}
}
break;
default:
FOUR_C_THROW(
"-nptype is not correct. Only everyGroupReadInputFile and "
"separateInputFiles are available");
break;
}

restartfromIsGiven = true;
}
}

// throw error in case restartfrom is given but no restart step is specified
if (restartfromIsGiven && !restartIsGiven)
{
FOUR_C_THROW("You need to specify a restart step when using restartfrom.");
}
}

void write_timemonitor(MPI_Comm comm)
{
std::shared_ptr<const Teuchos::Comm<int>> TeuchosComm =
Core::Communication::to_teuchos_comm<int>(comm);
Teuchos::TimeMonitor::summarize(Teuchos::Ptr(TeuchosComm.get()), std::cout, false, true, false);
}


FOUR_C_NAMESPACE_CLOSE
37 changes: 3 additions & 34 deletions apps/global_full/4C_global_full_io.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,11 @@
#include "4C_config.hpp"

#include "4C_comm_utils.hpp"
#include "4C_io_command_line_helpers.hpp"
#include "4C_io_input_file.hpp"

FOUR_C_NAMESPACE_OPEN

/**
* Gather some arguments from the command line and store them in a struct. This should be
* changed to a proper parser
*/
struct CommandlineArguments
{
int argc;
char** argv;

std::string input_file_name;
std::string output_file_identifier;
std::string restart_file_identifier;
int restart_step = 0;

Core::Communication::Communicators comms;
};

/**
* \brief Initializes the input file for reading.
* \note Currently, this function is a wrapper around Global::set_up_input_file to keep the main
Expand All @@ -52,29 +36,14 @@ void emit_general_metadata(const Core::IO::YamlNodeRef& root_ref);
* \brief Sets up the Global::Problem instance and puts all the parameters from the input file
* there.
*/
void setup_global_problem(Core::IO::InputFile& input_file, const CommandlineArguments& arguments);

void setup_global_problem(Core::IO::InputFile& input_file, const CommandlineArguments& arguments,
Core::Communication::Communicators& communicators);
/**
* \brief Returns the wall time in seconds.
*/
double walltime_in_seconds();

/**
* \brief Parses command line arguments and sets input, output, and restart file identifiers.
*/
void parse_commandline_arguments(CommandlineArguments& arguments);

/**
* \brief Parses input and output files from command line arguments.
*/
std::vector<std::string> parse_input_output_files(const int argc, char** argv, const int my_rank);

/**
* \brief Parses the restart definition from command line arguments.
*/
void parse_restart_definition(const std::vector<std::string>& inout, int in_out_args,
std::string& restart_file_identifier, const std::string& outfile_identifier, int restart_group,
CommandlineArguments& arguments);

/**
* \brief Writes the Teuchos::TimeMonitor information to std::cout
Expand Down
Loading