# This script's purpose is to demonstrate and explain the following functionalities of the SciPAL SymMps toolkit
# 1. create a spin-1/2 lattice with L=100 Spins
# 1a. create a fully polarized state |\psi> = |\uparrow \cdots \uparrow>
# 1b. create a random near-vacuum state by repeated application of \sum_{i}c_i S^+_i |\downarrow \cdots \downarrow> with random weights c_i
# 2. apply a local perturbation to a state flipping a spin at lattice site i=50
#
# Dependencies:
# none
#
# Input arguments:
# path to compiled SciPAL-SymMps toolkit
# type of created state (full|vacuum)
# Force OMP-/MKL thread numbers to be one otherwise thread spawning will slow down simulations
export OMP_NUM_THREADS=1
export MKL_NUM_THREADS=1
# clear log folder to avoid unnecessary blow-up of output files (each executable will append its output onto an existing output file)
rm log/*.output
# remove already existing lattice files to avoid loading of lattice data which we may not want to have
rm lattice.*
# We exit script if an executable returns with error code
set -eu
# just define a shortcut for the passed location of the toolbox ($1 must only define a path to the folder of the tool-kit containing bin (compiled binaries) and link (symbolic links with some reasonable names), e.g., in any singularity container you may pass /opt/symmps/gnu or /opt/symmps/mkl
EXEC_DIR=$1
# specify type of created state
# TYPE=full : a fully polarized state |\uparrow \cdots \uparrow>
# TYPE=vacuum : a random near-vacuum state by repeated application of \sum_{i}c_i S^+_i |\downarrow \cdots \downarrow> with random weights c_i
TYPE=$2
# create a lattice file containing defining a subspace of tensor-product Hilbert space with the following shortoptions:
# 1. -L defines number of lattice sites, i.e., copies of local Hilbert spaces
# 2. -F defines fundamental datatype of the Hilbert space to be double
# 3. -b defines used basis set, here we choose 'custom' basis set which contains the Spin-Basis, to get more information on any basis set run sym-create-lattice -b -G
# 4. -d defines dimension of the local Hilbert space, we want to describe S=1/2 degrees of freedom thus d=2
# 5. -g defines local symmetry generator which is used to construct the global symmetry generator in this case S^z=\sum_{i=1}^{L}S^z_i, note that only the local operator needs to be specified and since they all share the same representation in each individual local Hilbert space the index 'i' is dropped
# 6. -t defines target-symmetry sector for the global symmetry generator, in this case S^z=0
# 7. -o defines output filename for the created lattice (there is no particular naming convention, however you may want to encode the fundamental datatype in the filename)
case $TYPE in
full)
${EXEC_DIR}/link/sym-create-lattice -L 100 -F d -b custom -d 2 -g Sz -t 50.0 -o lattice.real
;;
vacuum)
${EXEC_DIR}/link/sym-create-lattice -L 100 -F d -b custom -d 2 -g Sz -t 0.0 -o lattice.real
;;
esac
# create a state with the following shortoptions:
# 1. -i defines lattice input file containing Hilbert space and local basis
# 2. -t defines type of created mps, choose 'full' means that all sites are initialized in eigenstate of the local symmetry generators with maximum eigenvalue, i.e., s_i=1/2
# 3. -o defines dest state filename
${EXEC_DIR}/link/sym-create-mps -i lattice.real -t $TYPE -o state.symmps
# apply local perturbation by flipping spin at site i=50 with the following shortoptions:
# 1. -i defines lattice input file containing Hulbert space and local basis
# 2. -S defines input file for source state
# 3. -D defines output file for target state
# 4. -O defines MPO identifier, in case you want to apply an MPO from passed lattice insert MPO-identifier here, we want to apply only a local perturbation which can be done by specifying the local operator and the lattice on which it should act with syntax @, the MPO is then created automatically
# 5. -m defines application method, here we choose variational application method which first performs a warmup sweep and then variationally minimizes the l2-distance to the target state |\psi>
# 6. -n if type is variational this defines the max. number of sweeps during variational optimization towards the target state
# 7. -e if type is variational this defines the escape precision which is given by the change in the l2-norm || |\psi> - |\phi> || between the two last sweeps where |\phi> is the optimized state
# 8. -d defines the maximum discarded weight for the target state
# 9. -w defines the maximum bond dimension of the target state
${EXEC_DIR}/link/sym-apply-mpo -i lattice.real -S state.symmps -D excited.symmps -O 'Sminus@50' -m variational -n 10 -e '1e-12' -d 1e-12 -w 100