diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index aaf0ffb85d58687e8196395b9d092e68438427ae..b83493c6c62fc7fd428b877ef93ef04202bda6d9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,7 +3,6 @@ ################################################################################ add_library(parser - inputs_file.cpp parser.cpp solver.cpp ) diff --git a/src/inputs_file.cpp b/src/inputs_file.cpp deleted file mode 100644 index cd02a69f960e8bfc0c10688a0571146b32e6b9db..0000000000000000000000000000000000000000 --- a/src/inputs_file.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#include -#include -#include -#include -#include - -#include "inputs.hpp" - -template struct overloaded : Ts... { using Ts::operator()...; }; -template -overloaded(Ts...) -> overloaded; // not needed as of C++20 - -namespace inputs_file { - -solver_settings::SolverSettings InputsFile::load() { - - std::ifstream infile(m_path); - if (!infile.good()) { - std::cout << "Error reading file: " << m_path << std::endl; - return solver_settings::SolverSettings(); - } - std::stringstream buffer; - buffer << infile.rdbuf(); - infile.close(); - - auto maybe_inputinfo = parser::parse_inputs(buffer.str()); - if (!maybe_inputinfo.has_value()) { - std::cout << "Error parsing file: " << m_path << std::endl; - return solver_settings::SolverSettings(); - } - - auto inputinfo = maybe_inputinfo.value(); - - // for (auto it = inputinfo.begin(); it != inputinfo.end(); ++it) { - // std::visit( - // overloaded{ - // [it](parser::NumberArray aa) { std::cout << it->first << " nums - // " << aa.size() << std::endl; - // }, - // [it](parser::StringArray aa) { std::cout << it->first << " - // strings " << aa.size() << std::endl; - // }, - // }, - // it->second); - // } - - auto maybe_solversettings = solver_settings::make_solver(inputinfo); - if (!maybe_solversettings.has_value()) { - std::cout << "Invalid solver settings file: " << m_path << std::endl; - return solver_settings::SolverSettings(); - } - return maybe_solversettings.value(); -} - -void InputsFile::save(solver_settings::SolverSettings settings) { - - std::ofstream out(m_path); - - auto [xx, yy, zz] = settings.geometry.axes; - out << std::endl; - out << " geometry.is_periodic = " << xx.periodic << " " << yy.periodic << " " - << zz.periodic << std::endl; - ; - out << " geometry.prob_lo = " << xx.low << " " << yy.low << " " << zz.low - << std::endl; - ; - out << " geometry.prob_hi = " << xx.high << " " << yy.high << " " - << zz.high; - ; - out.close(); -} - -} // namespace inputs_file diff --git a/src/main.cpp b/src/main.cpp index 1652050d9bd8750c1167e3a86b7b4c0d3160c3ee..2e925c7345bcd72f6440710f8eb64b1314a90a74 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,7 +2,7 @@ #include #include -#include "inputs.hpp" +#include "solver.hpp" std::string read_file(std::string inputs_file) { std::ifstream in_stream; @@ -20,7 +20,7 @@ int main(int argc, char *argv[]) { } std::string fname(argv[1]); auto inputs_str = read_file(fname); - auto maybe_success = parser::parse_inputs(inputs_str); + auto maybe_success = solver::parse_inputs(inputs_str); if (maybe_success.has_value()) { return 0; } diff --git a/src/meson.build b/src/meson.build index d620efda2ca11d291b00f74c1b7412cfc3ed7c11..fadb80576d382b88c79e2390b98b324b03549976 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,5 +1,4 @@ lib_parser = static_library('mfix-parser', - 'inputs_file.cpp', 'parser.cpp', 'solver.cpp', include_directories: tao_inc, diff --git a/src/parser.cpp b/src/parser.cpp index a77b4b9c16d639e62d6d31496401c5b3eb14714b..c55ae832e7133ec00c214abd4507b7ed93dbef01 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -6,7 +6,7 @@ #include // includes -#include "inputs.hpp" +#include "solver.hpp" using namespace tao::pegtl; @@ -17,7 +17,7 @@ struct parser_state { std::variant, std::vector> current_value; std::vector current_num_vec; std::vector current_str_vec; - parser::InputInfo info; + solver::InputInfo info; }; } // namespace @@ -144,9 +144,9 @@ std::optional do_parse(std::string str) { } // namespace -namespace parser { +namespace solver { -std::optional parse_inputs(std::string str) { +std::optional parse_inputs(std::string str) { auto maybe_state = do_parse(str); if (!maybe_state.has_value()) { return std::nullopt; diff --git a/src/solver.cpp b/src/solver.cpp index 2b34c6ce0e075b4b41ed88ccd50754cf9c4fbc41..d1caa8790a7e6f275b1f0d97a174001fa1f105af 100644 --- a/src/solver.cpp +++ b/src/solver.cpp @@ -1,7 +1,8 @@ #include #include +#include -#include "inputs.hpp" +#include "solver.hpp" namespace { @@ -9,9 +10,9 @@ void require(std::string key) { std::cout << "missing required key: " << key << std::endl; } -std::optional -do_make_solver(parser::InputInfo ii) { - solver_settings::SolverSettings ss; +std::optional +do_make_solver(solver::InputInfo ii) { + solver::SolverSettings ss; std::string PROB_LO("geometry.prob_lo"); std::string PROB_HI("geometry.prob_hi"); std::string PERIODIC("geometry.is_periodic"); @@ -27,9 +28,9 @@ do_make_solver(parser::InputInfo ii) { require(PERIODIC); return std::nullopt; } - auto lows = std::get(ii[PROB_LO]); - auto highs = std::get(ii[PROB_HI]); - auto is_periodic = std::get(ii[PERIODIC]); + auto lows = std::get(ii[PROB_LO]); + auto highs = std::get(ii[PROB_HI]); + auto is_periodic = std::get(ii[PERIODIC]); if (lows.size() != 3) { std::cout << "prob_lo needs 3 elements " << std::endl; return std::nullopt; @@ -56,14 +57,32 @@ do_make_solver(parser::InputInfo ii) { } } // namespace -namespace solver_settings { +namespace solver { -std::optional -make_solver(parser::InputInfo ii) { +std::optional +make_solver(solver::InputInfo ii) { auto maybe_state = do_make_solver(ii); if (!maybe_state.has_value()) { return std::nullopt; } return maybe_state.value(); } -} // namespace solver_settings + + + std::string serialize(solver::SolverSettings settings) { + + std::stringstream buffer; + + auto [xx, yy, zz] = settings.geometry.axes; + buffer << std::endl; + buffer << " geometry.is_periodic = " << xx.periodic << " " << yy.periodic << " " + << zz.periodic << std::endl; + buffer << " geometry.prob_lo = " << xx.low << " " << yy.low << " " << zz.low + << std::endl; + buffer << " geometry.prob_hi = " << xx.high << " " << yy.high << " " + << zz.high; + return buffer.str(); + } + + +} // namespace solver diff --git a/src/inputs.hpp b/src/solver.hpp similarity index 53% rename from src/inputs.hpp rename to src/solver.hpp index 446aff7748dc1556a3e147fd1fa8fe228366c23e..78cac8fc84330f64c3ed084cf229f3b054c143e9 100644 --- a/src/inputs.hpp +++ b/src/solver.hpp @@ -1,5 +1,5 @@ -#ifndef INPUTS_H_ -#define INPUTS_H_ +#ifndef SOLVER_H_ +#define SOLVER_H_ #include #include @@ -8,7 +8,7 @@ #include #include -namespace parser { +namespace solver { using NumberArray = std::vector; using StringArray = std::vector; @@ -16,10 +16,6 @@ using InputInfo = std::map>; std::optional parse_inputs(std::string); -} // namespace parser - -namespace solver_settings { - struct GeometryAxis { double low; double high; @@ -32,20 +28,8 @@ struct SolverSettings { GeometrySettings geometry; }; -std::optional make_solver(parser::InputInfo); -} // namespace solver_settings - -namespace inputs_file { -class InputsFile { -public: - InputsFile(std::string inputs_path) : m_path(inputs_path) {} - solver_settings::SolverSettings load(); - void save(solver_settings::SolverSettings); - -protected: - std::string m_path; -}; - -} // namespace inputs_file +std::optional make_solver(solver::InputInfo); +std::string serialize(solver::SolverSettings); +} // namespace solver #endif diff --git a/tests/inputs.t.cpp b/tests/inputs.t.cpp deleted file mode 100644 index 250a93fa814bbc90ed5f211067a6f89e604e739b..0000000000000000000000000000000000000000 --- a/tests/inputs.t.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// tests - -#include "catch2/catch.hpp" - -#include -#include -#include -#include - -TEST_CASE("load_save_file", "[]") { - std::string test_path("abc"); - std::ofstream outfile(test_path); - - std::string data(R"( - geometry.is_periodic = 0 0 0 # Is periodic in each direction? - geometry.prob_lo = 0. 0. 0. # lo corner of physical domain - geometry.prob_hi = 0.004 0.001 0.001 # hi corner of physical domain - )"); - - outfile << data; - outfile.close(); - - inputs_file::InputsFile test_file(test_path); - auto solver_setup = test_file.load(); - - std::get<1>(solver_setup.geometry.axes).periodic = 1; - test_file.save(solver_setup); - - std::ifstream infile(test_path); - std::stringstream buffer; - buffer << infile.rdbuf(); - infile.close(); - CHECK(buffer.str() == R"( - geometry.is_periodic = 0 1 0 - geometry.prob_lo = 0 0 0 - geometry.prob_hi = 0.004 0.001 0.001)"); -} diff --git a/tests/meson.build b/tests/meson.build index 71787c4c824433dd1f3e51911f9de489d5723072..2b302c396ee2de167025908845427c7ff4cd7da1 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -6,12 +6,3 @@ unit_exe = executable('unit_tests', link_with: lib_parser ) test('unit_test', unit_exe) - - -functional_test = executable('functional_tests', - 'inputs.t.cpp', - 'main.cpp', - include_directories: [parser_inc, catch2_inc], - link_with: lib_parser - ) -test('functional_test', functional_test) diff --git a/tests/parser.t.cpp b/tests/parser.t.cpp index 13163043fa87447da0e89fdfc0dcc5e31cccccd9..2d6860efaa3b8f024e51b324fae3ac0874e69c43 100644 --- a/tests/parser.t.cpp +++ b/tests/parser.t.cpp @@ -1,71 +1,71 @@ #include "catch2/catch.hpp" -#include +#include TEST_CASE("comment", "[]") { - auto maybe_st = parser::parse_inputs(R"( + auto maybe_st = solver::parse_inputs(R"( # this is a comment )"); CHECK(maybe_st.has_value()); } TEST_CASE("integer", "[]") { - auto maybe_st = parser::parse_inputs(R"( + auto maybe_st = solver::parse_inputs(R"( mfix.max_step = 100 )"); REQUIRE(maybe_st.has_value()); auto info = maybe_st.value(); auto value = info["mfix.max_step"]; - auto aa = std::get(value); + auto aa = std::get(value); CHECK(aa.size() == 1); CHECK(aa[0] == 100); } TEST_CASE("double", "[]") { - auto maybe_st = parser::parse_inputs(R"( + auto maybe_st = solver::parse_inputs(R"( mfix.stop_time = 0.20 )"); REQUIRE(maybe_st.has_value()); auto info = maybe_st.value(); auto value = info["mfix.stop_time"]; - auto aa = std::get(value); + auto aa = std::get(value); CHECK(aa.size() == 1); CHECK(aa[0] == 0.2); } TEST_CASE("string", "[]") { - auto maybe_st = parser::parse_inputs(R"( + auto maybe_st = solver::parse_inputs(R"( mfix.particle_init_type = "Auto" )"); REQUIRE(maybe_st.has_value()); auto info = maybe_st.value(); auto value = info["mfix.particle_init_type"]; - auto ss = std::get(value); + auto ss = std::get(value); CHECK(ss.size() == 1); CHECK(ss[0] == "Auto"); } TEST_CASE("implicit string", "[]") { - auto maybe_st = parser::parse_inputs(R"( + auto maybe_st = solver::parse_inputs(R"( fluid.solve = fluid )"); REQUIRE(maybe_st.has_value()); auto info = maybe_st.value(); auto value = info["fluid.solve"]; - auto ss = std::get(value); + auto ss = std::get(value); CHECK(ss.size() == 1); CHECK(ss[0] == "fluid"); } TEST_CASE("tabbed array", "[]") { - auto maybe_st = parser::parse_inputs(R"( + auto maybe_st = solver::parse_inputs(R"( amr.avg_vel_p = 0 0 0 )"); REQUIRE(maybe_st.has_value()); auto info = maybe_st.value(); auto value = info["amr.avg_vel_p"]; - auto aa = std::get(value); + auto aa = std::get(value); CHECK(aa.size() == 3); CHECK(aa[0] == 0.0); CHECK(aa[1] == 0.0); @@ -73,14 +73,14 @@ TEST_CASE("tabbed array", "[]") { } TEST_CASE("double array", "[]") { - auto maybe_st = parser::parse_inputs(R"( + auto maybe_st = solver::parse_inputs(R"( mfix.gravity = -9.81 0.0 0.0 )"); REQUIRE(maybe_st.has_value()); auto info = maybe_st.value(); auto value = info["mfix.gravity"]; - auto aa = std::get(value); + auto aa = std::get(value); CHECK(aa.size() == 3); CHECK(aa[0] == -9.81); CHECK(aa[1] == 0.0); @@ -88,14 +88,14 @@ TEST_CASE("double array", "[]") { } TEST_CASE("string array", "[]") { - auto maybe_st = parser::parse_inputs(R"( + auto maybe_st = solver::parse_inputs(R"( mfix.regions = abc ijk xyz )"); REQUIRE(maybe_st.has_value()); auto info = maybe_st.value(); auto value = info["mfix.regions"]; - auto aa = std::get(value); + auto aa = std::get(value); CHECK(aa.size() == 3); CHECK(aa[0] == "abc"); CHECK(aa[1] == "ijk"); @@ -103,7 +103,7 @@ TEST_CASE("string array", "[]") { } TEST_CASE("multiple arrays", "[]") { - auto maybe_st = parser::parse_inputs(R"( + auto maybe_st = solver::parse_inputs(R"( geometry.prob_lo = -4 -1 -2 geometry.prob_hi = 0.004 0.001 0.001 geometry.is_periodic = 1 0 1 @@ -116,21 +116,21 @@ geometry.is_periodic = 1 0 1 CHECK(info.count("geometry.is_periodic")); auto highs = info["geometry.prob_lo"]; - auto aa = std::get(highs); + auto aa = std::get(highs); CHECK(aa.size() == 3); CHECK(aa[0] == -4); CHECK(aa[1] == -1); CHECK(aa[2] == -2); auto lows = info["geometry.prob_hi"]; - auto bb = std::get(lows); + auto bb = std::get(lows); CHECK(bb.size() == 3); CHECK(bb[0] == 0.004); CHECK(bb[1] == 0.001); CHECK(bb[2] == 0.001); auto pers = info["geometry.is_periodic"]; - auto cc = std::get(pers); + auto cc = std::get(pers); CHECK(cc.size() == 3); CHECK(cc[0] == 1); CHECK(cc[1] == 0); @@ -138,7 +138,7 @@ geometry.is_periodic = 1 0 1 } TEST_CASE("whole_file", "[]") { - auto maybe_st = parser::parse_inputs(R"( + auto maybe_st = solver::parse_inputs(R"( #_______________________________________________________________________ # Solver settings diff --git a/tests/solver.t.cpp b/tests/solver.t.cpp index 53421740dcd1dae77373a1a18ca1895041034837..89c00bfc373717ee1838cf416bb495cc6cff2725 100644 --- a/tests/solver.t.cpp +++ b/tests/solver.t.cpp @@ -2,27 +2,27 @@ #include "catch2/catch.hpp" -#include +#include std::string PROB_LO("geometry.prob_lo"); std::string PROB_HI("geometry.prob_hi"); std::string PERIODIC("geometry.is_periodic"); TEST_CASE("empty (invalid) map", "[]") { - parser::InputInfo ii; - auto maybe_sv = solver_settings::make_solver(ii); + solver::InputInfo ii; + auto maybe_sv = solver::make_solver(ii); CHECK_FALSE(maybe_sv.has_value()); } TEST_CASE("from_origin", "[]") { - parser::InputInfo ii; - ii[PROB_LO] = parser::NumberArray({0, 0, 0}); - ii[PROB_HI] = parser::NumberArray({0.004, 0.001, 0.001}); - ii[PERIODIC] = parser::NumberArray({0, 0, 0}); + solver::InputInfo ii; + ii[PROB_LO] = solver::NumberArray({0, 0, 0}); + ii[PROB_HI] = solver::NumberArray({0.004, 0.001, 0.001}); + ii[PERIODIC] = solver::NumberArray({0, 0, 0}); CHECK(ii.count(PROB_LO)); CHECK(ii.count(PROB_HI)); CHECK(ii.count(PERIODIC)); - auto maybe_sv = solver_settings::make_solver(ii); + auto maybe_sv = solver::make_solver(ii); REQUIRE(maybe_sv.has_value()); auto sv = maybe_sv.value(); @@ -39,12 +39,12 @@ TEST_CASE("from_origin", "[]") { } TEST_CASE("negative_positive", "[]") { - parser::InputInfo ii; + solver::InputInfo ii; ii[PROB_LO] = std::vector({-4, -5, -6}); ii[PROB_HI] = std::vector({11.1, 22.2, 33.3}); - ii[PERIODIC] = parser::NumberArray({1, 0, 1}); + ii[PERIODIC] = solver::NumberArray({1, 0, 1}); - auto maybe_sv = solver_settings::make_solver(ii); + auto maybe_sv = solver::make_solver(ii); REQUIRE(maybe_sv.has_value()); auto sv = maybe_sv.value(); @@ -59,3 +59,27 @@ TEST_CASE("negative_positive", "[]") { CHECK(zz.periodic); CHECK_FALSE(yy.periodic); } + + +TEST_CASE("serialize", "[]") { + solver::SolverSettings ss; + + std::get<0>(ss.geometry.axes).periodic = 0; + std::get<1>(ss.geometry.axes).periodic = 1; + std::get<2>(ss.geometry.axes).periodic = 0; + + std::get<0>(ss.geometry.axes).low = 0; + std::get<1>(ss.geometry.axes).low = 0; + std::get<2>(ss.geometry.axes).low = 0; + + std::get<0>(ss.geometry.axes).high = 0.004; + std::get<1>(ss.geometry.axes).high = 0.001; + std::get<2>(ss.geometry.axes).high = 0.001; + + auto inputs_str = serialize(ss); + + CHECK(inputs_str == R"( + geometry.is_periodic = 0 1 0 + geometry.prob_lo = 0 0 0 + geometry.prob_hi = 0.004 0.001 0.001)"); +}