From 10eb70ae40f3c65267b57a8cc45c9096e3235cb5 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 21 Nov 2023 22:11:13 +0100 Subject: [PATCH 1/9] :art: allow fiction coordinates for simulation. --- .../algorithms/iter/bdl_input_iterator.hpp | 1 - .../algorithms/path_finding/distance.hpp | 2 +- .../physical_design/design_sidb_gates.hpp | 21 ++- .../assess_physical_population_stability.hpp | 2 +- .../sidb/calculate_energy_and_state_type.hpp | 1 - .../simulation/sidb/detect_bdl_pairs.hpp | 2 - .../simulation/sidb/is_ground_state.hpp | 1 - .../simulation/sidb/is_operational.hpp | 1 - ...defect_influence_position_and_distance.hpp | 115 +++++------- .../simulation/sidb/operational_domain.hpp | 4 - .../algorithms/simulation/sidb/quickexact.hpp | 8 +- include/fiction/layouts/bounding_box.hpp | 2 +- include/fiction/layouts/coordinates.hpp | 10 +- .../charge_distribution_surface.hpp | 4 +- .../fiction/technology/sidb_nm_position.hpp | 22 ++- include/fiction/utils/layout_utils.hpp | 34 ++-- .../physical_design/design_sidb_gates.cpp | 84 ++++++--- .../assess_physical_population_stability.cpp | 164 +++++++++++++++- .../sidb/can_positive_charges_occur.cpp | 72 ++++++- .../exhaustive_ground_state_simulation.cpp | 116 +++++++++++- ...defect_influence_position_and_distance.cpp | 38 +++- .../simulation/sidb/operational_domain.cpp | 121 ++++++++++++ .../algorithms/simulation/sidb/quickexact.cpp | 177 +++++++++++++++++- test/algorithms/simulation/sidb/quicksim.cpp | 102 ++++++++++ .../sidb/random_sidb_layout_generator.cpp | 41 ++++ .../charge_distribution_surface.cpp | 44 +---- test/technology/sidb_nm_position.cpp | 66 ++++++- test/utils/layout_utils.cpp | 58 +++++- 28 files changed, 1107 insertions(+), 206 deletions(-) diff --git a/include/fiction/algorithms/iter/bdl_input_iterator.hpp b/include/fiction/algorithms/iter/bdl_input_iterator.hpp index cd5a40e60..68d25d4e8 100644 --- a/include/fiction/algorithms/iter/bdl_input_iterator.hpp +++ b/include/fiction/algorithms/iter/bdl_input_iterator.hpp @@ -46,7 +46,6 @@ class bdl_input_iterator { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); - static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); set_all_inputs(); } diff --git a/include/fiction/algorithms/path_finding/distance.hpp b/include/fiction/algorithms/path_finding/distance.hpp index 5b2351a7a..943d42fa9 100644 --- a/include/fiction/algorithms/path_finding/distance.hpp +++ b/include/fiction/algorithms/path_finding/distance.hpp @@ -107,7 +107,7 @@ sidb_nanometer_distance([[maybe_unused]] const Lyt& lyt, const coordinate& { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not based on SiDB technology"); - static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); + //static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); const auto pos_c1 = sidb_nm_position(sp, source); const auto pos_c2 = sidb_nm_position(sp, target); diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 19e9329f9..4ac214a07 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -39,6 +39,7 @@ namespace fiction * This struct contains parameters and settings to design SiDB gates. * */ +template struct design_sidb_gates_params { /** @@ -66,7 +67,7 @@ struct design_sidb_gates_params /** * Canvas spanned by the northwest and southeast cell. */ - std::pair canvas{}; + std::pair canvas{}; /** * Number of SiDBs placed in the canvas to create a working gate. */ @@ -92,7 +93,7 @@ class design_sidb_gates_impl * @param tt Expected Boolean function of the layout given as a multi-output truth table. * @param ps Parameters and settings for the gate designer. */ - design_sidb_gates_impl(const Lyt& skeleton, const std::vector& tt, const design_sidb_gates_params& ps) : + design_sidb_gates_impl(const Lyt& skeleton, const std::vector& tt, const design_sidb_gates_params& ps) : skeleton_layout{skeleton}, truth_table{tt}, params{ps}, @@ -220,11 +221,11 @@ class design_sidb_gates_impl /** * Parameters for the *SiDB Gate Designer*. */ - const design_sidb_gates_params& params; + const design_sidb_gates_params& params; /** * All cells within the canvas. */ - const std::vector all_sidbs_in_cavas; + const std::vector all_sidbs_in_cavas; /** * Calculates all possible combinations of distributing the given number of SiDBs within a canvas * based on the provided parameters. It generates combinations of SiDB indices (representing the cell position in @@ -279,9 +280,8 @@ class design_sidb_gates_impl { for (std::size_t j = i + 1; j < cell_indices.size(); j++) { - if (sidb_nanometer_distance(skeleton_layout, - all_sidbs_in_cavas[cell_indices[i]], - all_sidbs_in_cavas[cell_indices[j]]) < 0.5) + if (sidb_nanometer_distance(skeleton_layout, all_sidbs_in_cavas[cell_indices[i]], + all_sidbs_in_cavas[cell_indices[j]]) < 0.5) { return true; } @@ -344,12 +344,13 @@ class design_sidb_gates_impl */ template [[nodiscard]] std::vector design_sidb_gates(const Lyt& skeleton, const std::vector& spec, - const design_sidb_gates_params& params = {}) noexcept + const design_sidb_gates_params& params = {}) noexcept { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); - static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); static_assert(kitty::is_truth_table::value, "TT is not a truth table"); + static_assert(!is_charge_distribution_surface_v, "Lyt cannot be a charge distribution surface"); + static_assert(!has_offset_ucoord_v, "Lyt cannot be based on offset coordinates"); assert(skeleton.num_pis() > 0 && "skeleton needs input cells"); assert(skeleton.num_pos() > 0 && "skeleton needs output cells"); @@ -361,7 +362,7 @@ template detail::design_sidb_gates_impl p{skeleton, spec, params}; - if (params.design_mode == design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE) + if (params.design_mode == design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE) { return p.run_exhaustive_design(); } diff --git a/include/fiction/algorithms/simulation/sidb/assess_physical_population_stability.hpp b/include/fiction/algorithms/simulation/sidb/assess_physical_population_stability.hpp index 7cf19c96c..bce65fa35 100644 --- a/include/fiction/algorithms/simulation/sidb/assess_physical_population_stability.hpp +++ b/include/fiction/algorithms/simulation/sidb/assess_physical_population_stability.hpp @@ -367,7 +367,7 @@ assess_physical_population_stability(const Lyt& lyt, const assess_physical_popul { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); - static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); + static_assert(!is_charge_distribution_surface_v, "Lyt is a charge distribution surface"); detail::assess_physical_population_stability_impl p{lyt, params}; return p.run(); diff --git a/include/fiction/algorithms/simulation/sidb/calculate_energy_and_state_type.hpp b/include/fiction/algorithms/simulation/sidb/calculate_energy_and_state_type.hpp index da2790e24..63f5e5ac2 100644 --- a/include/fiction/algorithms/simulation/sidb/calculate_energy_and_state_type.hpp +++ b/include/fiction/algorithms/simulation/sidb/calculate_energy_and_state_type.hpp @@ -50,7 +50,6 @@ calculate_energy_and_state_type(const sidb_energy_distribution& { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); - static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); static_assert(kitty::is_truth_table::value, "TT is not a truth table"); assert(!output_bdl_pairs.empty() && "No output cell provided."); diff --git a/include/fiction/algorithms/simulation/sidb/detect_bdl_pairs.hpp b/include/fiction/algorithms/simulation/sidb/detect_bdl_pairs.hpp index 5169a91ce..f779fe7d3 100644 --- a/include/fiction/algorithms/simulation/sidb/detect_bdl_pairs.hpp +++ b/include/fiction/algorithms/simulation/sidb/detect_bdl_pairs.hpp @@ -56,7 +56,6 @@ struct bdl_pair { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); - static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); } }; @@ -96,7 +95,6 @@ std::vector> detect_bdl_pairs(const Lyt& lyt, const typename techn { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); - static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); // sanity check for parameter settings assert(params.minimum_distance <= params.maximum_distance); diff --git a/include/fiction/algorithms/simulation/sidb/is_ground_state.hpp b/include/fiction/algorithms/simulation/sidb/is_ground_state.hpp index ddbcd0424..085ef971e 100644 --- a/include/fiction/algorithms/simulation/sidb/is_ground_state.hpp +++ b/include/fiction/algorithms/simulation/sidb/is_ground_state.hpp @@ -32,7 +32,6 @@ template { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); - static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); if (exhaustive_results.charge_distributions.empty()) { diff --git a/include/fiction/algorithms/simulation/sidb/is_operational.hpp b/include/fiction/algorithms/simulation/sidb/is_operational.hpp index 4ab337cae..aaa7a9f5f 100644 --- a/include/fiction/algorithms/simulation/sidb/is_operational.hpp +++ b/include/fiction/algorithms/simulation/sidb/is_operational.hpp @@ -272,7 +272,6 @@ is_operational(const Lyt& lyt, const std::vector& spec, const is_operational { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); - static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); static_assert(kitty::is_truth_table::value, "TT is not a truth table"); assert(lyt.num_pis() > 0 && "skeleton needs input cells"); diff --git a/include/fiction/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.hpp b/include/fiction/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.hpp index c276479d7..e6f5a5650 100644 --- a/include/fiction/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.hpp +++ b/include/fiction/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.hpp @@ -98,49 +98,53 @@ class maximum_defect_influence_position_and_distance_impl // simulate the impact of the defect at a given position on the ground state of the SiDB layout const auto process_defect = [&](const auto& defect) noexcept { - sidb_surface lyt_defect{}; + if (layout.get_cell_type(defect) == Lyt::technology::cell_type::EMPTY) + { + sidb_surface lyt_defect{}; - layout.foreach_cell([this, &lyt_defect](const auto& cell) - { lyt_defect.assign_cell_type(cell, layout.get_cell_type(cell)); }); + layout.foreach_cell([this, &lyt_defect](const auto& cell) + { lyt_defect.assign_cell_type(cell, layout.get_cell_type(cell)); }); - // assign defect to layout - lyt_defect.assign_sidb_defect(defect, params.defect); - // conduct simulation with defect - auto simulation_result_defect = quickexact(lyt_defect, params_defect); + // assign defect to layout + lyt_defect.assign_sidb_defect(defect, params.defect); + // conduct simulation with defect + auto simulation_result_defect = quickexact(lyt_defect, params_defect); - const auto min_energy_defect = minimum_energy(simulation_result_defect.charge_distributions); - uint64_t charge_index_defect_layout = 0; + const auto min_energy_defect = minimum_energy(simulation_result_defect.charge_distributions); + uint64_t charge_index_defect_layout = 0; - // get the charge index of the ground state - for (const auto& lyt_simulation_with_defect : simulation_result_defect.charge_distributions) - { - if (std::fabs(round_to_n_decimal_places(lyt_simulation_with_defect.get_system_energy(), 6) - - round_to_n_decimal_places(min_energy_defect, 6)) < std::numeric_limits::epsilon()) + // get the charge index of the ground state + for (const auto& lyt_simulation_with_defect : simulation_result_defect.charge_distributions) { - lyt_simulation_with_defect.charge_distribution_to_index_general(); - charge_index_defect_layout = lyt_simulation_with_defect.get_charge_index_and_base().first; - } - } - - // defect changes the ground state, i.e., the charge index is changed compared to the charge - // distribution without placed defect. - if (charge_index_defect_layout != charge_index_layout) - { - auto distance = std::numeric_limits::max(); - layout.foreach_cell( - [this, &defect, &distance](const auto& cell) + if (std::fabs(round_to_n_decimal_places(lyt_simulation_with_defect.get_system_energy(), 6) - + round_to_n_decimal_places(min_energy_defect, 6)) < + std::numeric_limits::epsilon()) { - if (sidb_nanometer_distance(layout, cell, defect) < distance) - { - distance = sidb_nanometer_distance(layout, cell, defect); - } - }); + lyt_simulation_with_defect.charge_distribution_to_index_general(); + charge_index_defect_layout = lyt_simulation_with_defect.get_charge_index_and_base().first; + } + } - // the distance is larger than the current maximum one. - if (distance > avoidance_distance) + // defect changes the ground state, i.e., the charge index is changed compared to the charge + // distribution without placed defect. + if (charge_index_defect_layout != charge_index_layout) { - max_defect_position = defect; - avoidance_distance = distance; + auto distance = std::numeric_limits::max(); + layout.foreach_cell( + [this, &defect, &distance](const auto& cell) + { + if (sidb_nanometer_distance(layout, cell, defect) < distance) + { + distance = sidb_nanometer_distance(layout, cell, defect); + } + }); + + // the distance is larger than the current maximum one. + if (distance > avoidance_distance) + { + max_defect_position = defect; + avoidance_distance = distance; + } } } }; @@ -187,43 +191,7 @@ class maximum_defect_influence_position_and_distance_impl se.x = se.x + params.additional_scanning_area.first; se.y = se.y + params.additional_scanning_area.second; - // start to place the defect at the north-west cell - auto defect_cell = nw; - - // maximum number of placable defects in the given bounding box - const uint64_t max_defect_positions = - static_cast(std::abs(se.x - nw.x) + 1) * static_cast(std::abs(se.y - nw.y) + 1) * 2; - defect_cells.reserve(max_defect_positions); - - // collect all cells in the bounding box area (spanned by the nw and se) going from top to down from left to - // right. - while (defect_cell <= se) - { - // Defect can only be placed at free locations. - if (layout.get_cell_type(defect_cell) == sidb_technology::cell_type::EMPTY) - { - defect_cells.push_back(defect_cell); - } - if (defect_cell.x < se.x) - { - defect_cell.x += 1; - } - else if ((defect_cell.x == se.x) && defect_cell.z == 0) - { - defect_cell.z += 1; - defect_cell.x = nw.x; - } - else if ((defect_cell.x == se.x) && defect_cell.z == 1) - { - defect_cell.x = nw.x; - defect_cell.y += 1; - defect_cell.z = 0; - } - else - { - break; - } - } + defect_cells = all_sidbs_in_spanned_area(nw, se); } }; @@ -249,7 +217,8 @@ maximum_defect_influence_position_and_distance(const Lyt& { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); - static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); + static_assert(!has_offset_ucoord_v, "Lyt should not be based on offset coordinates"); + static_assert(!is_charge_distribution_surface_v, "Lyt cannot be a charge distribution surface"); detail::maximum_defect_influence_position_and_distance_impl p{lyt, sim_params}; diff --git a/include/fiction/algorithms/simulation/sidb/operational_domain.hpp b/include/fiction/algorithms/simulation/sidb/operational_domain.hpp index f8a56d428..ee6726dcd 100644 --- a/include/fiction/algorithms/simulation/sidb/operational_domain.hpp +++ b/include/fiction/algorithms/simulation/sidb/operational_domain.hpp @@ -973,7 +973,6 @@ operational_domain operational_domain_grid_search(const Lyt& lyt, const std::vec { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); - static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); static_assert(kitty::is_truth_table::value, "TT is not a truth table"); operational_domain_stats st{}; @@ -1017,7 +1016,6 @@ operational_domain operational_domain_random_sampling(const Lyt& lyt, const std: { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); - static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); static_assert(kitty::is_truth_table::value, "TT is not a truth table"); operational_domain_stats st{}; @@ -1066,7 +1064,6 @@ operational_domain operational_domain_flood_fill(const Lyt& lyt, const std::vect { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); - static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); static_assert(kitty::is_truth_table::value, "TT is not a truth table"); operational_domain_stats st{}; @@ -1118,7 +1115,6 @@ operational_domain operational_domain_contour_tracing(const Lyt& lyt, const std: { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); - static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); static_assert(kitty::is_truth_table::value, "TT is not a truth table"); operational_domain_stats st{}; diff --git a/include/fiction/algorithms/simulation/sidb/quickexact.hpp b/include/fiction/algorithms/simulation/sidb/quickexact.hpp index 15fedafd8..55e37b149 100644 --- a/include/fiction/algorithms/simulation/sidb/quickexact.hpp +++ b/include/fiction/algorithms/simulation/sidb/quickexact.hpp @@ -125,12 +125,12 @@ class quickexact_impl { if constexpr (has_get_sidb_defect_v) { - charge_distribution_surface charge_layout{static_cast(layout)}; + charge_distribution_surface charge_layout{layout}; conduct_simulation(charge_layout, base_number); } else { - charge_distribution_surface charge_layout{static_cast(layout)}; + charge_distribution_surface charge_layout{layout}; conduct_simulation(charge_layout, base_number); } } @@ -261,7 +261,6 @@ class quickexact_impl { static_assert(is_cell_level_layout_v, "ChargeLyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "ChargeLyt is not an SiDB layout"); - static_assert(has_siqad_coord_v, "ChargeLyt is not based on SiQAD coordinates"); static_assert(is_charge_distribution_surface_v, "ChargeLyt is not a charge distribution surface"); if (base_number == required_simulation_base_number::THREE) @@ -327,7 +326,6 @@ class quickexact_impl { static_assert(is_cell_level_layout_v, "ChargeLyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "ChargeLyt is not an SiDB layout"); - static_assert(has_siqad_coord_v, "ChargeLyt is not based on SiQAD coordinates"); static_assert(is_charge_distribution_surface_v, "ChargeLyt is not a charge distribution surface"); charge_layout.assign_base_number(2); @@ -374,7 +372,6 @@ class quickexact_impl { static_assert(is_cell_level_layout_v, "ChargeLyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "ChargeLyt is not an SiDB layout"); - static_assert(has_siqad_coord_v, "ChargeLyt is not based on SiQAD coordinates"); static_assert(is_charge_distribution_surface_v, "ChargeLyt is not a charge distribution surface"); charge_layout.assign_all_charge_states(sidb_charge_state::NEGATIVE); @@ -583,7 +580,6 @@ template { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); - static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); detail::quickexact_impl p{lyt, params}; diff --git a/include/fiction/layouts/bounding_box.hpp b/include/fiction/layouts/bounding_box.hpp index a2c57a368..34a6fed4c 100644 --- a/include/fiction/layouts/bounding_box.hpp +++ b/include/fiction/layouts/bounding_box.hpp @@ -67,7 +67,7 @@ class bounding_box_2d int32_t min_y = std::numeric_limits::max(); int32_t max_y = std::numeric_limits::min(); - uint8_t min_z = 0; + uint8_t min_z = 1; uint8_t max_z = 0; layout.foreach_cell( diff --git a/include/fiction/layouts/coordinates.hpp b/include/fiction/layouts/coordinates.hpp index 0b6072015..270e5569c 100644 --- a/include/fiction/layouts/coordinates.hpp +++ b/include/fiction/layouts/coordinates.hpp @@ -780,15 +780,19 @@ struct coord_t * @param coord SiQAD coordinate to convert. * @return Coordinate of type `CoordinateType`. */ -template -constexpr CoordinateType to_fiction_coord(const coord_t& coord) noexcept +template +constexpr CoordinateTypeOutput to_fiction_coord(const CoordinateTypeInput& coord) noexcept { + if constexpr (std::is_same_v) + { + return coord; + } if (!coord.is_dead()) { return {coord.x, coord.y * 2 + coord.z}; } - return CoordinateType{}; + return CoordinateTypeOutput{}; } /** * Converts any coordinate type to SiQAD coordinates. diff --git a/include/fiction/technology/charge_distribution_surface.hpp b/include/fiction/technology/charge_distribution_surface.hpp index ed27f324b..bdb9270c2 100644 --- a/include/fiction/technology/charge_distribution_surface.hpp +++ b/include/fiction/technology/charge_distribution_surface.hpp @@ -242,7 +242,7 @@ class charge_distribution_surface : public Lyt Lyt(), strg{std::make_shared(params)} { - static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); + //static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); @@ -264,7 +264,7 @@ class charge_distribution_surface : public Lyt Lyt(lyt), strg{std::make_shared(params)} { - static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); + //static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); diff --git a/include/fiction/technology/sidb_nm_position.hpp b/include/fiction/technology/sidb_nm_position.hpp index 076197358..c8259c486 100644 --- a/include/fiction/technology/sidb_nm_position.hpp +++ b/include/fiction/technology/sidb_nm_position.hpp @@ -8,6 +8,7 @@ #include "fiction/algorithms/simulation/sidb/sidb_simulation_parameters.hpp" #include "fiction/layouts/cell_level_layout.hpp" #include "fiction/traits.hpp" +#include "fiction/layouts/coordinates.hpp" #include @@ -28,12 +29,21 @@ template { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); - static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); - - const auto x = (c.x * sp.lat_a) * 0.1; - const auto y = (c.y * sp.lat_b + c.z * sp.lat_c) * .1; - - return std::make_pair(x, y); + static_assert(has_siqad_coord_v || has_cube_coord_v || has_offset_ucoord_v, "Coordinate type is not supported"); + + if constexpr (has_siqad_coord_v) + { + const auto x = (c.x * sp.lat_a) * 0.1; + const auto y = (c.y * sp.lat_b + c.z * sp.lat_c) * .1; + return std::make_pair(x, y); + } + else + { + const auto cell_in_siqad = siqad::to_siqad_coord(c); + const auto x = (cell_in_siqad.x * sp.lat_a) * 0.1; + const auto y = (cell_in_siqad.y * sp.lat_b + cell_in_siqad.z * sp.lat_c) * .1; + return std::make_pair(x, y); + } } } // namespace fiction diff --git a/include/fiction/utils/layout_utils.hpp b/include/fiction/utils/layout_utils.hpp index 62071e5dc..b6a5474e8 100644 --- a/include/fiction/utils/layout_utils.hpp +++ b/include/fiction/utils/layout_utils.hpp @@ -367,10 +367,6 @@ Lyt convert_to_fiction_coordinates(const sidb_cell_clk_lyt_siqad& lyt) noexcept template CoordinateType random_coordinate(CoordinateType coordinate1, CoordinateType coordinate2) noexcept { - static_assert(std::is_same_v || std::is_same_v || - std::is_same_v, - "CoordinateType is unknown"); - static std::mt19937_64 generator(std::random_device{}()); if (coordinate1 > coordinate2) @@ -408,38 +404,40 @@ CoordinateType random_coordinate(CoordinateType coordinate1, CoordinateType coor * @param cell_se The southeast SiQAD cell defining the ending point of the area. * @return A vector containing all cells within the specified area. */ -[[nodiscard]] inline std::vector all_sidbs_in_spanned_area(const siqad::coord_t& cell_nw, - const siqad::coord_t& cell_se) noexcept +template +[[nodiscard]] inline std::vector all_sidbs_in_spanned_area(const CoordinateType& cell_nw, + const CoordinateType& cell_se) noexcept { - const auto c1_cube = siqad::to_fiction_coord(cell_nw); - const auto c2_cube = siqad::to_fiction_coord(cell_se); + const auto c1_cube = siqad::to_fiction_coord(cell_nw); + const auto c2_cube = siqad::to_fiction_coord(cell_se); const auto total_cell_count = static_cast(std::abs(c1_cube.x - c2_cube.x) + 1) * static_cast(std::abs(c1_cube.y - c2_cube.y) + 1); - std::vector all_cells{}; + std::vector all_cells{}; all_cells.reserve(total_cell_count); - auto current_cell = cell_nw; + auto current_cell = c1_cube; // collect all cells in the area (spanned by the nw `north-west` and se `south-east` cell) going from top to down // from left to right. - while (current_cell <= cell_se) + while (current_cell <= c2_cube) { - all_cells.push_back(current_cell); - if (current_cell.x < cell_se.x) + if constexpr (std::is_same_v) { - current_cell.x += 1; + all_cells.push_back(siqad::to_siqad_coord(current_cell)); + } + else + { + all_cells.push_back(siqad::to_fiction_coord(current_cell)); } - else if ((current_cell.x == cell_se.x) && current_cell.z == 0) + if (current_cell.x < cell_se.x) { - current_cell.z += 1; - current_cell.x = cell_nw.x; + current_cell.x += 1; } else { current_cell.x = cell_nw.x; current_cell.y += 1; - current_cell.z = 0; } } diff --git a/test/algorithms/physical_design/design_sidb_gates.cpp b/test/algorithms/physical_design/design_sidb_gates.cpp index 0cc960341..e8195ddb0 100644 --- a/test/algorithms/physical_design/design_sidb_gates.cpp +++ b/test/algorithms/physical_design/design_sidb_gates.cpp @@ -16,7 +16,9 @@ using namespace fiction; TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[design-sidb-gates]") { - using layout = sidb_cell_clk_lyt_siqad; + + using layout = sidb_cell_clk_lyt_siqad; + using layout_cube = cell_level_layout>>; layout lyt{}; @@ -42,17 +44,35 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ CHECK(lyt.num_cells() == 13); - const design_sidb_gates_params params{sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, - {{10, 4, 0}, {10, 4, 0}}, - 1, - sidb_simulation_engine::QUICKEXACT}; + const design_sidb_gates_params params{sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, + {{10, 4, 0}, {10, 4, 0}}, + 1, + sidb_simulation_engine::QUICKEXACT}; const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); REQUIRE(found_gate_layouts.size() == 1); CHECK(found_gate_layouts[0].num_cells() == 14); CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == layout::technology::NORMAL); + + // using cube coordinates + const auto lyt_in_cube_coord = convert_to_fiction_coordinates(lyt); + const design_sidb_gates_params params_cube{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, + {siqad::to_fiction_coord(siqad::coord_t{10, 4, 0}), + siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})}, + 1, + sidb_simulation_engine::QUICKEXACT}; + + const auto found_gate_layouts_cube = + design_sidb_gates(lyt_in_cube_coord, std::vector{create_xnor_tt()}, params_cube); + + REQUIRE(found_gate_layouts_cube.size() == 1); + CHECK(found_gate_layouts_cube[0].num_cells() == 14); + CHECK(found_gate_layouts_cube[0].get_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})) == + layout::technology::NORMAL); } TEST_CASE("Use SiQAD's AND gate skeleton to generate all possible AND gates", "[design-sidb-gates]") @@ -78,11 +98,11 @@ TEST_CASE("Use SiQAD's AND gate skeleton to generate all possible AND gates", "[ lyt.assign_cell_type({10, 9, 1}, sidb_technology::cell_type::NORMAL); - design_sidb_gates_params params{sidb_simulation_parameters{2, -0.28}, - design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, - {{4, 4, 0}, {14, 5, 1}}, - 1, - sidb_simulation_engine::EXGS}; + design_sidb_gates_params params{sidb_simulation_parameters{2, -0.28}, + design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, + {{4, 4, 0}, {14, 5, 1}}, + 1, + sidb_simulation_engine::EXGS}; SECTION("Exhaustive Generation") { @@ -92,7 +112,7 @@ TEST_CASE("Use SiQAD's AND gate skeleton to generate all possible AND gates", "[ SECTION("Random Generation") { - params.design_mode = design_sidb_gates_params::design_sidb_gates_mode::RANDOM; + params.design_mode = design_sidb_gates_params::design_sidb_gates_mode::RANDOM; const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); CHECK(!found_gate_layouts.empty()); } @@ -134,14 +154,15 @@ TEST_CASE("Use FO2 Bestagon gate without SiDB at {17, 11, 0} and generate origin lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); lyt.assign_cell_type({2, 19, 0}, sidb_technology::cell_type::NORMAL); - const design_sidb_gates_params params{sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, - {{17, 11, 0}, {17, 11, 0}}, - 1, - sidb_simulation_engine::QUICKEXACT}; - SECTION("generate original FO2") { + const design_sidb_gates_params params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, + {{17, 11, 0}, {17, 11, 0}}, + 1, + sidb_simulation_engine::QUICKEXACT}; + CHECK(lyt.get_cell_type({17, 11, 0}) == layout::technology::EMPTY); // generate gate by placing one SiDB @@ -155,6 +176,13 @@ TEST_CASE("Use FO2 Bestagon gate without SiDB at {17, 11, 0} and generate origin SECTION("replace the output perturbers by equivalent negatively charged defects") { + const design_sidb_gates_params params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, + {{17, 11, 0}, {17, 11, 0}}, + 1, + sidb_simulation_engine::QUICKEXACT}; + sidb_defect_cell_clk_lyt_siqad defect_layout{lyt}; defect_layout.assign_cell_type({36, 19, 0}, technology::cell_type::EMPTY); defect_layout.assign_cell_type({2, 19, 0}, technology::cell_type::EMPTY); @@ -207,15 +235,14 @@ TEST_CASE("Design AND Bestagon shaped gate", "[design-sidb-gates]") lyt.assign_cell_type({32, 18, 0}, sidb_technology::cell_type::OUTPUT); lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); - // generate gate by placing one SiDB - const design_sidb_gates_params params{sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::RANDOM, - {{14, 6, 0}, {24, 12, 0}}, - 3, - sidb_simulation_engine::QUICKEXACT}; - SECTION("Random Generation") { + const design_sidb_gates_params params{sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params::design_sidb_gates_mode::RANDOM, + {{14, 6, 0}, {24, 12, 0}}, + 3, + sidb_simulation_engine::QUICKEXACT}; + const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); REQUIRE(!found_gate_layouts.empty()); CHECK(found_gate_layouts.front().num_cells() == lyt.num_cells() + 3); @@ -225,6 +252,13 @@ TEST_CASE("Design AND Bestagon shaped gate", "[design-sidb-gates]") { sidb_defect_cell_clk_lyt_siqad defect_layout{lyt}; + const design_sidb_gates_params params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params::design_sidb_gates_mode::RANDOM, + {{14, 6, 0}, {24, 12, 0}}, + 3, + sidb_simulation_engine::QUICKEXACT}; + defect_layout.assign_sidb_defect( {15, 10, 0}, sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); diff --git a/test/algorithms/simulation/sidb/assess_physical_population_stability.cpp b/test/algorithms/simulation/sidb/assess_physical_population_stability.cpp index 1a5bc7694..3b25b8161 100644 --- a/test/algorithms/simulation/sidb/assess_physical_population_stability.cpp +++ b/test/algorithms/simulation/sidb/assess_physical_population_stability.cpp @@ -199,7 +199,7 @@ TEST_CASE("Bestagon AND gate", "[assess-physical-population-stability]") } } -TEST_CASE("Bestagon CROSSING gate input 11", "[assess-physical-population-stability]") +TEST_CASE("Bestagon CROSSING gate input 11, using siqad coordinates", "[assess-physical-population-stability]") { layout lyt{}; const auto params = assess_physical_population_stability_params{}; @@ -251,3 +251,165 @@ TEST_CASE("Bestagon CROSSING gate input 11", "[assess-physical-population-stabil REQUIRE_THAT(population_stability_detail.distance_corresponding_to_potential, Catch::Matchers::WithinAbs(6.88, 1e-5)); } + +TEST_CASE("Bestagon CROSSING gate input 11, using cube coordinates", "[assess-physical-population-stability]") +{ + cell_level_layout>> lyt{}; + + const auto params = assess_physical_population_stability_params{}; + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{36, 1, 0}), + sidb_technology::cell_type::INPUT); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{2, 1, 0}), + sidb_technology::cell_type::INPUT); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{20, 12, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{8, 3, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 5, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 11, 1}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{12, 4, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 15, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{26, 4, 0}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 9, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{24, 15, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{12, 16, 0}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{18, 9, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{26, 16, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{24, 13, 1}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{24, 5, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{30, 3, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{16, 13, 1}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{32, 2, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{20, 8, 0}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{30, 17, 0}), + sidb_technology::cell_type::OUTPUT); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{6, 18, 0}), + sidb_technology::cell_type::OUTPUT); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{32, 18, 0}), + sidb_technology::cell_type::OUTPUT); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{8, 17, 0}), + sidb_technology::cell_type::OUTPUT); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{2, 19, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{36, 19, 0}), + sidb_technology::cell_type::NORMAL); + + CHECK(lyt.num_cells() == 27); + + const auto result = assess_physical_population_stability(lyt, params); + REQUIRE(result.size() == 20); + const auto& population_stability_detail = result[0]; + CHECK(population_stability_detail.critical_cell == cube::coord_t{14, 18, 0}); + CHECK(population_stability_detail.transition_from_to == transition_type::NEUTRAL_TO_NEGATIVE); + CHECK(population_stability_detail.minimum_potential_difference_to_transition < 0.01); + REQUIRE_THAT(population_stability_detail.distance_corresponding_to_potential, + Catch::Matchers::WithinAbs(6.88, 1e-5)); +} + +TEST_CASE("Bestagon CROSSING gate input 11, using offset coordinates", "[assess-physical-population-stability]") +{ + cell_level_layout>> lyt{}; + + const auto params = assess_physical_population_stability_params{}; + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{36, 1, 0}), + sidb_technology::cell_type::INPUT); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{2, 1, 0}), + sidb_technology::cell_type::INPUT); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{20, 12, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{8, 3, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 5, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 11, 1}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{12, 4, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 15, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{26, 4, 0}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 9, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{24, 15, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{12, 16, 0}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{18, 9, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{26, 16, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{24, 13, 1}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{24, 5, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{30, 3, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{16, 13, 1}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{32, 2, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{20, 8, 0}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{30, 17, 0}), + sidb_technology::cell_type::OUTPUT); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{6, 18, 0}), + sidb_technology::cell_type::OUTPUT); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{32, 18, 0}), + sidb_technology::cell_type::OUTPUT); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{8, 17, 0}), + sidb_technology::cell_type::OUTPUT); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{2, 19, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{36, 19, 0}), + sidb_technology::cell_type::NORMAL); + + CHECK(lyt.num_cells() == 27); + + const auto result = assess_physical_population_stability(lyt, params); + REQUIRE(result.size() == 20); + const auto& population_stability_detail = result[0]; + CHECK(population_stability_detail.critical_cell == offset::ucoord_t{14, 18, 0}); + CHECK(population_stability_detail.transition_from_to == transition_type::NEUTRAL_TO_NEGATIVE); + CHECK(population_stability_detail.minimum_potential_difference_to_transition < 0.01); + REQUIRE_THAT(population_stability_detail.distance_corresponding_to_potential, + Catch::Matchers::WithinAbs(6.88, 1e-5)); +} diff --git a/test/algorithms/simulation/sidb/can_positive_charges_occur.cpp b/test/algorithms/simulation/sidb/can_positive_charges_occur.cpp index 0a7fa295b..c8326d4cc 100644 --- a/test/algorithms/simulation/sidb/can_positive_charges_occur.cpp +++ b/test/algorithms/simulation/sidb/can_positive_charges_occur.cpp @@ -37,7 +37,7 @@ TEMPLATE_TEST_CASE("One BDL pair with one perturber", "[can-positive-charges-occ } } -TEMPLATE_TEST_CASE("Y-shape SiDB OR gate with input 01", "[can-positive-charges-occur]", +TEMPLATE_TEST_CASE("Y-shape SiDB OR gate with input 01, using siqad coordinates", "[can-positive-charges-occur]", (cell_level_layout>>)) { TestType lyt{{20, 10}}; @@ -71,3 +71,73 @@ TEMPLATE_TEST_CASE("Y-shape SiDB OR gate with input 01", "[can-positive-charges- CHECK(can_positive_charges_occur(lyt, params)); } } + +TEMPLATE_TEST_CASE("Y-shape SiDB OR gate with input 01, using cube coordinates", "[can-positive-charges-occur]", + (cell_level_layout>>)) +{ + TestType lyt{{20, 10}}; + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{8, 3, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{12, 3, 0}), TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 2, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 5, 0}), TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 6, 1}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 8, 1}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{16, 1, 0}), TestType::cell_type::NORMAL); + + SECTION("Default values") + { + const sidb_simulation_parameters params{2, -0.32}; + CHECK(!can_positive_charges_occur(lyt, params)); + } + + SECTION("epsilon = 1, lambda = 1") + { + const sidb_simulation_parameters params{2, -0.32, 1, 1}; + CHECK(can_positive_charges_occur(lyt, params)); + } + + SECTION("epsilon = 1, lambda = 10") + { + const sidb_simulation_parameters params{2, -0.32, 1, 10}; + CHECK(can_positive_charges_occur(lyt, params)); + } +} + +TEMPLATE_TEST_CASE("Y-shape SiDB OR gate with input 01, using offset coordinates", "[can-positive-charges-occur]", + (cell_level_layout>>)) +{ + TestType lyt{{20, 10}}; + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{8, 3, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{12, 3, 0}), TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 2, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 5, 0}), TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 6, 1}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 8, 1}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{16, 1, 0}), TestType::cell_type::NORMAL); + + SECTION("Default values") + { + const sidb_simulation_parameters params{2, -0.32}; + CHECK(!can_positive_charges_occur(lyt, params)); + } + + SECTION("epsilon = 1, lambda = 1") + { + const sidb_simulation_parameters params{2, -0.32, 1, 1}; + CHECK(can_positive_charges_occur(lyt, params)); + } + + SECTION("epsilon = 1, lambda = 10") + { + const sidb_simulation_parameters params{2, -0.32, 1, 10}; + CHECK(can_positive_charges_occur(lyt, params)); + } +} diff --git a/test/algorithms/simulation/sidb/exhaustive_ground_state_simulation.cpp b/test/algorithms/simulation/sidb/exhaustive_ground_state_simulation.cpp index 820bc8284..1e39d3f10 100644 --- a/test/algorithms/simulation/sidb/exhaustive_ground_state_simulation.cpp +++ b/test/algorithms/simulation/sidb/exhaustive_ground_state_simulation.cpp @@ -65,7 +65,8 @@ TEMPLATE_TEST_CASE( } TEMPLATE_TEST_CASE( - "ExGS simulation of a two-pair BDL wire with one perturber", "[exhaustive-ground-state-simulation]", + "ExGS simulation of a two-pair BDL wire with one perturber, using siqad coordinates", + "[exhaustive-ground-state-simulation]", (cell_level_layout>>), (charge_distribution_surface>>>)) { @@ -109,6 +110,119 @@ TEMPLATE_TEST_CASE( Catch::Matchers::WithinAbs(0.2460493219, physical_constants::POP_STABILITY_ERR)); } +TEMPLATE_TEST_CASE("ExGS simulation of a two-pair BDL wire with one perturber, using offset coordinates", + "[exhaustive-ground-state-simulation]", + (cell_level_layout>>), + (charge_distribution_surface< + cell_level_layout>>>)) +{ + TestType lyt{}; + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{0, 0, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{5, 0, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{7, 0, 0}), + TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{11, 0, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{13, 0, 0}), + TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{17, 0, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{19, 0, 0}), + TestType::cell_type::NORMAL); + + const sidb_simulation_parameters params{2, -0.32}; + + const auto simulation_results = exhaustive_ground_state_simulation(lyt, params); + + const auto size_before = simulation_results.charge_distributions.size(); + + const auto simulation_results_after = exhaustive_ground_state_simulation(lyt, params); + auto size_after = simulation_results_after.charge_distributions.size(); + + CHECK(size_before == 1); + CHECK(size_after == 1); + + REQUIRE(!simulation_results_after.charge_distributions.empty()); + + const auto& charge_lyt_first = simulation_results_after.charge_distributions.front(); + + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{0, 0, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{5, 0, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{7, 0, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{11, 0, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{13, 0, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{17, 0, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{19, 0, 0})) == + sidb_charge_state::NEGATIVE); + + CHECK_THAT(charge_lyt_first.get_system_energy(), + Catch::Matchers::WithinAbs(0.2460493219, physical_constants::POP_STABILITY_ERR)); +} + +TEMPLATE_TEST_CASE( + "ExGS simulation of a two-pair BDL wire with one perturber, using cube coordinates", + "[exhaustive-ground-state-simulation]", + (cell_level_layout>>), + (charge_distribution_surface>>>)) +{ + TestType lyt{}; + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{0, 0, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{5, 0, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{7, 0, 0}), TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{11, 0, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{13, 0, 0}), TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{17, 0, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{19, 0, 0}), TestType::cell_type::NORMAL); + + const sidb_simulation_parameters params{2, -0.32}; + + const auto simulation_results = exhaustive_ground_state_simulation(lyt, params); + + const auto size_before = simulation_results.charge_distributions.size(); + + const auto simulation_results_after = exhaustive_ground_state_simulation(lyt, params); + auto size_after = simulation_results_after.charge_distributions.size(); + + CHECK(size_before == 1); + CHECK(size_after == 1); + + REQUIRE(!simulation_results_after.charge_distributions.empty()); + + const auto& charge_lyt_first = simulation_results_after.charge_distributions.front(); + + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{0, 0, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{5, 0, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{7, 0, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{11, 0, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{13, 0, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{17, 0, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{19, 0, 0})) == + sidb_charge_state::NEGATIVE); + + CHECK_THAT(charge_lyt_first.get_system_energy(), + Catch::Matchers::WithinAbs(0.2460493219, physical_constants::POP_STABILITY_ERR)); +} + TEMPLATE_TEST_CASE( "ExGS simulation of a Y-shape SiDB arrangement", "[exhaustive-ground-state-simulation]", (cell_level_layout>>), diff --git a/test/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.cpp b/test/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.cpp index 36eef1021..897956f4f 100644 --- a/test/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.cpp +++ b/test/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.cpp @@ -29,7 +29,7 @@ TEST_CASE("Test influence distance function", "[maximum-defect-influence-positio { const sidb_defect defect{sidb_defect_type::UNKNOWN, -1, sidb_simulation_parameters{}.epsilon_r, sidb_simulation_parameters{}.lambda_tf}; - const maximum_defect_influence_distance_params sim_params{defect, sidb_simulation_parameters{}, {50, 6}}; + const maximum_defect_influence_distance_params sim_params{defect, sidb_simulation_parameters{}, {2, 2}}; sidb_cell_clk_lyt_siqad lyt{}; lyt.assign_cell_type({0, 0, 0}, sidb_cell_clk_lyt_siqad::cell_type::NORMAL); @@ -103,6 +103,8 @@ TEST_CASE("Test influence distance function", "[maximum-defect-influence-positio CHECK(defect_pos.y == 4); CHECK(defect_pos.z == 1); + CHECK_THAT(distance, Catch::Matchers::WithinAbs(2.8999201713, physical_constants::POP_STABILITY_ERR)); + // number of threads given by the hardware const sidb_defect high_screening{sidb_defect_type::UNKNOWN, -1, sidb_simulation_parameters{}.epsilon_r, 1}; const maximum_defect_influence_distance_params sim_params_high_screening{high_screening, @@ -113,4 +115,38 @@ TEST_CASE("Test influence distance function", "[maximum-defect-influence-positio CHECK(distance_high_screeing < distance); } + + SECTION("QuickExact simulation of a Y-shape SiDB OR gate with input 01, using cube coordinate") + { + const sidb_defect defect{sidb_defect_type::UNKNOWN, -1, sidb_simulation_parameters{}.epsilon_r, + sidb_simulation_parameters{}.lambda_tf}; + const maximum_defect_influence_distance_params sim_params{defect, sidb_simulation_parameters{}}; + cell_level_layout>> lyt{{30,30}}; + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 0, 0}), + sidb_cell_clk_lyt_siqad::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{0, 1, 0}), + sidb_cell_clk_lyt_siqad::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{8, 1, 0}), + sidb_cell_clk_lyt_siqad::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{2, 2, 0}), + sidb_cell_clk_lyt_siqad::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0}), + sidb_cell_clk_lyt_siqad::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{4, 4, 0}), + sidb_cell_clk_lyt_siqad::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{4, 5, 1}), + sidb_cell_clk_lyt_siqad::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{4, 7, 1}), + sidb_cell_clk_lyt_siqad::cell_type::NORMAL); + + const auto [defect_pos, distance] = maximum_defect_influence_position_and_distance(lyt, sim_params); + CHECK(defect_pos.x == 12); + CHECK(defect_pos.y == 9); + CHECK(defect_pos.z == 0); + + CHECK_THAT(distance, Catch::Matchers::WithinAbs(2.8999201713, physical_constants::POP_STABILITY_ERR)); + + } } diff --git a/test/algorithms/simulation/sidb/operational_domain.cpp b/test/algorithms/simulation/sidb/operational_domain.cpp index 3d744ab0b..8e5e33e1b 100644 --- a/test/algorithms/simulation/sidb/operational_domain.cpp +++ b/test/algorithms/simulation/sidb/operational_domain.cpp @@ -513,3 +513,124 @@ TEST_CASE("SiQAD's AND gate operational domain computation", "[operational-domai CHECK(op_domain_stats.num_non_operational_parameter_combinations == 0); } } + +TEST_CASE("SiQAD's AND gate operational domain computation, using cube coordinates", "[operational-domain]") +{ + using layout = cell_level_layout>>; + + layout lyt{{20, 10}, "AND gate"}; + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{0, 0, 1}), + sidb_technology::cell_type::INPUT); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{2, 1, 1}), + sidb_technology::cell_type::INPUT); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{20, 0, 1}), + sidb_technology::cell_type::INPUT); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{18, 1, 1}), + sidb_technology::cell_type::INPUT); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{4, 2, 1}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{6, 3, 1}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 3, 1}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{16, 2, 1}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 6, 0}), + sidb_technology::cell_type::OUTPUT); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 7, 0}), + sidb_technology::cell_type::OUTPUT); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 9, 1}), + sidb_technology::cell_type::NORMAL); + + sidb_simulation_parameters sim_params{}; + sim_params.base = 2; + sim_params.mu_minus = -0.28; + + operational_domain_params op_domain_params{}; + op_domain_params.sim_params = sim_params; + op_domain_params.x_dimension = operational_domain::sweep_parameter::EPSILON_R; + op_domain_params.x_min = 5.1; + op_domain_params.x_max = 6.1; + op_domain_params.x_step = 0.1; + op_domain_params.y_dimension = operational_domain::sweep_parameter::LAMBDA_TF; + op_domain_params.y_min = 4.5; + op_domain_params.y_max = 5.5; + op_domain_params.y_step = 0.1; + + operational_domain_stats op_domain_stats{}; + + SECTION("grid_search") + { + const auto op_domain = + operational_domain_grid_search(lyt, std::vector{create_and_tt()}, op_domain_params, &op_domain_stats); + + // check if the operational domain has the correct size (10 steps in each dimension) + CHECK(op_domain.operational_values.size() == 100); + + // for the selected range, all samples should be within the parameters and operational + check_op_domain_params_and_operational_status(op_domain, op_domain_params, operational_status::OPERATIONAL); + + CHECK(mockturtle::to_seconds(op_domain_stats.time_total) > 0.0); + CHECK(op_domain_stats.num_simulator_invocations == 400); + CHECK(op_domain_stats.num_evaluated_parameter_combinations == 100); + CHECK(op_domain_stats.num_operational_parameter_combinations == 100); + CHECK(op_domain_stats.num_non_operational_parameter_combinations == 0); + } + SECTION("random_sampling") + { + const auto op_domain = operational_domain_random_sampling(lyt, std::vector{create_and_tt()}, 100, + op_domain_params, &op_domain_stats); + + // check if the operational domain has the correct size (max 10 steps in each dimension) + CHECK(op_domain.operational_values.size() <= 100); + + // for the selected range, all samples should be within the parameters and operational + check_op_domain_params_and_operational_status(op_domain, op_domain_params, operational_status::OPERATIONAL); + + CHECK(mockturtle::to_seconds(op_domain_stats.time_total) > 0.0); + CHECK(op_domain_stats.num_simulator_invocations <= 400); + CHECK(op_domain_stats.num_evaluated_parameter_combinations <= 100); + CHECK(op_domain_stats.num_operational_parameter_combinations <= 100); + CHECK(op_domain_stats.num_non_operational_parameter_combinations == 0); + } + SECTION("flood_fill") + { + const auto op_domain = + operational_domain_flood_fill(lyt, std::vector{create_and_tt()}, 1, op_domain_params, &op_domain_stats); + + // check if the operational domain has the correct size (10 steps in each dimension) + CHECK(op_domain.operational_values.size() == 100); + + // for the selected range, all samples should be within the parameters and operational + check_op_domain_params_and_operational_status(op_domain, op_domain_params, operational_status::OPERATIONAL); + + CHECK(mockturtle::to_seconds(op_domain_stats.time_total) > 0.0); + CHECK(op_domain_stats.num_simulator_invocations == 400); + CHECK(op_domain_stats.num_evaluated_parameter_combinations == 100); + CHECK(op_domain_stats.num_operational_parameter_combinations == 100); + CHECK(op_domain_stats.num_non_operational_parameter_combinations == 0); + } + SECTION("contour_tracing") + { + const auto op_domain = operational_domain_contour_tracing(lyt, std::vector{create_and_tt()}, 1, + op_domain_params, &op_domain_stats); + + // check if the operational domain has the correct size (max 10 steps in each dimension) + CHECK(op_domain.operational_values.size() <= 100); + + // for the selected range, all samples should be within the parameters and operational + check_op_domain_params_and_operational_status(op_domain, op_domain_params, operational_status::OPERATIONAL); + + CHECK(mockturtle::to_seconds(op_domain_stats.time_total) > 0.0); + CHECK(op_domain_stats.num_simulator_invocations <= 400); + CHECK(op_domain_stats.num_evaluated_parameter_combinations <= 100); + CHECK(op_domain_stats.num_operational_parameter_combinations <= 100); + CHECK(op_domain_stats.num_non_operational_parameter_combinations == 0); + } +} diff --git a/test/algorithms/simulation/sidb/quickexact.cpp b/test/algorithms/simulation/sidb/quickexact.cpp index 12a120d6c..fa98c26a0 100644 --- a/test/algorithms/simulation/sidb/quickexact.cpp +++ b/test/algorithms/simulation/sidb/quickexact.cpp @@ -480,8 +480,118 @@ TEMPLATE_TEST_CASE( Catch::Matchers::WithinAbs(0.4662582096, physical_constants::POP_STABILITY_ERR)); } +TEMPLATE_TEST_CASE("QuickExact simulation of a Y-shape SiDB OR gate with input 01, check energy and charge " + "distribution, using offset coordinates", + "[quickexact]", + (cell_level_layout>>), + (charge_distribution_surface< + cell_level_layout>>>)) +{ + TestType lyt{}; + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{16, 1, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 2, 0}), + TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{8, 3, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{12, 3, 0}), + TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 5, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 6, 1}), + TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 8, 1}), + TestType::cell_type::NORMAL); + + const quickexact_params sim_params{sidb_simulation_parameters{2, -0.28}}; + + const auto simulation_results = quickexact(lyt, sim_params); + + REQUIRE(!simulation_results.charge_distributions.empty()); + const auto& charge_lyt_first = simulation_results.charge_distributions.front(); + + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{12, 3, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{10, 8, 1})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{10, 6, 1})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{16, 1, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{10, 5, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{14, 2, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{8, 3, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0})) == + sidb_charge_state::NEGATIVE); + + CHECK_THAT(charge_lyt_first.get_system_energy(), + Catch::Matchers::WithinAbs(0.4662582096, physical_constants::POP_STABILITY_ERR)); +} + TEMPLATE_TEST_CASE( - "QuickExact simulation of a Y-shape SiDB OR gate with input 01 and local external potential at perturber", + "QuickExact simulation of a Y-shape SiDB OR gate with input 01, check energy and charge " + "distribution, using offset coordinates", + "[quickexact]", (cell_level_layout>>), + (charge_distribution_surface>>>)) +{ + TestType lyt{}; + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{16, 1, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 2, 0}), TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{8, 3, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{12, 3, 0}), TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 5, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 6, 1}), TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 8, 1}), TestType::cell_type::NORMAL); + + const quickexact_params sim_params{sidb_simulation_parameters{2, -0.28}}; + + const auto simulation_results = quickexact(lyt, sim_params); + + REQUIRE(!simulation_results.charge_distributions.empty()); + const auto& charge_lyt_first = simulation_results.charge_distributions.front(); + + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{12, 3, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{10, 8, 1})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{10, 6, 1})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{16, 1, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{10, 5, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{14, 2, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{8, 3, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0})) == + sidb_charge_state::NEGATIVE); + + CHECK_THAT(charge_lyt_first.get_system_energy(), + Catch::Matchers::WithinAbs(0.4662582096, physical_constants::POP_STABILITY_ERR)); +} + +TEMPLATE_TEST_CASE( + "QuickExact simulation of a Y-shape SiDB OR gate with input 01 and local external potential at perturber, using " + "siqad coordinates", "[quickexact]", (cell_level_layout>>), (charge_distribution_surface>>>)) { @@ -516,6 +626,50 @@ TEMPLATE_TEST_CASE( CHECK(charge_lyt_first.get_charge_state({8, 3, 0}) == sidb_charge_state::NEGATIVE); } +TEMPLATE_TEST_CASE( + "QuickExact simulation of a Y-shape SiDB OR gate with input 01 and local external potential at perturber, using " + "cube coordinates", + "[quickexact]", (cell_level_layout>>), + (charge_distribution_surface>>>)) +{ + TestType lyt{}; + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{8, 3, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{12, 3, 0}), TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 2, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 5, 0}), TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 6, 1}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 8, 1}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{16, 1, 0}), TestType::cell_type::NORMAL); + + quickexact_params params{sidb_simulation_parameters{3, -0.28}}; + params.local_external_potential.insert({{siqad::to_fiction_coord(siqad::coord_t{6, 2, 0}), -0.5}}); + + const auto simulation_results = quickexact(lyt, params); + + REQUIRE(!simulation_results.charge_distributions.empty()); + const auto& charge_lyt_first = simulation_results.charge_distributions.front(); + + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{12, 3, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{10, 8, 1})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{10, 6, 1})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{16, 1, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{10, 5, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{14, 2, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{8, 3, 0})) == + sidb_charge_state::NEGATIVE); +} + TEMPLATE_TEST_CASE( "QuickExact simulation of a Y-shape SiDB OR gate with input 01 and global external potential", "[quickexact]", (cell_level_layout>>), @@ -613,6 +767,27 @@ TEMPLATE_TEST_CASE( CHECK(charge_lyt_first.get_charge_state({30, 0, 0}) == sidb_charge_state::NEGATIVE); } +TEMPLATE_TEST_CASE( + "QuickExact with one SiDB and one negatively charged defect in proximity", "[quickexact]", + (sidb_surface>>>), + (charge_distribution_surface< + sidb_surface>>>>)) +{ + TestType lyt{}; + + lyt.assign_cell_type({0, 0, 0}, TestType::cell_type::NORMAL); + + const quickexact_params params{sidb_simulation_parameters{3, -0.32}}; + lyt.assign_sidb_defect({-1, -1, 1}, sidb_defect{sidb_defect_type::UNKNOWN, -1, params.physical_parameters.epsilon_r, + params.physical_parameters.lambda_tf}); + const auto simulation_results = quickexact(lyt, params); + + REQUIRE(!simulation_results.charge_distributions.empty()); + const auto& charge_lyt_first = simulation_results.charge_distributions.front(); + + CHECK(charge_lyt_first.get_charge_state({0, 0, 0}) == sidb_charge_state::NEUTRAL); +} + TEMPLATE_TEST_CASE( "QuickExact simulation of four SiDBs (far away) with one negatively charged defects in proximity", "[quickexact]", (sidb_surface>>>), diff --git a/test/algorithms/simulation/sidb/quicksim.cpp b/test/algorithms/simulation/sidb/quicksim.cpp index 6d45a45a1..b8de465b7 100644 --- a/test/algorithms/simulation/sidb/quicksim.cpp +++ b/test/algorithms/simulation/sidb/quicksim.cpp @@ -899,3 +899,105 @@ TEMPLATE_TEST_CASE( Catch::Matchers::WithinAbs(0.505173434, physical_constants::POP_STABILITY_ERR)); } } + +TEMPLATE_TEST_CASE( + "QuickSim simulation of a Y-shape SiDB arrangement with varying thread counts, cube coordinates", "[quicksim]", + (cell_level_layout>>), + (charge_distribution_surface>>>)) +{ + TestType lyt{}; + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{-11, -2, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{-10, -1, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{-4, -1, 0}), + TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{-3, -2, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{-7, 0, 1}), TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{-7, 1, 1}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{-7, 3, 0}), TestType::cell_type::NORMAL); + + const sidb_simulation_parameters params{2, -0.32}; + + quicksim_params quicksim_params{params}; + + REQUIRE(quicksim_params.phys_params.mu_minus == -0.32); + + const auto check_charge_configuration = [](const sidb_simulation_result& stats) noexcept + { + REQUIRE(!stats.charge_distributions.empty()); + + const auto& charge_lyt_first = stats.charge_distributions.front(); + + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{-11, -2, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{-10, -1, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{-3, -2, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{-4, -1, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{-7, 0, 1})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{-7, 1, 1})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{-7, 3, 0})) == + sidb_charge_state::NEGATIVE); + + CHECK_THAT(charge_lyt_first.get_system_energy(), + Catch::Matchers::WithinAbs(0.3191788254, physical_constants::POP_STABILITY_ERR)); + }; + + SECTION("Default settings") + { + const auto simulation_results = quicksim(lyt, quicksim_params); + + check_for_absence_of_positive_charges(simulation_results); + check_for_runtime_measurement(simulation_results); + check_charge_configuration(simulation_results); + } + SECTION("0 threads") + { + quicksim_params.number_threads = 0; + + const auto simulation_results = quicksim(lyt, quicksim_params); + + check_for_absence_of_positive_charges(simulation_results); + check_for_runtime_measurement(simulation_results); + check_charge_configuration(simulation_results); + } + SECTION("1 thread") + { + quicksim_params.number_threads = 1; + + const auto simulation_results = quicksim(lyt, quicksim_params); + + check_for_absence_of_positive_charges(simulation_results); + check_for_runtime_measurement(simulation_results); + check_charge_configuration(simulation_results); + } + SECTION("2 threads") + { + quicksim_params.number_threads = 2; + + const auto simulation_results = quicksim(lyt, quicksim_params); + + check_for_absence_of_positive_charges(simulation_results); + check_for_runtime_measurement(simulation_results); + check_charge_configuration(simulation_results); + } + SECTION("100 threads") + { + quicksim_params.number_threads = 100; + + const auto simulation_results = quicksim(lyt, quicksim_params); + + check_for_absence_of_positive_charges(simulation_results); + check_for_runtime_measurement(simulation_results); + check_charge_configuration(simulation_results); + } +} diff --git a/test/algorithms/simulation/sidb/random_sidb_layout_generator.cpp b/test/algorithms/simulation/sidb/random_sidb_layout_generator.cpp index a0f20a00f..f73d6b77e 100644 --- a/test/algorithms/simulation/sidb/random_sidb_layout_generator.cpp +++ b/test/algorithms/simulation/sidb/random_sidb_layout_generator.cpp @@ -641,3 +641,44 @@ TEST_CASE("Random siqad::coord_t layout generation with defects", "[generate-ran }); } } + +TEST_CASE("Random cube::coord_t layout generation with defects", "[generate-random-sidb-layout]") +{ + using lyt = sidb_surface>>>; + + const generate_random_sidb_layout_params params{ + {to_fiction_coord(siqad::coord_t{0, 0, 0}), + to_fiction_coord(siqad::coord_t{10, 2, 0})}, + 10, + generate_random_sidb_layout_params::positive_charges::ALLOWED, + 2}; + + lyt layout{}; + + layout.assign_sidb_defect(siqad::to_fiction_coord(siqad::coord_t{2, 2, 0}), + sidb_defect{sidb_defect_type::DB, -1, 5.6, 5}); + layout.assign_sidb_defect(siqad::to_fiction_coord(siqad::coord_t{4, 1, 0}), + sidb_defect{sidb_defect_type::SINGLE_DIHYDRIDE, 1, 7.6, 7}); + layout.assign_sidb_defect(siqad::to_fiction_coord(siqad::coord_t{5, 1, 0}), + sidb_defect{sidb_defect_type::SINGLE_DIHYDRIDE, 1, 7.6, 9}); + layout.assign_sidb_defect(siqad::to_fiction_coord(siqad::coord_t{7, 1, 0}), + sidb_defect{sidb_defect_type::SINGLE_DIHYDRIDE, 1, 2.6, 7}); + layout.assign_sidb_defect(siqad::to_fiction_coord(siqad::coord_t{2, 1, 0}), + sidb_defect{sidb_defect_type::SINGLE_DIHYDRIDE, 1, 7.6, 4}); + + const auto result_lyt = generate_random_sidb_layout(layout, params); + + CHECK(result_lyt.num_cells() == 10); + CHECK(result_lyt.num_defects() == 5); + + // check if all cells are not closer than two cells (Euclidean distance). + result_lyt.foreach_cell( + [](const auto& cell) + { + CHECK(cell != siqad::to_fiction_coord(siqad::coord_t{2, 2, 0})); + CHECK(cell != siqad::to_fiction_coord(siqad::coord_t{4, 1, 0})); + CHECK(cell != siqad::to_fiction_coord(siqad::coord_t{5, 1, 0})); + CHECK(cell != siqad::to_fiction_coord(siqad::coord_t{7, 1, 0})); + CHECK(cell != siqad::to_fiction_coord(siqad::coord_t{2, 1, 0})); + }); +} diff --git a/test/technology/charge_distribution_surface.cpp b/test/technology/charge_distribution_surface.cpp index f65da827e..13b748991 100644 --- a/test/technology/charge_distribution_surface.cpp +++ b/test/technology/charge_distribution_surface.cpp @@ -17,21 +17,9 @@ using namespace fiction; -TEMPLATE_TEST_CASE( - "Charge distribution surface traits and construction", "[charge-distribution-surface]", - (cell_level_layout>>), - (cell_level_layout>>), - (cell_level_layout>>), - (cell_level_layout>>), - (cell_level_layout>>), - - (sidb_surface>>>), - (sidb_surface>>>), - (sidb_surface>>>), - (sidb_surface< - cell_level_layout>>>), - (sidb_surface< - cell_level_layout>>>)) +TEMPLATE_TEST_CASE("Charge distribution surface traits and construction", "[charge-distribution-surface]", + (cell_level_layout>>), + (sidb_surface>>>)) { REQUIRE(is_cell_level_layout_v); CHECK(!has_assign_charge_state_v); @@ -55,13 +43,9 @@ TEMPLATE_TEST_CASE( CHECK(has_get_charge_state_v); } -TEMPLATE_TEST_CASE( - "Assign and delete charge states without defects", "[charge-distribution-surface]", - (cell_level_layout>>), - (cell_level_layout>>), - (cell_level_layout>>), - (cell_level_layout>>), - (cell_level_layout>>)) +TEMPLATE_TEST_CASE("Assign and delete charge states without defects", "[charge-distribution-surface]", + (cell_level_layout>>), + (sidb_surface>>>)) { TestType lyt{{11, 11}}; @@ -1327,13 +1311,7 @@ TEMPLATE_TEST_CASE( TEMPLATE_TEST_CASE( "Assign and delete charge states without defects, part one", "[charge-distribution-surface]", - (sidb_surface>>>), - (sidb_surface>>>), - (sidb_surface>>>), - (sidb_surface< - cell_level_layout>>>), - (sidb_surface< - cell_level_layout>>>)) + (sidb_surface>>>)) { TestType lyt{{11, 11}}; @@ -1583,13 +1561,7 @@ TEMPLATE_TEST_CASE( TEMPLATE_TEST_CASE( "Assign and delete charge states without defects, part two", "[charge-distribution-surface]", - (sidb_surface>>>), - (sidb_surface>>>), - (sidb_surface>>>), - (sidb_surface< - cell_level_layout>>>), - (sidb_surface< - cell_level_layout>>>)) + (sidb_surface>>>)) { TestType lyt{{11, 11}}; diff --git a/test/technology/sidb_nm_position.cpp b/test/technology/sidb_nm_position.cpp index 892d50ad5..ff4324c94 100644 --- a/test/technology/sidb_nm_position.cpp +++ b/test/technology/sidb_nm_position.cpp @@ -12,13 +12,12 @@ using namespace fiction; -TEST_CASE("SiDB position in nanometer", "[sidb_nm_position]") +TEST_CASE("SiDB position in nanometer for siqad coordinate", "[sidb_nm_position]") { using namespace Catch::Matchers; SECTION("Default lattice constants, positive cell coordinates") { - const sidb_cell_clk_lyt_siqad layout{}; const sidb_simulation_parameters params{}; const auto [pos_x, pos_y] = sidb_nm_position(params, {1, 0, 0}); @@ -48,7 +47,6 @@ TEST_CASE("SiDB position in nanometer", "[sidb_nm_position]") SECTION("Default lattice constants, negative cell coordinates") { - const sidb_cell_clk_lyt_siqad layout{}; const sidb_simulation_parameters params{}; const auto [pos_x, pos_y] = sidb_nm_position(params, {-1, 0, 0}); @@ -74,7 +72,6 @@ TEST_CASE("SiDB position in nanometer", "[sidb_nm_position]") SECTION("Special lattice constants, positive and negative cell coordinates") { - const sidb_cell_clk_lyt_siqad layout{}; const sidb_simulation_parameters params{3, -0.32, 5.6, 5.0, 1, 2, 3}; const auto [pos_x, pos_y] = sidb_nm_position(params, {-1, 0, 0}); @@ -106,3 +103,64 @@ TEST_CASE("SiDB position in nanometer", "[sidb_nm_position]") CHECK_THAT(pos6_y, WithinAbs(-1.7, 1E-5)); } } + +TEST_CASE("SiDB position in nanometer for fiction coordinates", "[sidb_nm_position]") +{ + using namespace Catch::Matchers; + + using sidb_cell_clk_lyt_cube = cell_level_layout>>; + + SECTION("Default lattice constants, positive cell coordinates") + { + const sidb_simulation_parameters params{}; + + const auto [pos_x, pos_y] = sidb_nm_position(params, {1, 0}); + CHECK_THAT(pos_x, WithinAbs(params.lat_a * 0.1, 1E-5)); + CHECK_THAT(pos_x, WithinAbs(params.lat_a * 0.1, 1E-5)); + + const auto [pos2_x, pos2_y] = sidb_nm_position(params, {0, 2}); + CHECK_THAT(pos2_x, WithinAbs(0.0, 1E-5)); + CHECK_THAT(pos2_y, WithinAbs(params.lat_b * 0.1, 1E-5)); + + const auto [pos3_x, pos3_y] = sidb_nm_position(params, {0, 17}); + CHECK_THAT(pos3_x, WithinAbs(0.0, 1E-5)); + CHECK_THAT(pos3_y, WithinAbs(params.lat_b * 0.8 + params.lat_c * 0.1, 1E-5)); + + const auto [pos4_x, pos4_y] = sidb_nm_position(params, {1, 2}); + CHECK_THAT(pos4_x, WithinAbs(params.lat_a * 0.1, 1E-5)); + CHECK_THAT(pos4_y, WithinAbs(params.lat_b * 0.1, 1E-5)); + + const auto [pos5_x, pos5_y] = sidb_nm_position(params, {1, 3}); + CHECK_THAT(pos5_x, WithinAbs(params.lat_a * 0.1, 1E-5)); + CHECK_THAT(pos5_y, WithinAbs(params.lat_b * 0.1 + params.lat_c * 0.1, 1E-5)); + + const auto [pos6_x, pos6_y] = sidb_nm_position(params, {1, 21}); + CHECK_THAT(pos6_x, WithinAbs(params.lat_a * 0.1, 1E-5)); + CHECK_THAT(pos6_y, WithinAbs(params.lat_b + params.lat_c * 0.1, 1E-5)); + } + + SECTION("Default lattice constants, negative cell coordinates") + { + const sidb_simulation_parameters params{}; + + const auto [pos_x, pos_y] = sidb_nm_position(params, {-1, 0}); + CHECK_THAT(pos_x, WithinAbs(-params.lat_a * 0.1, 1E-5)); + CHECK_THAT(pos_y, WithinAbs(0.0, 1E-5)); + + const auto [pos2_x, pos2_y] = sidb_nm_position(params, {0, -2}); + CHECK_THAT(pos2_x, WithinAbs(0.0, 1E-5)); + CHECK_THAT(pos2_y, WithinAbs(-params.lat_b * 0.1, 1E-5)); + + const auto [pos3_x, pos3_y] = sidb_nm_position(params, {-5, -10}); + CHECK_THAT(pos3_x, WithinAbs(-params.lat_a * 0.5, 1E-5)); + CHECK_THAT(pos3_y, WithinAbs(-params.lat_b * 0.5, 1E-5)); + + const auto [pos4_x, pos4_y] = sidb_nm_position(params, {-1, -3}); + CHECK_THAT(pos4_x, WithinAbs(-params.lat_a * 0.1, 1E-5)); + CHECK_THAT(pos4_y, WithinAbs(-params.lat_b * 0.1 + params.lat_c * 0.1, 1E-5)); + + const auto [pos5_x, pos5_y] = sidb_nm_position(params, {-1, -21}); + CHECK_THAT(pos5_x, WithinAbs(-params.lat_a * 0.1, 1E-5)); + CHECK_THAT(pos5_y, WithinAbs(-params.lat_b + params.lat_c * 0.1, 1E-5)); + } +} diff --git a/test/utils/layout_utils.cpp b/test/utils/layout_utils.cpp index 8e268ef9f..663af7e46 100644 --- a/test/utils/layout_utils.cpp +++ b/test/utils/layout_utils.cpp @@ -336,11 +336,11 @@ TEST_CASE("Generate random siqad::coord_t coordinate", "[layout-utils]") } } -TEST_CASE("Generate all cells in area spanned by two cells", "[layout-utils]") +TEST_CASE("Generate all cells in area spanned by two cells, using siqad coordinates", "[layout-utils]") { SECTION("two identical cells") { - const auto all_area_cells = all_sidbs_in_spanned_area({-10, -5, 0}, {-10, -5, 0}); + const auto all_area_cells = all_sidbs_in_spanned_area({-10, -5, 0}, {-10, -5, 0}); REQUIRE(all_area_cells.size() == 1); const auto first_cell = all_area_cells.front(); CHECK(first_cell.x == -10); @@ -350,7 +350,7 @@ TEST_CASE("Generate all cells in area spanned by two cells", "[layout-utils]") SECTION("two cells at the same y and z coordinate ") { - const auto all_area_cells = all_sidbs_in_spanned_area({-10, -5, 0}, {10, -5, 0}); + const auto all_area_cells = all_sidbs_in_spanned_area({-10, -5, 0}, {10, -5, 0}); REQUIRE(all_area_cells.size() == 21); const auto first_cell = all_area_cells.front(); CHECK(first_cell.x == -10); @@ -365,7 +365,7 @@ TEST_CASE("Generate all cells in area spanned by two cells", "[layout-utils]") SECTION("two cells at the same y coordinate ") { - const auto all_area_cells = all_sidbs_in_spanned_area({-10, 5, 0}, {10, 5, 1}); + const auto all_area_cells = all_sidbs_in_spanned_area({-10, 5, 0}, {10, 5, 1}); REQUIRE(all_area_cells.size() == 42); const auto first_cell = all_area_cells.front(); CHECK(first_cell.x == -10); @@ -380,7 +380,7 @@ TEST_CASE("Generate all cells in area spanned by two cells", "[layout-utils]") SECTION("two cells at the same x coordinate ") { - const auto all_area_cells = all_sidbs_in_spanned_area({10, 2, 0}, {10, 5, 1}); + const auto all_area_cells = all_sidbs_in_spanned_area({10, 2, 0}, {10, 5, 1}); REQUIRE(all_area_cells.size() == 8); const auto first_cell = all_area_cells.front(); CHECK(first_cell.x == 10); @@ -393,3 +393,51 @@ TEST_CASE("Generate all cells in area spanned by two cells", "[layout-utils]") CHECK(final_cell.z == 1); } } + +TEST_CASE("Generate all cells in area spanned by two cells, using cube coordinates", "[layout-utils]") +{ + SECTION("two identical cells") + { + const auto all_area_cells = all_sidbs_in_spanned_area({-10, -10, 0}, {-10, -10, 0}); + REQUIRE(all_area_cells.size() == 1); + const auto first_cell = all_area_cells.front(); + CHECK(first_cell.x == -10); + CHECK(first_cell.y == -10); + CHECK(first_cell.z == 0); + + const auto final_cell = all_area_cells.back(); + CHECK(final_cell.x == -10); + CHECK(final_cell.y == -10); + CHECK(final_cell.z == 0); + } + + SECTION("two cells at the same y coordinate ") + { + const auto all_area_cells = all_sidbs_in_spanned_area({-10, 10}, {10, 11}); + REQUIRE(all_area_cells.size() == 42); + const auto first_cell = all_area_cells.front(); + CHECK(first_cell.x == -10); + CHECK(first_cell.y == 10); + CHECK(first_cell.z == 0); + + const auto final_cell = all_area_cells.back(); + CHECK(final_cell.x == 10); + CHECK(final_cell.y == 11); + CHECK(final_cell.z == 0); + } + + SECTION("two cells at the same x coordinate ") + { + const auto all_area_cells = all_sidbs_in_spanned_area({10, 4, 0}, {10, 11}); + REQUIRE(all_area_cells.size() == 8); + const auto first_cell = all_area_cells.front(); + CHECK(first_cell.x == 10); + CHECK(first_cell.y == 4); + CHECK(first_cell.z == 0); + + const auto final_cell = all_area_cells.back(); + CHECK(final_cell.x == 10); + CHECK(final_cell.y == 11); + CHECK(final_cell.z == 0); + } +} From b8e2160e39129cae32d798ec45532c10de336391 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 21 Nov 2023 22:15:02 +0100 Subject: [PATCH 2/9] :art: remove redundant static_cast. --- include/fiction/technology/charge_distribution_surface.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/fiction/technology/charge_distribution_surface.hpp b/include/fiction/technology/charge_distribution_surface.hpp index bdb9270c2..2d9bd792d 100644 --- a/include/fiction/technology/charge_distribution_surface.hpp +++ b/include/fiction/technology/charge_distribution_surface.hpp @@ -242,7 +242,6 @@ class charge_distribution_surface : public Lyt Lyt(), strg{std::make_shared(params)} { - //static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); @@ -264,7 +263,6 @@ class charge_distribution_surface : public Lyt Lyt(lyt), strg{std::make_shared(params)} { - //static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); From c22e3e84f65199ec88c7b43e02662e433bc6ff47 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 22 Nov 2023 07:15:18 +0100 Subject: [PATCH 3/9] :art: add static_cast --- include/fiction/algorithms/simulation/sidb/quickexact.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/fiction/algorithms/simulation/sidb/quickexact.hpp b/include/fiction/algorithms/simulation/sidb/quickexact.hpp index 55e37b149..138a0e326 100644 --- a/include/fiction/algorithms/simulation/sidb/quickexact.hpp +++ b/include/fiction/algorithms/simulation/sidb/quickexact.hpp @@ -125,12 +125,12 @@ class quickexact_impl { if constexpr (has_get_sidb_defect_v) { - charge_distribution_surface charge_layout{layout}; + charge_distribution_surface charge_layout{static_cast(layout)}; conduct_simulation(charge_layout, base_number); } else { - charge_distribution_surface charge_layout{layout}; + charge_distribution_surface charge_layout{static_cast(layout)}; conduct_simulation(charge_layout, base_number); } } From 835a19b8ee28e5d8cd957add1f602c455f64e81f Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 22 Nov 2023 07:33:32 +0100 Subject: [PATCH 4/9] :white_check_mark: add further test for bdl input iterator. --- test/algorithms/iter/bdl_input_iterator.cpp | 172 ++++++++++++++------ 1 file changed, 122 insertions(+), 50 deletions(-) diff --git a/test/algorithms/iter/bdl_input_iterator.cpp b/test/algorithms/iter/bdl_input_iterator.cpp index 7aabba41a..4641ef077 100644 --- a/test/algorithms/iter/bdl_input_iterator.cpp +++ b/test/algorithms/iter/bdl_input_iterator.cpp @@ -5,8 +5,10 @@ #include #include +#include #include #include +#include #include #include @@ -226,63 +228,133 @@ TEST_CASE("SiQAD's AND gate iteration", "[bdl-input-iterator]") lyt.assign_cell_type({10, 9, 1}, sidb_technology::cell_type::NORMAL); - bdl_input_iterator bii{lyt}; - - for (auto i = 0; bii < 4; ++bii, ++i) + SECTION("siqad coordinates") { - switch (i) - { - case 0: - { - const auto& lyt_0 = *bii; - - CHECK(lyt_0.get_cell_type({0, 0, 1}) == sidb_technology::cell_type::INPUT); - CHECK(lyt_0.get_cell_type({2, 1, 1}) == sidb_technology::cell_type::EMPTY); - - CHECK(lyt_0.get_cell_type({20, 0, 1}) == sidb_technology::cell_type::INPUT); - CHECK(lyt_0.get_cell_type({18, 1, 1}) == sidb_technology::cell_type::EMPTY); + bdl_input_iterator bii{lyt}; - break; - } - case 1: - { - const auto& lyt_1 = *bii; - - CHECK(lyt_1.get_cell_type({0, 0, 1}) == sidb_technology::cell_type::INPUT); - CHECK(lyt_1.get_cell_type({2, 1, 1}) == sidb_technology::cell_type::EMPTY); - - CHECK(lyt_1.get_cell_type({20, 0, 1}) == sidb_technology::cell_type::EMPTY); - CHECK(lyt_1.get_cell_type({18, 1, 1}) == sidb_technology::cell_type::INPUT); - - break; - } - case 2: + for (auto i = 0; bii < 4; ++bii, ++i) + { + switch (i) { - const auto& lyt_2 = *bii; - - CHECK(lyt_2.get_cell_type({0, 0, 1}) == sidb_technology::cell_type::EMPTY); - CHECK(lyt_2.get_cell_type({2, 1, 1}) == sidb_technology::cell_type::INPUT); - - CHECK(lyt_2.get_cell_type({20, 0, 1}) == sidb_technology::cell_type::INPUT); - CHECK(lyt_2.get_cell_type({18, 1, 1}) == sidb_technology::cell_type::EMPTY); - - break; + case 0: + { + const auto& lyt_0 = *bii; + + CHECK(lyt_0.get_cell_type({0, 0, 1}) == sidb_technology::cell_type::INPUT); + CHECK(lyt_0.get_cell_type({2, 1, 1}) == sidb_technology::cell_type::EMPTY); + + CHECK(lyt_0.get_cell_type({20, 0, 1}) == sidb_technology::cell_type::INPUT); + CHECK(lyt_0.get_cell_type({18, 1, 1}) == sidb_technology::cell_type::EMPTY); + + break; + } + case 1: + { + const auto& lyt_1 = *bii; + + CHECK(lyt_1.get_cell_type({0, 0, 1}) == sidb_technology::cell_type::INPUT); + CHECK(lyt_1.get_cell_type({2, 1, 1}) == sidb_technology::cell_type::EMPTY); + + CHECK(lyt_1.get_cell_type({20, 0, 1}) == sidb_technology::cell_type::EMPTY); + CHECK(lyt_1.get_cell_type({18, 1, 1}) == sidb_technology::cell_type::INPUT); + + break; + } + case 2: + { + const auto& lyt_2 = *bii; + + CHECK(lyt_2.get_cell_type({0, 0, 1}) == sidb_technology::cell_type::EMPTY); + CHECK(lyt_2.get_cell_type({2, 1, 1}) == sidb_technology::cell_type::INPUT); + + CHECK(lyt_2.get_cell_type({20, 0, 1}) == sidb_technology::cell_type::INPUT); + CHECK(lyt_2.get_cell_type({18, 1, 1}) == sidb_technology::cell_type::EMPTY); + + break; + } + case 3: + { + const auto& lyt_3 = *bii; + + CHECK(lyt_3.get_cell_type({0, 0, 1}) == sidb_technology::cell_type::EMPTY); + CHECK(lyt_3.get_cell_type({2, 1, 1}) == sidb_technology::cell_type::INPUT); + + CHECK(lyt_3.get_cell_type({20, 0, 1}) == sidb_technology::cell_type::EMPTY); + CHECK(lyt_3.get_cell_type({18, 1, 1}) == sidb_technology::cell_type::INPUT); + + break; + } + default: + { + CHECK(false); + } } - case 3: - { - const auto& lyt_3 = *bii; - - CHECK(lyt_3.get_cell_type({0, 0, 1}) == sidb_technology::cell_type::EMPTY); - CHECK(lyt_3.get_cell_type({2, 1, 1}) == sidb_technology::cell_type::INPUT); + } + } - CHECK(lyt_3.get_cell_type({20, 0, 1}) == sidb_technology::cell_type::EMPTY); - CHECK(lyt_3.get_cell_type({18, 1, 1}) == sidb_technology::cell_type::INPUT); + SECTION("cube coordinates") + { + const auto layout_cube = convert_to_fiction_coordinates< + cell_level_layout>>>(lyt); + bdl_input_iterator>>> bii{ + layout_cube}; - break; - } - default: + for (auto i = 0; bii < 4; ++bii, ++i) + { + switch (i) { - CHECK(false); + case 0: + { + const auto& lyt_0 = *bii; + + CHECK(lyt_0.get_cell_type({0, 1}) == sidb_technology::cell_type::INPUT); + CHECK(lyt_0.get_cell_type({2, 3}) == sidb_technology::cell_type::EMPTY); + + CHECK(lyt_0.get_cell_type({20, 1}) == sidb_technology::cell_type::INPUT); + CHECK(lyt_0.get_cell_type({18, 3}) == sidb_technology::cell_type::EMPTY); + + break; + } + case 1: + { + const auto& lyt_1 = *bii; + + CHECK(lyt_1.get_cell_type({0, 1}) == sidb_technology::cell_type::INPUT); + CHECK(lyt_1.get_cell_type({2, 3}) == sidb_technology::cell_type::EMPTY); + + CHECK(lyt_1.get_cell_type({20, 1}) == sidb_technology::cell_type::EMPTY); + CHECK(lyt_1.get_cell_type({18, 3}) == sidb_technology::cell_type::INPUT); + + break; + } + case 2: + { + const auto& lyt_2 = *bii; + + CHECK(lyt_2.get_cell_type({0, 1}) == sidb_technology::cell_type::EMPTY); + CHECK(lyt_2.get_cell_type({2, 3}) == sidb_technology::cell_type::INPUT); + + CHECK(lyt_2.get_cell_type({20, 1}) == sidb_technology::cell_type::INPUT); + CHECK(lyt_2.get_cell_type({18, 3}) == sidb_technology::cell_type::EMPTY); + + break; + } + case 3: + { + const auto& lyt_3 = *bii; + + CHECK(lyt_3.get_cell_type({0, 1}) == sidb_technology::cell_type::EMPTY); + CHECK(lyt_3.get_cell_type({2, 3}) == sidb_technology::cell_type::INPUT); + + CHECK(lyt_3.get_cell_type({20, 1}) == sidb_technology::cell_type::EMPTY); + CHECK(lyt_3.get_cell_type({18, 3}) == sidb_technology::cell_type::INPUT); + + break; + } + default: + { + CHECK(false); + } } } } From 91f2d1a2fc09cc0390d412ed7aa49a37e94072f4 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 22 Nov 2023 07:36:23 +0100 Subject: [PATCH 5/9] :art: add missing namespace. --- .../simulation/sidb/random_sidb_layout_generator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/algorithms/simulation/sidb/random_sidb_layout_generator.cpp b/test/algorithms/simulation/sidb/random_sidb_layout_generator.cpp index f73d6b77e..747b196d2 100644 --- a/test/algorithms/simulation/sidb/random_sidb_layout_generator.cpp +++ b/test/algorithms/simulation/sidb/random_sidb_layout_generator.cpp @@ -647,8 +647,8 @@ TEST_CASE("Random cube::coord_t layout generation with defects", "[generate-rand using lyt = sidb_surface>>>; const generate_random_sidb_layout_params params{ - {to_fiction_coord(siqad::coord_t{0, 0, 0}), - to_fiction_coord(siqad::coord_t{10, 2, 0})}, + {siqad::to_fiction_coord(siqad::coord_t{0, 0, 0}), + siqad::to_fiction_coord(siqad::coord_t{10, 2, 0})}, 10, generate_random_sidb_layout_params::positive_charges::ALLOWED, 2}; From 6ccb477b8e8656f1f2ba51166c7b2d3ef9958900 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 22 Nov 2023 08:56:56 +0100 Subject: [PATCH 6/9] :art: allow offset coordinates for gate design --- .../algorithms/path_finding/distance.hpp | 1 - .../physical_design/design_sidb_gates.hpp | 21 +++-- .../assess_physical_population_stability.hpp | 2 +- include/fiction/layouts/coordinates.hpp | 12 +-- .../fiction/technology/sidb_nm_position.hpp | 7 +- include/fiction/utils/layout_utils.hpp | 93 +++++++++++++------ test/algorithms/iter/bdl_input_iterator.cpp | 67 +++++++++++++ .../physical_design/design_sidb_gates.cpp | 23 ++++- test/utils/layout_utils.cpp | 48 ++++++++++ 9 files changed, 220 insertions(+), 54 deletions(-) diff --git a/include/fiction/algorithms/path_finding/distance.hpp b/include/fiction/algorithms/path_finding/distance.hpp index 943d42fa9..7b532eb37 100644 --- a/include/fiction/algorithms/path_finding/distance.hpp +++ b/include/fiction/algorithms/path_finding/distance.hpp @@ -107,7 +107,6 @@ sidb_nanometer_distance([[maybe_unused]] const Lyt& lyt, const coordinate& { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not based on SiDB technology"); - //static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); const auto pos_c1 = sidb_nm_position(sp, source); const auto pos_c2 = sidb_nm_position(sp, target); diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 4ac214a07..69d4d43a9 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -38,6 +38,8 @@ namespace fiction /** * This struct contains parameters and settings to design SiDB gates. * + * @tparam Cell-level layout type. + * */ template struct design_sidb_gates_params @@ -97,7 +99,7 @@ class design_sidb_gates_impl skeleton_layout{skeleton}, truth_table{tt}, params{ps}, - all_sidbs_in_cavas{all_sidbs_in_spanned_area(params.canvas.first, params.canvas.second)} + all_sidbs_in_canvas{all_sidbs_in_spanned_area(params.canvas.first, params.canvas.second)} {} /** * Design gates exhaustively and in parallel. @@ -225,7 +227,7 @@ class design_sidb_gates_impl /** * All cells within the canvas. */ - const std::vector all_sidbs_in_cavas; + const std::vector all_sidbs_in_canvas; /** * Calculates all possible combinations of distributing the given number of SiDBs within a canvas * based on the provided parameters. It generates combinations of SiDB indices (representing the cell position in @@ -237,9 +239,9 @@ class design_sidb_gates_impl [[nodiscard]] std::vector> determine_all_combinations_of_given_sidbs_in_canvas() noexcept { std::vector> all_combinations{}; - all_combinations.reserve(binomial_coefficient(all_sidbs_in_cavas.size(), params.number_of_sidbs)); + all_combinations.reserve(binomial_coefficient(all_sidbs_in_canvas.size(), params.number_of_sidbs)); - std::vector numbers(all_sidbs_in_cavas.size()); + std::vector numbers(all_sidbs_in_canvas.size()); std::iota(numbers.begin(), numbers.end(), 0); combinations::for_each_combination( @@ -280,8 +282,8 @@ class design_sidb_gates_impl { for (std::size_t j = i + 1; j < cell_indices.size(); j++) { - if (sidb_nanometer_distance(skeleton_layout, all_sidbs_in_cavas[cell_indices[i]], - all_sidbs_in_cavas[cell_indices[j]]) < 0.5) + if (sidb_nanometer_distance(skeleton_layout, all_sidbs_in_canvas[cell_indices[i]], + all_sidbs_in_canvas[cell_indices[j]]) < 0.5) { return true; } @@ -301,11 +303,11 @@ class design_sidb_gates_impl for (const auto i : cell_indices) { - assert(i < all_sidbs_in_cavas.size() && "cell indices are out-of-range"); + assert(i < all_sidbs_in_canvas.size() && "cell indices are out-of-range"); - if (lyt_copy.get_cell_type(all_sidbs_in_cavas[i]) == sidb_technology::cell_type::EMPTY) + if (lyt_copy.get_cell_type(all_sidbs_in_canvas[i]) == sidb_technology::cell_type::EMPTY) { - lyt_copy.assign_cell_type(all_sidbs_in_cavas[i], sidb_technology::cell_type::NORMAL); + lyt_copy.assign_cell_type(all_sidbs_in_canvas[i], sidb_technology::cell_type::NORMAL); } } @@ -350,7 +352,6 @@ template static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); static_assert(kitty::is_truth_table::value, "TT is not a truth table"); static_assert(!is_charge_distribution_surface_v, "Lyt cannot be a charge distribution surface"); - static_assert(!has_offset_ucoord_v, "Lyt cannot be based on offset coordinates"); assert(skeleton.num_pis() > 0 && "skeleton needs input cells"); assert(skeleton.num_pos() > 0 && "skeleton needs output cells"); diff --git a/include/fiction/algorithms/simulation/sidb/assess_physical_population_stability.hpp b/include/fiction/algorithms/simulation/sidb/assess_physical_population_stability.hpp index bce65fa35..f844d694f 100644 --- a/include/fiction/algorithms/simulation/sidb/assess_physical_population_stability.hpp +++ b/include/fiction/algorithms/simulation/sidb/assess_physical_population_stability.hpp @@ -367,7 +367,7 @@ assess_physical_population_stability(const Lyt& lyt, const assess_physical_popul { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); - static_assert(!is_charge_distribution_surface_v, "Lyt is a charge distribution surface"); + static_assert(!is_charge_distribution_surface_v, "Lyt cannot be a charge distribution surface"); detail::assess_physical_population_stability_impl p{lyt, params}; return p.run(); diff --git a/include/fiction/layouts/coordinates.hpp b/include/fiction/layouts/coordinates.hpp index 270e5569c..8ac369b88 100644 --- a/include/fiction/layouts/coordinates.hpp +++ b/include/fiction/layouts/coordinates.hpp @@ -776,23 +776,19 @@ struct coord_t /** * Converts SiQAD coordinates to other coordinates (offset, cube). * - * @tparam CoordinateType Coordinate type to convert to. + * @tparam CoordinateType The wanted coordinate type. * @param coord SiQAD coordinate to convert. * @return Coordinate of type `CoordinateType`. */ -template -constexpr CoordinateTypeOutput to_fiction_coord(const CoordinateTypeInput& coord) noexcept +template +constexpr CoordinateType to_fiction_coord(const siqad::coord_t& coord) noexcept { - if constexpr (std::is_same_v) - { - return coord; - } if (!coord.is_dead()) { return {coord.x, coord.y * 2 + coord.z}; } - return CoordinateTypeOutput{}; + return CoordinateType{}; } /** * Converts any coordinate type to SiQAD coordinates. diff --git a/include/fiction/technology/sidb_nm_position.hpp b/include/fiction/technology/sidb_nm_position.hpp index c8259c486..36e490c4f 100644 --- a/include/fiction/technology/sidb_nm_position.hpp +++ b/include/fiction/technology/sidb_nm_position.hpp @@ -7,8 +7,8 @@ #include "fiction/algorithms/simulation/sidb/sidb_simulation_parameters.hpp" #include "fiction/layouts/cell_level_layout.hpp" -#include "fiction/traits.hpp" #include "fiction/layouts/coordinates.hpp" +#include "fiction/traits.hpp" #include @@ -29,7 +29,6 @@ template { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); - static_assert(has_siqad_coord_v || has_cube_coord_v || has_offset_ucoord_v, "Coordinate type is not supported"); if constexpr (has_siqad_coord_v) { @@ -40,8 +39,8 @@ template else { const auto cell_in_siqad = siqad::to_siqad_coord(c); - const auto x = (cell_in_siqad.x * sp.lat_a) * 0.1; - const auto y = (cell_in_siqad.y * sp.lat_b + cell_in_siqad.z * sp.lat_c) * .1; + const auto x = (cell_in_siqad.x * sp.lat_a) * 0.1; + const auto y = (cell_in_siqad.y * sp.lat_b + cell_in_siqad.z * sp.lat_c) * .1; return std::make_pair(x, y); } } diff --git a/include/fiction/utils/layout_utils.hpp b/include/fiction/utils/layout_utils.hpp index b6a5474e8..e56674baf 100644 --- a/include/fiction/utils/layout_utils.hpp +++ b/include/fiction/utils/layout_utils.hpp @@ -328,6 +328,17 @@ Lyt convert_to_fiction_coordinates(const sidb_cell_clk_lyt_siqad& lyt) noexcept static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); + bool has_negative_coordinates = false; + + lyt.foreach_cell( + [&has_negative_coordinates](const auto& c) + { + if (c.x < 0 || c.y < 0) + { + has_negative_coordinates = true; + } + }); + Lyt lyt_new{{lyt.x(), 2 * lyt.y() + 1}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; const auto assign_coordinates = [&lyt_new](const auto& base_lyt) noexcept @@ -341,7 +352,7 @@ Lyt convert_to_fiction_coordinates(const sidb_cell_clk_lyt_siqad& lyt) noexcept }); }; - if (has_offset_ucoord_v && !lyt.is_empty()) + if (has_offset_ucoord_v && !lyt.is_empty() && has_negative_coordinates) { auto lyt_normalized = normalize_layout_coordinates(lyt); assign_coordinates(lyt_normalized); @@ -408,40 +419,66 @@ template [[nodiscard]] inline std::vector all_sidbs_in_spanned_area(const CoordinateType& cell_nw, const CoordinateType& cell_se) noexcept { - const auto c1_cube = siqad::to_fiction_coord(cell_nw); - const auto c2_cube = siqad::to_fiction_coord(cell_se); - const auto total_cell_count = static_cast(std::abs(c1_cube.x - c2_cube.x) + 1) * - static_cast(std::abs(c1_cube.y - c2_cube.y) + 1); - - std::vector all_cells{}; - all_cells.reserve(total_cell_count); - - auto current_cell = c1_cube; - - // collect all cells in the area (spanned by the nw `north-west` and se `south-east` cell) going from top to down - // from left to right. - while (current_cell <= c2_cube) + // for siqad coordinates + if constexpr (std::is_same_v) { - if constexpr (std::is_same_v) + const auto c1_cube = siqad::to_fiction_coord(cell_nw); + const auto c2_cube = siqad::to_fiction_coord(cell_se); + const auto total_cell_count = static_cast(std::abs(c1_cube.x - c2_cube.x) + 1) * + static_cast(std::abs(c1_cube.y - c2_cube.y) + 1); + std::vector all_cells{}; + all_cells.reserve(total_cell_count); + + auto current_cell = c1_cube; + + // collect all cells in the area (spanned by the nw `north-west` and se `south-east` cell) going from top to + // down from left to right. + while (current_cell <= c2_cube) { all_cells.push_back(siqad::to_siqad_coord(current_cell)); + if (current_cell.x < cell_se.x) + { + current_cell.x += 1; + } + else + { + current_cell.x = cell_nw.x; + current_cell.y += 1; + } } - else - { - all_cells.push_back(siqad::to_fiction_coord(current_cell)); - } - if (current_cell.x < cell_se.x) - { - current_cell.x += 1; - } - else + + return all_cells; + } + // for cube and offset coordinates + else + { + const auto total_cell_count = static_cast(std::abs(cell_nw.x - cell_se.x) + 1) * + static_cast(std::abs(cell_nw.y - cell_se.y) + 1); + std::vector all_cells{}; + all_cells.reserve(total_cell_count); + + auto current_cell = cell_nw; + + // collect all cells in the area (spanned by the nw `north-west` and se `south-east` cell) going from top to + // down from left to right. + while (current_cell <= cell_se) { - current_cell.x = cell_nw.x; - current_cell.y += 1; + + all_cells.push_back(current_cell); + + if (current_cell.x < cell_se.x) + { + current_cell.x += 1; + } + else + { + current_cell.x = cell_nw.x; + current_cell.y += 1; + } } - } - return all_cells; + return all_cells; + } } } // namespace fiction diff --git a/test/algorithms/iter/bdl_input_iterator.cpp b/test/algorithms/iter/bdl_input_iterator.cpp index 4641ef077..a3ee32971 100644 --- a/test/algorithms/iter/bdl_input_iterator.cpp +++ b/test/algorithms/iter/bdl_input_iterator.cpp @@ -358,4 +358,71 @@ TEST_CASE("SiQAD's AND gate iteration", "[bdl-input-iterator]") } } } + + SECTION("offset coordinates") + { + const auto layout_offset = convert_to_fiction_coordinates< + cell_level_layout>>>(lyt); + bdl_input_iterator>>> bii{ + layout_offset}; + + for (auto i = 0; bii < 4; ++bii, ++i) + { + switch (i) + { + case 0: + { + const auto& lyt_0 = *bii; + + CHECK(lyt_0.get_cell_type({0, 1}) == sidb_technology::cell_type::INPUT); + CHECK(lyt_0.get_cell_type({2, 3}) == sidb_technology::cell_type::EMPTY); + + CHECK(lyt_0.get_cell_type({20, 1}) == sidb_technology::cell_type::INPUT); + CHECK(lyt_0.get_cell_type({18, 3}) == sidb_technology::cell_type::EMPTY); + + break; + } + case 1: + { + const auto& lyt_1 = *bii; + + CHECK(lyt_1.get_cell_type({0, 1}) == sidb_technology::cell_type::INPUT); + CHECK(lyt_1.get_cell_type({2, 3}) == sidb_technology::cell_type::EMPTY); + + CHECK(lyt_1.get_cell_type({20, 1}) == sidb_technology::cell_type::EMPTY); + CHECK(lyt_1.get_cell_type({18, 3}) == sidb_technology::cell_type::INPUT); + + break; + } + case 2: + { + const auto& lyt_2 = *bii; + + CHECK(lyt_2.get_cell_type({0, 1}) == sidb_technology::cell_type::EMPTY); + CHECK(lyt_2.get_cell_type({2, 3}) == sidb_technology::cell_type::INPUT); + + CHECK(lyt_2.get_cell_type({20, 1}) == sidb_technology::cell_type::INPUT); + CHECK(lyt_2.get_cell_type({18, 3}) == sidb_technology::cell_type::EMPTY); + + break; + } + case 3: + { + const auto& lyt_3 = *bii; + + CHECK(lyt_3.get_cell_type({0, 1}) == sidb_technology::cell_type::EMPTY); + CHECK(lyt_3.get_cell_type({2, 3}) == sidb_technology::cell_type::INPUT); + + CHECK(lyt_3.get_cell_type({20, 1}) == sidb_technology::cell_type::EMPTY); + CHECK(lyt_3.get_cell_type({18, 3}) == sidb_technology::cell_type::INPUT); + + break; + } + default: + { + CHECK(false); + } + } + } + } } diff --git a/test/algorithms/physical_design/design_sidb_gates.cpp b/test/algorithms/physical_design/design_sidb_gates.cpp index e8195ddb0..5f7ee24fb 100644 --- a/test/algorithms/physical_design/design_sidb_gates.cpp +++ b/test/algorithms/physical_design/design_sidb_gates.cpp @@ -17,8 +17,9 @@ using namespace fiction; TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[design-sidb-gates]") { - using layout = sidb_cell_clk_lyt_siqad; - using layout_cube = cell_level_layout>>; + using layout = sidb_cell_clk_lyt_siqad; + using layout_cube = cell_level_layout>>; + using layout_offset = cell_level_layout>>; layout lyt{}; @@ -73,6 +74,24 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ CHECK(found_gate_layouts_cube[0].num_cells() == 14); CHECK(found_gate_layouts_cube[0].get_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})) == layout::technology::NORMAL); + + // using offset coordinates + const auto lyt_in_offset_coord = convert_to_fiction_coordinates(lyt); + const design_sidb_gates_params params_offset{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, + {siqad::to_fiction_coord(siqad::coord_t{10, 4, 0}), + siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})}, + 1, + sidb_simulation_engine::QUICKEXACT}; + + const auto found_gate_layouts_offset = + design_sidb_gates(lyt_in_offset_coord, std::vector{create_xnor_tt()}, params_offset); + + REQUIRE(found_gate_layouts_offset.size() == 1); + CHECK(found_gate_layouts_offset[0].num_cells() == 14); + CHECK(found_gate_layouts_offset[0].get_cell_type( + siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})) == layout::technology::NORMAL); } TEST_CASE("Use SiQAD's AND gate skeleton to generate all possible AND gates", "[design-sidb-gates]") diff --git a/test/utils/layout_utils.cpp b/test/utils/layout_utils.cpp index 663af7e46..3a16d0e9d 100644 --- a/test/utils/layout_utils.cpp +++ b/test/utils/layout_utils.cpp @@ -441,3 +441,51 @@ TEST_CASE("Generate all cells in area spanned by two cells, using cube coordinat CHECK(final_cell.z == 0); } } + +TEST_CASE("Generate all cells in area spanned by two cells, using offset coordinates", "[layout-utils]") +{ + SECTION("two identical cells") + { + const auto all_area_cells = all_sidbs_in_spanned_area({10, 10, 0}, {10, 10, 0}); + REQUIRE(all_area_cells.size() == 1); + const auto first_cell = all_area_cells.front(); + CHECK(first_cell.x == 10); + CHECK(first_cell.y == 10); + CHECK(first_cell.z == 0); + + const auto final_cell = all_area_cells.back(); + CHECK(final_cell.x == 10); + CHECK(final_cell.y == 10); + CHECK(final_cell.z == 0); + } + + SECTION("two cells at the same y coordinate ") + { + const auto all_area_cells = all_sidbs_in_spanned_area({0, 10}, {20, 11}); + REQUIRE(all_area_cells.size() == 42); + const auto first_cell = all_area_cells.front(); + CHECK(first_cell.x == 0); + CHECK(first_cell.y == 10); + CHECK(first_cell.z == 0); + + const auto final_cell = all_area_cells.back(); + CHECK(final_cell.x == 20); + CHECK(final_cell.y == 11); + CHECK(final_cell.z == 0); + } + + SECTION("two cells at the same x coordinate ") + { + const auto all_area_cells = all_sidbs_in_spanned_area({10, 4, 0}, {10, 11}); + REQUIRE(all_area_cells.size() == 8); + const auto first_cell = all_area_cells.front(); + CHECK(first_cell.x == 10); + CHECK(first_cell.y == 4); + CHECK(first_cell.z == 0); + + const auto final_cell = all_area_cells.back(); + CHECK(final_cell.x == 10); + CHECK(final_cell.y == 11); + CHECK(final_cell.z == 0); + } +} From 559e1898734257cecc314b4acabf95bc48ed2637 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 22 Nov 2023 09:40:37 +0100 Subject: [PATCH 7/9] :art: reformat code --- include/fiction/utils/layout_utils.hpp | 4 +-- .../sidb/can_positive_charges_occur.cpp | 28 ++++++++++++------- ...defect_influence_position_and_distance.cpp | 3 +- .../algorithms/simulation/sidb/quickexact.cpp | 2 +- .../charge_distribution_surface.cpp | 10 +++---- 5 files changed, 26 insertions(+), 21 deletions(-) diff --git a/include/fiction/utils/layout_utils.hpp b/include/fiction/utils/layout_utils.hpp index e56674baf..1dc1b640c 100644 --- a/include/fiction/utils/layout_utils.hpp +++ b/include/fiction/utils/layout_utils.hpp @@ -452,8 +452,8 @@ template // for cube and offset coordinates else { - const auto total_cell_count = static_cast(std::abs(cell_nw.x - cell_se.x) + 1) * - static_cast(std::abs(cell_nw.y - cell_se.y) + 1); + const auto total_cell_count = static_cast(std::abs(cell_nw.x - cell_se.x) + 1) * + static_cast(std::abs(cell_nw.y - cell_se.y) + 1); std::vector all_cells{}; all_cells.reserve(total_cell_count); diff --git a/test/algorithms/simulation/sidb/can_positive_charges_occur.cpp b/test/algorithms/simulation/sidb/can_positive_charges_occur.cpp index c8326d4cc..1fd7822d1 100644 --- a/test/algorithms/simulation/sidb/can_positive_charges_occur.cpp +++ b/test/algorithms/simulation/sidb/can_positive_charges_occur.cpp @@ -112,16 +112,24 @@ TEMPLATE_TEST_CASE("Y-shape SiDB OR gate with input 01, using offset coordinates { TestType lyt{{20, 10}}; - lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0}), TestType::cell_type::NORMAL); - lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{8, 3, 0}), TestType::cell_type::NORMAL); - lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{12, 3, 0}), TestType::cell_type::NORMAL); - - lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 2, 0}), TestType::cell_type::NORMAL); - lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 5, 0}), TestType::cell_type::NORMAL); - - lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 6, 1}), TestType::cell_type::NORMAL); - lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 8, 1}), TestType::cell_type::NORMAL); - lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{16, 1, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{8, 3, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{12, 3, 0}), + TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 2, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 5, 0}), + TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 6, 1}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 8, 1}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{16, 1, 0}), + TestType::cell_type::NORMAL); SECTION("Default values") { diff --git a/test/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.cpp b/test/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.cpp index 897956f4f..e56265d3d 100644 --- a/test/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.cpp +++ b/test/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.cpp @@ -121,7 +121,7 @@ TEST_CASE("Test influence distance function", "[maximum-defect-influence-positio const sidb_defect defect{sidb_defect_type::UNKNOWN, -1, sidb_simulation_parameters{}.epsilon_r, sidb_simulation_parameters{}.lambda_tf}; const maximum_defect_influence_distance_params sim_params{defect, sidb_simulation_parameters{}}; - cell_level_layout>> lyt{{30,30}}; + cell_level_layout>> lyt{{30, 30}}; lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 0, 0}), sidb_cell_clk_lyt_siqad::cell_type::NORMAL); @@ -147,6 +147,5 @@ TEST_CASE("Test influence distance function", "[maximum-defect-influence-positio CHECK(defect_pos.z == 0); CHECK_THAT(distance, Catch::Matchers::WithinAbs(2.8999201713, physical_constants::POP_STABILITY_ERR)); - } } diff --git a/test/algorithms/simulation/sidb/quickexact.cpp b/test/algorithms/simulation/sidb/quickexact.cpp index fa98c26a0..77517b5fa 100644 --- a/test/algorithms/simulation/sidb/quickexact.cpp +++ b/test/algorithms/simulation/sidb/quickexact.cpp @@ -779,7 +779,7 @@ TEMPLATE_TEST_CASE( const quickexact_params params{sidb_simulation_parameters{3, -0.32}}; lyt.assign_sidb_defect({-1, -1, 1}, sidb_defect{sidb_defect_type::UNKNOWN, -1, params.physical_parameters.epsilon_r, - params.physical_parameters.lambda_tf}); + params.physical_parameters.lambda_tf}); const auto simulation_results = quickexact(lyt, params); REQUIRE(!simulation_results.charge_distributions.empty()); diff --git a/test/technology/charge_distribution_surface.cpp b/test/technology/charge_distribution_surface.cpp index 13b748991..ca961fcc7 100644 --- a/test/technology/charge_distribution_surface.cpp +++ b/test/technology/charge_distribution_surface.cpp @@ -1309,9 +1309,8 @@ TEMPLATE_TEST_CASE("Assign and delete charge states without defects", "[charge-d } } -TEMPLATE_TEST_CASE( - "Assign and delete charge states without defects, part one", "[charge-distribution-surface]", - (sidb_surface>>>)) +TEMPLATE_TEST_CASE("Assign and delete charge states without defects, part one", "[charge-distribution-surface]", + (sidb_surface>>>)) { TestType lyt{{11, 11}}; @@ -1559,9 +1558,8 @@ TEMPLATE_TEST_CASE( } } -TEMPLATE_TEST_CASE( - "Assign and delete charge states without defects, part two", "[charge-distribution-surface]", - (sidb_surface>>>)) +TEMPLATE_TEST_CASE("Assign and delete charge states without defects, part two", "[charge-distribution-surface]", + (sidb_surface>>>)) { TestType lyt{{11, 11}}; From e28b1b4833b37709e633dacfab22eb943fec85a3 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 22 Nov 2023 12:45:11 +0100 Subject: [PATCH 8/9] :art: small fix. --- include/fiction/utils/layout_utils.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/fiction/utils/layout_utils.hpp b/include/fiction/utils/layout_utils.hpp index 1dc1b640c..243986cd2 100644 --- a/include/fiction/utils/layout_utils.hpp +++ b/include/fiction/utils/layout_utils.hpp @@ -452,8 +452,9 @@ template // for cube and offset coordinates else { - const auto total_cell_count = static_cast(std::abs(cell_nw.x - cell_se.x) + 1) * - static_cast(std::abs(cell_nw.y - cell_se.y) + 1); + const auto total_cell_count = + static_cast(std::abs(static_cast(cell_nw.x) - static_cast(cell_se.x)) + 1) * + static_cast(std::abs(static_cast(cell_nw.y) - static_cast(cell_se.y)) + 1); std::vector all_cells{}; all_cells.reserve(total_cell_count); From 776f60bc5d281bbfd094288254c3f2a2f9f484e5 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Fri, 24 Nov 2023 16:24:25 +0100 Subject: [PATCH 9/9] :art: implement Marcel's suggestions. --- docs/utils/utils.rst | 2 +- .../physical_design/design_sidb_gates.hpp | 2 +- ...defect_influence_position_and_distance.hpp | 7 ++--- include/fiction/layouts/coordinates.hpp | 2 +- .../charge_distribution_surface.hpp | 2 +- .../fiction/technology/sidb_nm_position.hpp | 13 +++++---- include/fiction/utils/layout_utils.hpp | 28 +++++++++++-------- test/technology/sidb_nm_position.cpp | 4 +-- test/utils/layout_utils.cpp | 20 ++++++------- 9 files changed, 44 insertions(+), 36 deletions(-) diff --git a/docs/utils/utils.rst b/docs/utils/utils.rst index 18f2c0022..3dab74a67 100644 --- a/docs/utils/utils.rst +++ b/docs/utils/utils.rst @@ -62,7 +62,7 @@ Layout Utils .. doxygenfunction:: fiction::convert_to_siqad_coordinates .. doxygenfunction:: fiction::convert_to_fiction_coordinates .. doxygenfunction:: fiction::random_coordinate -.. doxygenfunction:: fiction::all_sidbs_in_spanned_area +.. doxygenfunction:: fiction::all_coordinates_in_spanned_area Placement Utils diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 69d4d43a9..5186fe0d0 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -99,7 +99,7 @@ class design_sidb_gates_impl skeleton_layout{skeleton}, truth_table{tt}, params{ps}, - all_sidbs_in_canvas{all_sidbs_in_spanned_area(params.canvas.first, params.canvas.second)} + all_sidbs_in_canvas{all_coordinates_in_spanned_area(params.canvas.first, params.canvas.second)} {} /** * Design gates exhaustively and in parallel. diff --git a/include/fiction/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.hpp b/include/fiction/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.hpp index e6f5a5650..d15001d90 100644 --- a/include/fiction/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.hpp +++ b/include/fiction/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.hpp @@ -39,8 +39,7 @@ struct maximum_defect_influence_distance_params * The pair describes the width and height of the area around the gate, which is * also used to place defects. * - * @note The height of the area (second entry of the pair) is given in the y coordinate of the SiQAD coordinates. - * This means that it describes the number of dimer rows. + * @note If SiQAD coordinates are used, the second entry describes the number of dimer rows. */ std::pair additional_scanning_area{50, 6}; }; @@ -191,7 +190,7 @@ class maximum_defect_influence_position_and_distance_impl se.x = se.x + params.additional_scanning_area.first; se.y = se.y + params.additional_scanning_area.second; - defect_cells = all_sidbs_in_spanned_area(nw, se); + defect_cells = all_coordinates_in_spanned_area(nw, se); } }; @@ -217,7 +216,7 @@ maximum_defect_influence_position_and_distance(const Lyt& { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); - static_assert(!has_offset_ucoord_v, "Lyt should not be based on offset coordinates"); + static_assert(!has_offset_ucoord_v, "Lyt cannot be based on offset coordinates"); static_assert(!is_charge_distribution_surface_v, "Lyt cannot be a charge distribution surface"); detail::maximum_defect_influence_position_and_distance_impl p{lyt, sim_params}; diff --git a/include/fiction/layouts/coordinates.hpp b/include/fiction/layouts/coordinates.hpp index 8ac369b88..70731229c 100644 --- a/include/fiction/layouts/coordinates.hpp +++ b/include/fiction/layouts/coordinates.hpp @@ -776,7 +776,7 @@ struct coord_t /** * Converts SiQAD coordinates to other coordinates (offset, cube). * - * @tparam CoordinateType The wanted coordinate type. + * @tparam CoordinateType The desired coordinate type. * @param coord SiQAD coordinate to convert. * @return Coordinate of type `CoordinateType`. */ diff --git a/include/fiction/technology/charge_distribution_surface.hpp b/include/fiction/technology/charge_distribution_surface.hpp index 2d9bd792d..f007b2785 100644 --- a/include/fiction/technology/charge_distribution_surface.hpp +++ b/include/fiction/technology/charge_distribution_surface.hpp @@ -83,7 +83,7 @@ enum class charge_distribution_history * A layout type to layer on top of any SiDB cell-level layout. It implements an interface to store and access * SiDBs' charge states. * - * @tparam Lyt Cell-level layout based in SiQAD coordinates. + * @tparam Lyt Cell-level layout. * @tparam has_sidb_charge_distribution Automatically determines whether a charge distribution interface is already * present. */ diff --git a/include/fiction/technology/sidb_nm_position.hpp b/include/fiction/technology/sidb_nm_position.hpp index 36e490c4f..a7023d627 100644 --- a/include/fiction/technology/sidb_nm_position.hpp +++ b/include/fiction/technology/sidb_nm_position.hpp @@ -33,15 +33,18 @@ template if constexpr (has_siqad_coord_v) { const auto x = (c.x * sp.lat_a) * 0.1; - const auto y = (c.y * sp.lat_b + c.z * sp.lat_c) * .1; - return std::make_pair(x, y); + const auto y = (c.y * sp.lat_b + c.z * sp.lat_c) * 0.1; + + return {x, y}; } else { const auto cell_in_siqad = siqad::to_siqad_coord(c); - const auto x = (cell_in_siqad.x * sp.lat_a) * 0.1; - const auto y = (cell_in_siqad.y * sp.lat_b + cell_in_siqad.z * sp.lat_c) * .1; - return std::make_pair(x, y); + + const auto x = (cell_in_siqad.x * sp.lat_a) * 0.1; + const auto y = (cell_in_siqad.y * sp.lat_b + cell_in_siqad.z * sp.lat_c) * 0.1; + + return {x, y}; } } } // namespace fiction diff --git a/include/fiction/utils/layout_utils.hpp b/include/fiction/utils/layout_utils.hpp index 243986cd2..5c371908d 100644 --- a/include/fiction/utils/layout_utils.hpp +++ b/include/fiction/utils/layout_utils.hpp @@ -328,15 +328,20 @@ Lyt convert_to_fiction_coordinates(const sidb_cell_clk_lyt_siqad& lyt) noexcept static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); - bool has_negative_coordinates = false; + bool are_cells_assigned_to_negative_coordinates = false; + // determine if cells are assigned to negative coordinates. If true, the layout must be normalized first when + // converting to offset coordinates. lyt.foreach_cell( - [&has_negative_coordinates](const auto& c) + [&are_cells_assigned_to_negative_coordinates](const auto& c) { if (c.x < 0 || c.y < 0) { - has_negative_coordinates = true; + are_cells_assigned_to_negative_coordinates = true; + return false; // abort } + + return true; // keep looping }); Lyt lyt_new{{lyt.x(), 2 * lyt.y() + 1}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; @@ -352,7 +357,7 @@ Lyt convert_to_fiction_coordinates(const sidb_cell_clk_lyt_siqad& lyt) noexcept }); }; - if (has_offset_ucoord_v && !lyt.is_empty() && has_negative_coordinates) + if (has_offset_ucoord_v && !lyt.is_empty() && are_cells_assigned_to_negative_coordinates) { auto lyt_normalized = normalize_layout_coordinates(lyt); assign_coordinates(lyt_normalized); @@ -405,21 +410,22 @@ CoordinateType random_coordinate(CoordinateType coordinate1, CoordinateType coor } } /** - * Generates a vector of all SiQAD cells within an area spanned by two SiQAD coordinates. + * Generates a vector of all coordinates within an area spanned by two coordinates. * - * This function calculates and returns a vector of all SiQAD cells that span the area + * This function calculates and returns a vector of all coordinates that span the area * between the northwest (cell_nw) and southeast (cell_se) cells, inclusive. * The cells are generated in a top-down, left-to-right fashion within the specified area. * - * @param cell_nw The northwest SiQAD cell defining the starting point of the area. - * @param cell_se The southeast SiQAD cell defining the ending point of the area. + * @tparam CoordinateType Coordinate Type. + * @param cell_nw The northwest cell defining the starting point of the area. + * @param cell_se The southeast cell defining the ending point of the area. * @return A vector containing all cells within the specified area. */ template -[[nodiscard]] inline std::vector all_sidbs_in_spanned_area(const CoordinateType& cell_nw, - const CoordinateType& cell_se) noexcept +[[nodiscard]] inline std::vector all_coordinates_in_spanned_area(const CoordinateType& cell_nw, + const CoordinateType& cell_se) noexcept { - // for siqad coordinates + // for SiQAD coordinates if constexpr (std::is_same_v) { const auto c1_cube = siqad::to_fiction_coord(cell_nw); diff --git a/test/technology/sidb_nm_position.cpp b/test/technology/sidb_nm_position.cpp index ff4324c94..121c1d20e 100644 --- a/test/technology/sidb_nm_position.cpp +++ b/test/technology/sidb_nm_position.cpp @@ -12,7 +12,7 @@ using namespace fiction; -TEST_CASE("SiDB position in nanometer for siqad coordinate", "[sidb_nm_position]") +TEST_CASE("SiDB position in nanometer for siqad coordinates", "[sidb-nm-position]") { using namespace Catch::Matchers; @@ -104,7 +104,7 @@ TEST_CASE("SiDB position in nanometer for siqad coordinate", "[sidb_nm_position] } } -TEST_CASE("SiDB position in nanometer for fiction coordinates", "[sidb_nm_position]") +TEST_CASE("SiDB position in nanometer for fiction coordinates", "[sidb-nm-position]") { using namespace Catch::Matchers; diff --git a/test/utils/layout_utils.cpp b/test/utils/layout_utils.cpp index 3a16d0e9d..5336c2bc2 100644 --- a/test/utils/layout_utils.cpp +++ b/test/utils/layout_utils.cpp @@ -340,7 +340,7 @@ TEST_CASE("Generate all cells in area spanned by two cells, using siqad coordina { SECTION("two identical cells") { - const auto all_area_cells = all_sidbs_in_spanned_area({-10, -5, 0}, {-10, -5, 0}); + const auto all_area_cells = all_coordinates_in_spanned_area({-10, -5, 0}, {-10, -5, 0}); REQUIRE(all_area_cells.size() == 1); const auto first_cell = all_area_cells.front(); CHECK(first_cell.x == -10); @@ -350,7 +350,7 @@ TEST_CASE("Generate all cells in area spanned by two cells, using siqad coordina SECTION("two cells at the same y and z coordinate ") { - const auto all_area_cells = all_sidbs_in_spanned_area({-10, -5, 0}, {10, -5, 0}); + const auto all_area_cells = all_coordinates_in_spanned_area({-10, -5, 0}, {10, -5, 0}); REQUIRE(all_area_cells.size() == 21); const auto first_cell = all_area_cells.front(); CHECK(first_cell.x == -10); @@ -365,7 +365,7 @@ TEST_CASE("Generate all cells in area spanned by two cells, using siqad coordina SECTION("two cells at the same y coordinate ") { - const auto all_area_cells = all_sidbs_in_spanned_area({-10, 5, 0}, {10, 5, 1}); + const auto all_area_cells = all_coordinates_in_spanned_area({-10, 5, 0}, {10, 5, 1}); REQUIRE(all_area_cells.size() == 42); const auto first_cell = all_area_cells.front(); CHECK(first_cell.x == -10); @@ -380,7 +380,7 @@ TEST_CASE("Generate all cells in area spanned by two cells, using siqad coordina SECTION("two cells at the same x coordinate ") { - const auto all_area_cells = all_sidbs_in_spanned_area({10, 2, 0}, {10, 5, 1}); + const auto all_area_cells = all_coordinates_in_spanned_area({10, 2, 0}, {10, 5, 1}); REQUIRE(all_area_cells.size() == 8); const auto first_cell = all_area_cells.front(); CHECK(first_cell.x == 10); @@ -398,7 +398,7 @@ TEST_CASE("Generate all cells in area spanned by two cells, using cube coordinat { SECTION("two identical cells") { - const auto all_area_cells = all_sidbs_in_spanned_area({-10, -10, 0}, {-10, -10, 0}); + const auto all_area_cells = all_coordinates_in_spanned_area({-10, -10, 0}, {-10, -10, 0}); REQUIRE(all_area_cells.size() == 1); const auto first_cell = all_area_cells.front(); CHECK(first_cell.x == -10); @@ -413,7 +413,7 @@ TEST_CASE("Generate all cells in area spanned by two cells, using cube coordinat SECTION("two cells at the same y coordinate ") { - const auto all_area_cells = all_sidbs_in_spanned_area({-10, 10}, {10, 11}); + const auto all_area_cells = all_coordinates_in_spanned_area({-10, 10}, {10, 11}); REQUIRE(all_area_cells.size() == 42); const auto first_cell = all_area_cells.front(); CHECK(first_cell.x == -10); @@ -428,7 +428,7 @@ TEST_CASE("Generate all cells in area spanned by two cells, using cube coordinat SECTION("two cells at the same x coordinate ") { - const auto all_area_cells = all_sidbs_in_spanned_area({10, 4, 0}, {10, 11}); + const auto all_area_cells = all_coordinates_in_spanned_area({10, 4, 0}, {10, 11}); REQUIRE(all_area_cells.size() == 8); const auto first_cell = all_area_cells.front(); CHECK(first_cell.x == 10); @@ -446,7 +446,7 @@ TEST_CASE("Generate all cells in area spanned by two cells, using offset coordin { SECTION("two identical cells") { - const auto all_area_cells = all_sidbs_in_spanned_area({10, 10, 0}, {10, 10, 0}); + const auto all_area_cells = all_coordinates_in_spanned_area({10, 10, 0}, {10, 10, 0}); REQUIRE(all_area_cells.size() == 1); const auto first_cell = all_area_cells.front(); CHECK(first_cell.x == 10); @@ -461,7 +461,7 @@ TEST_CASE("Generate all cells in area spanned by two cells, using offset coordin SECTION("two cells at the same y coordinate ") { - const auto all_area_cells = all_sidbs_in_spanned_area({0, 10}, {20, 11}); + const auto all_area_cells = all_coordinates_in_spanned_area({0, 10}, {20, 11}); REQUIRE(all_area_cells.size() == 42); const auto first_cell = all_area_cells.front(); CHECK(first_cell.x == 0); @@ -476,7 +476,7 @@ TEST_CASE("Generate all cells in area spanned by two cells, using offset coordin SECTION("two cells at the same x coordinate ") { - const auto all_area_cells = all_sidbs_in_spanned_area({10, 4, 0}, {10, 11}); + const auto all_area_cells = all_coordinates_in_spanned_area({10, 4, 0}, {10, 11}); REQUIRE(all_area_cells.size() == 8); const auto first_cell = all_area_cells.front(); CHECK(first_cell.x == 10);