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

🎨 support cds as input for all simulators #310

Merged
merged 14 commits into from
Oct 12, 2023
1 change: 1 addition & 0 deletions docs/algorithms/sidb_simulation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Exhaustive Ground State Simulation

**Header:** ``fiction/algorithms/simulation/sidb/quickexact.hpp``

.. doxygenenum:: fiction::required_simulation_base_number
.. doxygenstruct:: fiction::quickexact_params
:members:
.. doxygenfunction:: fiction::quickexact
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ template <typename Lyt>
// The charge layout is initialized with negatively charged SiDBs. Therefore, the local electrostatic potentials are
// maximal. In this extreme case, if the banding is not sufficient for any SiDB to be positively charged, it will
// not be for any other charge distribution. Therefore, no positively charged SiDBs can occur.
const charge_distribution_surface charge_lyt{lyt, sim_params, sidb_charge_state::NEGATIVE};
charge_distribution_surface<Lyt> charge_lyt{lyt};
charge_lyt.assign_physical_parameters(sim_params);
charge_lyt.assign_all_charge_states(sidb_charge_state::NEGATIVE);

charge_lyt.foreach_cell(
[&result, &mu_plus, charge_lyt](const auto& c) noexcept
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ exhaustive_ground_state_simulation(const Lyt& lyt,
{
const mockturtle::stopwatch stop{time_counter};

charge_distribution_surface charge_lyt{lyt};
charge_distribution_surface<Lyt> charge_lyt{lyt};

charge_lyt.assign_physical_parameters(params);
charge_lyt.assign_all_charge_states(sidb_charge_state::NEGATIVE);
Expand Down
162 changes: 110 additions & 52 deletions include/fiction/algorithms/simulation/sidb/quickexact.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,20 @@

namespace fiction
{
/**
* Base number required for the correct physical simulation.
*/
enum class required_simulation_base_number
{
/**
* Three state simulation (i.e., negative, neutral, and positive) is required.
*/
THREE,
/**
* Two state simulation (i.e., negative and neutral) is sufficient.
*/
TWO
};
/**
* This struct stores the parameters for the *QuickExact* algorithm.
*/
Expand Down Expand Up @@ -73,9 +87,12 @@ class quickexact_impl
public:
quickexact_impl(const Lyt& lyt, const quickexact_params<Lyt>& parameter) :
layout{lyt},
charge_lyt{lyt, parameter.physical_parameters, sidb_charge_state::NEGATIVE},
charge_lyt{lyt},
params{parameter}
{}
{
charge_lyt.assign_all_charge_states(sidb_charge_state::NEGATIVE);
charge_lyt.assign_physical_parameters(parameter.physical_parameters);
}

sidb_simulation_result<Lyt> run() noexcept
{
Expand All @@ -89,11 +106,18 @@ class quickexact_impl
initialize_charge_layout();

// Determine if three state simulation (i.e., positively charged SiDBs can occur) is required.
const bool three_state_simulation_required =
(params.base_number_detection == quickexact_params<Lyt>::automatic_base_number_detection::ON &&
required_simulation_base_number base_number{};
if ((params.base_number_detection == quickexact_params<Lyt>::automatic_base_number_detection::ON &&
charge_lyt.is_three_state_simulation_required()) ||
(params.base_number_detection == quickexact_params<Lyt>::automatic_base_number_detection::OFF &&
params.physical_parameters.base == 3);
params.physical_parameters.base == 3))
{
base_number = required_simulation_base_number::THREE;
}
else
{
base_number = required_simulation_base_number::TWO;
}
Drewniok marked this conversation as resolved.
Show resolved Hide resolved

// If layout has at least two SiDBs, all SiDBs that have to be negatively charged are erased from the
// layout.
Expand All @@ -104,54 +128,15 @@ class quickexact_impl
// If the layout consists of SiDBs that do not need to be negatively charged.
if (!all_sidbs_in_lyt_without_negative_preassigned_ones.empty())
{
// The first cell from all_sidbs_in_lyt_without_negative_preassigned_ones is chosen as the
// dependent-cell to initialize the layout (pre-assigned negatively charged SiDBs were erased with
// generate_layout_without_negative_sidbs). All SiDBs are set to neutrally charged.
charge_distribution_surface charge_lyt_with_assigned_dependent_cell{
layout, params.physical_parameters, sidb_charge_state::NEUTRAL,
all_sidbs_in_lyt_without_negative_preassigned_ones[0]};

charge_lyt_with_assigned_dependent_cell.assign_local_external_potential(
params.local_external_potential);
charge_lyt_with_assigned_dependent_cell.assign_global_external_potential(params.global_potential);

if constexpr (has_get_sidb_defect_v<Lyt>)
{
for (const auto& [cell, defect] : real_placed_defects)
{
charge_lyt_with_assigned_dependent_cell.add_sidb_defect_to_potential_landscape(cell,
defect);
}
charge_distribution_surface charge_layout{static_cast<sidb_defect_cell_clk_lyt_siqad>(layout)};
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
conduct_simulation(charge_layout, base_number);
}

// IMPORTANT: The pre-assigned negatively charged SiDBs (they have to be negatively charged to
// fulfill the population stability) are considered as negatively charged defects in the layout.
// Hence, there are no "real" defects assigned, but in order to set some SiDBs with a fixed negative
// charge, this way of implementation is chosen.
for (const auto& cell : preassigned_negative_sidbs)
{
charge_lyt_with_assigned_dependent_cell.add_sidb_defect_to_potential_landscape(
cell, sidb_defect{sidb_defect_type::UNKNOWN, -1,
charge_lyt_with_assigned_dependent_cell.get_phys_params().epsilon_r,
charge_lyt_with_assigned_dependent_cell.get_phys_params().lambda_tf});
}

// Update all local potentials, system energy and physically validity. The Flag is set to "Variable"
// to allow dependent cell to change its charge state based on the N-1 SiDBs to fulfill the local
// population stability in its position.
charge_lyt_with_assigned_dependent_cell.update_after_charge_change(dependent_cell_mode::VARIABLE);

// If no positively charged SiDB can occur in the layout.
if (!three_state_simulation_required)
{
result.additional_simulation_parameters.emplace_back("base_number", uint64_t{2});
two_state_simulation(charge_lyt_with_assigned_dependent_cell);
}
// If positively charged SiDBs can occur in the layout, 3-state simulation is conducted.
else
{
result.additional_simulation_parameters.emplace_back("base_number", uint64_t{3});
three_state_simulation(charge_lyt_with_assigned_dependent_cell);
charge_distribution_surface charge_layout{static_cast<sidb_cell_clk_lyt_siqad>(layout)};
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
conduct_simulation(charge_layout, base_number);
}
}

Expand All @@ -174,7 +159,7 @@ class quickexact_impl
// to external potentials or defects.
else if (number_of_sidbs == 1)
{
if (three_state_simulation_required)
if (base_number == required_simulation_base_number::THREE)
{
charge_lyt.assign_base_number(3);
}
Expand Down Expand Up @@ -268,14 +253,80 @@ class quickexact_impl
* Simulation results.
*/
sidb_simulation_result<Lyt> result{};
/**
* This function initializes the charge layout with necessary parameters, and conducts
* the physical simulation based on whether a three-state simulation is required.
*
* @tparam ChargeLyt The type of Charge Layout.
* @tparam ChargeLyt The type representing the charge layout to simulate.
* @param base_number `THREE` if a three-state simulation is required, `TWO` otherwise.
*/
template <typename ChargeLyt>
void conduct_simulation(ChargeLyt& charge_layout, const required_simulation_base_number base_number) noexcept
{
static_assert(is_cell_level_layout_v<ChargeLyt>, "ChargeLyt is not a cell-level layout");
static_assert(has_sidb_technology_v<ChargeLyt>, "ChargeLyt is not an SiDB layout");
static_assert(has_siqad_coord_v<ChargeLyt>, "ChargeLyt is not based on SiQAD coordinates");
static_assert(is_charge_distribution_surface_v<ChargeLyt>, "ChargeLyt is not a charge distribution surface");

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]);

charge_layout.assign_local_external_potential(params.local_external_potential);
charge_layout.assign_global_external_potential(params.global_potential);

// IMPORTANT: The pre-assigned negatively charged SiDBs (they have to be negatively charged to
// fulfill the population stability) are considered as negatively charged defects in the layout.
// Hence, there are no "real" defects assigned, but in order to set some SiDBs with a fixed
// negative charge, this way of implementation is chosen.
for (const auto& cell : preassigned_negative_sidbs)
{
charge_layout.add_sidb_defect_to_potential_landscape(
cell, sidb_defect{sidb_defect_type::UNKNOWN, -1, charge_layout.get_phys_params().epsilon_r,
charge_layout.get_phys_params().lambda_tf});
}

// Update all local potentials, system energy, and physical validity. The flag is set to
// `VARIABLE` to allow the dependent cell to change its charge state based on the N-1 SiDBs to
// fulfill the local population stability at its position.
charge_layout.update_after_charge_change(dependent_cell_mode::VARIABLE);

if constexpr (has_get_sidb_defect_v<Lyt>)
{
for (const auto& [cell, defect] : real_placed_defects)
{
charge_layout.add_sidb_defect_to_potential_landscape(cell, defect);
}
}

if (base_number == required_simulation_base_number::TWO)
{
result.additional_simulation_parameters.emplace_back("base_number", uint64_t{2});
two_state_simulation(charge_layout);
}
// If positively charged SiDBs can occur in the layout, 3-state simulation is conducted.
else
{
result.additional_simulation_parameters.emplace_back("base_number", uint64_t{3});
three_state_simulation(charge_layout);
}
}

/**
* This function conducts 2-state physical simulation (negative, neutral).
*
* @tparam ChargeLyt Type of the charge distribution surface.
* @param charge_layout Initialized charge layout.
*/
void two_state_simulation(charge_distribution_surface<Lyt>& charge_layout) noexcept
template <typename ChargeLyt>
void two_state_simulation(ChargeLyt& charge_layout) noexcept
{
static_assert(is_cell_level_layout_v<ChargeLyt>, "ChargeLyt is not a cell-level layout");
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
static_assert(has_sidb_technology_v<ChargeLyt>, "ChargeLyt is not an SiDB layout");
static_assert(has_siqad_coord_v<ChargeLyt>, "ChargeLyt is not based on SiQAD coordinates");
static_assert(is_charge_distribution_surface_v<ChargeLyt>, "ChargeLyt is not a charge distribution surface");

charge_layout.assign_base_number(2);
uint64_t previous_charge_index = 0;

Expand Down Expand Up @@ -320,10 +371,17 @@ class quickexact_impl
/**
* This function conducts 3-state physical simulation (negative, neutral, positive).
*
* @tparam ChargeLyt Type of the charge distribution surface.
* @param charge_layout Initialized charge layout.
*/
void three_state_simulation(charge_distribution_surface<Lyt>& charge_layout) noexcept
template <typename ChargeLyt>
void three_state_simulation(ChargeLyt& charge_layout) noexcept
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
{
static_assert(is_cell_level_layout_v<ChargeLyt>, "ChargeLyt is not a cell-level layout");
static_assert(has_sidb_technology_v<ChargeLyt>, "ChargeLyt is not an SiDB layout");
static_assert(has_siqad_coord_v<ChargeLyt>, "ChargeLyt is not based on SiQAD coordinates");
static_assert(is_charge_distribution_surface_v<ChargeLyt>, "ChargeLyt is not a charge distribution surface");

charge_layout.assign_all_charge_states(sidb_charge_state::NEGATIVE);
charge_layout.update_after_charge_change();
// Not executed to detect if 3-state simulation is required, but to detect the SiDBs that could be positively
Expand Down Expand Up @@ -466,7 +524,6 @@ class quickexact_impl
* - It assigns the local external potential from the `params.local_external_potential` configuration to the charge
* layout.
* - It assigns the global external potential from `params.global_potential` to the charge layout.
*
*/
void initialize_charge_layout() noexcept
{
Expand Down Expand Up @@ -496,6 +553,7 @@ class quickexact_impl
number_of_sidbs = charge_lyt.num_cells();
}
/**
*
* This function is used to generate a layout without the SiDBs that are pre-assigned to be negatively charged in a
* physically-valid layout.
*/
Expand Down
2 changes: 1 addition & 1 deletion include/fiction/algorithms/simulation/sidb/quicksim.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ sidb_simulation_result<Lyt> quicksim(const Lyt& lyt, const quicksim_params& ps =
{
const mockturtle::stopwatch stop{time_counter};

charge_distribution_surface charge_lyt{lyt};
charge_distribution_surface<Lyt> charge_lyt{lyt};

// set the given physical parameters
charge_lyt.assign_physical_parameters(ps.phys_params);
Expand Down
Loading
Loading