Physical Simulation of SiDBs

These headers provide auxiliary functionality for the physical simulation of SiDBs layouts.

SiDB Charge States

Possible charge states of SiDBs.

Header: fiction/technology/sidb_charge_state.hpp

enum class fiction::sidb_charge_state : int8_t

Charge states of SiDBs.

Values:

enumerator NEGATIVE
enumerator NEUTRAL
enumerator POSITIVE
enumerator NONE
static const std::vector<sidb_charge_state> fiction::SIDB_CHARGE_STATES_BASE_2{sidb_charge_state::NEGATIVE, sidb_charge_state::NEUTRAL}

Charge states of SiDBs for the context of base 2 simulation.

static const std::vector<sidb_charge_state> fiction::SIDB_CHARGE_STATES_BASE_3{sidb_charge_state::NEGATIVE, sidb_charge_state::NEUTRAL, sidb_charge_state::POSITIVE}

Charge states of SiDBs for the context of base-3 (full base) simulation.

inline std::vector<sidb_charge_state> fiction::sidb_charge_states_for_base_number(const uint8_t base) noexcept

Charge states of SiDBs for a given simulation base number. The full base states are returned for an invalid simulation base.

Parameters:

base – The simulation base number to get the associated SiDB charge states for.

Returns:

NEG, NEUT, POS for base 3 (full base), and NEG, NEUT otherwise, associated with base 2 simulation.

inline constexpr int8_t fiction::charge_state_to_sign(const sidb_charge_state &cs) noexcept

Converts the charge state into an integer (-1, 0, 1).

Parameters:

cs – SiDB charge state.

Returns:

Integer representing the SiDB’s charge state.

inline constexpr sidb_charge_state fiction::sign_to_charge_state(const int8_t sg) noexcept

Converts an integer (-1, 0, 1) into a charge state.

Parameters:

sg – Integer (-1, 0, 1) representing a charge state.

Returns:

sidb_charge_state representation of sg.

inline std::string fiction::charge_configuration_to_string(const std::vector<sidb_charge_state> &charge_distribution) noexcept

Converts a vector of charge states to a string representation ("-101...").

Parameters:

charge_distribution – A vector of SiDBs charge states.

Returns:

A string representation of the charge states.

SiDB Charge Distribution Surface

The charge distribution surface can be layered on top of any SiDB layout to add representation of possible charge distributions of the SiDBs. Charge distribution surfaces are returned by the SiDB physical simulation algorithms.

Header: fiction/technology/charge_distribution_surface.hpp

enum class fiction::dependent_cell_mode : uint8_t

An enumeration of modes for the dependent cell.

Values:

enumerator FIXED

The charge state of the dependent cell is not changed based on the local electrostatic potential at its position.

enumerator VARIABLE

The charge state of the dependent cell is changed based on the local electrostatic potential at its position.

enum class fiction::energy_calculation : uint8_t

An enumeration of modes for calculation of the electrostatic potential energy of a given charge distribution.

Values:

enumerator KEEP_OLD_ENERGY_VALUE

The electrostatic potential energy of a given charge distribution is not updated after it is changed.

enumerator UPDATE_ENERGY

The electrostatic potential energy of a given charge distribution is updated after it is changed.

enum class fiction::charge_distribution_history : uint8_t

An enumeration of modes to decide if the previous charge distribution is used to simply the computation of the properties of a new charge distribution.

Values:

enumerator CONSIDER

The previous charge distribution is used.

enumerator NEGLECT

The previous charge distribution is not used. Hence, the local electrostatic potential of the given charge distribution is calculated from scratch.

enum class fiction::charge_index_recomputation : uint8_t

An enumeration of modes to specifying if the charge index should be recomputed fully.

Values:

enumerator FROM_SCRATCH

The charge index is recomputed from scratch.

enumerator IGNORE_LEADING_ZEROES

The charge index is recomputed with the leading zeroes ignored. This optimization can be applied if we know that the charge index was incremented after the last charge index computation.

enum class fiction::charge_distribution_mode : uint8_t

An enumeration of modes for handling the charge distribution when assigning a charge index to the charge distribution surface.

Values:

enumerator UPDATE_CHARGE_DISTRIBUTION

The charge distribution is updated after the charge index is assigned to the charge distribution surface.

enumerator KEEP_CHARGE_DISTRIBUTION

The charge distribution is kept and is not updated after a charge index is assigned to the charge distribution surface.

enum class fiction::charge_index_mode : uint8_t

An enumeration of modes for handling the charge index during charge state assignment.

Values:

enumerator UPDATE_CHARGE_INDEX

The charge state is assigned to the cell and the charge index is updated.

enumerator KEEP_CHARGE_INDEX

The charge state is assigned to the cell but the old charge index is kept.

template<typename Lyt, bool has_charge_distribution_interface = std::conjunction_v<has_assign_charge_state<Lyt>, has_get_charge_state<Lyt>>>
class charge_distribution_surface : public Lyt

A layout type to layer on top of any SiDB cell-level layout. It implements an interface to store and access SiDBs’ charge states.

Template Parameters:
  • Lyt – SiDB cell-level layout type.

  • has_charge_distribution_interface – Automatically determines whether a charge distribution interface is already present.

template<typename Lyt>
class charge_distribution_surface<Lyt, true> : public Lyt
template<typename Lyt>
class charge_distribution_surface<Lyt, false> : public Lyt

Public Functions

inline explicit charge_distribution_surface(const sidb_simulation_parameters &params = sidb_simulation_parameters{}, const sidb_charge_state cs = sidb_charge_state::NEGATIVE)

Standard constructor for empty layouts.

Parameters:
  • params – Physical parameters used for the simulation (µ_minus, base number, …).

  • cs – The charge state used for the initialization of all SiDBs, default is a negative charge.

inline explicit charge_distribution_surface(const Lyt &lyt, const sidb_simulation_parameters &params = sidb_simulation_parameters{}, const sidb_charge_state cs = sidb_charge_state::NEGATIVE, const cds_configuration configuration = cds_configuration::CHARGE_LOCATION_AND_ELECTROSTATIC)

Standard constructor for existing layouts.

Parameters:
  • lyt – SiDB cell-level layout.

  • params – Physical parameters used for the simulation (µ_minus, base number, …).

  • cs – The charge state used for the initialization of all SiDBs, default is a negative charge.

  • configuration – Specifies the configuration for charge distribution settings. Determines whether only charge locations are considered or if both charge locations and electrostatic interactions are included.

inline charge_distribution_surface(const charge_distribution_surface<Lyt> &cds)

Copy constructor.

Parameters:

cds – Other charge_distribution_surface.

inline charge_distribution_surface &operator=(const charge_distribution_surface &other)

Copy assignment operator.

Parameters:

othercharge_distribution_surface.

inline charge_distribution_surface clone() const noexcept

Clones the current charge distribution surface and returns a deep copy.

Returns:

A deep copy of the current charge_distribution_surface, preserving all its properties.

inline std::vector<std::pair<double, double>> get_all_sidb_locations_in_nm() const noexcept

This function returns the locations of all SiDBs in nm of the form (x,y).

Returns:

Vector of SiDB nanometer positions (unit: nm).

inline void assign_cell_type(const typename Lyt::cell &c, const typename Lyt::cell_type &ct) noexcept

This function assigns a cell type to a given cell of the underlying cell-level layout.

Parameters:
  • c – Cell whose type is changed.

  • ct – Cell type which is assigned to the given cell.

inline void assign_physical_parameters(const sidb_simulation_parameters &params) noexcept

This function assigns the physical parameters for the simulation.

Parameters:

params – Physical parameters to be assigned.

inline sidb_simulation_parameters get_simulation_params() const noexcept

This function retrieves the physical parameters of the simulation.

Returns:

sidb_simulation_parameters struct containing the physical parameters of the simulation.

inline bool charge_exists(const sidb_charge_state cs) const noexcept

This function checks if any SiDB exhibits the given charge state.

Parameters:

cs – Charge state.

inline int64_t cell_to_index(const typename Lyt::cell &c) const noexcept

This function searches the index of an SiDB.

Parameters:

c – The cell to find the index of.

Returns:

The index of the cell in the layout. Returns -1 if the cell is not part of the layout.

inline void assign_charge_state(const typename Lyt::cell &c, const sidb_charge_state cs, const charge_index_mode index_mode = charge_index_mode::UPDATE_CHARGE_INDEX) noexcept

This function assigns the given charge state to the given cell of the layout.

Parameters:
  • c – The cell to which a charge state is to be assigned.

  • cs – The charge state to be assigned to the cell.

  • index_mode – Mode to determine whether the charge index should be updated.

inline void assign_charge_by_cell_index(const uint64_t index, const sidb_charge_state cs) noexcept

This function assigns the given charge state to the cell of the layout at the specified index. It updates the cell_charge member of strg object with the new charge state of the specified cell.

Parameters:
  • index – The index of the cell.

  • cs – The charge state to be assign to the cell.

inline void assign_all_charge_states(const sidb_charge_state cs, const charge_index_mode index_mode = charge_index_mode::UPDATE_CHARGE_INDEX) noexcept

This function assigns the charge state of all SiDBs in the layout to a given charge state.

Parameters:
  • cs – The charge state to be assigned to all the SiDBs.

  • index_mode – Mode to determine whether the charge index should be updated.

inline void assign_dependent_cell(const typename Lyt::cell &c) noexcept

This function assigns the dependent cell (i.e., cell which charge state is set based on the neighbor cells and the population stability).

Note

c has to be part of the initialized charge distribution surface layout.

Parameters:

c – cell which is set as the dependent cell.

inline void assign_base_number(const uint8_t base) noexcept

This function assigns the base number for the simulation.

Parameters:

base – Base number to be assigned.

inline void add_sidb_defect_to_potential_landscape(const typename Lyt::cell &c, const sidb_defect &defect) noexcept

This function adds a defect to the layout.

Parameters:
  • c – The cell to which a defect is added.

  • defect – Defect which is added to the layout.

inline void erase_defect(const typename Lyt::cell &c) noexcept

This function erases a defect to the layout.

Parameters:

c – The cell where a defect is erased.

inline void assign_charge_state_by_index(const uint64_t index, const sidb_charge_state cs, const charge_index_mode index_mode = charge_index_mode::UPDATE_CHARGE_INDEX) noexcept

This function assigns the given charge state to the cell (accessed by index) of the layout.

Parameters:
  • index – The index of the cell to which a charge state is to be assigned.

  • cs – The charge state to be assigned to the cell.

  • index_mode – Mode to determine whether the charge index should be updated.

inline sidb_charge_state get_charge_state(const typename Lyt::cell &c) const noexcept

This function returns the charge state of a given cell.

Parameters:

c – The cell.

Returns:

The charge state of the given cell.

inline sidb_charge_state get_charge_state_by_index(const uint64_t index) const noexcept

This function returns the charge state of a cell of the layout at a given index.

Parameters:

index – The index of the cell.

Returns:

The charge state of the cell at the given index.

inline std::vector<sidb_charge_state> get_all_sidb_charges() const noexcept

This function returns all SiDB charges of the placed SiDBs as a vector.

Returns:

Vector of SiDB charge states.

inline std::vector<uint64_t> negative_sidb_detection() const noexcept

This function can be used to detect which SiDBs must be negatively charged due to their location. Important: This function must be applied to a charge layout where all SiDBs are negatively initialized.

Returns:

Vector of SiDB indices that must be negatively charged to fulfill the population stability.

inline double get_nm_distance_between_sidbs(const typename Lyt::cell &c1, const typename Lyt::cell &c2) const noexcept

This function returns the distance between two cells in nanometer (unit: nm).

Parameters:
  • c1 – the first cell to compare.

  • c2 – the second cell to compare.

Returns:

a constexpr double representing the distance in nm between the two cells.

inline double get_nm_distance_by_indices(const uint64_t index1, const uint64_t index2) const noexcept

This function calculates and returns the distance between two cells in nanometer (accessed by indices) (unit: nm).

Parameters:
  • index1 – The first index.

  • index2 – The second index.

Returns:

The distance in nanometer between index1 and index2 (indices correspond to unique SiDBs) (unit: nm).

inline double calculate_chargeless_potential_between_sidbs_by_index(const uint64_t index1, const uint64_t index2) const noexcept

This function calculates and returns the chargeless electrostatic potential between two cells (SiDBs) in Volt (unit: V).

Parameters:
  • index1 – The first index.

  • index1 – The second index.

Returns:

The chargeless electrostatic potential between index1 and index2 (unit: V).

inline double calculate_chargeless_potential_between_sidbs(const typename Lyt::cell &c1, const typename Lyt::cell &c2) const noexcept

This function calculates and returns the chargeless potential in Volt of a pair of cells based on their distance and simulation parameters (unit: V).

Parameters:
  • c1 – The first cell.

  • c2 – The second cell.

Returns:

The potential between c1 and c2 (unit: V).

inline double get_chargeless_potential_between_sidbs(const typename Lyt::cell &c1, const typename Lyt::cell &c2) const noexcept

This function returns the chargeless electrostatic potential between two cells in V (unit: V).

Note

If the signed electrostatic potential \(V_{i,j}\) is required, use the get_potential_between_sidbs function.

Parameters:
  • c1 – The first cell.

  • c2 – The second cell.

Returns:

The chargeless electrostatic potential between c1 and c2, i.e, \(\frac{V_{i,j}}{n_j}\) (unit: V).

inline double get_chargeless_potential_by_indices(const uint64_t index1, const uint64_t index2) const noexcept

This function calculates and returns the chargeless potential of two indices (representing two SiDBs) in Volt.

Parameters:
  • index1 – The first index.

  • index2 – The second index.

Returns:

The potential between index1 and index2.

inline double get_potential_between_sidbs(const typename Lyt::cell &c1, const typename Lyt::cell &c2) const noexcept

This function calculates and returns the electrostatic potential at one cell (c1) generated by another cell (c2) in Volt (unit: V).

Note

If the chargeless electrostatic potential \(\frac{V_{i,j}}{n_j}\) is required, use the get_chargeless_potential_between_sidbs function.

Parameters:
  • c1 – The first cell.

  • c2 – The second cell.

Returns:

The electrostatic potential between c1 and c2, i.e., \(V_{i,j}\) (unit: V).

inline void update_local_potential(const charge_distribution_history history_mode = charge_distribution_history::NEGLECT) noexcept

This function calculates the local electrostatic potential in Volt for each SiDB position, including external electrostatic potentials (generated by electrodes, defects, etc.) (unit: V).

Parameters:

history_modecharge_distribution_history::NEGLECT if the information (local electrostatic energy) of the previous charge distribution is used to make the update more efficient, charge_distribution_history::CONSIDER otherwise.

inline std::optional<double> get_local_potential(const typename Lyt::cell &c) const noexcept

The function returns the local electrostatic potential at a given SiDB position in V.

Parameters:

c – The cell defining the SiDB position.

Returns:

Local potential at given cell position. If there is no SiDB at the given cell, std::nullopt is returned (unit: V).

inline std::optional<double> get_local_potential_by_index(const uint64_t index) const noexcept

This function returns the local electrostatic potential at a given index position in Volt (unit: V).

Parameters:

index – The index defining the SiDB position.

Returns:

local potential at given index position. If there is no SiDB at the given index (which corresponds to a unique cell), std::nullopt is returned (unit: V).

inline void assign_local_potential_by_index(const uint64_t index, const double loc_pot) noexcept

This function allows the local electrostatic potential for some given index position to be set externally.

Parameters:
  • index – The index defining the SiDB position.

  • loc_pot – The local electrostatic potential to assign to the given index position (unit: V).

inline void assign_system_energy_to_zero() noexcept

This function assign the electrostatic system energy to zero (unit: eV). It can be used if only one SiDB is charged.

inline void recompute_system_energy() noexcept

This function calculates the system’s total electrostatic potential energy and stores it in the storage (unit: eV).

inline double get_electrostatic_potential_energy() const noexcept

This function returns the currently stored system’s total electrostatic potential energy in eV.

Returns:

The system’s total electrostatic potential energy (unit: eV).

inline void update_after_charge_change(const dependent_cell_mode dep_cell = dependent_cell_mode::FIXED, const energy_calculation energy_calculation_mode = energy_calculation::UPDATE_ENERGY, const charge_distribution_history history_mode = charge_distribution_history::NEGLECT) noexcept

The function updates the local potential (unit: Volt) and the system energy (unit: eV) after a charge change.

Parameters:
inline bool is_configuration_stable() const noexcept

The configuration stability of the current charge distribution is evaluated. It is performed as the last check towards a judgement of physical validity of the present charge distribution layout.

Returns:

true if and only if the present charge distribution layout is deemed to be configuration stable.

inline void validity_check() noexcept

The physical validity of the current charge distribution is evaluated and stored in the storage struct. A charge distribution is valid if the Population Stability and the Configuration Stability is fulfilled.

inline bool is_physically_valid() const noexcept

This function returns the currently stored validity of the present charge distribution layout.

Returns:

The validity of the present charge distribution.

inline void declare_physically_valid() noexcept

This function declares present charge distribution layout as physically valid by external judgement.

inline void charge_distribution_to_index_general() const noexcept

The charge distribution of the charge distribution surface is converted to a unique index. It is used to map every possible charge distribution of an SiDB layout to a unique index.

IMPORTANT: This function can be used whenever a charge distribution needs to be converted to a charge index. However, this function is not optimized compared to charge_distribution_to_index.

inline void charge_distribution_to_index() const noexcept

The charge distribution of the charge distribution surface is converted to a unique index. It is used to map every possible charge distribution of an SiDB layout to a unique index.

inline charge_index_base get_charge_index_and_base() const noexcept

The charge index of the current charge distribution is returned.

Returns:

A pair with the charge index and the used base.

inline void increase_charge_index_by_one(const dependent_cell_mode dep_cell = dependent_cell_mode::FIXED, const energy_calculation energy_calculation_mode = energy_calculation::UPDATE_ENERGY, const charge_distribution_history history_mode = charge_distribution_history::NEGLECT, const exact_sidb_simulation_engine engine = exact_sidb_simulation_engine::EXGS) noexcept

The charge index is increased by one, but only if it is less than the maximum charge index for the given layout. If that’s the case, it is increased by one and afterward, the charge configuration is updated by invoking the index_to_charge_distribution() function.

Parameters:
inline uint64_t get_max_charge_index() const noexcept

This function returns the maximum index of the cell-level layout.

Returns:

The maximal possible charge distribution index.

inline void assign_charge_index(const uint64_t charge_index, const charge_distribution_mode cdc = charge_distribution_mode::UPDATE_CHARGE_DISTRIBUTION) noexcept

Assigns a given charge index to the charge distribution layout. Charge distribution is updated according to the set charge index.

Parameters:
  • charge_index – charge index of the new charge distribution.

  • cdc – Setting to determine if the charge distribution should be updated after the charge index is assigned.

inline void adjacent_search(const double alpha, std::vector<uint64_t> &negative_indices) noexcept

This function is used for the QuickSim algorithm (see quicksim.hpp). It gets a vector with indices representing negatively charged SiDBs as input. Afterward, a distant and a neutrally charged SiDB is localized using a min-max diversity algorithm. This selected SiDB is set to “negative” and the index is added to the input vector such that the next iteration works correctly.

Parameters:
  • alpha – A parameter for the algorithm (default: 0.7).

  • negative_indices – Vector of SiDBs indices that are already negatively charged (double occupied).

inline void assign_global_external_potential(const double potential_value, dependent_cell_mode dep_cell = dependent_cell_mode::FIXED) noexcept

This function can be used to assign a global external electrostatic potential in Volt (unit: V) to the layout (e.g this could be a planar external electrode). It is added to previously stored values.

Parameters:
  • potential_value – Value of the global external electrostatic potential in Volt (e.g. -0.3). Charge-transition levels are shifted by this value.

  • dep_celldependent_cell_mode::FIXED if the state of the dependent cell should not change, dependent_cell_mode::VARIABLE if it should.

inline bool is_three_state_simulation_required() noexcept

This function determines if given layout has to be simulated with three states since positively charged SiDBs can occur due to the local potential analysis. In addition, all SiDBs that can be positively charged are collected.

Note

All SiDBs have to be set to negatively charged.

Returns:

return value is true when three state simulation is required.

inline std::size_t num_negative_sidbs() const noexcept

Counts the number of SiDBs with a negative charge state.

Returns:

The number of SiDBs with a negative charge state.

inline std::size_t num_neutral_sidbs() const noexcept

Counts the number of SiDBs with a neutral charge state.

Returns:

The number of SiDBs with a neutral charge state.

inline std::size_t num_positive_sidbs() const noexcept

Counts the number of SiDBs with a positive charge state.

Returns:

The number of SiDBs with a positive charge state.

inline std::vector<typename Lyt::cell> get_positive_candidates() const noexcept

This functions returns all cells that could be positively charged. However, this must not be necessarily the case in a physically valid layout.

Returns:

All cell that could be positively charged.

inline int64_t three_state_cell_to_index(const typename Lyt::cell &c) const noexcept

This function searches the index of a cell which is part of the sublayout (i.e. it should be a cell which can be positively charged).

Parameters:

c – Cell that should be part of the sublayout.

Returns:

Index (i.e. position in the vector) of the input cell.

inline int64_t two_state_cell_to_index(const typename Lyt::cell &c) const noexcept

This function searches the index of a cell which is not part of the sublayout (i.e. it should be a cell which is either neutrally or negatively charged).

Parameters:

c – Cell that should not be part of the sublayout.

Returns:

Index (i.e. position in the vector) of the input cell.

inline Lyt::cell index_to_cell(const uint64_t index) const noexcept

This function searches the cell of a given index.

Parameters:

c – The index to find the cell of.

Returns:

The cell in the layout for the given index. Returns dead-coordinate if the index is not assigned to a not empty cell in the layout.

inline Lyt::cell index_to_three_state_cell(const uint64_t index) const noexcept

This function finds the cell for a given index which is a candidate to be positively charged of a given index.

Parameters:

index – The index to find the cell of (cell is candidate to be positively charged).

Returns:

Positive cell candidate. Dead-coordinate is returned if the index is not assigned to a not empty cell in the layout.

inline Lyt::cell index_to_two_state_cell(const uint64_t index) const noexcept

This function finds the cell which can only be neutrally or negatively charged of a given index.

Parameters:

index – The index to find the cell of.

Returns:

The cell (which cannot be positively charged) in the layout for the given index. Dead-coordinate is returned if the index is not assigned to a not empty cell in the layout.

inline double chargeless_potential_at_given_distance(const double distance) const noexcept

This function calculates and returns the chargeless electrostatic potential in Volt for a given distance in nanometer.

Parameters:

distance – Distance in nanometer between position and defect (unit: nm).

Returns:

The chargeless electrostatic potential at a given distance (unit: V).

inline double chargeless_potential_generated_by_defect_at_given_distance(const double distance, const sidb_defect &defect = sidb_defect{}) const noexcept

This function calculates the chargeless potential in Volt generated by a defect at a given distance in nanometer.

Parameters:
  • distance – Distance between position and defect (unit: nm.

  • sidb_defect – Defect (including defect specific parameters).

Returns:

The chargeless electrostatic potential in Volt generated by the defect at a given distance (unit: V).

inline void assign_local_external_potential(const std::unordered_map<typename Lyt::cell, double> &external_potential) noexcept

This function can be used to assign an external local electrostatic potential in Volt to the layout, which is added to previously stored values. All important attributes of the charge layout are updated automatically.

Parameters:
  • cell – Cell to which the local external potential is applied.

  • external_voltage – External electrostatic potential in Volt applied to different cells.

inline std::unordered_map<typename Lyt::cell, double> get_local_external_potentials() const noexcept

This function returns the local external electrostatic potential in Volt applied to the layout.

Returns:

External electrostatic potential as unordered map. The cell is used as key and the external electrostatic potential in Volt (unit: V) at its position as value.

inline void reset_local_external_potentials() noexcept

This function can be used to reset all external local electrostatic potentials to 0 Volt. All important attributes of the charge layout are updated automatically.

inline std::unordered_map<typename Lyt::cell, double> get_local_defect_potentials() const noexcept

This function returns the local electrostatic potentials which are generated by defects.

Returns:

Local electrostatic potential in Volt generated by the defects at each each cell.

inline std::unordered_map<typename Lyt::cell, const sidb_defect> get_defects() const noexcept

This function returns the defects.

Returns:

Placed defects with cell position and type.

inline void update_charge_state_of_dependent_cell() noexcept

The charge state of the dependent-SiDB is updated based on the local electrostatic potential at its position. All other local electrostatic potentials are then also updated if the charge state of the dependent-SiDB has changed.

inline uint64_t get_charge_index_of_sub_layout() const noexcept

This function returns the charge index of the sublayout (cells that can be positively charged).

Returns:

The charge distribution index of the sublayout.

inline void charge_index_gray_code_to_charge_distribution(const uint64_t new_gray_code, const uint64_t old_gray_code) noexcept

This function changes the current charge distribution based on two given Gray codes (Important: The two Gray codes should only differ by one bit)

Parameters:
  • new_gray_code – Gray code as uint64_t of the new charge distribution.

  • old_gray_code – Gray code as uint64_t of the previous charge distribution layout.

inline void increase_charge_index_of_sub_layout_by_one(const dependent_cell_mode dependent_cell = dependent_cell_mode::FIXED, const energy_calculation recompute_system_energy = energy_calculation::UPDATE_ENERGY, const charge_distribution_history consider_history = charge_distribution_history::NEGLECT, const exact_sidb_simulation_engine engine = exact_sidb_simulation_engine::QUICKEXACT) noexcept

The charge index of the sublayout is increased by one and the charge distribution is updated correspondingly.

Parameters:
inline void assign_charge_index_by_gray_code(const uint64_t current_gray_code, const uint64_t previous_gray_code, const dependent_cell_mode dep_cell = dependent_cell_mode::FIXED, const energy_calculation energy_calc_mode = energy_calculation::UPDATE_ENERGY, const charge_distribution_history history_mode = charge_distribution_history::NEGLECT) noexcept

The charge index is assigned by a Gray code number in decimal.

Parameters:
inline void reset_charge_index_sub_layout(const exact_sidb_simulation_engine engine = exact_sidb_simulation_engine::QUICKEXACT) noexcept

Resets the charge index of the sublayout (cells of the layout that can also be positively charged).

Parameters:

engine – The simulation engine used.

inline uint64_t get_max_charge_index_sub_layout() const noexcept

Returns the maximum index of the sublayout (cells that can be positively charged).

Returns:

The maximal possible charge distribution index of the sublayout.

inline void assign_charge_index_by_two_gray_codes(const uint64_t gray_code, const uint64_t gray_code_old) noexcept

Assign a given charge index to the charge distribution layout. This function should be used if new and old charge index are given as Gray code to provide high performance.

Parameters:
  • gray_code – charge index (as Gray code in decimal) of the new charge distribution.

  • gray_code_old – charge index (as Gray code in decimal) of the old charge distribution.

inline std::vector<typename Lyt::cell> get_sidb_order() const noexcept

This function returns all SiDBs of the layout.

Returns:

Vector with all cells.

inline void add_sidb(const typename Lyt::cell &c, const sidb_charge_state charge) noexcept

This function can be used to add an SiDB to the layout. The SiDB is only added to the cell_charge and the sidb_order vector.

Parameters:
  • c – Cell which is added to the layout.

  • charge – Charge state of the added cell.

template<>
struct charge_distribution_storage

Public Functions

inline explicit charge_distribution_storage(const sidb_simulation_parameters &params = sidb_simulation_parameters{})

Standard constructor for the charge_distribution_storage.

Parameters:

params – Physical parameters used for the simulation (µ_minus, base number, …).

Public Members

sidb_simulation_parameters simulation_parameters = {}

Stores all physical parameters used for the simulation.

std::vector<typename Lyt::cell> sidb_order = {}

All cells that are occupied by an SiDB are stored in order.

std::vector<typename Lyt::cell> sidb_order_without_three_state_cells = {}

All cells that cannot be positively charged in a physically valid layout.

std::vector<sidb_charge_state> cell_charge = {}

The SiDBs’ charge states are stored. Corresponding cells are stored in sidb_order.

distance_matrix nm_dist_mat = {}

Distance between SiDBs are stored as matrix (unit: nm).

potential_matrix pot_mat = {}

Electrostatic potential between SiDBs are stored as matrix (here, still charge-independent, unit: V).

std::unordered_map<typename Lyt::cell, double> defect_local_pot = {}

Electrostatic potential at each SiDB position which is generated by defects (unit: eV).

std::unordered_map<typename Lyt::cell, double> local_external_pot = {}

External electrostatic potential in V at each SiDB position (can be used when different potentials are applied to different SiDBs).

local_potential local_pot = {}

Electrostatic potential at each SiDB position. Has to be updated when charge distribution is changed (unit: V).

double system_energy = {0.0}

Stores the electrostatic energy of a given charge distribution (unit: eV).

bool validity = false

Label if given charge distribution is physically valid (see https://ieeexplore.ieee.org/document/8963859).

charge_index_base charge_index_and_base = {}

Each charge distribution is assigned a unique index (first entry of pair), second one stores the base number (2- or 3-state simulation).

uint64_t charge_index_sublayout = {}

Charge index of the sublayout (collection of SiDBs that could be positively charged for a specific charge configuration of the layout).

uint64_t max_charge_index = {}

Depending on the number of SiDBs and the base number, a maximal number of possible charge distributions exists.

uint64_t max_charge_index_sulayout = {}

Depending on the number of SiDBs in the SiDBs, a maximal number of possible charge distributions exists.

std::pair<int64_t, int8_t> cell_history_gray_code = {}

This pair stores the cell index and its previously charge state (important when all possible charge distributions are enumerated and checked for physical validity).

std::vector<std::pair<uint64_t, int8_t>> cell_history = {}

This vector stores the cells and its previously charge states of the charge distribution before the charge index was changed.

std::unordered_map<typename Lyt::cell, const sidb_defect> defects = {}

This unordered map stores the cells and the placed defect.

Lyt::cell dependent_cell = {}

Dependent cell is the cell which charge state is determined by all other SiDBs in the layout.

uint64_t dependent_cell_index = {}

Charge index of the dependent cell in the layout.

std::vector<typename Lyt::cell> three_state_cells = {}

This vector collects all cells that could potentially be positively charged based on the maximum possible local potential.

bool dependent_cell_in_sub_layout = {}

True indicates that the dependent SiDB is in the sublayout.

Is SiDB gate design deemed impossible

Header: fiction/technology/is_sidb_gate_design_impossible.hpp

struct is_sidb_gate_design_impossible_params

This struct contains parameters to determine if SiDB gate design is impossible.

Public Members

sidb_simulation_parameters simulation_params = {}

All parameters for physical SiDB simulations.

bdl_input_iterator_params bdl_iterator_params = {}

Parameters used for the BDL input iterator.

template<typename Lyt, typename TT>
bool fiction::is_sidb_gate_design_impossible(const Lyt &skeleton_with_defects, const std::vector<TT> &spec, const is_sidb_gate_design_impossible_params &params = {}) noexcept

This function evaluates whether it is impossible to design an SiDB gate for a given truth table and a given skeleton with atomic defects. It determines the possible charge states at the output BDL pairs. Atomic defects can cause a BDL pair to be neutrally charged only. Thus, the BDL pair would not work as intended.

Template Parameters:
  • Lyt – SiDB cell-level layout type.

  • TT – The truth table type.

Parameters:
  • skeleton_with_defects – An SiDB skeleton layout with atomic defects.

  • spec – A vector of truth tables (each truth table is representing one output) representing the gate’s intended functionality.

  • params – Parameters to determine if the gate design is impossible.

Returns:

true if gate design is impossible, false otherwise.

Physical Constants

Header: fiction/technology/physical_constants.hpp

constexpr double fiction::constants::physical::BOLTZMANN_CONSTANT = 1.38064852 * 1E-23

The Boltzmann constant \(k_B\) in \(J \cdot K^{-1}\).

constexpr double fiction::constants::physical::EV_TO_JOULE = ELEMENTARY_CHARGE

The conversion factor from electronvolts to joules.

constexpr double fiction::constants::physical::EPSILON = 8.8541878 * 1E-12

The vacuum permittivity \(\epsilon_0\) in \(F \cdot m^{-1}\).

constexpr double fiction::constants::physical::ELEMENTARY_CHARGE = 1.6021766 * 1E-19

The elementary charge \(e\) in \(C\).

constexpr double fiction::constants::physical::K_E = 8.987552 * 1E9

The Coulomb constant \(k\) in \(N \cdot m^{2} \cdot C^{-2}\).

constexpr double fiction::constants::ERROR_MARGIN = 1E-6

This error margin is used for the comparison of floating-point numbers.

constexpr double fiction::constants::PI = 3.14159265359

A value of \(\pi\) that is accurate to 11 decimal places.

Euclidean distance between two SiDBs in nanometers

Header: fiction/technology/sidb_nm_distance.hpp

template<typename Lyt>
constexpr double fiction::sidb_nm_distance(const Lyt &lyt, const coordinate<Lyt> &source, const coordinate<Lyt> &target) noexcept

Computes the distance between two SiDB cells in nanometers (unit: nm).

Template Parameters:

Lyt – SiDB cell-level layout type.

Parameters:
  • source – The source cell.

  • target – The target cell.

Returns:

The distance between the two cells in nanometers (unit: nm).

SiDB Cluster Hierarchy

Header: fiction/technology/sidb_cluster_hierarchy.hpp

A cluster hierarchy can be computed over any SiDB layout, resulting in a useful structure for simulation of possible charge distributions. This header provides the structures used for *Ground State Space* construction, which enables the *ClusterComplete* exact SiDB simulator.

enum class fiction::sidb_cluster_hierarchy_linkage_method : uint8_t

An enumeration of cluster linkage methods. The chosen method defines how clusters are merged in the agglomerative clustering procedure, by, e.g., defining an inter-cluster distance to minimize for the cluster to merge. For more information, visit: https://docs.tibco.com/pub/spotfire/6.5.1/doc/html/hc/hc_clustering_methods_overview.htm.

Values:

enumerator COMPLETE

Complete linkage takes the maximum distance between nodes in a cluster.

enumerator SINGLE

Single linkage takes the minimum distance between nodes in a cluster.

enumerator UNWEIGHTED_AVERAGE

Unweighted average linkage takes the average distance between nodes in a cluster, disregarding the number of elements in a node.

enumerator WEIGHTED_AVERAGE

Weighted average linkage takes the average distance between nodes in a cluster, weighing in the number of elements in a node.

enumerator MINIMUM_VARIANCE

Known as Ward’s method, this type of linkage merges clusters based on a minimum variance measure.

struct sidb_binary_cluster_hierarchy_node

The struct used to store a binary cluster hierarchy that may be used to store the result of the hierarchical clustering returned by ALGLIB functionality.

Public Functions

inline sidb_binary_cluster_hierarchy_node(phmap::flat_hash_set<uint64_t> &&sidbs, std::array<sidb_binary_cluster_hierarchy_node_ptr, 2> &&children) noexcept

Binary cluster hierarchy node constructor.

Parameters:
  • sidbs – The set of SiDBs to contain in this node.

  • children – The pair of binary cluster hierarchy node pointers that become the children of this node.

Public Members

phmap::flat_hash_set<uint64_t> c

The set of SiDB indices contained in the node

std::array<sidb_binary_cluster_hierarchy_node_ptr, 2> sub

The two children of the node.

template<typename Lyt>
static sidb_binary_cluster_hierarchy_node fiction::sidb_cluster_hierarchy(Lyt &lyt, sidb_cluster_hierarchy_linkage_method linkage_method = sidb_cluster_hierarchy_linkage_method::MINIMUM_VARIANCE) noexcept

This function performs the ALGLIB agglomerative clustering algorithm for a given SiDB layout. By default, the cluster are created by a minimal positional variance heuristic, also known as Ward’s method.

Template Parameters:

Lyt – SiDB cell-level layout type.

Parameters:
  • lyt – The layout to create a cluster hierarchy of.

  • linkage_method – The agglomerative clustering linking heuristic that is used by ALGLIB.

struct sidb_cluster_receptor_state

A receptor state pairs the potential receiving cluster with the identifier of the SiDB.

Public Members

const sidb_cluster_ptr &cluster

Receptor cluster.

const uint64_t sidb_ix

SiDB index. It is contained in the receptor cluster.

struct sidb_cluster_projector_state

A projector state pairs the potential projecting cluster with the associated multiset charge configuration.

enum class fiction::bound_direction : uint8_t

The electrostatic potential bounds required for the Ground State Space algorithm. As the domain in which our potential bounds live are simply the real numbers, we may think of the lower bound and upper bound domains to be separate partial order structures on the real number line, inverse to each other. The Ground State Space algorithm requires the properties of a lower semi-lattice for these domains, ie. all finite meets must exist. This is implemented for the lower and upper bound respectively simply by taking a minimum or a maximum. One may think of meets as follows, which is very relevant to intention of their application: a meet, or greatest lower bound, is the maximal information common to a set (of potential bounds). This semantic operation is essential to the Ground State Space algorithm, which thus envelops without loss of accuracy.

Values:

enumerator LOWER

Lower bounds live in the set \((-\infty\f, \infty]\) and are ordered by >.

enumerator UPPER

Upper bounds live in the set \([-\infty, \infty)\) and are ordered by <.

template<bound_direction bound>
static constexpr double fiction::potential_bound_top() noexcept

The respective top elements of the lower semi-lattices in which our potential bounds live, ie., the respective elements of most information. This means that any meet with a top element (weakly) reduces the information, and thus any meet computed in iteration through binary application may start out with this element.

Template Parameters:

bound – Potential bound domain to return the element of most information of.

Returns:

The element of most information respective to the potential bound domain.

template<bound_direction bound>
static constexpr void fiction::take_meet_of_potential_bounds(double &a, const double b) noexcept

This function computes a binary meet, overwriting the first argument with the result. It takes the minimum in case of a lower bound, and a maximum in case of an upper bound, each corresponding to the minimal information common to the arguments.

Template Parameters:

bound – The potential bound domain which defines the implementation of the meet.

Parameters:
  • a – First potential bound which is overwritten with the result of the meet.

  • b – Second potential bound.

template<typename PotentialBoundsType>
struct potential_bounds_store

This defines a store in which the bounds on the local electrostatic potential for an SiDB (index) may be stored. For the Ground State Space algorithm, this is used to keep track of the respective lower and upper bounds on the partial sum of the potential projected from SiDBs in a subhierarchy that is local to SiDBs that are also in the subhierarchy. During ClusterComplete simulation, the stored potential bounds represent information of the complete hierarchy, thus all SiDB interactions.

Public Functions

inline constexpr uint64_t num_sidbs() const noexcept

Getter for the size of the potential bounds store, i.e., the number of SiDBs considered in this store.

Returns:

The size of the potential bounds store.

template<bound_direction bound>
inline constexpr double get(const uint64_t sidb_ix) const noexcept

Getter for a (partial) potential sum bound local to an SiDB.

Template Parameters:

bound – The potential bound to obtain.

Parameters:

sidb_ix – SiDB (index) to obtain the potential bound of.

Returns:

The potential bound for this SiDB.

template<bound_direction bound>
inline void set(const uint64_t sidb_ix, const double bound_value) noexcept

Setter for a (partial) potential sum bound local to an SiDB.

Template Parameters:

bound – The potential bound to obtain.

Parameters:
  • sidb_ix – SiDB (index) to set the potential bound for.

  • bound_value – New bound to set.

inline void set(const uint64_t sidb_ix, const double min, const double max) noexcept

Setter for (partial) potential sum bounds local to an SiDB.

Parameters:
  • sidb_ix – SiDB (index) to set the potential bounds for.

  • min – New lower bound to set.

  • max – New upper bound to set.

template<bound_direction bound>
inline void update(const uint64_t sidb_ix, const double bound_diff) noexcept

Relative setter for a (partial) potential sum bound local to an SiDB.

Template Parameters:

bound – The potential bound to update.

Parameters:
  • sidb_ix – SiDB (index) to update the potential bound of.

  • bound_diff – Bound difference to apply.

inline void update(const uint64_t sidb_ix, const double min_diff, const double max_diff) noexcept

Relative setter for (partial) potential sum bounds local to an SiDB.

Parameters:
  • sidb_ix – SiDB (index) to update the potential bounds of.

  • min_diff – Difference in lower bound potential to apply.

  • max_diff – Difference in upper bound potential to apply.

inline void initialize_complete_potential_bounds(const uint64_t num_sidbs) noexcept

Initialize potential bounds for the given number of SiDBs (applicable to a complete potential bounds store only).

Parameters:

num_sidbs – The number of SiDBs in the layout that is simulated.

inline potential_bounds_store &operator+=(const potential_bounds_store &other) noexcept

Add a complete potential bound store to this (also a complete potential bound store) through pointwise updates.

Parameters:

other – Other complete potential bound store.

Returns:

Reference to this.

inline potential_bounds_store &operator-=(const potential_bounds_store &other) noexcept

Subtract a complete potential bound store to this (also a complete potential bound store) through pointwise updates, i.e., updates for each SiDB and for each bound (LB, UB).

Parameters:

other – Other complete potential bound store.

Returns:

Reference to this.

using fiction::partial_potential_bounds_store = potential_bounds_store<phmap::flat_hash_map<uint64_t, std::array<double, 2>>>

The aggregates are used in the construction; they represent information of a subhierarchy.

using fiction::complete_potential_bounds_store = potential_bounds_store<std::vector<std::array<double, 2>>>

The aggregates represent information for a clustering of the complete layout; they are used in the destruction.

struct sidb_charge_space_composition

A charge space composition holds a number of projector states of sibling clusters. Summing the multiset charge configuration associated with each, we obtain an element of the charge space of their parent. Additionally, we have a store for the bounds on the partial potential sum local to each SiDB contained by the parent, i.e., partial in the sense that SiDBs not contained by the parent are not taken into account. The potential bounds for each SiDB correspond to the meet on the potential bounds for each (sub-)composition of the respective cluster charge states associated with the multiset charge configuration of each projector state in this composition of siblings.

Public Members

std::vector<sidb_cluster_projector_state> proj_states

Projector states associated with charge space elements that make up the composition.

complete_potential_bounds_store pot_bounds = {}

Flattened (hierarchical) potential bounds specific to this composition.

struct sidb_clustering_state

A clustering state is very similar to a cluster state composition, though it uses unique pointers to the cluster states that may be moved. Thereby, this is the essential type of the dynamic objects in ClusterComplete’s operation, which always represent information of the complete layout.

Public Functions

inline explicit sidb_clustering_state(const uint64_t num_sidbs) noexcept

Default constructor.

Parameters:

num_sidbs – Number of SiDBs in the layout that the clustering state should consider.

~sidb_clustering_state() = default

Destructor.

inline sidb_clustering_state(const sidb_clustering_state &other) noexcept

Copy constructor.

Parameters:

other – Other clustering state to copy.

inline sidb_clustering_state &operator=(const sidb_clustering_state &other) noexcept

Copy assignment operator.

Assigns the contents of another sidb_clustering_state instance to this instance. Performs a deep copy of proj_states and a complete copy of pot_bounds.

Parameters:

other – The sidb_clustering_state instance to copy from.

Returns:

A reference to this sidb_clustering_state instance after assignment.

sidb_clustering_state(sidb_clustering_state &&other) noexcept = default

Move constructor.

Parameters:

other – Other clustering state to move.

sidb_clustering_state &operator=(sidb_clustering_state &&other) noexcept = default

Move assignment operator.

Parameters:

other – Other clustering state to move.

Public Members

std::vector<sidb_cluster_projector_state_ptr> proj_states

Projector states associated with charge space elements that make up the clustering state.

complete_potential_bounds_store pot_bounds = {}

Flattened (hierarchical) potential bounds specific to this clustering state.

struct sidb_cluster_charge_state

A cluster charge state is a multiset charge configuration. We may compress it into a 64 bit unsigned integer by putting the number of negative and positive charges in the upper and lower 32 bits respectively. The number of neutral charges may then be inferred for a given cluster by considering its size. Cluster charge states are the crucial objects of the state spaces, called charge spaces, since they not only hold information of the multiset charge configuration, but also the set of compositions, each of which compose into the current cluster charge state.

Public Functions

inline sidb_cluster_charge_state() noexcept

Default constructor, creates a cluster charge state without any negative and positive charges.

inline sidb_cluster_charge_state(const sidb_cluster_ptr &singleton, const sidb_charge_state cs, const double loc_ext_pot, const uint64_t total_num_sidbs) noexcept

Constructor for a charge space element of a singleton cluster. It has a single composition, which is a cluster state of the singleton cluster and the singleton multiset charge configuration itself.

Parameters:
  • singleton – Singleton cluster to put in the compositions of this cluster charge state.

  • cs – Charge state to lift to a singleton multiset charge configuration.

  • loc_ext_pot – The local external potential at the SiDB in the singleton cluster. Specifically, this is the sum of the local defect potential and the local external potential.

  • total_num_sidbs – The total number of SiDBs in the layout.

inline explicit sidb_cluster_charge_state(const uint64_t m) noexcept

Constructor for cluster charge state given a multiset charge configuration represented in its compressed form. It allows the compressed form to be lifted to the full type to facilitate equality checks.

Parameters:

m – The multiset charge configuration to create a cluster charge state of.

inline explicit constexpr operator uint64_t() const noexcept

Explicit instructions for the compiler on how to cast a cluster charge state to an 64-bit unsigned integer.

Returns:

The 64-bit unsigned integer representing the compressed form of the cluster charge state.

inline constexpr void add_charge(const sidb_charge_state cs) noexcept

Modifier of the cluster charge state, adding a single charge state.

Parameters:

cs – The charge state to add.

inline sidb_cluster_charge_state(const std::initializer_list<sidb_charge_state> &charge_states) noexcept

Constructor of a cluster charge state allowing initializer list construction.

Parameters:

charge_states – initializer list of charge states to form into a cluster charge state.

inline constexpr bool operator==(const sidb_cluster_charge_state &other) const noexcept

Defines the equality operation of cluster charge states, which disregards the compositions.

Parameters:

other – Other cluster charge state to test for equality with the current.

Returns:

true if and only if the compressed forms are equal.

inline std::size_t operator()(const sidb_cluster_charge_state &m) const noexcept

Defined a hashing of a cluster charge state. Since we need only separate cluster charge states by their compressed form, we may compute a hash over this for optimal performance when used in a hash set.

Parameters:

m – Cluster charge state to compute the hash of.

Returns:

The hash of the given cluster charge state.

inline constexpr sidb_cluster_charge_state &operator+=(const sidb_cluster_charge_state &other) noexcept

Defines addition of cluster charge states through multiset concatenation. Disregards compositions.

Parameters:

other – Other cluster charge state to concatenate with the current.

Returns:

The concatenated cluster charge state, which is the modified version of the current.

inline constexpr sidb_cluster_charge_state &operator-=(const sidb_cluster_charge_state &other) noexcept

Defines subtraction of cluster charge states through multiset difference. Disregards compositions.

Parameters:

other – Other cluster charge state to take the difference of w.r.t. with the current.

Returns:

The cluster charge state that is their difference, which is the modified version of the current.

Public Members

uint64_t neg_count

Number of negative charges in the cluster charge state (32 available bits).

uint64_t pos_count

Number of positive charges in the cluster charge state (32 available bits).

mutable std::vector<sidb_charge_space_composition> compositions

Stored compositions of this cluster charge state.

static constexpr sidb_charge_state fiction::singleton_multiset_conf_to_charge_state(const uint64_t m) noexcept

Function to convert a singleton cluster charge state in its compressed form to a charge state.

Parameters:

m – A singleton multiset charge configuration.

Returns:

The charge state associated with the sole element contained in the given multiset charge configuration.

struct potential_projection

This struct defines the type of an electrostatic potential projection, which pairs a multiset charge configuration with the potential value (in eV) associated with the potential projection in the given context. The context is given by potential projection stores in the decorated cluster hierarchies, which links the projecting cluster with SiDB that receives this potential projection.

Public Functions

potential_projection() noexcept = default

Default constructor, used as a starting point for an accumulation of potential projections.

inline potential_projection(const double pot, const uint64_t mul) noexcept

Trivial copy constructor.

Parameters:
  • pot – Potential value to copy.

  • mul – Multiset charge configuration to copy.

inline potential_projection(const double inter_sidb_pot, const sidb_charge_state cs) noexcept

Constructor for a potential projection from a singleton cluster, thereby lifting a value in the potential matrix to a potential projection.

Parameters:
  • inter_sidb_pot – Potential value of which the absolute value may be found in the potential matrix in an associated charge_distribution_surface object.

  • cs – Charge state associated with the singleton cluster projector for this potential projection.

inline constexpr bool operator<(const potential_projection &other) const noexcept

Defines an ordering of potential projections through comparison of the potential value. To prevent potential projections of equal potential value but different associated multiset charge configurations to be regarded as equal, a comparison of the latter is used as a “fail-safe”.

Parameters:

other – Other potential projection to compare with the current.

Returns:

true if and only if the potential value of the current is lower than that of other, or if the potential values are equal and the compressed form of the multiset charge configuration is strictly less than that of other.

inline constexpr potential_projection &operator+=(const potential_projection &other) noexcept

Defines summation of potential projections through addition of the potential values and concatenation of the associated multiset charge configurations. The latter may simply be implemented by addition of the compressed forms.

Parameters:

other – Other potential projection to sum with the current.

Returns:

The current potential projection to which the other potential projection is now added.

Public Members

double pot_val = {0.0}

Potential projection value (unit: eV).

uint64_t multiset = {0}

Associated multiset charge configuration.

struct potential_projection_order

This struct defines the type of potential projection order, along with getter and setter operations. Essentially, a potential projection order is an ordered collection of potential projections, which allow rapid access and modifications of the potential projection bounds by relying on the ordering defined on potential projections, and canonical operations on ordered set containers. In the decorated cluster hierarchy, each cluster has a potential projection order onto each SiDB in the layout from which the hierarchy was created.

Public Types

using pot_proj_order = phmap::btree_set<potential_projection>

A potential projection order is an ordered set.

Public Functions

potential_projection_order() noexcept = default

Default constructor, creating the empty potential projection order.

inline potential_projection_order(const double loc_ext_pot, const uint8_t base, const bool self_projection) noexcept

Constructor for a potential projection from a singleton cluster onto the SiDB contained in it.

Parameters:
  • loc_ext_pot – The local external potential at the SiDB in the singleton cluster. Specifically, this is the sum of the local defect potential and the local external potential.

  • base – The simulation base. This defines whether positive charges are considered.

  • self_projection – Separates the constructor type from inter-SiDB potential projections.

inline potential_projection_order(const double inter_sidb_pot, const uint8_t base) noexcept

Constructor for a potential projection from a singleton cluster onto an SiDB.

Parameters:
  • inter_sidb_pot – The chargeless potential between the SiDB in the singleton cluster and the one projected onto, as found in the potential matrix in an associated charge_distribution_surface object.

  • base – The simulation base. This defines whether positive charges are considered.

template<bound_direction bound>
inline constexpr const potential_projection &get_bound() const noexcept

A getter for a potential projection bound, which is the first or last item in the ordered set.

Template Parameters:

bound – The bound to obtain.

Returns:

The potential projection that forms the requested bound on the potential projection order.

template<bound_direction bound>
inline const potential_projection &get_next_bound() const noexcept

A getter for the next potential projection bound, which is the first potential projection when traversing the ordering either from below or from above, that differs in its multiset charge configuration from the relevant potential projection bound.

Template Parameters:

bound – The bound to obtain.

Returns:

The potential projection that would be the requested bound on the potential projection order if the current relevant bound would be erased.

template<bound_direction bound>
inline const potential_projection &get_pot_proj_for_m_conf(const uint64_t m_conf) const noexcept

A getter for the potential projection bound given a multiset charge configuration specification, which is the first potential projection in the ordering when traversing either from below or from above, that matches its multiset charge configuration to the argument.

Template Parameters:

bound – The bound to obtain.

Parameters:

m_conf – The multiset charge configuration to match.

Returns:

The potential projection that forms the requested bound on the subset of the potential projection order of potential projections that match their multiset charge configuration to the argument.

inline void remove_m_conf(const uint64_t m_conf) noexcept

Removes all occurrences of potential projections that match their multiset charge configuration to the argument.

Parameters:

m_conf – The multiset charge configuration of which all occurrences must be removed.

inline void add(const potential_projection &pp) noexcept

Adds a potential projection to the ordering, automatically placing it appropriately.

Parameters:

pp – Potential projection to add.

Public Members

pot_proj_order order

The potential projection ordering.

using fiction::sidb_cluster_charge_state_space = phmap::flat_hash_set<sidb_cluster_charge_state, sidb_cluster_charge_state>

The type of a charge space is defined. It is a set of cluster charge states, forming the state space in our setting.

using fiction::sidb_clustering = phmap::flat_hash_set<sidb_cluster_ptr, sidb_cluster_ptr_hash>

A clustering is a set of disjoint clusters, i.e., none share an SiDB.

struct sidb_cluster

This struct defined the fully decorated cluster hierarchy type which follows the structure of a “general tree”. It contains multiple stores:

  • a set of indices that correspond to the SiDBs as stored in a charge_distribution_surface object,

  • a store of potential bounds for each SiDB in the cluster that give the fraction of the local electrostatic potential that is received from outside the cluster, and

  • a store containing the potential projection orders onto each SiDB, inside and outside the cluster.

Public Types

using uid_t = uint64_t

For semantic clarity, this type alias creates a separate type for unique identifiers.

using sidb_ix = uint64_t

For semantic clarity, this type alias creates a separate type for SiDB indices.

Public Functions

inline sidb_cluster(std::vector<sidb_ix> &&c, std::vector<sidb_ix> &&other_c, sidb_clustering &&x, const uid_t unique_id) noexcept

SiDB cluster hierarchy constructor.

Parameters:
  • c – Set of SiDB indices for the cluster to contain.

  • other_c – Set of SiDB indices in the layout that the cluster will not contain.

  • x – A set of cluster hierarchies to set as the children of this cluster.

  • unique_id – The unsigned integer to identify the cluster hierarchy uniquely with. For the case of a singleton cluster, the unique identifier is set to be the index of the single SiDB it contains.

inline sidb_cluster_ptr get_parent() const noexcept

This function returns a shared pointer to the parent of this cluster.

Returns:

A shared pointer to the parent of this cluster

inline void initialize_singleton_cluster_charge_space(const double loc_pot_min, const double loc_pot_max, const double loc_ext_pot, const uint8_t base, const sidb_cluster_ptr &self_ptr) noexcept

This function initializes the charge space of a singleton cluster corresponding with the given simulation base, and sets the initial bounds on the potential received from outside the cluster as the local potential bounds. The local potential bounds do not include the local external potential at the SiDB in the singleton, as this is passed separately.

Parameters:
  • loc_pot_min – The minimum local potential for the SiDB in the singleton cluster.

  • loc_pot_max – The maximum local potential for the SiDB in the singleton cluster.

  • loc_ext_pot – The local external potential at the SiDB in the singleton cluster. Specifically, this is the sum of the local defect potential and the local external potential.

  • base – The simulation base.

  • self_ptr – Shared pointer to itself.

inline uint64_t num_sidbs() const noexcept

Function to return the number of SiDBs contained in the cluster.

Returns:

The number of SiDBs contained in the cluster.

inline constexpr bool operator==(const sidb_cluster &other) const noexcept

Equality operation on cluster hierarchies. Checks the respective unique identifiers for equality.

Parameters:

other – Cluster (hierarchy) to compare to.

Returns:

true if and only if the unique identifiers match.

Public Members

const uid_t uid

Unique identifier. Equal to the SiDB index for singleton clusters.

std::vector<sidb_ix> sidbs

The SiDBs contained by the cluster.

std::vector<sidb_ix> external_sidbs

The SiDBs in the layout that are not contained by the cluster.

sidb_clustering children

The set of children of a cluster is a clustering.

std::weak_ptr<sidb_cluster> parent

Every cluster carries a pointer to its parent. For the top cluster, this is nullptr.

partial_potential_bounds_store received_ext_pot_bounds = {}

The bounds on the electrostatic potential sum of SiDBs external to this cluster, local to an SiDB in the cluster.

phmap::flat_hash_map<sidb_ix, potential_projection_order> pot_projs

The bounds on the electrostatic potential that is projected from this cluster for the different multiset charge configurations in the charge space.

sidb_cluster_charge_state_space charge_space

The charge state space of the cluster.

static const std::vector<sidb_charge_space_composition> &fiction::get_projector_state_compositions(const sidb_cluster_projector_state &pst) noexcept

This function is used to obtain the cluster charge state compositions of the multiset charge configuration in a projector state. The corresponding charge space element of the projector is found and its compositions are returned.

Parameters:

pst – Projector state of which the corresponding compositions are requested.

Returns:

The compositions associated with the multiset charge configuration of the projecting cluster.

static sidb_cluster_ptr fiction::to_unique_sidb_cluster(const uint64_t total_sidbs, const sidb_binary_cluster_hierarchy_node &n, uint64_t &uid) noexcept

This recursive function is used to convert a binary cluster hierarchy, as for instance returned by sidb_cluster_hierarchy function that uses ALGLIB’s clusterizer. The returned structure includes parent pointers.

Parameters:
  • n – A node from a binary cluster hierarchy, as for instance returned by parsing ALGLIB’s result.

  • uid – Variable reference which is updated in each execution to ensure uniqueness.

Returns:

A uniquely identified node in a decorated cluster hierarchy that follows the “general tree” structure.

static sidb_cluster_ptr fiction::to_sidb_cluster(const sidb_binary_cluster_hierarchy_node &n) noexcept

This function initiates the recursive procedure of converting a binary cluster hierarchy to our bespoke version.

Parameters:

n – A node from a binary cluster hierarchy, as for instance returned by parsing ALGLIB’s result.

Returns:

A uniquely identified node in a decorated cluster hierarchy that follows the “general tree” structure.