Example with dynamical charge and spin interactions
Below is a short example demonstrating how to set up a computation in the presence of dynamical interactions in the charge and longitudinal and transverse spin channels.
from triqs.gf import *
import triqs.utility.mpi as mpi
from triqs_ctseg import Solver
gf_struct = [("up",[0]), ("down",[0])]
S = Solver(beta = 20.0, gf_struct = gf_struct)
#set noninteracting Green's function
mu, eps0, V = 2.0, 0.3, 1.0
S.G0_iw << inverse(iOmega_n + mu - V**2 * inverse(iOmega_n - eps0))
#set dynamical charge and longitudinal spin interactions
w_ch, w_sp = 1.0, 0.8 #screening frequencies
g_ch, g_sp = 0.4, 0.7 #coupling strengths
sigz = lambda s1, s2 : 1 if s1==s2 else -1
import itertools
from triqs.gf.descriptors import Function
for b1, b2 in itertools.product(dict(gf_struct).keys(), repeat=2):
S.D0_iw[b1+"|"+b2] << Function(lambda w : g_ch**2*2*w_ch/(w**2-w_ch**2)\
+ g_sp**2*2*w_sp/(w**2-w_sp**2)*sigz(b1,b2) )
#set transverse spin interaction
S.Jperp_iw << Function(lambda w : 4 * g_sp**2 * 2*w_sp/(w**2-w_sp**2))
from triqs.operators import *
U = 2.0
S.solve(h_int = U * n('up',0)*n('down',0),
n_cycles = 10000, length_cycle = 100, n_warmup_cycles = 100)
from h5 import *
if mpi.is_master_node():
with HDFArchive("dyn_interactions.h5",'w') as A:
A['G_tau'] = S.G_tau
Starting serial run at: 2024-05-14 22:02:50.554936
Traceback (most recent call last):
File "<stdin>", line 25, in <module>
File "/home/build/ctseg/python/triqs_ctseg/solver.py", line 34, in solve
solve_status = SolverCore.solve(self, **kwargs)
RuntimeError: .. Error occurred at Tue May 14 22:02:50 2024
.. Error .. calling C++ overload
.. solve() -> void
.. in implementation of method SolverCore.solve
.. C++ error was :
Triqs runtime error
at /src/ctseg/c++/triqs_ctseg/solver_core.cpp : 216
Error: The Monte-Carlo 'move'-move is currently incompatible with the dynamic spin-spin interaction Jperp
Exception was thrown on node
Let us decompose the various steps:
Import the Solver
class:
from triqs_ctseg import Solver
Declare and construct a Solver
instance:
gf_struct = [("up",[0]), ("down",[0])]
S = Solver(beta = 20.0, gf_struct = gf_struct)
Here, gf_struct
is a Python dictionary that specifies the block structure of the Green’s function, here one \(1\times 1\) ([0]
is of length 1) for each spin (up
, down
).
Some construction parameters are mandatory, others are optional. See here for a complete list.
Initialize the inputs of the solver. In this script, we want to define the noninteracting Green’s function as:
with
In the script, this is done via an accessor called G0_iw
. It is set by the user in the following way:
S.G0_iw << inverse(iOmega_n + mu - V**2 * inverse(iOmega_n - eps0))
Similarly, we want to define dynamical interactions:
This is done through the D0_iw
and Jperp_iw
accessors:
for b1, b2 in itertools.product(dict(gf_struct).keys(), repeat=2):
S.D0_iw[b1+"|"+b2] << Function(lambda w : g_ch**2*2*w_ch/(w**2-w_ch**2)\
+ g_sp**2*2*w_sp/(w**2-w_sp**2)*sigz(b1,b2) )
S.Jperp_iw << Function(lambda w : 4 * g_sp**2 * 2*w_sp/(w**2-w_sp**2))
For a complete list of the accessors (both input and output), see here.
Call the solve()
method:
S.solve(h_int = U * n('up',0)*n('down',0),
n_cycles = 10000, length_cycle = 100, n_warmup_cycles = 100)
h_int
is the local many-body Hamiltonian, it is an operator expression. n_cycles
, length_cycle
and n_warmup_cycles
respectively set the number of configuration measurements, the number of Monte-Carlo updates between two measurements and the number of thermalization cycles.
The fact that Jperp_iw
is nonzero is automatically detected by the code and the corresponding Monte-Carlo updates are turned on.
The solve()
method comes with mandatory and optional parameters, whose complete list can be found here.
To know more about the solver, visit one of the following pages: