From f659d101e7e5281cf04decc47b2676ff29ff395d Mon Sep 17 00:00:00 2001 From: Christoph Groth <christoph.groth@cea.fr> Date: Thu, 27 Jul 2017 11:12:57 +0200 Subject: [PATCH] builder: split up _transfer_symmetry --- kwant/builder.py | 59 ++++++++++++++++++++---------------------------- 1 file changed, 25 insertions(+), 34 deletions(-) diff --git a/kwant/builder.py b/kwant/builder.py index 1e86c67d..fd8146a2 100644 --- a/kwant/builder.py +++ b/kwant/builder.py @@ -576,10 +576,7 @@ class BuilderLead(Lead): The order of interface sites is kept during finalization. """ - syst = InfiniteSystem(self.builder, self.interface) - _transfer_symmetry(syst, self.builder) - - return syst + return InfiniteSystem(self.builder, self.interface) # Check that a modes/selfenergy function has a keyword-only parameter @@ -1576,17 +1573,13 @@ class Builder: `Symmetry` can be finalized. """ if self.symmetry.num_directions == 0: - syst = FiniteSystem(self) + return FiniteSystem(self) elif self.symmetry.num_directions == 1: - syst = InfiniteSystem(self) + return InfiniteSystem(self) else: raise ValueError('Currently, only builders without or with a 1D ' 'translational symmetry can be finalized.') - _transfer_symmetry(syst, self) - - return syst - ################ Finalized systems @@ -1620,21 +1613,11 @@ def discrete_symmetry(self, args=(), *, params=None): self._symmetries)) -def _transfer_symmetry(syst, builder): - """Take a symmetry from builder and transfer it to finalized system.""" - def operator(op): - if op is None: - return - return Density(syst, op, check_hermiticity=False) - - # Conservation law requires preprocessing to split it into eigenvectors - # and eigenvalues. - cons_law = builder.conservation_law - - if cons_law is None: - syst._cons_law = None - - elif callable(cons_law): +def _translate_cons_law(cons_law): + """Translate a conservation law from builder format to something that can + be used to initialize operator.Density. + """ + if callable(cons_law): @wraps(cons_law) def vals(site, *args, **kwargs): if site.family.norbs == 1: @@ -1647,8 +1630,6 @@ def _transfer_symmetry(syst, builder): return 1 return np.linalg.eigh(cons_law(site, *args, **kwargs))[1] - syst._cons_law = operator(vals), operator(vecs) - elif isinstance(cons_law, collections.Mapping): vals = {family: (value if family.norbs == 1 else ta.array(np.diag(np.linalg.eigvalsh(value)))) @@ -1656,7 +1637,6 @@ def _transfer_symmetry(syst, builder): vecs = {family: (1 if family.norbs == 1 else ta.array(np.linalg.eigh(value)[1])) for family, value in cons_law.items()} - syst._cons_law = operator(vals), operator(vecs) else: try: @@ -1667,11 +1647,22 @@ def _transfer_symmetry(syst, builder): raise e # skip coverage vals, vecs = cons_law, 1 - syst._cons_law = operator(vals), operator(vecs) + return vals, vecs - syst._symmetries = [operator(symm) for symm in (builder.time_reversal, - builder.particle_hole, - builder.chiral)] + +def _init_discrete_symmetries(self, builder): + def _operator(op): + return Density(self, op, check_hermiticity=False) + + if builder.conservation_law is None: + self._cons_law = None + else: + self._cons_law = tuple(map( + _operator, _translate_cons_law(builder.conservation_law))) + self._symmetries = tuple(None if op is None else _operator(op) + for op in [builder.time_reversal, + builder.particle_hole, + builder.chiral]) class FiniteSystem(system.FiniteSystem): @@ -1765,7 +1756,7 @@ class FiniteSystem(system.FiniteSystem): self._ham_param_map = _ham_param_map self.lead_interfaces = lead_interfaces self.symmetry = builder.symmetry - + _init_discrete_symmetries(self, builder) def hamiltonian(self, i, j, *args, params=None): if args and params: @@ -1989,7 +1980,7 @@ class InfiniteSystem(system.InfiniteSystem): self.onsite_hamiltonians = onsite_hamiltonians self._ham_param_map = _ham_param_map self.symmetry = builder.symmetry - + _init_discrete_symmetries(self, builder) def hamiltonian(self, i, j, *args, params=None): if args and params: -- GitLab