Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🎨 added a new function get_chargeless_potential_between_sidbs #138

Merged
merged 8 commits into from
Mar 14, 2023
23 changes: 21 additions & 2 deletions include/fiction/technology/charge_distribution_surface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,25 @@ class charge_distribution_surface<Lyt, false> : public Lyt
return strg->dist_mat[index1][index2];
}
/**
* Calculates and returns the electrostatic potential between two cells.
* Calculates and returns the chargeless electrostatic potential between two cells.
*
marcelwa marked this conversation as resolved.
Show resolved Hide resolved
* @param c1 The first cell
* @param c2 The second cell
* @return The chargeless electrostatic potential between `c1` and `c2` (V_i,j / n_j).
*/
[[nodiscard]] double get_chargeless_potential_between_sidbs(const typename Lyt::cell& c1,
const typename Lyt::cell& c2) const noexcept
{
if (const auto index1 = cell_to_index(c1), index2 = cell_to_index(c2); (index1 != -1) && (index2 != -1))
{
return strg->pot_mat[static_cast<uint64_t>(index1)][static_cast<uint64_t>(index2)];
}

return 0;
}

/**
* Calculates and returns the electrostatic potential at one cell (c1) generated by another cell (c2).
marcelwa marked this conversation as resolved.
Show resolved Hide resolved
*
* @param c1 The first cell
* @param c2 The second cell
Expand All @@ -402,7 +420,8 @@ class charge_distribution_surface<Lyt, false> : public Lyt
{
if (const auto index1 = cell_to_index(c1), index2 = cell_to_index(c2); (index1 != -1) && (index2 != -1))
{
return strg->pot_mat[static_cast<uint64_t>(index1)][static_cast<uint64_t>(index2)];
return strg->pot_mat[static_cast<uint64_t>(index1)][static_cast<uint64_t>(index2)] *
charge_state_to_sign(get_charge_state(c2));
}

return 0;
Expand Down
61 changes: 50 additions & 11 deletions test/technology/charge_distribution_surface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

#include <catch2/catch_template_test_macros.hpp>

#include "catch2/matchers/catch_matchers_floating_point.hpp"
marcelwa marked this conversation as resolved.
Show resolved Hide resolved

#include <fiction/layouts/cartesian_layout.hpp>
#include <fiction/layouts/cell_level_layout.hpp>
#include <fiction/layouts/clocked_layout.hpp>
Expand Down Expand Up @@ -143,18 +145,18 @@ TEMPLATE_TEST_CASE(
// all SiDBs' charge states are set to neutral
charge_layout.set_all_charge_states(sidb_charge_state::NEUTRAL);
//
// // read SiDBs' charge states
// read SiDBs' charge states
CHECK(charge_layout.get_charge_state({5, 4}) == sidb_charge_state::NEUTRAL);
CHECK(charge_layout.get_charge_state({5, 5}) == sidb_charge_state::NEUTRAL);
CHECK(charge_layout.get_charge_state({5, 6}) == sidb_charge_state::NEUTRAL);
CHECK(charge_layout.get_charge_state({5, 1}) == sidb_charge_state::NONE);
//
charge_layout.set_all_charge_states(sidb_charge_state::NEUTRAL);
//
// // all SiDBs' charge states are set to negative
// all SiDBs' charge states are set to negative
charge_layout.set_all_charge_states(sidb_charge_state::NEGATIVE);
//
// // read SiDBs' charge states
// read SiDBs' charge states
CHECK(charge_layout.get_charge_state({5, 4}) == sidb_charge_state::NEGATIVE);
CHECK(charge_layout.get_charge_state({5, 5}) == sidb_charge_state::NEGATIVE);
CHECK(charge_layout.get_charge_state({5, 6}) == sidb_charge_state::NEGATIVE);
Expand Down Expand Up @@ -207,15 +209,15 @@ TEMPLATE_TEST_CASE(
lyt.assign_cell_type({1, 10, 1}, TestType::cell_type::NORMAL);
charge_distribution_surface charge_layout{lyt, sidb_simulation_parameters{}};

CHECK(charge_layout.get_potential_between_sidbs({0, 0, 0}, {0, 0, 0}) == 0.0);
CHECK(charge_layout.get_potential_between_sidbs({1, 8, 0}, {1, 8, 0}) == 0.0);
CHECK(charge_layout.get_potential_between_sidbs({1, 10, 1}, {1, 10, 1}) == 0.0);
CHECK((charge_layout.get_potential_between_sidbs({1, 8, 0}, {0, 0, 0}) - 0.0121934043) < 0.00000001);
CHECK(std::abs(charge_layout.get_potential_between_sidbs({0, 0, 0}, {1, 10, 1}) -
charge_layout.get_potential_between_sidbs({1, 10, 1}, {0, 0, 0})) <
CHECK(charge_layout.get_chargeless_potential_between_sidbs({0, 0, 0}, {0, 0, 0}) == 0.0);
CHECK(charge_layout.get_chargeless_potential_between_sidbs({1, 8, 0}, {1, 8, 0}) == 0.0);
CHECK(charge_layout.get_chargeless_potential_between_sidbs({1, 10, 1}, {1, 10, 1}) == 0.0);
CHECK((charge_layout.get_chargeless_potential_between_sidbs({1, 8, 0}, {0, 0, 0}) - 0.0121934043) < 0.00000001);
CHECK(std::abs(charge_layout.get_chargeless_potential_between_sidbs({0, 0, 0}, {1, 10, 1}) -
charge_layout.get_chargeless_potential_between_sidbs({1, 10, 1}, {0, 0, 0})) <
physical_constants::POP_STABILITY_ERR);
CHECK(charge_layout.get_potential_between_sidbs({0, 0, 0}, {1, 8, 0}) >
charge_layout.get_potential_between_sidbs({1, 10, 1}, {0, 0, 0}));
CHECK(charge_layout.get_chargeless_potential_between_sidbs({0, 0, 0}, {1, 8, 0}) >
charge_layout.get_chargeless_potential_between_sidbs({1, 10, 1}, {0, 0, 0}));
}
//
SECTION("Local Potential")
Expand Down Expand Up @@ -372,4 +374,41 @@ TEMPLATE_TEST_CASE(
charge_layout_new.increase_charge_index_by_one();
CHECK(charge_layout_new.get_charge_index().first == 15);
}

SECTION("using chargeless and normal potential function")
{
TestType lyt_new{{11, 11}};
const sidb_simulation_parameters params{3, -0.32, 5.0 * 1E-9, 3.84 * 1E-10, 7.68 * 1E-10, 2.25 * 1E-10};

lyt_new.assign_cell_type({0, 0, 1}, TestType::cell_type::NORMAL);
lyt_new.assign_cell_type({1, 3, 0}, TestType::cell_type::NORMAL);
lyt_new.assign_cell_type({10, 5, 1}, TestType::cell_type::NORMAL);

charge_distribution_surface charge_layout_new{lyt_new, params};

charge_layout_new.assign_charge_state({0, 0, 1}, sidb_charge_state::NEGATIVE);
charge_layout_new.assign_charge_state({1, 3, 0}, sidb_charge_state::POSITIVE);
charge_layout_new.assign_charge_state({10, 5, 1}, sidb_charge_state::NEUTRAL);

CHECK(charge_layout_new.get_charge_state({0, 0, 1}) == sidb_charge_state::NEGATIVE);
CHECK(charge_layout_new.get_charge_state({1, 3, 0}) == sidb_charge_state::POSITIVE);
CHECK(charge_layout_new.get_charge_state({10, 5, 1}) == sidb_charge_state::NEUTRAL);

CHECK(charge_layout_new.get_chargeless_potential_between_sidbs({0, 0, 1}, {1, 3, 0}) > 0);
CHECK(charge_layout_new.get_potential_between_sidbs({0, 0, 1}, {1, 3, 0}) > 0);

CHECK(charge_layout_new.get_chargeless_potential_between_sidbs({0, 0, 1}, {10, 5, 1}) > 0);
CHECK(charge_layout_new.get_potential_between_sidbs({0, 0, 1}, {10, 5, 1}) == 0.0);

CHECK(charge_layout_new.get_chargeless_potential_between_sidbs({10, 5, 1}, {0, 0, 1}) > 0);
CHECK(charge_layout_new.get_potential_between_sidbs({10, 5, 1}, {0, 0, 1}) < 0);

CHECK_THAT(charge_layout_new.get_potential_between_sidbs({10, 5, 1}, {0, 0, 1}) +
charge_layout_new.get_chargeless_potential_between_sidbs({10, 5, 1}, {0, 0, 1}),
Catch::Matchers::WithinAbs(0.000000, 0.000001));

CHECK_THAT(charge_layout_new.get_potential_between_sidbs({0, 0, 1}, {1, 3, 0}) -
charge_layout_new.get_chargeless_potential_between_sidbs({0, 0, 1}, {1, 3, 0}),
Catch::Matchers::WithinAbs(0.000000, 0.000001));
}
}