diff --git a/docs/algorithms/sidb_simulation.rst b/docs/algorithms/sidb_simulation.rst index 8ef2e1b45..0cb45b969 100644 --- a/docs/algorithms/sidb_simulation.rst +++ b/docs/algorithms/sidb_simulation.rst @@ -101,6 +101,7 @@ Random Layout Generator **Header:** ``fiction/algorithms/simulation/sidb/random_layout_generator.hpp`` -.. doxygenstruct:: fiction::random_layout_params +.. doxygenenum:: fiction::positive_charges +.. doxygenstruct:: fiction::generate_random_layout_params .. doxygenfunction:: fiction::generate_random_layout -.. doxygenfunction:: fiction::generate_multiple_random_layout +.. doxygenfunction:: fiction::generate_multiple_random_layouts diff --git a/docs/io/physical_simulation.rst b/docs/io/physical_simulation.rst index 7358f78df..77ad98978 100644 --- a/docs/io/physical_simulation.rst +++ b/docs/io/physical_simulation.rst @@ -64,10 +64,10 @@ SiQAD .. doxygenfunction:: fiction::write_sqd_sim_result(const sidb_simulation_result& sim_result, std::ostream& os) .. doxygenfunction:: fiction::write_sqd_sim_result(const sidb_simulation_result& sim_result, const std::string_view& filename) -**Header:** ``fiction/io/write_txt_sim_result.hpp`` +**Header:** ``fiction/io/write_loc_sim_result.hpp`` -.. doxygenfunction:: fiction::write_txt_sim_result(const sidb_simulation_result& sim_result, std::ostream& os) -.. doxygenfunction:: fiction::write_txt_sim_result(const sidb_simulation_result& sim_result, const std::string_view& filename) +.. doxygenfunction:: fiction::write_loc_sim_result(const sidb_simulation_result& sim_result, std::ostream& os) +.. doxygenfunction:: fiction::write_loc_sim_result(const sidb_simulation_result& sim_result, const std::string_view& filename) **Header:** ``fiction/io/read_sqd_layout.hpp`` diff --git a/experiments/random_layout_generation/random_layout_generation.cpp b/experiments/random_layout_generation/random_layout_generation.cpp index 7b41128bc..6ce548fd9 100644 --- a/experiments/random_layout_generation/random_layout_generation.cpp +++ b/experiments/random_layout_generation/random_layout_generation.cpp @@ -6,6 +6,8 @@ #include #include +#include + #include #include #include @@ -13,13 +15,77 @@ using namespace fiction; -int main() // NOLINT +int main(int argc, const char* argv[]) // NOLINT { + std::unordered_map> options{{"--folder_name", "layout_random_cli/"}, + {"--NW_x", "0"}, + {"--NW_y", "0"}, + {"--SE_x", "20"}, + {"--SE_y", "20"}, + {"--positive_charges", "FORBIDDEN"}, + {"--lower", "5"}, + {"--upper", "10"}, + {"--num_layouts", "10"}, + {"--step", "1"}}; + + // Parse command-line arguments + for (auto i = 1u; i < argc; ++i) + { + const std::string arg = argv[i]; + if (options.count(arg) > 0) + { + if (i + 1 < argc) + { + options[arg] = argv[i + 1]; + ++i; // Skip the next argument + } + else + { + std::cerr << "Error: Argument " << arg << " is missing a value." << std::endl; + return 1; + } + } + } + + // Extract values from options map + const std::string folder_name = std::get(options["--folder_name"]); + // x-coordinate of north-west cell. + const int32_t nw_x = std::stoi(std::get(options["--NW_x"])); + // y-coordinate of north-west cell. + const int32_t nw_y = std::stoi(std::get(options["--NW_y"])); + // x-coordinate of south-east cell. + const int32_t se_x = std::stoi(std::get(options["--SE_x"])); + // y-coordinate of south-east cell. + const int32_t se_y = std::stoi(std::get(options["--SE_y"])); + const std::string charges_str = std::get(options["--positive_charges"]); + // It labels if positively charged SiDBs are allowed. + const positive_charges charges = + (charges_str == "ALLOWED") ? positive_charges::ALLOWED : positive_charges::FORBIDDEN; + // Number of SiDBs of the first bunch of layouts. + const uint64_t lower_limit = std::stoull(std::get(options["--lower"])); + // Number of SiDBs of the last bunch of layouts. + const uint64_t upper_limit = std::stoull(std::get(options["--upper"])); + // Number of layouts for each number of placed SiDBs (e.g., num_layouts = 10 means that 10 different layouts for a + // given number of SiDBs is generated). + const uint64_t number_of_layouts = std::stoull(std::get(options["--num_layouts"])); + // Step size for moving from lower limit to upper limit. + const uint64_t step = std::stoull(std::get(options["--step"])); + + // Print the parsed values + std::cout << "Folder name: " << folder_name << std::endl; + std::cout << fmt::format("NW: {} | {}", nw_x, nw_y) << std::endl; + std::cout << fmt::format("SE: {} | {}", se_x, se_y) << std::endl; + std::cout << fmt::format("positive_charges: {}", charges_str) << std::endl; + std::cout << "lower_limit: " << lower_limit << std::endl; + std::cout << "upper_limit: " << upper_limit << std::endl; + std::cout << "number_of_layouts: " << number_of_layouts << std::endl; + std::cout << "step: " << step << std::endl; + + // This script generates random layouts as .sqd file. + using cell_level_layout = cell_level_layout>>; + try { - // This script generates random layouts as .sqd file. - using cell_level_layout = cell_level_layout>>; - constexpr const char* folder_name = "random_layouts_test_new/"; std::filesystem::path folder_path(EXPERIMENTS_PATH); folder_path /= folder_name; @@ -39,25 +105,14 @@ int main() // NOLINT std::cout << "Failed to create folder" << std::endl; } } - // number of randomly generated layouts for a given number of placed SiDBs. - const uint64_t number_of_layouts = 10; - // number of SiDBs of the first bunch of randomly generated layouts. - uint64_t number_of_sidbs_lower_limit = 20; - // number of SiDBs of the final bunch of randomly generated layouts. - uint64_t number_of_sidbs_upper_limit = 21; - if (number_of_sidbs_upper_limit < number_of_sidbs_lower_limit) + for (uint64_t place_sidbs = lower_limit; place_sidbs <= upper_limit; place_sidbs += step) { - std::swap(number_of_sidbs_upper_limit, number_of_sidbs_lower_limit); - } - - for (uint64_t num_sidbs = number_of_sidbs_lower_limit; num_sidbs < number_of_sidbs_upper_limit; num_sidbs++) - { - const std::filesystem::path dir_path = folder_path.string() + "number_sidbs_" + std::to_string(num_sidbs); + const std::filesystem::path dir_path = folder_path.string() + "number_sidbs_" + std::to_string(place_sidbs); const std::filesystem::path dir_path_sqd = - folder_path.string() + "number_sidbs_" + std::to_string(num_sidbs) + "/sqd"; + folder_path.string() + "number_sidbs_" + std::to_string(place_sidbs) + "/sqd"; const std::filesystem::path dir_path_loc = - folder_path.string() + "number_sidbs_" + std::to_string(num_sidbs) + "/loc"; + folder_path.string() + "number_sidbs_" + std::to_string(place_sidbs) + "/loc"; try { if (!std::filesystem::exists(dir_path)) @@ -72,13 +127,14 @@ int main() // NOLINT std::cout << "Folder already exists." << std::endl; } - const random_layout_params params{{{0, 0}, {20, 20}}, num_sidbs, false}; - + const generate_random_layout_params params{ + {{nw_x, nw_y}, {se_x, se_y}}, place_sidbs, charges, 2, + static_cast(10E6), number_of_layouts}; const auto unique_lyts = - generate_multiple_random_layout(params, cell_level_layout{}, number_of_layouts); + generate_multiple_random_layouts(cell_level_layout{}, params); for (auto i = 0u; i < unique_lyts.size(); i++) { - write_sqd_layout(unique_lyts[i], dir_path_sqd.string() + "/layout_" + std::to_string(i) + ".sqd"); + write_sqd_layout(unique_lyts[i], fmt::format("{}/layout_{}.sqd", dir_path_sqd.string(), i)); } } catch (const std::filesystem::filesystem_error& ex) diff --git a/experiments/random_layout_generation/simulation_result_file.cpp b/experiments/random_layout_generation/simulation_result_file.cpp index 24fe567e7..efbeee376 100644 --- a/experiments/random_layout_generation/simulation_result_file.cpp +++ b/experiments/random_layout_generation/simulation_result_file.cpp @@ -4,7 +4,7 @@ #include "fiction/algorithms/simulation/sidb/exhaustive_ground_state_simulation.hpp" #include "fiction/io/read_sqd_layout.hpp" -#include "fiction/io/write_txt_sim_result.hpp" +#include "fiction/io/write_loc_sim_result.hpp" #include "fiction/technology/charge_distribution_surface.hpp" #include "fiction/types.hpp" @@ -17,14 +17,45 @@ using namespace fiction; -int main() // NOLINT +int main(int argc, const char* argv[]) // NOLINT { // This script uses the randomly generated layouts (hence, random_layout_generation.cpp should be executed first), // simulates them, and collects the simulation results as a text file. The text file has three columns: x,y, charge // state (as integer) of the ground state. + + std::unordered_map> options{{"--folder_name", "layout_random_cli/"}, + {"--mu_minus", "-0.32"}}; + + // Parse command-line arguments + for (auto i = 1u; i < argc; ++i) + { + const std::string arg = argv[i]; + if (options.count(arg) > 0) + { + if (i + 1 < argc) + { + options[arg] = argv[i + 1]; + ++i; // Skip the next argument + } + else + { + std::cerr << "Error: Argument " << arg << " is missing a value." << std::endl; + return 1; + } + } + } + + // Folder name where the randomly generated layouts are located. + const std::string folder_name = std::get(options["--folder_name"]); + // µ-value used for the simulation. + const double mu = std::stod(std::get(options["--mu_minus"])); + + // Print the parsed values + std::cout << "Folder name: " << folder_name << std::endl; + std::cout << fmt::format("µ_minus: {}", mu) << std::endl; + try { - constexpr const char* folder_name = "random_layouts_test_new/"; std::filesystem::path folder_path(EXPERIMENTS_PATH); folder_path /= folder_name; @@ -50,31 +81,31 @@ int main() // NOLINT auto lyt = read_sqd_layout(benchmark.string()); - const sidb_simulation_parameters params{2, -0.32}; + const sidb_simulation_parameters params{2, units::energy::electron_volt_t{mu}}; const auto simulation_results = exhaustive_ground_state_simulation(lyt, params); std::stringstream ss; - ss << std::fixed << std::setprecision(3) << -params.mu; - std::string const file_path = - folder.path().string() + "/loc/" + name + "_sim_µ_minus_" + ss.str() + ".txt"; + const std::string file_path = fmt::format("{}/loc/{}_sim_µ_minus_{:.3f}.txt", + folder.path().string(), name, -params.mu.value()); + // Some layouts where positively charged SiDBs may occur cannot be simulated (i.e., no // physically valid charge distribution is found) because the physical model currently works // reliably for layouts with neutrally and negatively charged SiDBs. if (!simulation_results.charge_distributions.empty()) { - write_txt_sim_result(simulation_results, file_path); + write_loc_sim_result(simulation_results, file_path); } } } else { - std::cout << "Folder" + std::string("/sqd") + "does not exist." << std::endl; + std::cout << "Folder */sqd* does not exist." << std::endl; } } } else { - std::cout << "Folder" + std::string(folder_name) + "does not exist." << std::endl; + std::cout << fmt::format("Folder {} does not exist", folder_name) << std::endl; } } catch (const std::filesystem::filesystem_error& ex) diff --git a/include/fiction/algorithms/simulation/sidb/random_layout_generator.hpp b/include/fiction/algorithms/simulation/sidb/random_layout_generator.hpp index 51fdef835..51eed4b0d 100644 --- a/include/fiction/algorithms/simulation/sidb/random_layout_generator.hpp +++ b/include/fiction/algorithms/simulation/sidb/random_layout_generator.hpp @@ -21,15 +21,33 @@ #include #include #include +#include #include namespace fiction { + +/** + * An enumeration of modes to use for the generation of random layout to control control the appearance of positive + * charges. + */ +enum class positive_charges +{ + /** + * Positive charges can occur (i.e. SiDBs can be placed right next to each other). + */ + ALLOWED, + /** + * Positive charges are not allowed to occur (i.e. SiDBs need to be seperated by a few lattice points). + */ + FORBIDDEN +}; + /** * This struct stores the parameters for the *generate_random_layout* algorithm. */ template -struct random_layout_params +struct generate_random_layout_params { /** * Two coordinates that span the region where SiDBs may be placed (order is not important). @@ -42,16 +60,24 @@ struct random_layout_params /** * If positively charged SiDBs should be prevented, SiDBs are not placed closer than the minimal_spacing. */ - bool prevent_positive_charges = true; + positive_charges positive_sidbs = positive_charges::ALLOWED; /** - * If positively charged SiDBs should be prevented, SiDBs are not placed closer than this value (2 cells as - * Euclidean distance by default). + * If positively charged SiDBs should be prevented, SiDBs are not placed closer than this value (Euclidean distance + * of two cells). */ double minimal_spacing = 2; /** * Maximal number of steps to place the given number of SiDBs. */ uint64_t maximal_attempts = 10E6; + /** + * The desired number of unique layouts to be generated. + */ + uint64_t number_of_unique_generated_layouts = 1; + /** + * The maximum number of attempts allowed to generate the given number of unique layouts (default: \f$ 10^{6} \f$). + */ + uint64_t maximal_attempts_for_multiple_layouts = 10E6; }; /** @@ -61,10 +87,10 @@ struct random_layout_params * @param params The parameters for generating the random layout. * @param lyt_skeleton A layout to which random cells are added (useful if you need to add random cells to a given * layout). - * @return A randomly generated layout of SiDBs. + * @return A randomly-generated layout of SiDBs. */ template -Lyt generate_random_layout(const random_layout_params& params, const Lyt& lyt_skeleton) +Lyt generate_random_layout(const Lyt& lyt_skeleton, const generate_random_layout_params& params) { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); @@ -78,8 +104,7 @@ Lyt generate_random_layout(const random_layout_params& params, const Lyt& l { lyt.assign_cell_type(cell, lyt_skeleton.get_cell_type(cell)); }); } - bool successful_generation = false; - uint64_t attempt_counter = 0; + uint64_t attempt_counter = 0; // Stops if either all SiDBs are placed or the maximum number of attempts were performed. while (lyt.num_cells() < number_of_sidbs_of_final_layout && attempt_counter < params.maximal_attempts) @@ -88,7 +113,7 @@ Lyt generate_random_layout(const random_layout_params& params, const Lyt& l bool constraint_violation_positive_sidbs = false; - if (params.prevent_positive_charges) + if (params.positive_sidbs == positive_charges::FORBIDDEN) { // Checks if the new coordinate is not closer than 2 cells (Euclidean distance) from an already // placed SiDB. @@ -116,26 +141,24 @@ Lyt generate_random_layout(const random_layout_params& params, const Lyt& l * Generates multiple unique random layouts of SiDBs based on the provided parameters. * * @tparam Lyt The layout type. - * @param params The parameters for generating the random layouts. * @param lyt_skeleton A layout to which random cells are added (useful if you need to add random cells to a given * layout). - * @param number_of_unique_generated_layouts The desired number of unique layouts to be generated. - * @param maximal_attempts The maximum number of attempts allowed to generate a unique layout (default: \f$ 10^{6} \f$). + * @param params The parameters for generating the random layouts. * @return A vector containing the unique randomly generated layouts. */ template -std::vector generate_multiple_random_layout(const random_layout_params& params, const Lyt& lyt_skeleton, - const uint64_t number_of_unique_generated_layouts, - const uint64_t maximal_attemps = 10E6) +std::vector generate_multiple_random_layouts(const Lyt& lyt_skeleton, + const generate_random_layout_params& params) { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); std::vector unique_lyts{}; - unique_lyts.reserve(number_of_unique_generated_layouts); + unique_lyts.reserve(params.number_of_unique_generated_layouts); uint64_t counter = 0; - while (unique_lyts.size() < number_of_unique_generated_layouts && counter < maximal_attemps) + while (unique_lyts.size() < params.number_of_unique_generated_layouts && + counter < params.maximal_attempts_for_multiple_layouts) { - const auto random_lyt = generate_random_layout(params, lyt_skeleton); + const auto random_lyt = generate_random_layout(lyt_skeleton, params); uint64_t identical_layout_counter = 0; for (const auto& old_lyt : unique_lyts) diff --git a/include/fiction/io/write_txt_sim_result.hpp b/include/fiction/io/write_loc_sim_result.hpp similarity index 74% rename from include/fiction/io/write_txt_sim_result.hpp rename to include/fiction/io/write_loc_sim_result.hpp index d9023ccc6..8ae598650 100644 --- a/include/fiction/io/write_txt_sim_result.hpp +++ b/include/fiction/io/write_loc_sim_result.hpp @@ -2,8 +2,8 @@ // Created by Jan Drewniok on 09.06.23. // -#ifndef FICTION_WRITE_TXT_SIM_RESULT_HPP -#define FICTION_WRITE_TXT_SIM_RESULT_HPP +#ifndef FICTION_WRITE_LOC_SIM_RESULT_HPP +#define FICTION_WRITE_LOC_SIM_RESULT_HPP #include "fiction/algorithms/simulation/sidb/exhaustive_ground_state_simulation.hpp" #include "fiction/algorithms/simulation/sidb/minimum_energy.hpp" @@ -30,16 +30,12 @@ template class write_txt_sim_result_impl { public: - write_txt_sim_result_impl(const sidb_simulation_result& result, std::ostream& s) : - - sim_result{result}, - os{s} - - {} + write_txt_sim_result_impl(const sidb_simulation_result& result, std::ostream& s) : sim_result{result}, os{s} {} void run() { - auto min_energy = + // This part searches for the ground state(s) among all physically valid charge distributions. + const auto min_energy = round_to_n_decimal_places(minimum_energy(sim_result.charge_distributions), 6); std::vector> ground_state_layouts{}; @@ -50,21 +46,17 @@ class write_txt_sim_result_impl ground_state_layouts.emplace_back(charge_distribution_surface{valid_layout}); } } + if (!ground_state_layouts.empty()) { - - // Set the floating-point precision for the output file - os << std::fixed << std::setprecision(3); - // Write the column headers - os << "x [nm];" - << "y [nm];"; + os << "x [nm]; y [nm];"; for (uint64_t i = 0; i < ground_state_layouts.size(); i++) { - os << "GS_" << std::to_string(i) << ";"; + os << fmt::format("GS_{};", i); } - os << std::endl; + os << '\n'; auto sidbs = ground_state_layouts.front().get_all_sidb_cells(); const auto physical_parameter = ground_state_layouts.front().get_phys_params(); @@ -72,13 +64,13 @@ class write_txt_sim_result_impl std::sort(sidbs.begin(), sidbs.end()); for (const auto& sidb : sidbs) { - auto pos = sidb_nm_position(physical_parameter, sidb); - os << pos.first << ";" << pos.second << ";"; + const auto pos = sidb_nm_position(physical_parameter, sidb); + os << fmt::format("{:.3f};{:.3f};", pos.first.value(), pos.second.value()); for (const auto& valid_layout : ground_state_layouts) { - os << std::to_string(charge_state_to_sign(valid_layout.get_charge_state(sidb))) << ";"; + os << fmt::format("{};", charge_state_to_sign(valid_layout.get_charge_state(sidb))); } - os << std::endl; + os << "\n"; } } }; @@ -87,7 +79,7 @@ class write_txt_sim_result_impl /** * Simulation results. */ - sidb_simulation_result sim_result; + const sidb_simulation_result& sim_result; /** * Output stream used for writing the simulation result. */ @@ -107,7 +99,7 @@ class write_txt_sim_result_impl * @param os The output stream to write into. */ template -void write_txt_sim_result(const sidb_simulation_result& sim_result, std::ostream& os) +void write_loc_sim_result(const sidb_simulation_result& sim_result, std::ostream& os) { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt must be an SiDB layout"); @@ -123,10 +115,10 @@ void write_txt_sim_result(const sidb_simulation_result& sim_result, std::os * This overload uses a file name to create and write into. * * @tparam sim_result Simulation result of physical simulation. - * @param filename The file name to create and write into. Should preferably use the `.sqd` extension. + * @param filename The file name to create and write into. */ template -void write_txt_sim_result(const sidb_simulation_result& sim_result, const std::string_view& filename) +void write_loc_sim_result(const sidb_simulation_result& sim_result, const std::string_view& filename) { std::ofstream os{filename.data(), std::ofstream::out}; @@ -135,10 +127,10 @@ void write_txt_sim_result(const sidb_simulation_result& sim_result, const s throw std::ofstream::failure("could not open file"); } - write_txt_sim_result(sim_result, os); + write_loc_sim_result(sim_result, os); os.close(); } } // namespace fiction -#endif // FICTION_WRITE_TXT_SIM_RESULT_HPP +#endif // FICTION_WRITE_LOC_SIM_RESULT_HPP diff --git a/test/algorithms/simulation/sidb/random_layout_generator.cpp b/test/algorithms/simulation/sidb/random_layout_generator.cpp index bcd6b64ab..dcc070b40 100644 --- a/test/algorithms/simulation/sidb/random_layout_generator.cpp +++ b/test/algorithms/simulation/sidb/random_layout_generator.cpp @@ -23,9 +23,9 @@ TEST_CASE("Random cube::coord_t layout generation", "[generate_random_layout]") SECTION("empty parameters") { - const random_layout_params params{}; + const generate_random_layout_params params{}; - const auto lyt = generate_random_layout(params, cube_layout{}); + const auto lyt = generate_random_layout(cube_layout{}, params); CHECK(lyt.num_cells() == 0); CHECK(lyt.x() == 0); @@ -34,9 +34,9 @@ TEST_CASE("Random cube::coord_t layout generation", "[generate_random_layout]") SECTION("given corner coordinates, wrong order") { - const random_layout_params params{{{5, 7, 2}, {-10, -10, 0}}}; + const generate_random_layout_params params{{{5, 7, 2}, {-10, -10, 0}}}; - const auto result_lyt = generate_random_layout(params, cube_layout{}); + const auto result_lyt = generate_random_layout(cube_layout{}, params); CHECK(result_lyt.num_cells() == 0); result_lyt.foreach_cell( @@ -50,9 +50,9 @@ TEST_CASE("Random cube::coord_t layout generation", "[generate_random_layout]") SECTION("given corner coordinates") { - const random_layout_params params{{{-10, -10, 0}, {5, 7, 2}}}; + const generate_random_layout_params params{{{-10, -10, 0}, {5, 7, 2}}}; - const auto result_lyt = generate_random_layout(params, cube_layout{}); + const auto result_lyt = generate_random_layout(cube_layout{}, params); CHECK(result_lyt.num_cells() == 0); result_lyt.foreach_cell( @@ -66,9 +66,9 @@ TEST_CASE("Random cube::coord_t layout generation", "[generate_random_layout]") SECTION("given two identical coordinates") { - const random_layout_params params{{{-10, -10, 1}, {-10, -10, 1}}, 1}; + const generate_random_layout_params params{{{-10, -10, 1}, {-10, -10, 1}}, 1}; - const auto result_lyt = generate_random_layout(params, cube_layout{}); + const auto result_lyt = generate_random_layout(cube_layout{}, params); CHECK(result_lyt.num_cells() == 1); result_lyt.foreach_cell( @@ -82,9 +82,9 @@ TEST_CASE("Random cube::coord_t layout generation", "[generate_random_layout]") SECTION("given corner coordinates and number of placed SiDBs") { - const random_layout_params params{{{-10, -10, 0}, {5, 7, 1}}, 10}; + const generate_random_layout_params params{{{-10, -10, 0}, {5, 7, 1}}, 10}; - const auto result_lyt = generate_random_layout(params, cube_layout{}); + const auto result_lyt = generate_random_layout(cube_layout{}, params); CHECK(result_lyt.num_cells() == 10); result_lyt.foreach_cell( @@ -101,9 +101,11 @@ TEST_CASE("Random cube::coord_t layout generation", "[generate_random_layout]") SECTION("given corner coordinates and number of placed SiDBs, and forbid positive charges") { - const random_layout_params params{{{0, 0, 0}, {90, 90, 0}}, 100, false}; + const generate_random_layout_params params{{{0, 0, 0}, {90, 90, 0}}, + 100, + positive_charges::ALLOWED}; - const auto result_lyt = generate_random_layout(params, cube_layout{}); + const auto result_lyt = generate_random_layout(cube_layout{}, params); CHECK(result_lyt.num_cells() == 100); result_lyt.foreach_cell( @@ -116,9 +118,11 @@ TEST_CASE("Random cube::coord_t layout generation", "[generate_random_layout]") SECTION("given corner coordinates and number of placed SiDBs, and allow positive charges") { - const random_layout_params params{{{0, 0, 0}, {90, 90, 0}}, 100, true}; + const generate_random_layout_params params{{{0, 0, 0}, {90, 90, 0}}, + 100, + positive_charges::FORBIDDEN}; - const auto result_lyt = generate_random_layout(params, cube_layout{}); + const auto result_lyt = generate_random_layout(cube_layout{}, params); CHECK(result_lyt.num_cells() == 100); result_lyt.foreach_cell( @@ -144,8 +148,9 @@ TEST_CASE("Random cube::coord_t layout generation", "[generate_random_layout]") SECTION("given previous layouts") { - const random_layout_params params{{{-5, -2}, {9, 9}}, 10}; - const auto result_lyts = generate_multiple_random_layout(params, cube_layout{}, 3); + const generate_random_layout_params params{ + {{-5, -2}, {9, 9}}, 10, positive_charges::FORBIDDEN, 2, static_cast(10E6), 3}; + const auto result_lyts = generate_multiple_random_layouts(cube_layout{}, params); CHECK(result_lyts.size() == 3); for (const auto& lyt : result_lyts) @@ -163,8 +168,9 @@ TEST_CASE("Random cube::coord_t layout generation", "[generate_random_layout]") SECTION("Check uniqueness of two layouts") { - const random_layout_params params{{{0, 0}, {9, 9}}, 10}; - const auto result_lyts = generate_multiple_random_layout(params, cube_layout{}, 2); + const generate_random_layout_params params{ + {{0, 0}, {9, 9}}, 10, positive_charges::FORBIDDEN, 2, static_cast(10E6), 2}; + const auto result_lyts = generate_multiple_random_layouts(cube_layout{}, params); REQUIRE(result_lyts.size() == 2); const auto& first_lyt = result_lyts.front(); @@ -191,9 +197,9 @@ TEST_CASE("Random offset::ucoord_t layout generation", "[generate_random_layout] { SECTION("empty parameters") { - const random_layout_params params{}; + const generate_random_layout_params params{}; - const auto lyt = generate_random_layout(params, sidb_cell_clk_lyt{}); + const auto lyt = generate_random_layout(sidb_cell_clk_lyt{}, params); CHECK(lyt.num_cells() == 0); CHECK(lyt.x() == 0); @@ -202,9 +208,9 @@ TEST_CASE("Random offset::ucoord_t layout generation", "[generate_random_layout] SECTION("given corner coordinates") { - const random_layout_params params{{{1, 1, 0}, {5, 7, 2}}}; + const generate_random_layout_params params{{{1, 1, 0}, {5, 7, 2}}}; - const auto result_lyt = generate_random_layout(params, sidb_cell_clk_lyt{}); + const auto result_lyt = generate_random_layout(sidb_cell_clk_lyt{}, params); CHECK(result_lyt.num_cells() == 0); result_lyt.foreach_cell( @@ -218,9 +224,9 @@ TEST_CASE("Random offset::ucoord_t layout generation", "[generate_random_layout] SECTION("given two identical coordinates") { - const random_layout_params params{{{5, 5, 1}, {5, 5, 1}}, 1}; + const generate_random_layout_params params{{{5, 5, 1}, {5, 5, 1}}, 1}; - const auto result_lyt = generate_random_layout(params, sidb_cell_clk_lyt{}); + const auto result_lyt = generate_random_layout(sidb_cell_clk_lyt{}, params); CHECK(result_lyt.num_cells() == 1); result_lyt.foreach_cell( @@ -234,9 +240,9 @@ TEST_CASE("Random offset::ucoord_t layout generation", "[generate_random_layout] SECTION("given corner coordinates and number of placed SiDBs") { - const random_layout_params params{{{1, 1, 0}, {50, 7, 1}}, 10}; + const generate_random_layout_params params{{{1, 1, 0}, {50, 7, 1}}, 10}; - const auto result_lyt = generate_random_layout(params, sidb_cell_clk_lyt{}); + const auto result_lyt = generate_random_layout(sidb_cell_clk_lyt{}, params); CHECK(result_lyt.num_cells() == 10); result_lyt.foreach_cell( @@ -253,9 +259,11 @@ TEST_CASE("Random offset::ucoord_t layout generation", "[generate_random_layout] SECTION("given corner coordinates and number of placed SiDBs, and forbid positive charges") { - const random_layout_params params{{{0, 0, 0}, {90, 90, 0}}, 100, false}; + const generate_random_layout_params params{{{0, 0, 0}, {90, 90, 0}}, + 100, + positive_charges::ALLOWED}; - const auto result_lyt = generate_random_layout(params, sidb_cell_clk_lyt{}); + const auto result_lyt = generate_random_layout(sidb_cell_clk_lyt{}, params); CHECK(result_lyt.num_cells() == 100); result_lyt.foreach_cell( @@ -268,9 +276,11 @@ TEST_CASE("Random offset::ucoord_t layout generation", "[generate_random_layout] SECTION("given corner coordinates and number of placed SiDBs, and allow positive charges") { - const random_layout_params params{{{0, 0, 0}, {90, 90, 0}}, 100, true}; + const generate_random_layout_params params{{{0, 0, 0}, {90, 90, 0}}, + 100, + positive_charges::FORBIDDEN}; - const auto result_lyt = generate_random_layout(params, sidb_cell_clk_lyt{}); + const auto result_lyt = generate_random_layout(sidb_cell_clk_lyt{}, params); CHECK(result_lyt.num_cells() == 100); result_lyt.foreach_cell( @@ -296,8 +306,9 @@ TEST_CASE("Random offset::ucoord_t layout generation", "[generate_random_layout] SECTION("given previous layouts") { - const random_layout_params params{{{0, 0}, {9, 9, 2}}, 10}; - const auto result_lyts = generate_multiple_random_layout(params, sidb_cell_clk_lyt{}, 3); + const generate_random_layout_params params{ + {{0, 0}, {9, 9, 2}}, 10, positive_charges::FORBIDDEN, 2, static_cast(10E6), 3}; + const auto result_lyts = generate_multiple_random_layouts(sidb_cell_clk_lyt{}, params); CHECK(result_lyts.size() == 3); for (const auto& lyt : result_lyts) @@ -313,8 +324,9 @@ TEST_CASE("Random offset::ucoord_t layout generation", "[generate_random_layout] SECTION("Check uniqueness of two layouts") { - const random_layout_params params{{{0, 0}, {9, 9}}, 10}; - const auto result_lyts = generate_multiple_random_layout(params, sidb_cell_clk_lyt{}, 2); + const generate_random_layout_params params{ + {{0, 0}, {9, 9}}, 10, positive_charges::FORBIDDEN, 2, static_cast(10E6), 2}; + const auto result_lyts = generate_multiple_random_layouts(sidb_cell_clk_lyt{}, params); REQUIRE(result_lyts.size() == 2); const auto& first_lyt = result_lyts.front(); @@ -338,24 +350,25 @@ TEST_CASE("Random offset::ucoord_t layout generation", "[generate_random_layout] SECTION("Check correct use of skeleton layout when generating only one random layout") { - const random_layout_params params{{{0, 0}, {9, 9}}, 10}; - sidb_cell_clk_lyt skeleton_layout{}; + const generate_random_layout_params params{{{0, 0}, {9, 9}}, 10}; + sidb_cell_clk_lyt skeleton_layout{}; skeleton_layout.assign_cell_type({0, 0}, sidb_cell_clk_lyt::technology::NORMAL); skeleton_layout.assign_cell_type({9, 1}, sidb_cell_clk_lyt::technology::NORMAL); skeleton_layout.assign_cell_type({5, 0}, sidb_cell_clk_lyt::technology::NORMAL); - const auto result_lyt = generate_random_layout(params, skeleton_layout); + const auto result_lyt = generate_random_layout(skeleton_layout, params); CHECK(result_lyt.num_cells() == 13); } SECTION("Check correct use of skeleton layout when generating multiple random layouts") { - const random_layout_params params{{{0, 0}, {9, 9}}, 10}; - sidb_cell_clk_lyt skeleton_layout{}; + const generate_random_layout_params params{ + {{0, 0}, {9, 9}}, 10, positive_charges::FORBIDDEN, 2, static_cast(10E6), 2}; + sidb_cell_clk_lyt skeleton_layout{}; skeleton_layout.assign_cell_type({0, 0}, sidb_cell_clk_lyt::technology::NORMAL); skeleton_layout.assign_cell_type({3, 0}, sidb_cell_clk_lyt::technology::NORMAL); skeleton_layout.assign_cell_type({9, 1}, sidb_cell_clk_lyt::technology::NORMAL); - const auto result_lyts = generate_multiple_random_layout(params, skeleton_layout, 2); + const auto result_lyts = generate_multiple_random_layouts(skeleton_layout, params); REQUIRE(result_lyts.size() == 2); CHECK(result_lyts.front().num_cells() == 13); @@ -367,9 +380,9 @@ TEST_CASE("Random siqad::coord_t layout generation", "[generate_random_layout]") { SECTION("empty parameters") { - const random_layout_params params{}; + const generate_random_layout_params params{}; - const auto lyt = generate_random_layout(params, sidb_cell_clk_lyt{}); + const auto lyt = generate_random_layout(sidb_cell_clk_lyt{}, params); CHECK(lyt.num_cells() == 0); CHECK(lyt.x() == 0); @@ -378,9 +391,9 @@ TEST_CASE("Random siqad::coord_t layout generation", "[generate_random_layout]") SECTION("given two identical coordinates") { - const random_layout_params params{{{5, 5, 1}, {5, 5, 1}}, 1}; + const generate_random_layout_params params{{{5, 5, 1}, {5, 5, 1}}, 1}; - const auto result_lyt = generate_random_layout(params, sidb_cell_clk_lyt{}); + const auto result_lyt = generate_random_layout(sidb_cell_clk_lyt{}, params); CHECK(result_lyt.num_cells() == 1); result_lyt.foreach_cell( @@ -394,9 +407,9 @@ TEST_CASE("Random siqad::coord_t layout generation", "[generate_random_layout]") SECTION("given corner coordinates") { - const random_layout_params params{{{1, 1, 0}, {5, 7, 1}}}; + const generate_random_layout_params params{{{1, 1, 0}, {5, 7, 1}}}; - const auto result_lyt = generate_random_layout(params, sidb_cell_clk_lyt{}); + const auto result_lyt = generate_random_layout(sidb_cell_clk_lyt{}, params); CHECK(result_lyt.num_cells() == 0); result_lyt.foreach_cell( @@ -410,9 +423,9 @@ TEST_CASE("Random siqad::coord_t layout generation", "[generate_random_layout]") SECTION("given corner coordinates and number of placed SiDBs") { - const random_layout_params params{{{1, 1, 0}, {50, 7, 1}}, 10}; + const generate_random_layout_params params{{{1, 1, 0}, {50, 7, 1}}, 10}; - const auto result_lyt = generate_random_layout(params, sidb_cell_clk_lyt{}); + const auto result_lyt = generate_random_layout(sidb_cell_clk_lyt{}, params); CHECK(result_lyt.num_cells() == 10); result_lyt.foreach_cell( @@ -429,9 +442,11 @@ TEST_CASE("Random siqad::coord_t layout generation", "[generate_random_layout]") SECTION("given corner coordinates and number of placed SiDBs, and forbid positive charges") { - const random_layout_params params{{{0, 0, 0}, {90, 90, 0}}, 100, false}; + const generate_random_layout_params params{{{0, 0, 0}, {90, 90, 0}}, + 100, + positive_charges::ALLOWED}; - const auto result_lyt = generate_random_layout(params, sidb_cell_clk_lyt{}); + const auto result_lyt = generate_random_layout(sidb_cell_clk_lyt{}, params); CHECK(result_lyt.num_cells() == 100); result_lyt.foreach_cell( @@ -444,9 +459,11 @@ TEST_CASE("Random siqad::coord_t layout generation", "[generate_random_layout]") SECTION("given corner coordinates and number of placed SiDBs, and allow positive charges") { - const random_layout_params params{{{0, 0, 0}, {90, 90, 0}}, 100, true}; + const generate_random_layout_params params{{{0, 0, 0}, {90, 90, 0}}, + 100, + positive_charges::FORBIDDEN}; - const auto result_lyt = generate_random_layout(params, sidb_cell_clk_lyt{}); + const auto result_lyt = generate_random_layout(sidb_cell_clk_lyt{}, params); CHECK(result_lyt.num_cells() == 100); result_lyt.foreach_cell( @@ -473,8 +490,9 @@ TEST_CASE("Random siqad::coord_t layout generation", "[generate_random_layout]") SECTION("given previous layouts") { - const random_layout_params params{{{0, 0, 1}, {9, 9, 1}}, 10}; - const auto result_lyts = generate_multiple_random_layout(params, sidb_cell_clk_lyt{}, 3); + const generate_random_layout_params params{ + {{0, 0, 1}, {9, 9, 1}}, 10, positive_charges::FORBIDDEN, 2, static_cast(10E6), 3}; + const auto result_lyts = generate_multiple_random_layouts(sidb_cell_clk_lyt{}, params); CHECK(result_lyts.size() == 3); for (const auto& lyt : result_lyts) @@ -493,8 +511,9 @@ TEST_CASE("Random siqad::coord_t layout generation", "[generate_random_layout]") SECTION("Check uniqueness of two layouts") { - const random_layout_params params{{{0, 0, 1}, {9, 9, 0}}, 10}; - const auto result_lyts = generate_multiple_random_layout(params, sidb_cell_clk_lyt{}, 2); + const generate_random_layout_params params{ + {{0, 0, 1}, {9, 9, 0}}, 10, positive_charges::FORBIDDEN, 2, static_cast(10E6), 2}; + const auto result_lyts = generate_multiple_random_layouts(sidb_cell_clk_lyt{}, params); REQUIRE(result_lyts.size() == 2); const auto& first_lyt = result_lyts.front(); diff --git a/test/io/write_txt_sim_result.cpp b/test/io/write_loc_sim_result.cpp similarity index 76% rename from test/io/write_txt_sim_result.cpp rename to test/io/write_loc_sim_result.cpp index 7be832f3b..93946c8aa 100644 --- a/test/io/write_txt_sim_result.cpp +++ b/test/io/write_loc_sim_result.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include #include @@ -38,17 +38,18 @@ TEST_CASE("writes expected output", "[write_txt_sim_result]") lyt.assign_cell_type({5, 0}, sidb_cell_clk_lyt_siqad::cell_type::NORMAL); lyt.assign_cell_type({8, 0}, sidb_cell_clk_lyt_siqad::cell_type::NORMAL); - const sidb_simulation_parameters params{2, -0.32}; + const sidb_simulation_parameters params{2, -0.32_eV}; const auto simulation_results = exhaustive_ground_state_simulation(lyt, params); std::stringstream ss; - write_txt_sim_result(simulation_results, ss); + write_loc_sim_result(simulation_results, ss); const std::string expected_output = R"(x [nm];y [nm];GS_0;GS_1; - 0.000;0.000;-1;-1; - 1.152;0.000;0;-1; - 1.920;0.000;-1;0; - 3.072;0.000;-1;-1;)"; + 0.0;0.0;-1;-1; + 1.152;0.0;0;-1; + 1.92;0.0;-1;0; + 3.072;0.0;-1;-1;)"; + REQUIRE(compare_output(ss.str(), expected_output)); } @@ -58,16 +59,17 @@ TEST_CASE("writes expected output", "[write_txt_sim_result]") lyt.assign_cell_type({3, 0}, sidb_cell_clk_lyt_siqad::cell_type::NORMAL); lyt.assign_cell_type({5, 0}, sidb_cell_clk_lyt_siqad::cell_type::NORMAL); - const sidb_simulation_parameters params{2, -0.32}; + const sidb_simulation_parameters params{2, -0.32_eV}; const auto simulation_results = exhaustive_ground_state_simulation(lyt, params); std::stringstream ss; - write_txt_sim_result(simulation_results, ss); + write_loc_sim_result(simulation_results, ss); const std::string expected_output = R"(x [nm];y [nm];GS_0; - 0.000;0.000;-1; - 1.152;0.000;0; - 1.920;0.000;-1;)"; + 0.0;0.0;-1; + 1.152;0.0;0; + 1.92;0.0;-1;)"; + REQUIRE(compare_output(ss.str(), expected_output)); } }