diff --git a/elasticity.cc b/elasticity.cc index 006cdef..c63c0ba 100644 --- a/elasticity.cc +++ b/elasticity.cc @@ -1,4 +1,5 @@ #include +#include #include "source/linear_elasticity/include/linear_elasticity.h" #include "source/nonlinear_elasticity/include/nonlinear_elasticity.h" @@ -45,26 +46,53 @@ main(int argc, char **argv) // Store the name of the parameter file const std::string parameter_file = argc > 1 ? argv[1] : "parameters.prm"; - // Extract case path for the output directory - size_t pos = parameter_file.find_last_of("/"); - std::string case_path = - std::string::npos == pos ? "" : parameter_file.substr(0, pos + 1); + // Create output directory for the current case + // Query output directory from the parameter file + ParameterHandler prm; + Parameters::Time time; + time.add_output_parameters(prm); + prm.parse_input(parameter_file, "", true); + + // force trailing / so we can handle everything in loop + std::string pathname = time.output_folder; + if (pathname[pathname.size() - 1] != '/') + pathname += '/'; + + size_t pre = 0; + size_t pos; + mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; + while ((pos = pathname.find_first_of('/', pre)) != std::string::npos) + { + const std::string subdir = pathname.substr(0, pos++); + pre = pos; + + // if leading '/', first string is 0 length + if (subdir.size() == 0) + continue; + + int mkdir_return_value; + if ((mkdir_return_value = mkdir(subdir.c_str(), mode)) && + (errno != EEXIST)) + { + AssertThrow(mkdir_return_value, + ExcMessage("Can't create: " + pathname)); + return mkdir_return_value; + } + } // Query solver type from the parameter file - ParameterHandler prm; Parameters::Solver solver; solver.add_output_parameters(prm); prm.parse_input(parameter_file, "", true); if (solver.model == "neo-Hookean") // nonlinear { - Nonlinear_Elasticity::Solid solid(case_path, parameter_file); + Nonlinear_Elasticity::Solid solid(parameter_file); solid.run(); } else if (solver.model == "linear") // linear { - Linear_Elasticity::ElastoDynamics elastic_solver(case_path, - parameter_file); + Linear_Elasticity::ElastoDynamics elastic_solver(parameter_file); elastic_solver.run(); } else diff --git a/include/adapter/parameters.cc b/include/adapter/parameters.cc index dc73797..1e1a006 100644 --- a/include/adapter/parameters.cc +++ b/include/adapter/parameters.cc @@ -18,6 +18,10 @@ namespace Parameters output_interval, "Write results every x timesteps", Patterns::Integer(0)); + prm.add_parameter("Output folder", + output_folder, + "Output folder", + Patterns::Anything()); } prm.leave_subsection(); } diff --git a/include/adapter/parameters.h b/include/adapter/parameters.h index fc6c6f8..e891415 100644 --- a/include/adapter/parameters.h +++ b/include/adapter/parameters.h @@ -16,9 +16,11 @@ namespace Parameters */ struct Time { - double end_time = 1; - double delta_t = 0.1; - int output_interval = 1; + double end_time = 1; + double delta_t = 0.1; + int output_interval = 1; + std::string output_folder = ""; + void add_output_parameters(ParameterHandler &prm); diff --git a/parameters.prm b/parameters.prm index d767d85..60aa171 100644 --- a/parameters.prm +++ b/parameters.prm @@ -11,6 +11,9 @@ subsection Time # Write results every x timesteps set Output interval = 10 + + # Output folder + set Output folder = dealii-output end subsection Discretization diff --git a/source/linear_elasticity/include/linear_elasticity.h b/source/linear_elasticity/include/linear_elasticity.h index ae270fa..732fd7a 100644 --- a/source/linear_elasticity/include/linear_elasticity.h +++ b/source/linear_elasticity/include/linear_elasticity.h @@ -55,8 +55,7 @@ namespace Linear_Elasticity class ElastoDynamics { public: - ElastoDynamics(const std::string &case_path, - const std::string ¶meter_file); + ElastoDynamics(const std::string ¶meter_file); ~ElastoDynamics(); // As usual in dealii, the run function covers the main time loop of the @@ -148,8 +147,6 @@ namespace Linear_Elasticity // in case of an implicit coupling. This vector is directly used in the // Adapter class std::vector *> state_variables; - // for the output directory - const std::string case_path; }; } // namespace Linear_Elasticity diff --git a/source/linear_elasticity/linear_elasticity.cc b/source/linear_elasticity/linear_elasticity.cc index 1c7dfc8..0a1eebc 100644 --- a/source/linear_elasticity/linear_elasticity.cc +++ b/source/linear_elasticity/linear_elasticity.cc @@ -52,8 +52,7 @@ namespace Linear_Elasticity // Constructor template - ElastoDynamics::ElastoDynamics(const std::string &case_path, - const std::string ¶meter_file) + ElastoDynamics::ElastoDynamics(const std::string ¶meter_file) : parameters(parameter_file) , interface_boundary_id(6) , dof_handler(triangulation) @@ -64,7 +63,6 @@ namespace Linear_Elasticity , timer(std::cout, TimerOutput::summary, TimerOutput::wall_times) , time(parameters.end_time, parameters.delta_t) , adapter(parameters, interface_boundary_id) - , case_path(case_path) {} @@ -616,24 +614,16 @@ namespace Linear_Elasticity parameters.poly_degree, DataOut::curved_boundary); - // Check, if the output directory exists - std::ifstream output_directory(case_path + "dealii_output"); - AssertThrow( - output_directory, - ExcMessage( - "Unable to find the output directory. " - "By default, this program stores result files in a directory called dealii_output. " - "This needs to be located in your case directory, where the parameter file is located as well.")); - - // Store all files in a seperate folder called dealii_ouput std::ofstream output( - case_path + "dealii_output/solution-" + - std::to_string(time.get_timestep() / parameters.output_interval) + + parameters.output_folder + "/solution-" + + Utilities::int_to_string(time.get_timestep() / parameters.output_interval, + 3) + ".vtk"); data_out.write_vtk(output); std::cout << "\t Output written to solution-" + - std::to_string(time.get_timestep() / - parameters.output_interval) + + Utilities::int_to_string(time.get_timestep() / + parameters.output_interval, + 3) + ".vtk \n" << std::endl; timer.leave_subsection("Output results"); diff --git a/source/nonlinear_elasticity/include/nonlinear_elasticity.h b/source/nonlinear_elasticity/include/nonlinear_elasticity.h index b354c8f..b752e05 100644 --- a/source/nonlinear_elasticity/include/nonlinear_elasticity.h +++ b/source/nonlinear_elasticity/include/nonlinear_elasticity.h @@ -132,7 +132,7 @@ namespace Nonlinear_Elasticity class Solid { public: - Solid(const std::string &case_path, const std::string ¶meter_file); + Solid(const std::string ¶meter_file); virtual ~Solid(); @@ -256,9 +256,6 @@ namespace Nonlinear_Elasticity const unsigned int clamped_boundary_id = 1; const unsigned int out_of_plane_clamped_mesh_id = 8; - // ..and store the directory, in order to output the result files there - const std::string case_path; - AffineConstraints constraints; BlockSparsityPattern sparsity_pattern; BlockSparseMatrix tangent_matrix; diff --git a/source/nonlinear_elasticity/nonlinear_elasticity.cc b/source/nonlinear_elasticity/nonlinear_elasticity.cc index 5821989..155a403 100644 --- a/source/nonlinear_elasticity/nonlinear_elasticity.cc +++ b/source/nonlinear_elasticity/nonlinear_elasticity.cc @@ -60,8 +60,7 @@ namespace Nonlinear_Elasticity // Constructor initializes member variables and reads the parameter file template - Solid::Solid(const std::string &case_path, - const std::string ¶meter_file) + Solid::Solid(const std::string ¶meter_file) : parameters(Parameters::AllParameters(parameter_file)) , vol_reference(0.0) , vol_current(0.0) @@ -78,7 +77,6 @@ namespace Nonlinear_Elasticity , n_q_points(qf_cell.size()) , n_q_points_f(qf_face.size()) , boundary_interface_id(7) - , case_path(case_path) , timer(std::cout, TimerOutput::summary, TimerOutput::wall_times) , time(parameters.end_time, parameters.delta_t) , adapter(parameters, boundary_interface_id) @@ -1223,12 +1221,19 @@ namespace Nonlinear_Elasticity data_out.build_patches(q_mapping, degree, DataOut::curved_boundary); - std::ostringstream filename; - filename << case_path << "solution-" - << time.get_timestep() / parameters.output_interval << ".vtk"; - - std::ofstream output(filename.str().c_str()); + std::ofstream output( + parameters.output_folder + "/solution-" + + Utilities::int_to_string(time.get_timestep() / parameters.output_interval, + 3) + + ".vtk"); data_out.write_vtk(output); + std::cout << "\t Output written to solution-" + + Utilities::int_to_string(time.get_timestep() / + parameters.output_interval, + 3) + + ".vtk \n" + << std::endl; + timer.leave_subsection("Output results"); }