diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index ccaa20785..ae45e20a8 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -250,13 +250,20 @@ class design_sidb_gates_impl for (std::size_t i = 0; i < number_of_used_threads; ++i) { threads.emplace_back( - [i, chunk_size, &all_combinations, &add_combination_to_layout_and_check_operation]() + [i, chunk_size, &all_combinations, &add_combination_to_layout_and_check_operation, &solution_found, + this]() { const std::size_t start_index = i * chunk_size; const std::size_t end_index = std::min(start_index + chunk_size, all_combinations.size()); for (std::size_t j = start_index; j < end_index; ++j) { + if (solution_found && + (params.termination_cond == + design_sidb_gates_params>::termination_condition::AFTER_FIRST_SOLUTION)) + { + return; + } add_combination_to_layout_and_check_operation(all_combinations[j]); } }); diff --git a/include/fiction/technology/charge_distribution_surface.hpp b/include/fiction/technology/charge_distribution_surface.hpp index 77b5c94d9..5c5326d25 100644 --- a/include/fiction/technology/charge_distribution_surface.hpp +++ b/include/fiction/technology/charge_distribution_surface.hpp @@ -536,7 +536,8 @@ class charge_distribution_surface : public Lyt void add_sidb_defect_to_potential_landscape(const typename Lyt::cell& c, const sidb_defect& defect) noexcept { // check if defect is not placed on SiDB position - if (std::find(strg->sidb_order.cbegin(), strg->sidb_order.cend(), c) == strg->sidb_order.end()) + if (std::find(strg->sidb_order.cbegin(), strg->sidb_order.cend(), c) == strg->sidb_order.end() && + is_charged_defect_type(defect)) { // check if defect was not added yet. if (strg->defects.find(c) == strg->defects.end()) diff --git a/test/algorithms/physical_design/design_sidb_gates.cpp b/test/algorithms/physical_design/design_sidb_gates.cpp index 648cf08f1..95ab0f67d 100644 --- a/test/algorithms/physical_design/design_sidb_gates.cpp +++ b/test/algorithms/physical_design/design_sidb_gates.cpp @@ -400,16 +400,27 @@ TEST_CASE("Design NOR Bestagon shaped gate on H-Si 111", "[design-sidb-gates]") SECTION("Exhaustive Generation, allowing kinks") { - const design_sidb_gates_params> params{ + design_sidb_gates_params> params{ is_operational_params{sidb_simulation_parameters{2, -0.32}, sidb_simulation_engine::QUICKEXACT}, design_sidb_gates_params< cell>::design_sidb_gates_mode::AUTOMATIC_EXHAUSTIVE_GATE_DESIGNER, {{10, 13, 0}, {14, 17, 0}}, 3}; - const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_nor_tt()}, params); - REQUIRE(found_gate_layouts.size() == 14); - CHECK(found_gate_layouts.front().num_cells() == lyt.num_cells() + 3); + SECTION("all design") + { + const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_nor_tt()}, params); + REQUIRE(found_gate_layouts.size() == 14); + CHECK(found_gate_layouts.front().num_cells() == lyt.num_cells() + 3); + } + SECTION("terminate after first solution is found") + { + params.termination_cond = design_sidb_gates_params< + cell>::termination_condition::AFTER_FIRST_SOLUTION; + const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_nor_tt()}, params); + REQUIRE(found_gate_layouts.size() <= std::thread::hardware_concurrency()); + CHECK(found_gate_layouts.front().num_cells() == lyt.num_cells() + 3); + } } SECTION("Exhaustive Generation, forbidding kinks") diff --git a/test/technology/charge_distribution_surface.cpp b/test/technology/charge_distribution_surface.cpp index 11b6755c7..6131d161d 100644 --- a/test/technology/charge_distribution_surface.cpp +++ b/test/technology/charge_distribution_surface.cpp @@ -564,7 +564,7 @@ TEMPLATE_TEST_CASE("Assign and delete charge states without defects", "[charge-d lyt.assign_cell_type({1, 8, 0}, TestType::cell_type::NORMAL); lyt.assign_cell_type({1, 10, 1}, TestType::cell_type::NORMAL); - charge_distribution_surface charge_layout{lyt, sidb_simulation_parameters{}}; + const charge_distribution_surface charge_layout{lyt, sidb_simulation_parameters{}}; CHECK_THAT(charge_layout.get_chargeless_potential_between_sidbs({2, 8, 0}, {2, 10, 1}), Catch::Matchers::WithinAbs(0.0, 0.00001)); @@ -887,8 +887,8 @@ TEMPLATE_TEST_CASE("Assign and delete charge states without defects", "[charge-d lyt_new.assign_cell_type({0, 0, 0}, TestType::cell_type::NORMAL); - charge_distribution_surface charge_layout_new{lyt_new, params}; - const auto negative_sidbs = charge_layout_new.negative_sidb_detection(); + const charge_distribution_surface charge_layout_new{lyt_new, params}; + const auto negative_sidbs = charge_layout_new.negative_sidb_detection(); REQUIRE(negative_sidbs.size() == 1); } @@ -1314,7 +1314,7 @@ TEMPLATE_TEST_CASE("Assign and delete charge states without defects, part one", { TestType lyt{}; - SECTION("Assign defect") + SECTION("Assign charged defect") { lyt.assign_cell_type({5, 4}, TestType::cell_type::NORMAL); lyt.assign_cell_type({5, 5}, TestType::cell_type::NORMAL); @@ -1325,6 +1325,19 @@ TEMPLATE_TEST_CASE("Assign and delete charge states without defects, part one", charge_layout.get_simulation_params().lambda_tf}); } + SECTION("Assign neutral defect") + { + lyt.assign_cell_type({5, 4}, TestType::cell_type::NORMAL); + charge_distribution_surface charge_layout{lyt, sidb_simulation_parameters{}}; + charge_layout.add_sidb_defect_to_potential_landscape( + {5, 6}, sidb_defect{sidb_defect_type::UNKNOWN, 0, charge_layout.get_simulation_params().epsilon_r, + charge_layout.get_simulation_params().lambda_tf}); + + REQUIRE(charge_layout.get_local_potential({5, 4}).has_value()); + CHECK_THAT(charge_layout.get_local_potential({5, 4}).value(), + Catch::Matchers::WithinAbs(0, physical_constants::POP_STABILITY_ERR)); + } + SECTION("perturber is replaced by an equivalent defect") { lyt.assign_cell_type({5, 4}, TestType::cell_type::NORMAL); @@ -1909,17 +1922,27 @@ TEMPLATE_TEST_CASE("Assign and delete charge states without defects, part two", CHECK(charge_layout.get_charge_state({0, 0, 0}) == sidb_charge_state::NEGATIVE); CHECK(charge_layout.get_charge_state({3, 0, 0}) == sidb_charge_state::NEGATIVE); CHECK(charge_layout.get_charge_state({5, 0, 0}) == sidb_charge_state::NEGATIVE); - auto loc_one_wo_defect = charge_layout.get_local_potential({0, 0, 0}).value(); - auto loc_two_wo_defect = charge_layout.get_local_potential({3, 0, 0}).value(); - auto loc_three_wo_defect = charge_layout.get_local_potential({5, 0, 0}).value(); + + REQUIRE(charge_layout.get_local_potential({0, 0, 0}).has_value()); + REQUIRE(charge_layout.get_local_potential({3, 0, 0}).has_value()); + REQUIRE(charge_layout.get_local_potential({5, 0, 0}).has_value()); + + const auto loc_one_wo_defect = charge_layout.get_local_potential({0, 0, 0}).value(); + const auto loc_two_wo_defect = charge_layout.get_local_potential({3, 0, 0}).value(); + const auto loc_three_wo_defect = charge_layout.get_local_potential({5, 0, 0}).value(); charge_layout.add_sidb_defect_to_potential_landscape( {-4, 0, 0}, sidb_defect{sidb_defect_type::UNKNOWN, -1, charge_layout.get_simulation_params().epsilon_r, charge_layout.get_simulation_params().lambda_tf}); - auto loc_one_w_negative_defect = charge_layout.get_local_potential({0, 0, 0}).value(); - auto loc_two_w_negative_defect = charge_layout.get_local_potential({3, 0, 0}).value(); - auto loc_three_w_negative_defect = charge_layout.get_local_potential({5, 0, 0}).value(); - auto defect_potentials_negative = charge_layout.get_local_defect_potentials(); + + REQUIRE(charge_layout.get_local_potential({0, 0, 0}).has_value()); + REQUIRE(charge_layout.get_local_potential({3, 0, 0}).has_value()); + REQUIRE(charge_layout.get_local_potential({5, 0, 0}).has_value()); + + const auto loc_one_w_negative_defect = charge_layout.get_local_potential({0, 0, 0}).value(); + const auto loc_two_w_negative_defect = charge_layout.get_local_potential({3, 0, 0}).value(); + const auto loc_three_w_negative_defect = charge_layout.get_local_potential({5, 0, 0}).value(); + const auto defect_potentials_negative = charge_layout.get_local_defect_potentials(); REQUIRE(!defect_potentials_negative.empty()); CHECK(loc_one_wo_defect > loc_one_w_negative_defect); @@ -1929,35 +1952,31 @@ TEMPLATE_TEST_CASE("Assign and delete charge states without defects, part two", charge_layout.add_sidb_defect_to_potential_landscape( {-4, 0, 0}, sidb_defect{sidb_defect_type::UNKNOWN, 0, charge_layout.get_simulation_params().epsilon_r, charge_layout.get_simulation_params().lambda_tf}); - auto loc_one_w_neutral_defect = charge_layout.get_local_potential({0, 0, 0}).value(); - auto loc_two_w_neutral_defect = charge_layout.get_local_potential({3, 0, 0}).value(); - auto loc_three_w_neutral_defect = charge_layout.get_local_potential({5, 0, 0}).value(); - CHECK_THAT(loc_one_wo_defect - loc_one_w_neutral_defect, - Catch::Matchers::WithinAbs(0, physical_constants::POP_STABILITY_ERR)); - CHECK_THAT(loc_two_wo_defect - loc_two_w_neutral_defect, - Catch::Matchers::WithinAbs(0, physical_constants::POP_STABILITY_ERR)); - CHECK_THAT(loc_three_wo_defect - loc_three_w_neutral_defect, - Catch::Matchers::WithinAbs(0, physical_constants::POP_STABILITY_ERR)); + + REQUIRE(charge_layout.get_local_potential({0, 0, 0}).has_value()); + REQUIRE(charge_layout.get_local_potential({3, 0, 0}).has_value()); + REQUIRE(charge_layout.get_local_potential({5, 0, 0}).has_value()); + + const auto loc_one_w_neutral_defect = charge_layout.get_local_potential({0, 0, 0}).value(); + const auto loc_two_w_neutral_defect = charge_layout.get_local_potential({3, 0, 0}).value(); + const auto loc_three_w_neutral_defect = charge_layout.get_local_potential({5, 0, 0}).value(); charge_layout.add_sidb_defect_to_potential_landscape( {-4, 0, 0}, sidb_defect{sidb_defect_type::UNKNOWN, 1, charge_layout.get_simulation_params().epsilon_r, charge_layout.get_simulation_params().lambda_tf}); - auto loc_one_w_positive_defect = charge_layout.get_local_potential({0, 0, 0}).value(); - auto loc_two_w_positive_defect = charge_layout.get_local_potential({3, 0, 0}).value(); - auto loc_three_w_positive_defect = charge_layout.get_local_potential({5, 0, 0}).value(); - auto defect_potentials_positive = charge_layout.get_local_defect_potentials(); + + REQUIRE(charge_layout.get_local_potential({0, 0, 0}).has_value()); + REQUIRE(charge_layout.get_local_potential({3, 0, 0}).has_value()); + REQUIRE(charge_layout.get_local_potential({5, 0, 0}).has_value()); + const auto loc_one_w_positive_defect = charge_layout.get_local_potential({0, 0, 0}).value(); + const auto loc_two_w_positive_defect = charge_layout.get_local_potential({3, 0, 0}).value(); + const auto loc_three_w_positive_defect = charge_layout.get_local_potential({5, 0, 0}).value(); + const auto defect_potentials_positive = charge_layout.get_local_defect_potentials(); REQUIRE(!defect_potentials_positive.empty()); CHECK(loc_one_w_positive_defect > loc_one_w_neutral_defect); CHECK(loc_two_w_positive_defect > loc_two_w_neutral_defect); CHECK(loc_three_w_positive_defect > loc_three_w_neutral_defect); - - CHECK_THAT((defect_potentials_negative[{0, 0, 0}] + defect_potentials_positive[{0, 0, 0}]), - Catch::Matchers::WithinAbs(0.0, 0.000001)); - CHECK_THAT((defect_potentials_negative[{3, 0, 0}] + defect_potentials_positive[{3, 0, 0}]), - Catch::Matchers::WithinAbs(0.0, 0.000001)); - CHECK_THAT((defect_potentials_negative[{5, 0, 0}] + defect_potentials_positive[{5, 0, 0}]), - Catch::Matchers::WithinAbs(0.0, 0.000001)); } SECTION("experiments with defects | assigning and reassigning defects") @@ -2002,13 +2021,6 @@ TEMPLATE_TEST_CASE("Assign and delete charge states without defects, part two", auto loc_two_w_neutral_defect = charge_layout.get_local_potential({3, 0, 0}).value(); auto loc_three_w_neutral_defect = charge_layout.get_local_potential({5, 0, 0}).value(); - CHECK_THAT(loc_one_wo_defect - loc_one_w_neutral_defect, - Catch::Matchers::WithinAbs(0, physical_constants::POP_STABILITY_ERR)); - CHECK_THAT(loc_two_wo_defect - loc_two_w_neutral_defect, - Catch::Matchers::WithinAbs(0, physical_constants::POP_STABILITY_ERR)); - CHECK_THAT(loc_three_wo_defect - loc_three_w_neutral_defect, - Catch::Matchers::WithinAbs(0, physical_constants::POP_STABILITY_ERR)); - charge_layout.add_sidb_defect_to_potential_landscape( {-4, 0, 0}, sidb_defect{sidb_defect_type::UNKNOWN, 1, charge_layout.get_simulation_params().epsilon_r, charge_layout.get_simulation_params().lambda_tf});