Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
a12ae38
Switch for Langevin proposal and function for calculating force
Jan 15, 2025
0c3b65a
Proposal with Langevin equation for local moves
Jan 15, 2025
a2a4ba2
Merge branch 'master' into 305-proposal-of-updates-with-langevin-equa…
Apr 16, 2025
380815d
First version of Langevin proposal on one time slice
Apr 17, 2025
12227d0
Warning message if fields are not type 3
Apr 22, 2025
f2db2d8
Global Metropolis-adjusted Langevin algorithm (MALA)
Apr 25, 2025
cf13f54
Same format for global_tau and global_langevin_tau
Apr 28, 2025
1bed453
Choice of the fields in the Global_MALA
Apr 29, 2025
b72cbca
Single S0 instead of the whole thing
Apr 29, 2025
6229b8e
Variable renaming
Apr 29, 2025
227489d
Override functions Include N_Global_Langevin_tau
Apr 30, 2025
dce7e11
Bug in Wrapgr_Langevin_update; phase not updated
May 14, 2025
49acb4d
Global MALA: don't check precision before move is acceptec or rejected
May 22, 2025
b5962a7
Draft version of table with updating schemes
May 23, 2025
86f8fdb
Control forces and max force for global MALA
Jun 2, 2025
9019de4
Control forces and max force for global tau MALA
Jun 3, 2025
f345af8
Control forces and max force for sequential MALA
Jun 3, 2025
aebf65e
check forces before and after update
Jul 18, 2025
63693fc
Merge branch 'master' into 305-proposal-of-updates-with-langevin-equa…
Jul 21, 2025
87f98e6
Merge branch 'master' into 305-proposal-of-updates-with-langevin-equa…
Oct 7, 2025
e28ab3d
Update doc.pdf
Oct 14, 2025
a103ab8
Update
Oct 30, 2025
7a8a58f
base implementation of Ham_Langevin_HMC_S0_single
Oct 30, 2025
69f6aef
Handle non type 3 fields for Global tau MALA updates
Nov 3, 2025
08fe884
Merge branch 'master' into 305-proposal-of-updates-with-langevin-equa…
Nov 3, 2025
1cdbc91
Update
Nov 5, 2025
eb7d66e
Merge branch 'master' into 305-proposal-of-updates-with-langevin-equa…
Nov 5, 2025
a180e0b
Merge branch 'master' into 305-proposal-of-updates-with-langevin-equa…
Nov 5, 2025
ca76770
Update
Nov 5, 2025
4362739
Update
Nov 5, 2025
680df87
Update doc.pdf
Nov 5, 2025
9b196a3
Merge branch 'master' into 305-proposal-of-updates-with-langevin-equa…
fassaad Feb 5, 2026
27ead59
CLeaned up issue when only Mala_global_tau and no sequential move…
fassaad Feb 5, 2026
467053b
Worked on Documentation
fassaad Feb 8, 2026
1cd8972
WWorking on doc
fassaad Feb 8, 2026
e8fd3e1
Working on doc for Updating
fassaad Feb 8, 2026
e4a9dbb
Update
fassaad Feb 9, 2026
6a6d3f7
Worked on the documentation.
fassaad Feb 9, 2026
d6f1e9d
Merge branch 'master' into 305-proposal-of-updates-with-langevin-equa…
fassaad Feb 21, 2026
2c05d25
Merge branch 'master' into 305-proposal-of-updates-with-langevin-equa…
fassaad Mar 25, 2026
55a5ead
Worked on the documentation, and added code snipets for Langevin ah…
fassaad Mar 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions Documentation/Doc.idx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
\indexentry{\texttt{Checkerboard}}{28}
\indexentry{\texttt{Symm}}{30}
\indexentry{\texttt{Symm}}{30}
\indexentry{\texttt{Symm}}{31}
\indexentry{\texttt{Precision Green} }{33}
\indexentry{\texttt{Precision Phase}}{33}
\indexentry{\path{NWrap}}{33}
\indexentry{\texttt{Square} }{83}
\indexentry{\path{Bilayer_square}}{84}
\indexentry{\path{N_leg_ladder}}{84}
\indexentry{\path{Honeycomb}}{84}
\indexentry{\texttt{Bilayer\_honeycomb}}{84}
\indexentry{\texttt{Triangular}}{85}
\indexentry{\texttt{Kagome}}{85}
Binary file added Documentation/doc.pdf

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I'm not mistaken, we planed to clean the doc.pdf outside of the repo and use artefacts of the pipeline on the website. @jonasschwab is this still the case?

Binary file not shown.
15 changes: 15 additions & 0 deletions Documentation/hmc.tex
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,18 @@ \subsubsection{Hybrid Monte dynamics} \label{sec:hmc}

To test the code, we have carried out high precision calculations of the 6-sites Hubbard chain with open boundary conditions (see Sec.~\ref{sec:langevin}) at $\beta t = 4$. Using \textit{only} hybrid molecular dynamics updates we obtain: $ \langle \hat{H} \rangle = -2.81715 \pm 0.00023 $. This compares very well with the discrete field sequential updating run: $ \langle \hat{H} \rangle = -2.81706 \pm 0.00013 $.

Specifically to start the above HMC run, the user again has to define the subroutine \texttt{Ham\_Langevin\_HMC\_S0} in the base Hamiltonian module that computes the derivative of the bosonic part action with respect to the fields
and in the parameter file chose the option:
\begin{lstlisting}[style=fortran]
&VAR_QMC

......
Sequential = .F. ! Sequential moves
......
Delta_t_Langevin_HMC = 0.5 ! Default time step for Langevin and HMC updates.
N_HMC_sweeps = 1 ! # of HMC updates between sequential ones
Leapfrog_steps = 100 ! Number of leapfrog iterations
......
/
\end{lstlisting}
For this parameter choice, since \texttt{Sequential = .F.}, the code will carry out only hybrid molecular dynamics updates. The user can of course choose to carry out both sequential and hybrid molecular dynamics updates by setting \texttt{Sequential = .T.} and choosing a finite value for \texttt{N\_HMC\_sweeps}. It is also interesting to note that HMC time step can be chosen much larger than for the Langevin dynamics. The Langevin integrator suffers from systematic errors in the time step whereas the HMC integrator does not.
19 changes: 19 additions & 0 deletions Documentation/langevin.tex
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,25 @@ \subsubsection*{Example - Hubbard chain at half-filling}

Controlling Langevin dynamics when the action has logarithmic divergences is a challenge, and it is not a given that the results are satisfactory. For our specific problem we can solve this issue by considering open boundary conditions. Following an argument put forward in \cite{Assaad07}, we can show, using world lines, that the determinant is always positive. In this case the action does not have logarithmic divergences and the Langevin dynamics works beautifully well, see Fig.~\ref{Langevin.fig}.

Practically to start the Langevin dynamic run the user will have to provide the function
\begin{lstlisting}[style=fortran]
Subroutine Ham_Langevin_HMC_S0(Forces_0)
Real (Kind=Kind(0.d0)), Intent(inout), allocatable :: Forces_0(:,:)
! Forces_0(n,nt) = \frac{\partial S_0}{\partial s_{n,\tau}}.
! Here n is the index of the field in the operator list and nt is the time slice.
End Subroutine Ham_Langevin_HMC_S0
\end{lstlisting}
and in the parameter file chose the option:
\begin{lstlisting}[style=fortran]
&VAR_QMC
......
Langevin = .T. ! Langevin update
Delta_t_Langevin_HMC = 0.01 ! Default time step for Langevin and HMC updates.
Max_Force = 5.0 ! Max Force for Langevin
......
/
\end{lstlisting}

\begin{figure}[H]
\begin{center}
\includegraphics[scale=0.9,clip]{Langevin.pdf}
Expand Down
272 changes: 250 additions & 22 deletions Documentation/updating.tex

Large diffs are not rendered by default.

137 changes: 133 additions & 4 deletions Prog/Hamiltonian_main_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -149,13 +149,16 @@ Module Hamiltonian_main
procedure, nopass :: Pr_obs => Pr_obs_base
procedure, nopass :: Init_obs => Init_obs_base
procedure, nopass :: Global_move_tau => Global_move_tau_base
procedure, nopass :: Global_MALA_move_tau => Global_MALA_move_tau_base
procedure, nopass :: Hamiltonian_set_nsigma => Hamiltonian_set_nsigma_base
procedure, nopass :: Overide_global_tau_sampling_parameters => Overide_global_tau_sampling_parameters_base
procedure, nopass :: Global_move => Global_move_base
procedure, nopass :: Global_MALA_move => Global_MALA_move_base
procedure, nopass :: Delta_S0_global => Delta_S0_global_base
procedure, nopass :: Get_Delta_S0_global => Get_Delta_S0_global_base
procedure, nopass :: S0 => S0_base
procedure, nopass :: Ham_Langevin_HMC_S0 => Ham_Langevin_HMC_S0_base
procedure, nopass :: Ham_Langevin_HMC_S0_single => Ham_Langevin_HMC_S0_single_base
procedure, nopass :: weight_reconstruction => weight_reconstruction_base
procedure, nopass :: GR_reconstruction => GR_reconstruction_base
procedure, nopass :: GRT_reconstruction => GRT_reconstruction_base
Expand Down Expand Up @@ -626,6 +629,94 @@ Subroutine Global_move_tau_base(T0_Proposal_ratio, S0_ratio, &
CALL Terminate_on_error(ERROR_HAMILTONIAN,__FILE__,__LINE__)
end Subroutine Global_move_tau_base

!--------------------------------------------------------------------
!> @author
!> ALF Collaboration
!>
!> @brief
!> Specify a global langevin move on a given time slice tau.
!>
!> @details
!> @param[in] ntau Integer
!> \verbatim
!> Time slice
!> \endverbatim
!> @param[out] Flip_length Integer
!> \verbatim
!> Number of flips stored in the first Flip_length entries of the array Flip_values.
!> Has to be smaller than NDIM
!> \endverbatim
!> @param[out] Flip_list Integer(Ndim)
!> \verbatim
!> List of spins to be flipped: nsigma%f(Flip_list(1),ntau) ... nsigma%f(Flip_list(Flip_Length),ntau)
!> Note that Ndim = size(Op_V,1)
!> \endverbatim
!--------------------------------------------------------------------
Subroutine Global_MALA_move_tau_base(Flip_list, Flip_length,ntau)

Implicit none
Integer , INTENT(OUT) :: Flip_list(:)
Integer, INTENT(OUT) :: Flip_length
Integer, INTENT(IN) :: ntau

Logical, save :: first_call=.True.
integer :: n

Flip_length = size(flip_list,1)
do n = 1, Flip_length
flip_list(n) = n
enddo

If (first_call) then
write(output_unit,*)
write(output_unit,*) "ATTENTION: Base implementation of Global_MALA_move_tau is being called!"
write(output_unit,*) "All fields of type 3 will be updated in the global tau MALA moves."
write(output_unit,*) "Suppressing further printouts of this message."
write(output_unit,*)
first_call=.false.
endif

end Subroutine Global_MALA_move_tau_base

!--------------------------------------------------------------------
!> @author
!> ALF Collaboration
!>
!> @brief
!> Specify a global Metropolis-adjusted langevin move.
!>
!> @details
!> @param[out] Flip_length Integer
!> \verbatim
!> Number of flips stored in the first Flip_length entries of the array Flip_values.
!> Has to be smaller than NDIM*Ltrot
!> \endverbatim
!> @param[out] Flip_list Integer(Ndim,Ltrot)
!> \verbatim
!> List of spins to be flipped: nsigma%f(Flip_list(1,1),Flip_list(1,2)) ... nsigma%f(Flip_list(Flip_Length,1),Flip_list(Flip_Length,2))
!> Note that Ndim = size(Op_V,1)
!> \endverbatim
!--------------------------------------------------------------------
Subroutine Global_MALA_move_base(Flip_list)

Implicit none
Integer , INTENT(OUT) :: Flip_list(:,:)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flip list essentially tags a field to be updated via MALA moves if the entry is set to 1, correct? Wouldn't it be better turning this into a logical array? And change the name to something like perform_MALA or MALA_tag or enable_MALA?


Logical, save :: first_call=.True.

If (first_call) then
write(output_unit,*)
write(output_unit,*) "ATTENTION: Base implementation of Global_MALA_move is being called!"
write(output_unit,*) "All fields of type 3 will be updated in the global MALA moves."
write(output_unit,*) "Suppressing further printouts of this message."
write(output_unit,*)
first_call=.false.
endif

Flip_list = 1

end Subroutine Global_MALA_move_base

!--------------------------------------------------------------------
!> @author
!> ALF Collaboration
Expand Down Expand Up @@ -665,10 +756,11 @@ end Subroutine Hamiltonian_set_nsigma_base
!> @details
!> \endverbatim
!--------------------------------------------------------------------
Subroutine Overide_global_tau_sampling_parameters_base(Nt_sequential_start,Nt_sequential_end,N_Global_tau)
Subroutine Overide_global_tau_sampling_parameters_base(Nt_sequential_start,Nt_sequential_end, &
& N_Global_tau, N_Global_tau_MALA)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can probably remove this override sampling function now and use the new QMC variables functionality and set those variables according to the model parameters in the hamiltonian directly.


Implicit none
Integer, Intent(INOUT) :: Nt_sequential_start,Nt_sequential_end, N_Global_tau
Integer, Intent(INOUT) :: Nt_sequential_start,Nt_sequential_end, N_Global_tau, N_Global_tau_MALA

!!$ write(output_unit,*)
!!$ write(output_unit,*) "ATTENTION: Base implementation of Overide_global_tau_sampling_parameters is getting calling!"
Expand Down Expand Up @@ -698,9 +790,9 @@ Subroutine Ham_Langevin_HMC_S0_base(Forces_0)

if (first_call) then
write(output_unit,*)
write(output_unit,*) "ATTENTION: Base implementation of Ham_Langevin_HMC_S0 is getting calling!"
write(output_unit,*) "ATTENTION: Base implementation of Ham_Langevin_HMC_S0 is being called!"
write(output_unit,*) "This assumes trivial S0 action and is likely incorrect!"
write(output_unit,*) "Consider overwritting this routine according to the model in your Hamiltonian."
write(output_unit,*) "Consider overwriting this routine according to the model in your Hamiltonian."
write(output_unit,*) "Suppressing further printouts of this message."
write(output_unit,*)
first_call=.False.
Expand All @@ -709,6 +801,43 @@ Subroutine Ham_Langevin_HMC_S0_base(Forces_0)

end Subroutine Ham_Langevin_HMC_S0_base

!--------------------------------------------------------------------
!> @author
!> ALF Collaboration
!>
!> @brief
!> Forces_0(n,nt) = \partial S_0 / \partial s(n,nt) are calculated and returned to main program.
!>
!-------------------------------------------------------------------
Subroutine Ham_Langevin_HMC_S0_single_base(Force_0,n,nt)

Implicit none

Real (Kind=Kind(0.d0)), Intent(inout) :: Force_0
integer , intent(in) :: n, nt

logical, save :: first_call=.True.
real (kind=kind(0.d0)), allocatable :: forces_0(:,:)

allocate(forces_0(size(nsigma%f,1),size(nsigma%f,2)))
call ham%Ham_Langevin_HMC_S0(Forces_0)
force_0 = forces_0(n,nt)

if (first_call) then
write(output_unit,*)
write(output_unit,*) "ATTENTION: Base implementation of Ham_Langevin_HMC_S0_single is being called!"
write(output_unit,*) "This uses the subroutine Ham_Langevin_HMC_S0, which provides all bosonic forces."
write(output_unit,*) "Since Ham_Langevin_HMC_S0_single only requires one force this might be inefficient."
write(output_unit,*) "Consider overwriting this routine according to the model in your Hamiltonian."
write(output_unit,*) "Suppressing further printouts of this message."
write(output_unit,*)
first_call=.False.
endif

deallocate(forces_0)

end Subroutine Ham_Langevin_HMC_S0_single_base

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assumed S0(phi) = 1/2 phi^2, which is dangerous and likely incorrect as the warning message states. Now I'm thinking it would be better to flip the logic around, i.e., HMC_S0_base builds all forces_0 out of the single version, accompanied by an inefficiency warning asking the user to override it.
Here, it's probably best to terminate and given an error message instead of assuming the simplest gaussian form of S0.


!--------------------------------------------------------------------
!> @author
Expand Down
132 changes: 130 additions & 2 deletions Prog/Hamiltonians/Hamiltonian_Hubbard_smod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@
procedure, nopass :: S0
procedure, nopass :: Ham_Langevin_HMC_S0
procedure, nopass :: Get_Delta_S0_global
procedure, nopass :: Global_move_tau
procedure, nopass :: Overide_global_tau_sampling_parameters
procedure, nopass :: Global_move
#ifdef HDF5
procedure, nopass :: write_parameters_hdf5
#endif
Expand Down Expand Up @@ -960,5 +963,130 @@ Real (Kind=kind(0.d0)) Function Get_Delta_S0_global(Nsigma_old)
! S0 = exp( (-Hs_new**2 + nsigma%f(n,nt)**2 ) /2.d0 )

end Function Get_Delta_S0_global

end submodule ham_Hubbard_smod

!--------------------------------------------------------------------
!> @author
!> ALF Collaboration
!>
!> @brief
!> Specify a global move on a given time slice tau.
!>
!> @details
!> @param[in] ntau Integer
!> \verbatim
!> Time slice
!> \endverbatim
!> @param[out] T0_Proposal_ratio, Real
!> \verbatim
!> T0_Proposal_ratio = T0( sigma_new -> sigma ) / T0( sigma -> sigma_new)
!> \endverbatim
!> @param[out] S0_ratio, Real
!> \verbatim
!> S0_ratio = e^( S_0(sigma_new) ) / e^( S_0(sigma) )
!> \endverbatim
!> @param[out] Flip_length Integer
!> \verbatim
!> Number of flips stored in the first Flip_length entries of the array Flip_values.
!> Has to be smaller than NDIM
!> \endverbatim
!> @param[out] Flip_list Integer(Ndim)
!> \verbatim
!> List of spins to be flipped: nsigma%f(Flip_list(1),ntau) ... nsigma%f(Flip_list(Flip_Length),ntau)
!> Note that Ndim = size(Op_V,1)
!> \endverbatim
!> @param[out] Flip_value Real(Ndim)
!> \verbatim
!> Flip_value(:)= nsigma%flip(Flip_list(:),ntau)
!> Note that Ndim = size(Op_V,1)
!> \endverbatim
!--------------------------------------------------------------------
Subroutine Global_move_tau(T0_Proposal_ratio, S0_ratio, &
& Flip_list, Flip_length,Flip_value,ntau)

Implicit none
Real (Kind = Kind(0.d0)), INTENT(OUT) :: T0_Proposal_ratio, S0_ratio
Integer , INTENT(OUT) :: Flip_list(:)
Complex (Kind = Kind(0.d0)),INTENT(OUT) :: Flip_value(:)
Integer, INTENT(OUT) :: Flip_length
Integer, INTENT(IN) :: ntau

If (.not.Continuous) then
Write(6,*) "Error: Global_move_tau_base is implemented only continuous HS fields. Please implement it or set Continuous = False in the input file. "
CALL Terminate_on_error(ERROR_HAMILTONIAN,__FILE__,__LINE__)
endif
Flip_length = 1
Flip_list(1) = nranf(Size(Op_V,1))
Flip_value(1) = nsigma%flip(Flip_list(1),ntau)
T0_Proposal_ratio = 1.d0
S0_ratio = S0(Flip_list(1),ntau,Flip_value(1))


end Subroutine Global_move_tau

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this relate to MALA moves?


!--------------------------------------------------------------------
!> @author
!> ALF Collaboration
!>
!> @brief
!> This routine allows to user to determine the global_tau sampling parameters at run time
!> It is especially usefull if these parameters are dependent on other parameters.
!>
!> @details
!> \endverbatim
!--------------------------------------------------------------------
Subroutine Overide_global_tau_sampling_parameters(Nt_sequential_start,Nt_sequential_end, &
& N_Global_tau, N_Global_tau_MALA)

Implicit none
Integer, Intent(INOUT) :: Nt_sequential_start,Nt_sequential_end, N_Global_tau, N_Global_tau_MALA

N_Global_tau = Size(Op_V,1)

end Subroutine Overide_global_tau_sampling_parameters

!--------------------------------------------------------------------
!> @author
!> ALF Collaboration
!>
!> @brief
!> Global moves
!>
!> @details
!> This routine generates a
!> global update and returns the propability T0_Proposal_ratio = T0( sigma_out-> sigma_in ) / T0( sigma_in -> sigma_out)
!> @param [IN] nsigma_old, Type(Fields)
!> \verbatim
!> Old configuration. The new configuration is stored in nsigma.
!> \endverbatim
!> @param [OUT] T0_Proposal_ratio Real
!> \verbatimam
!> T0_Proposal_ratio = T0( sigma_new -> sigma_old ) / T0( sigma_old -> sigma_new)
!> \endverbatim
!> @param [OUT] Size_clust Real
!> \verbatim
!> Size of cluster that will be flipped.
!> \endverbatim
!-------------------------------------------------------------------
Subroutine Global_move(T0_Proposal_ratio, nsigma_old, size_clust)

Implicit none
Real (Kind=Kind(0.d0)), intent(out) :: T0_Proposal_ratio, size_clust
Type (Fields), Intent(IN) :: nsigma_old

Integer :: nt, n

If (.not.Continuous) then
Write(6,*) "Error: Global_move_tau_base is implemented only continuous HS fields. Please implement it or set Continuous = False in the input file. "
CALL Terminate_on_error(ERROR_HAMILTONIAN,__FILE__,__LINE__)
endif
size_clust = Ltrot
n = nranf(Size(Op_V,1))
do nt = 1,Ltrot
nsigma%f(n,nt) = -nsigma_old%f(n,nt)
enddo
T0_Proposal_ratio = 1


End Subroutine Global_move

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the relation between those global moves and MALA updates?


end submodule ham_Hubbard_smod
4 changes: 2 additions & 2 deletions Prog/Hamiltonians/Hamiltonian_LRC_smod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -823,10 +823,10 @@ end Subroutine Global_move_tau
!> @details
!> \endverbatim
!--------------------------------------------------------------------
Subroutine Overide_global_tau_sampling_parameters(Nt_sequential_start,Nt_sequential_end,N_Global_tau)
Subroutine Overide_global_tau_sampling_parameters(Nt_sequential_start,Nt_sequential_end,N_Global_tau, N_Global_tau_MALA)

Implicit none
Integer, Intent(INOUT) :: Nt_sequential_start,Nt_sequential_end, N_Global_tau
Integer, Intent(INOUT) :: Nt_sequential_start,Nt_sequential_end, N_Global_tau, N_Global_tau_MALA

If ( str_to_upper(Model) == "LRC" ) then
Nt_sequential_start = 1
Expand Down
Loading
Loading