Source code for kirchhoff.circuit_dual
# @Author: Felix Kramer <kramer>
# @Date: 07-11-2021
# @Email: felixuwekramer@proton.me
# @Last modified by: kramer
# @Last modified time: 08-07-2022
import numpy as np
from dataclasses import dataclass, field
# custom embeddings/architectures for mono networkx
from kirchhoff.circuit_init import Circuit
from kirchhoff.circuit_flow import FlowCircuit
from kirchhoff.circuit_flux import FluxCircuit
# custom primer
import kirchhoff.init_dual as init_dual
# custom output functions
import kirchhoff.draw_networkx as dx
def construct_from_graphSet(graphSet, circuit_type='default'):
circuitConstructor = {
'default': Circuit,
'circuit': Circuit,
'flow': FlowCircuit,
'flux': FluxCircuit,
}
circuitSet = []
if circuit_type in circuitConstructor:
for g in graphSet.layer:
K = circuitConstructor[circuit_type](g)
circuitSet.append(K)
else:
print('Warning: Invalid graph mode, choose default')
for g in graphSet.layer:
K = circuitConstructor['default'](g)
circuitSet.append(K)
return circuitSet
[docs]def initialize_dual_from_catenation(
dual_type='catenation',
num_periods=1,
circuit_type='default'
):
"""
Initialize a dual spatially embedded circuit, with internal graphs based on
simple catenatednetwork skeletons.
Args:
dual_type (string):\n
The type of dual skeleton (simple, diamond, laves, catenation).
num_periods (int):\n
Repetition number of the lattice's unit cell.
Returns:
dual_circuit: A dual circuit system.
"""
graphSet = init_dual.init_dualCatenation(dual_type, num_periods)
circuitSet = construct_from_graphSet(graphSet, circuit_type)
for i, g in enumerate(graphSet.layer):
circuitSet[i].info = circuitSet[i].set_info(g, dual_type)
kirchhoff_dual = DualCircuit(circuitSet)
return kirchhoff_dual
[docs]def initialize_dual_from_minsurf(
dual_type='simple',
num_periods=2,
circuit_type='default'
):
"""
Initialize a dual spatially embedded flux circuit, with internal graphs
based on the network skeletons of triply-periodic minimal surfaces.
Args:
dual_type (string):\n
The type of dual skeleton (simple, diamond, laves, catenation).
num_periods (int):\n
Repetition number of the lattice's unit cell.
Returns:
dual_circuit: A flow_circuit object.
"""
graphSet = init_dual.init_dual_minsurf_graphs(dual_type, num_periods)
circuitSet = construct_from_graphSet(graphSet, circuit_type)
for i, g in enumerate(graphSet.layer):
circuitSet[i].info = circuitSet[i].set_info(g, dual_type)
kirchhoff_dual = DualCircuit(circuitSet)
kirchhoff_dual.e_adj = graphSet.e_adj
kirchhoff_dual.e_adj_idx = graphSet.e_adj_idx
kirchhoff_dual.distance_edges()
return kirchhoff_dual
[docs]@dataclass
class DualCircuit():
"""
A base class for flow circuits.
Attributes
----------
layer (list):\n
List of the graphs contained in the multilayer circuit.
e_adj (list):\n
A list off edge affiliation between the different layers, edge
view.
e_adj_idx (list):\n
A list off edge affiliation between the different layers, label
view.
n_adj (list): An internal nodal varaible.
"""
layer: list = field(default_factory=list, repr=False)
e_adj: list = field(default_factory=list, repr=False)
e_adj_idx: list = field(default_factory=list, repr=False)
n_adj: list = field(default_factory=list, repr=False)
[docs] def distance_edges(self):
"""
Compute the distance of affiliated edges in the multilayer circuit.
"""
self.dist_adj = np.zeros(len(self.e_adj_idx))
for i, e in enumerate(self.e_adj_idx):
g1 = self.layer[0].G
pos1 = [g1.nodes[node]['pos'] for node in e[0]]
p1 = np.mean(pos1, axis=0)
g2 = self.layer[1].G
pos2 = [g2.nodes[node]['pos'] for node in e[1]]
p2 = np.mean(pos2, axis=0)
self.dist_adj[i] = np.linalg.norm(p1-p2)
# def check_no_overlap(self, scale):
#
# """
# Test whether the multilayer systems have geometrically
# overlapping edges.
#
# Returns:
# bool: True if systems geometrically overlap, otherwise False
#
# """
#
#
# check = True
# K1 = self.layer[0]
# K2 = self.layer[1]
#
# for e in self.e_adj:
# r1 = K1.C[e[0], e[0]]
# r2 = K2.C[e[1], e[1]]
#
# if r1+r2 > scale*0.5:
# check = False
# break
#
# return check
# def clipp_graph(self):
#
# """
# Prune the internal graph variables, using an edge weight threshold
# criterium.
# """
#
# for i in range(2):
# self.layer[i].clipp_graph()
# output
[docs] def plot_circuit(self, *args, **kwargs):
"""
Use Plotly.GraphObjects to create interactive plots that have
optionally the graph atributes displayed.
Args:
kwargs (dictionary):\n
A dictionary for plotly keywords customizing the plots' layout.
Returns:
plotly.graph_objects.Figure: A plotly figure displaying the
circuit.
"""
fig = dx.plot_networkx_dual(self, *args, **kwargs)
return fig