def main(PostProcess=False, muvals=50, tvals=50):
    """
    Simulation of an infinite HC dipolar model executed with MPI as data
    parallel simulation.

    **Arguments**

    PostProcess : boolean, optional
        ``False`` means we are running a simulation and so write files and a
        pbs script. ``True`` means we are just postprocessing a simulation,
        and so only generate the internal data we need for extracting
        observables.
    """

    # Build operators
    Operators = mps.BuildBoseOperators(1)

    # Define Hamiltonian MPO
    H = mps.MPO(Operators, PostProcess=PostProcess)
    H.AddMPOTerm('site', 'nbtotal', hparam='mu', weight=-1.0)
    H.AddMPOTerm('bond', ['bdagger', 'b'], hparam='t', weight=-1.0)
    invrcube = lambda x : 1.0 / (x**3)
    H.AddMPOTerm('InfiniteFunction', ['nbtotal','nbtotal'], hparam='U',
                 weight=1.0, func=invrcube, L=1000, tol=1e-9)
    H.printMPO()

    # ground state observables
    myObservables = mps.Observables(Operators)
    # Site terms
    myObservables.AddObservable('site', 'nbtotal', 'n')
    # correlation functions
    myObservables.AddObservable('corr', ['nbtotal', 'nbtotal'], 'nn')
    myObservables.AddObservable('corr', ['bdagger', 'b'], 'spdm')
    # Get correlation functions out to a distance of 1000
    myObservables.SpecifyCorrelationRange(1000)

    # Convergence setup
    bond_dimensions = [12, 16, 20, 32]
    myConv = mps.iMPSConvParam(max_bond_dimension=bond_dimensions[0],
                               variance_tol=-1.0, max_num_imps_iter=1000)
    for ii in range(1, len(bond_dimensions)):
        myConv.AddModifiedConvergenceParameters(0, ['max_bond_dimension',
                                                    'max_num_imps_iter'],
                                                [bond_dimensions[ii], 500])

    L = 2
    U = 1.0
    mumin = 0.5
    mumax = 1.8
    muiter = np.linspace(mumin, mumax, muvals)

    tmin = 0.01
    tmax = 0.4
    titer = np.linspace(tmin, tmax, tvals)

    parameters = []

    for ii in range(muiter.shape[0]):
        mu = muiter[ii]

        for jj in range(titer.shape[0]):
            tt = titer[jj]

            parameters.append({
                'simtype'                   : 'Infinite',
                # Directories
                'job_ID'                    : 'HCDipolar',
                'unique_ID'                 : '_mu%2.4f_t%2.4f'%(mu, tt),
                'Write_Directory'           : 'TMP_09/',
                'Output_Directory'          : 'OUTPUTS_09/',
                # System size and Hamiltonian parameters
                'L'                         : L,
                'U'                         : U,
                'mu' : mu,
                't' : tt,
                #Convergence parameters
                'MPSObservables'            : myObservables,
                'MPSConvergenceParameters'  : myConv,
                'logfile'                   : True
            })

    comp_info = {
        'queueing' : 'slurm',
        'time' : '12:00:00',
        'nodes' : ['128'],
        'mpi' : 'srun',
        'ThisFileName' : os.path.abspath( __file__ )
    }

    MainFiles = mps.WriteMPSParallelFiles(parameters,
                                          Operators, H, comp_info,
                                          PostProcess=PostProcess)

    ## For serial a run as comparison
    # MainFiles = mps.WriteFiles(parameters, Operators, H,
    #                           PostProcess=PostProcess)
    # if(not PostProcess):
    #     if os.path.isfile('./Execute_MPSMain'):
    #         RunDir = './'
    #     else:
    #         RunDir = None
    #     mps.runMPS(MainFiles, RunDir=RunDir)
    #     return

    if(PostProcess):
        # extract observables
        Outputs = mps.ReadStaticObservables(parameters)

        # heading for where postprocessing is to be written
        outputstub = 'HCDOut/' + parameters[0]['job_ID']
        if(not os.path.isdir('./HCDOut')): os.makedirs('./HCDOut')

        scalarfilenames = []
        scalarfile = []
        i = 0

        # create a scalar file and file name for each \chi
        for chi in bond_dimensions:
            scalarfilenames.append(outputstub + 'chi' + str(chi) + 'scalar.dat')
            scalarfile.append(open(scalarfilenames[i], 'w+'))
            i += 1

        for Output in Outputs:
            mu = Output['mu']
            t = Output['t']
            if((Output['mu'] == mu) and (Output['t'] == t)):
                # Simulation metadata
                state = Output['state']
                chi = Output['bond_dimension']
                error_code = Output['error_code']
                Number_of_Ground_States = Output['N_Ground_States']
                of = Output['Orthogonality_Fidelity']
                trunc = Output['Truncation_error']
                tolerance = Output['Fixed_Point_Tolerance']
                converged = Output['converged']
                energy_density = Output['energy_density']
                correlation_length = Output['Correlation_length']

                if(error_code != 0):
                    print('Warning! Parameters ' + str(mu) + ' ' + str(t) + ' '
                          + str(state) + ' ' + str(chi) + ' have error code '
                          + str(error_code))
                if(not converged):
                    print('Warning! Parameters ' + str(mu) + ' ' + str(t) + ' '
                          + str(state) + ' ' + str(chi) + ' did not converge ', of,
                          trunc, tolerance)

                # average density of unit cell
                number = Output['n']
                ucdensity = sum(number) / Output['L']
                print('mu t n', mu, t, number, ucdensity)

                # connected correlation function
                raw_nn = Output['nn']
                nn_connected = []

                for ii in range(len(raw_nn)):
                    nn_connected.append(raw_nn[ii] - 0.0 * ucdensity**2)

                # Single-particle density matrix
                spdm = Output['spdm']

                # Scalar quantities
                if(state == 0):
                    sfile = scalarfile[Output['convergence_parameter'] - 1]
                    sfile.write('%30.15E'%(mu) + '%30.15E'%(t)
                                + '%30.15E'%(ucdensity) + '%30.15E'%(energy_density)
                                + '%30.15E'%(correlation_length)
                                + '%30.15E'%(1.0 * Number_of_Ground_States)
                                + '%30.15E'%(of) + '%30.15E'%(trunc) + '\n')

                # correlation functions
                corrfilename = outputstub + 'mu' + str(mu) + 't' + str(t) \
                               + 'chi' + str(chi) + str(state) + 'corr.dat'
                corrfile = open(corrfilename, 'w')
                for ii in range(1, myObservables.correlation_range):
                    corrfile.write('%16i'%(ii) + '%30.15E'%(nn_connected[ii])
                                   + '%30.15E'%(spdm[ii]) + '\n')
                corrfile.close()

        for ii in range(len(scalarfile)):
            scalarfile[ii].close()
예제 #2
0
import MPSPyLib as mps
import numpy as np
from sys import version_info
import matplotlib.pyplot as plt
import sys

# Build operators
Operators = mps.BuildBoseOperators(5)
Operators['interaction'] = 0.5 * (
    np.dot(Operators['nbtotal'], Operators['nbtotal']) - Operators['nbtotal'])

# Define Hamiltonian MPO
H = mps.MPO(Operators)
H.AddMPOTerm('bond', ['bdagger', 'b'], hparam='t', weight=-1.0)
H.AddMPOTerm('site', 'interaction', hparam='U', weight=1.0)

myObservables = mps.Observables(Operators)
myObservables.AddObservable('site', 'nbtotal', 'n')
myObservables.AddObservable('Lambda', [])

myConv = mps.MPSConvParam(max_bond_dimension=20, max_num_sweeps=6)
myConv.AddModifiedConvergenceParameters(0, ['max_bond_dimension', 'local_tol'],
                                        [50, 1E-14])

myKrylovConv = mps.KrylovConvParam(max_num_lanczos_iter=20, lanczos_tol=1E-6)

dynObservables = mps.Observables(Operators)
dynObservables.AddObservable('site', 'nbtotal', name='n')
dynObservables.AddObservable('Lambda', [])

tau = 10
def main(PostProcess=False, ShowPlots=True):
    """
    Introductory example for openMPS to simulate the finite size dynamics of
    the Bose-Hubbard model with number conservation. Two modes are available
    when running the example from command line:

    * ``python BoseHubbardDynamics.py --PostProcess=F`` : runs the MPSFortLib to
      determine the ground state statics (initial state) and then the dynamics.
      (default if ``--PostProcess`` not present.)
    * ``python BoseHubbardDynamics.py --PostProcess=T`` : plotting the results
      of the simulation run before.
    * The option ``--ShowPlots=T`` (``--ShowPlots=F``) lets you turn on (off)
      the GUI windows with the plots. Default to on if not passed to the
      command line.
    """

    # Build operators
    Operators = mps.BuildBoseOperators(5)
    Operators['interaction'] = 0.5 * (np.dot(
        Operators['nbtotal'], Operators['nbtotal']) - Operators['nbtotal'])

    # Define Hamiltonian MPO
    H = mps.MPO(Operators)
    H.AddMPOTerm('bond', ['bdagger', 'b'], hparam='t', weight=-1.0)
    H.AddMPOTerm('site', 'interaction', hparam='U', weight=1.0)

    # Ground state observables
    myObservables = mps.Observables(Operators)
    # Site terms
    myObservables.AddObservable('site', 'nbtotal', 'n')
    # Correlation functions
    myObservables.AddObservable('corr', ['nbtotal', 'nbtotal'], 'nn')
    myObservables.AddObservable('corr', ['bdagger', 'b'], 'spdm')

    # Convergence parameters
    myConv = mps.MPSConvParam(max_bond_dimension=20, max_num_sweeps=6)
    myConv.AddModifiedConvergenceParameters(
        0, ['max_bond_dimension', 'local_tol'], [50, 1E-14])

    myDynConv = mps.TDVPConvParam(max_num_lanczos_iter=20, lanczos_tol=1E-6)

    # Dynamics time evolution observables
    dynObservables = mps.Observables(Operators)
    # Site terms
    dynObservables.AddObservable('site', 'nbtotal', name='n')

    # Specify constants and parameter lists
    U = 10.0
    t = 1.0
    staticsParameters = []
    L = 6
    tlist = [5.0, 20.0]

    for tau in tlist:
        # Quench function ramping down
        def Ufuncdown(t, tau=tau):
            return 10.0 + 2.0 * (1.0 - 10.0) * t / tau

        # Quench function ramping back up
        def Ufuncup(t, tau=tau):
            return 1.0 + 2.0 * (10.0 - 1.0) * (t - 0.5 * tau) / tau

        Quenches = mps.QuenchList(H)
        Quenches.AddQuench(['U'],
                           0.5 * tau,
                           min(0.5 * tau / 100.0, 0.1), [Ufuncdown],
                           ConvergenceParameters=myDynConv)
        Quenches.AddQuench(['U'],
                           0.5 * tau,
                           min(0.5 * tau / 100.0, 0.1), [Ufuncup],
                           ConvergenceParameters=myDynConv)

        staticsParameters.append({
            'simtype': 'Finite',
            # Directories
            'job_ID': 'Bose_Hubbard_mod',
            'unique_ID': 'tau_' + str(tau),
            'Write_Directory': 'TMP_03/',
            'Output_Directory': 'OUTPUTS_03/',
            # System size and Hamiltonian parameters
            'L': L,
            't': t,
            'U': U,
            # Specification of symmetries and good quantum numbers
            'Abelian_generators': ['nbtotal'],
            'Abelian_quantum_numbers': [L],
            # Convergence parameters
            'verbose': 1,
            'logfile': True,
            'MPSObservables': myObservables,
            'MPSConvergenceParameters': myConv,
            'Quenches': Quenches,
            'DynamicsObservables': dynObservables
        })

    # Write Fortran-readable main files
    MainFiles = mps.WriteFiles(staticsParameters,
                               Operators,
                               H,
                               PostProcess=PostProcess)

    # Run the simulations and quit if not just post processing
    if (not PostProcess):
        if os.path.isfile('./Execute_MPSMain'):
            RunDir = './'
        else:
            RunDir = None
        mps.runMPS(MainFiles, RunDir=RunDir)
        return

    # Postprocessing and plotting
    # ---------------------------

    Outputs = mps.ReadStaticObservables(staticsParameters)
    DynOutputs = mps.ReadDynamicObservables(staticsParameters)

    ii = 0
    le_list = [[], []]

    for t in tlist:
        myfile = 'outmod' + str(t) + '.dat'
        hfile = open(myfile, 'w')
        for p in DynOutputs[ii]:
            hfile.write('%30.15E' % (p['time']) + '%30.15E' % (p['U']) +
                        '%30.15E' % (p['Loschmidt_Echo'].real) + '%30.15E' %
                        (p['Loschmidt_Echo'].imag) + '%30.15E' %
                        (p['bond_dimension']) + '\n')
            le_list[ii].append(abs(p['Loschmidt_Echo'])**2)

        hfile.close()
        ii += 1

    plt.rc('font', family='serif')
    plt.rc('mathtext', fontset='cm')
    plt.plot(np.linspace(0, 1, len(le_list[0])),
             le_list[0],
             'r-',
             label="tq=5")
    plt.plot(np.linspace(0, 1, len(le_list[1])),
             le_list[1],
             'g-',
             label="tq=20")
    plt.xlabel(r"Time in percent " r"$t / t_q$", fontsize=16)
    plt.ylabel(r"Loschmidt Echo "
               r"$| \langle \psi(t) | \psi(0) \rangle |^2$",
               fontsize=16)
    plt.legend(loc="lower left")
    if (ShowPlots):
        plt.savefig('03_BoseHubbardDynamics.pdf', bbox_inches='tight')
        plt.show()

    return
def simulate(L, ExpName, PostProcess=False, ShowPlot=True):
    """
    PostProcess = False:
        Runs the MPSFortLib to simulate the finite size statics of the BoseHubbard model
        using number conservation
    PostProcess = True:
        Obtain the simulated results from the already run simulation
    """

    # Build operators
    Operators = mps.BuildBoseOperators(6)
    Operators['interaction'] = 0.5 * (np.dot(
        Operators['nbtotal'], Operators['nbtotal']) - Operators['nbtotal'])
    # Define Hamiltonian of transverse Ising model
    H = mps.MPO(Operators)
    H.AddMPOTerm('bond', ['bdagger', 'b'], hparam='t', weight=-1.0)
    H.AddMPOTerm('site', 'interaction', hparam='U', weight=1.0)
    #H.AddMPOTerm('bond', ['nbtotal', 'nbtotal'], hparam='V', weight=1.0)

    # ground state observables
    myObservables = mps.Observables(Operators)
    # site terms
    myObservables.AddObservable('site', 'nbtotal', name='n')
    #myObservables.AddObservable('DensityMatrix_i', [])
    #myObservables.AddObservable('DensityMatrix_ij', [])
    myObservables.AddObservable('MI', True)
    myConv = mps.MPSConvParam(max_bond_dimension=200,
                              variance_tol=1E-8,
                              local_tol=1E-8,
                              max_num_sweeps=7)
    #modparam = ['max_bond_dimension', 'max_num_sweeps']
    #myConv.AddModifiedConvergenceParameters(0, modparam, [80, 4])

    # Specify constants and parameter lists
    U = 1.0
    tlist = np.linspace(0.02, 1.00, 50)
    #tlist = np.linspace(0.01, 0.41, 41)
    #tlist = np.linspace(0.1, 0.4, 5)
    parameters = []
    N = L

    for t in tlist:
        parameters.append({
            'simtype':
            'Finite',
            # Directories
            'job_ID':
            'Bose_Hubbard_Statics',
            'unique_ID':
            't_' + str(t) + 'N_' + str(N),
            'Write_Directory':
            '{}/TMP_BoseHubbard_L_{}/'.format(ExpName, L),
            'Output_Directory':
            '{}/OUTPUTS_BoseHubbard_L_{}/'.format(ExpName, L),
            # System size and Hamiltonian parameters
            'L':
            L,
            't':
            t,
            'U':
            U,
            # Specification of symmetries and good quantum numbers
            'Abelian_generators': ['nbtotal'],
            # Define filling
            'Abelian_quantum_numbers': [N],
            # Convergence parameters
            'verbose':
            1,
            'logfile':
            True,
            'MPSObservables':
            myObservables,
            'MPSConvergenceParameters':
            myConv
        })

    # Write Fortran-readable main files
    MainFiles = mps.WriteFiles(parameters,
                               Operators,
                               H,
                               PostProcess=PostProcess)

    # Run the simulations and quit if we are not just Post
    if (not PostProcess):
        if os.path.isfile('./Execute_MPSMain'):
            RunDir = './'
        else:
            RunDir = None
        mps.runMPS(MainFiles, RunDir=RunDir)
        return None, tlist

    # PostProcess
    # -----------
    MI_list = []
    Outputs = mps.ReadStaticObservables(parameters)
    M = int(L / 2)
    for Output in Outputs:
        print(Output['converged'])
        MI_list.append(Output['MI'][3][M])

    timestamp = int(time.time() * 1000.0)
    if ShowPlot:
        plt.style.use('seaborn-colorblind')
        #plt.style.use('seaborn-whitegrid')
        plt.rc('font', family='serif')
        plt.rc('mathtext', fontset='cm')
        plt.scatter(tlist, MI_list)
        plt.xlabel(r"Tunneling " r"$J/U$", fontsize=16)
        plt.ylabel(r"Mutual information (4,L/2+1)", fontsize=16)
        plt.savefig('{}/BoseHubbard_MI_L_{}_{}.pdf'.format(
            exp_name, L, timestamp),
                    bbox_inches='tight')
        plt.show()

    return Outputs, tlist
def main(PostProcess=False, ShowPlots=True):
    """
    Introductory example for openMPS to simulate the finite size statics of
    the Bose-Hubbard model using number conservation. Two modes are available
    when running the example from command line:

    * ``python BoseHubbardStatics.py --PostProcess=F`` : runs the MPSFortLib to
      determine the ground state statics (initial state) and then the dynamics.
      (default if ``--PostProcess`` not present.)
    * ``python BoseHubbardStatics.py --PostProcess=T`` : plotting the results
      of the simulation run before.
    * The option ``--ShowPlots=T`` (``--ShowPlots=F``) lets you turn on (off)
      the GUI windows with the plots. Default to on if not passed to the
      command line.
    """
    # Cannot use time.clock as it does not capture subprocesses
    t0 = time()

    # Build operators
    Operators = mps.BuildBoseOperators(6)
    Operators['interaction'] = 0.5 * (np.dot(
        Operators['nbtotal'], Operators['nbtotal']) - Operators['nbtotal'])
    # Define Hamiltonian MPO
    H = mps.MPO(Operators)
    H.AddMPOTerm('bond', ['bdagger', 'b'], hparam='t', weight=-1.0)
    H.AddMPOTerm('site', 'interaction', hparam='U', weight=1.0)

    # ground state observables
    myObservables = mps.Observables(Operators)
    # Site terms
    myObservables.AddObservable('site', 'nbtotal', 'n')
    # correlation functions
    myObservables.AddObservable('corr', ['nbtotal', 'nbtotal'], 'nn')
    myObservables.AddObservable('corr', ['bdagger', 'b'], 'spdm')

    myConv = mps.MPSConvParam(max_num_sweeps=7)

    U = 1.0
    tlist = np.linspace(0, 0.4, 21)
    parameters = []
    L = 10
    Nlist = np.linspace(1, 11, 11)

    for t in tlist:
        for N in Nlist:
            parameters.append({
                'simtype': 'Finite',
                # Directories
                'job_ID': 'Bose_Hubbard_statics',
                'unique_ID': 't_' + str(t) + 'N_' + str(N),
                'Write_Directory': 'TMP_02/',
                'Output_Directory': 'OUTPUTS_02/',
                # System size and Hamiltonian parameters
                'L': L,
                't': t,
                'U': U,
                # Specification of symmetries and good quantum numbers
                'Abelian_generators': ['nbtotal'],
                # Define Filling
                'Abelian_quantum_numbers': [N],
                # Convergence parameters
                'verbose': 1,
                'logfile': True,
                'MPSObservables': myObservables,
                'MPSConvergenceParameters': myConv
            })

    # Write Fortran-readable main files
    MainFiles = mps.WriteFiles(parameters,
                               Operators,
                               H,
                               PostProcess=PostProcess)
    # Run the simulations and quit if we are not just Post
    if (not PostProcess):
        if os.path.isfile('./Execute_MPSMain'):
            RunDir = './'
        else:
            RunDir = None
        mps.runMPS(MainFiles, RunDir=RunDir)
        return

    # Postprocessing and plotting
    # ---------------------------

    Outputs = mps.ReadStaticObservables(parameters)

    depletion = np.zeros((Nlist.shape[0], tlist.shape[0]))
    energies = np.zeros((Nlist.shape[0], tlist.shape[0]))
    tinternal = np.zeros((Nlist.shape[0], tlist.shape[0]))
    chempotmu = np.zeros((Nlist.shape[0], tlist.shape[0]))

    kk = -1
    for ii in range(tlist.shape[0]):
        tinternal[:, ii] = tlist[ii]

        for jj in range(Nlist.shape[0]):
            kk += 1

            spdm = np.linalg.eigh(Outputs[kk]['spdm'])[0]
            depletion[jj, ii] = 1.0 - np.max(spdm) / np.sum(spdm)

            energies[jj, ii] = Outputs[kk]['energy']

        chempotmu[0, ii] = energies[0, ii]
        chempotmu[1:, ii] = energies[1:, ii] - energies[:-1, ii]

    if (ShowPlots):
        plotIt(tinternal, chempotmu, depletion)

    return