# Some basic questions on DMRG

**URL:** <https://itensor.discourse.group/t/some-basic-questions-on-dmrg/2044>\
**Category:** DMRG and Numerical Methods\
**Tags:** dmrg\
**Created:** [October 8, 2024, 11:29am UTC](https://itensor.discourse.group/t/some-basic-questions-on-dmrg/2044 "2024-10-08T11:29:38Z")\
**Posts on this page:** 1\
**Showing post:** 2

<div class="post-metadata">

**Author:** ![sandipanmanna](https://avatars.discourse-cdn.com/v4/letter/s/ee7513/32.png) [@sandipanmanna](https://itensor.discourse.group/u/sandipanmanna)\
**Post date:** [October 12, 2024, 8:19am UTC](https://itensor.discourse.group/t/some-basic-questions-on-dmrg/2044/2 "2024-10-12T08:19:11Z")

</div>

Hi! Thanks for posting. ITensor DMRG backend has an observer object to handle exactly the situation like yours. You can refer to this section ([Observer System for DMRG](https://itensor.github.io/ITensors.jl/stable/Observer.html#observer)) in documentation. Your can also refer to the past discussion [here](https://itensor.discourse.group/t/how-to-save-mps-data-during-the-dmrg-calculation/949/1).

1. You can just create a new observer object to achieve the same. Pass this object to the inbuilt DMRG routine. Here is a MWE for storing the output to a file called dmrg\_output.txt.

```auto
mutable struct DemoObserver <: AbstractObserver
  energy_tol::Float64
  last_energy::Float64
  output_file::String
  DemoObserver(energy_tol=0.0, output_file="dmrg_output.txt") = new(energy_tol, 1000.0, output_file)
end

function ITensors.checkdone!(o::DemoObserver; kwargs...)
 sw = kwargs[:sweep]
 energy = kwargs[:energy]
 if abs(energy-o.last_energy)/abs(energy) < o.energy_tol
   println("Stopping DMRG after sweep $sw")
   return true
 end
 # Otherwise, update last_energy and keep going
 o.last_energy = energy
 return false
end

function ITensors.measure!(o::DemoObserver; kwargs...)
 energy = kwargs[:energy]
 sweep = kwargs[:sweep]
 bond = kwargs[:bond]
 outputlevel = kwargs[:outputlevel]
 
 # Write to file
 open(o.output_file, "a") do f
   write(f, "Sweep $sweep, Energy $energy\n")
 end
 
 if outputlevel > 0
   println("Sweep $sweep at bond $bond, the energy is $energy")
 end
end

```

This is adapted from the linked documentation. Notice the new memeber attribute, output\_file in DemoObserver class.

1. Yeah, you can suppress terminal output by providing outputlevel=0 in the DMRG keyword argument. Here is a driver code for the same. This uses the DemoObserver object to store the output to a file.

```auto
let
   N = 10
   etol = 1E-4
 
   s = siteinds("S=1/2",N)
 
   a = OpSum()
   for n=1:N-1
     a += "Sz",n,"Sz",n+1
     a += 0.5,"S+",n,"S-",n+1
     a += 0.5,"S-",n,"S+",n+1
   end
   H = MPO(a,s)
   psi0 = random_mps(s;linkdims=4)
 
   nsweeps = 5
   cutoff = 1E-8
   maxdim = [10,20,100]
 
   obs = DemoObserver(etol)
 
   energy, psi = dmrg(H,psi0; nsweeps, cutoff, maxdim, observer=obs, outputlevel=0)
 
   return
 end

```

1. I guess this depends on the Hamiltonian (spectrum gap). In my experience, I have obtained upto 4 excited states reliably. The degeneracy in spectrum may also affect the calculations. Obtaining excited states may require significantly more DMRG sweeps than the ground states.

---

_[View the full topic](https://itensor.discourse.group/t/some-basic-questions-on-dmrg/2044)._
