diff --git a/include/fiction/algorithms/simulation/sidb/quickexact.hpp b/include/fiction/algorithms/simulation/sidb/quickexact.hpp index 2bda96cb7..7e42b83f9 100644 --- a/include/fiction/algorithms/simulation/sidb/quickexact.hpp +++ b/include/fiction/algorithms/simulation/sidb/quickexact.hpp @@ -264,6 +264,14 @@ class quickexact_impl 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) + { + charge_lyt.assign_base_number(3); + } + else + { + charge_lyt.assign_base_number(2); + } charge_layout.assign_physical_parameters(params.physical_parameters); charge_layout.assign_all_charge_states(sidb_charge_state::NEUTRAL); charge_layout.assign_dependent_cell(all_sidbs_in_lyt_without_negative_preassigned_ones[0]); diff --git a/include/fiction/technology/charge_distribution_surface.hpp b/include/fiction/technology/charge_distribution_surface.hpp index d38de7590..f3967dfcd 100644 --- a/include/fiction/technology/charge_distribution_surface.hpp +++ b/include/fiction/technology/charge_distribution_surface.hpp @@ -1555,18 +1555,23 @@ class charge_distribution_surface : public Lyt } else if ((loc_pot_cell + strg->phys_params.mu_plus()) > -physical_constants::POP_STABILITY_ERR) { - if (strg->cell_charge[strg->dependent_cell_index] != sidb_charge_state::POSITIVE) + // dependent-cell can only be positively charged when the base number is set to three state simulation. + if (strg->charge_index_and_base.second == 3) { - const auto charge_diff = (-charge_state_to_sign(strg->cell_charge[strg->dependent_cell_index]) + 1); - for (uint64_t i = 0u; i < strg->pot_mat.size(); ++i) + if (strg->cell_charge[strg->dependent_cell_index] != sidb_charge_state::POSITIVE) { - if (i != strg->dependent_cell_index) + const auto charge_diff = + (-charge_state_to_sign(strg->cell_charge[strg->dependent_cell_index]) + 1); + strg->cell_charge[strg->dependent_cell_index] = sidb_charge_state::POSITIVE; + for (uint64_t i = 0u; i < strg->pot_mat.size(); ++i) { - strg->local_pot[i] += - (this->get_potential_by_indices(i, strg->dependent_cell_index)) * charge_diff; + if (i != strg->dependent_cell_index) + { + strg->local_pot[i] += + (this->get_potential_by_indices(i, strg->dependent_cell_index)) * charge_diff; + } } } - strg->cell_charge[strg->dependent_cell_index] = sidb_charge_state::POSITIVE; } } diff --git a/test/algorithms/simulation/sidb/quickexact.cpp b/test/algorithms/simulation/sidb/quickexact.cpp index 41960fb74..afa379a4b 100644 --- a/test/algorithms/simulation/sidb/quickexact.cpp +++ b/test/algorithms/simulation/sidb/quickexact.cpp @@ -1405,3 +1405,33 @@ TEMPLATE_TEST_CASE( Catch::Matchers::WithinAbs(-5.0592576221, physical_constants::POP_STABILITY_ERR)); } } + +TEMPLATE_TEST_CASE( + "QuickExact simulation of two SiDBs placed directly next to each other with non-realistic relative permittivity", + "[quickexact]", (cell_level_layout>>), + (charge_distribution_surface>>>)) +{ + TestType lyt{}; + lyt.assign_cell_type({1, 3, 0}, TestType::cell_type::NORMAL); + lyt.assign_cell_type({2, 3, 0}, TestType::cell_type::NORMAL); + + SECTION("automatic base number detection is off") + { + const quickexact_params params{sidb_simulation_parameters{2, -0.32, 1.0e-3}, + quickexact_params::automatic_base_number_detection::OFF}; + + const auto simulation_results = quickexact(lyt, params); + + CHECK(simulation_results.charge_distributions.empty()); + } + + SECTION("automatic base number detection is on") + { + const quickexact_params params{sidb_simulation_parameters{2, -0.32, 1.0e-3}, + quickexact_params::automatic_base_number_detection::ON}; + + const auto simulation_results = quickexact(lyt, params); + + CHECK(simulation_results.charge_distributions.size() == 2); + } +} diff --git a/test/technology/charge_distribution_surface.cpp b/test/technology/charge_distribution_surface.cpp index 7bd5c77fb..f65da827e 100644 --- a/test/technology/charge_distribution_surface.cpp +++ b/test/technology/charge_distribution_surface.cpp @@ -1065,6 +1065,38 @@ TEMPLATE_TEST_CASE( } } + SECTION("dependent cell in alignment with the base number") + { + TestType lyt_new{{11, 11}}; + const sidb_simulation_parameters params{2, -0.32}; + + lyt_new.assign_cell_type({0, 1, 1}, TestType::cell_type::NORMAL); + lyt_new.assign_cell_type({0, 1, 0}, TestType::cell_type::NORMAL); + lyt_new.assign_cell_type({2, 1, 1}, TestType::cell_type::NORMAL); + + charge_distribution_surface charge_layout_new{lyt_new, params, sidb_charge_state::NEGATIVE}; + charge_layout_new.assign_dependent_cell({0, 1, 1}); + + charge_layout_new.assign_charge_state({0, 1, 1}, sidb_charge_state::NEGATIVE); + charge_layout_new.assign_charge_state({0, 1, 0}, sidb_charge_state::NEGATIVE); + charge_layout_new.assign_charge_state({2, 1, 1}, sidb_charge_state::NEGATIVE); + charge_layout_new.update_after_charge_change(); + + charge_layout_new.update_charge_state_of_dependent_cell(); + CHECK(charge_layout_new.get_charge_state({0, 1, 1}) == sidb_charge_state::NEGATIVE); + CHECK(charge_layout_new.get_charge_state({0, 1, 0}) == sidb_charge_state::NEGATIVE); + CHECK(charge_layout_new.get_charge_state({2, 1, 1}) == sidb_charge_state::NEGATIVE); + + charge_layout_new.assign_base_number(3); + charge_layout_new.assign_charge_state({0, 1, 1}, sidb_charge_state::NEGATIVE); + charge_layout_new.assign_charge_state({0, 1, 0}, sidb_charge_state::NEGATIVE); + charge_layout_new.assign_charge_state({2, 1, 1}, sidb_charge_state::NEGATIVE); + charge_layout_new.update_after_charge_change(dependent_cell_mode::VARIABLE); + CHECK(charge_layout_new.get_charge_state({0, 1, 1}) == sidb_charge_state::POSITIVE); + CHECK(charge_layout_new.get_charge_state({0, 1, 0}) == sidb_charge_state::NEGATIVE); + CHECK(charge_layout_new.get_charge_state({2, 1, 1}) == sidb_charge_state::NEGATIVE); + } + SECTION("adding dependent cell and compare local potential and system energy") { TestType lyt_new{{11, 11}};